Add a composable ratatui TUI to ppvm-cli#166
Open
david-pl wants to merge 20 commits into
Open
Conversation
Unified single-screen TUI for `ppvm-cli`: bare `ppvm` launches a REPL + step-debugger on one screen (program listing, tableau state via state_string(), measurement record, command line). New `crates/ppvm-tui` lib holds terminal-agnostic `Widget` components + AppState; `ppvm-cli` owns only the terminal and event loop. Deps pinned to ratatui/crossterm 0.29 to match stellarscope so panels can dock together later. PauliSum REPL backend deferred. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fold gdb-style breakpoint injection into the design: at a breakpoint, typed gate ops update the tableau/record and stepping resumes where it paused. Requires one small engine change in ppvm-vihaco — a pc/code-preserving injection method (save pc + code len, run the op, truncate the appended op, restore pc). Removes the corresponding deferred item from scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Seven TDD tasks: engine pc-preserving injection (ppvm-vihaco); scaffold ppvm-tui + CodeView; command grammar; AppState REPL dispatch + key handling; program loading/stepping/breakpoint injection; ratatui widgets + composer; ppvm-cli wiring (optional subcommand launches the TUI). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Save/restore the program counter and code-vector length around execute_single_instruction so a paused debugger's position is byte-for-byte unchanged after injecting a gate at a breakpoint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…path The previous implementation used `?` after execute_single_instruction, which skipped the truncate + pc restore when the call returned Err, leaving leaked appended ops and a wrong pc in the loaded program. Now the restore runs unconditionally via a local `result` binding. Also adds a test (apply_circuit_instruction_preserves_pc_and_code_on_error) that exercises the error path and asserts both invariants hold. Separately, moves the #[cfg(test)] mod tests block in ppvm-cli/src/main.rs to after fn main() to fix the clippy::items_after_test_module lint under --all-targets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a movable edit cursor (Left/Right/Home/End, insert/Backspace/Delete at the cursor) rendered via the terminal's own cursor (Frame::set_cursor_position, offset past the shared CommandLine::PROMPT), and Up/Down command history over submitted lines with an in-progress draft stash and consecutive-duplicate skipping. All hand-rolled, no new dependency, unit-tested without a terminal plus a TestBackend cursor placement check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`:help` (aliases `:h`, `:?`) toggles a floating, centered overlay listing the meta/debug commands and the full gate grammar. Implemented as a render-time overlay driven by a `show_help` flag, so it works in both REPL and debug modes without touching the key-handling model or the composability contract. `:help` is also surfaced in the footer hint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
…ack on gate injection Two state-leak fixes surfaced in review of the TUI: - `new_device` now clears `self.module`, so switching to a REPL device forgets any previously loaded program. Otherwise `:reset` resurrected the old program instead of resetting the fresh device. - `apply_circuit_instruction` now restores the CPU operand stack depth on every path, alongside the existing pc/code restore. `circuit.measure` / `circuit.trace` push a result onto the stack for bytecode to consume, and an errored gate can leave its consts behind; with no consumer during an injected gate, a stray operand would desync a resumed program's stack and grow a REPL session's stack without bound. The measurement record (a separate observer effect) is unaffected, so the REPL's `=> bits` echo still works. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`ppvm-tui` pulls in ratatui/crossterm, which target native terminals and don't compile for wasm32-unknown-unknown (crossterm's `sys` module has no browser-wasm backend). Exclude it from the browser-wasm workspace build alongside `ppvm-cli` and `ppvm-python-native`; the reusable engine stays covered via the library crates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a composable ratatui TUI to
ppvm-cli. Bareppvmlaunches a unified single-screen REPL + step-debugger;ppvm <file>opens a program paused at the first instruction. The existingrun/dump/parse/debugsubcommands are unchanged.crates/ppvm-tuiholds the terminal-agnostic pieces: anAppStateowning appvm_vihaco::composite::PPVM, the command grammar, and four ratatuiWidgetview components (Program/State/Measurement-record/Command line).ppvm-cli(bin) owns only terminal setup (RAII restore on panic) and the blocking event loop.impl Widget for &…View-style;handle_key(KeyEvent) -> bool), and deps are pinned toratatui/crossterm0.29.0to matchstellarscopeso panels can dock together later.Features
device Nthen gate ops (h 0,cnot 0 1,rx 0 0.5,measure 0, …); outcomes echo as=> bits.:load, Enter = step,:c= continue to next breakpoint/end,:reset; authoredbreakpoints pause.apply_circuit_instructionpreserve the program counter (ppvm-vihaco).:helptoggles a command-reference overlay (works in both modes).Base branch
Targets
david/42-circuit-component(notmain) — this branch was cut from it and depends on itsvihaco-circuit-isawork. The merge commit here also pulls in that branch'sAdd back eyrefix (a pre-existing derive-macro build breakage), so the branch compiles.Design docs
docs/superpowers/specs/2026-07-01-cli-tui-design.mddocs/superpowers/plans/2026-07-01-cli-tui.mdTesting
cargo test --workspace— green (0 failures).ppvm-tui: 36 tests (command grammar, REPL/debug state transitions, breakpoint injection resume, cursor/history editing, help toggle,TestBackendrender checks).clippy --all-targetsclean.Built TDD, task-by-task, with per-task + whole-branch review.
Draft: opened for review before it's ready to merge.
🤖 Generated with Claude Code