Skip to content

test: add 163 tests for tui and ui-core crates#388

Merged
simonrw merged 7 commits intomainfrom
test/tui-crate-testing
Apr 5, 2026
Merged

test: add 163 tests for tui and ui-core crates#388
simonrw merged 7 commits intomainfrom
test/tui-crate-testing

Conversation

@simonrw
Copy link
Copy Markdown
Owner

@simonrw simonrw commented Apr 4, 2026

Summary

Add comprehensive test coverage for the tui and ui-core crates, going from zero tests to 163 tests covering state logic, input handling, syntax highlighting, UI rendering snapshots, event draining, and breakpoint persistence.

Context

The TUI crate had no tests at all, making it risky to refactor or extend. The crate has a clean layered architecture (state, input, rendering, session) that lends itself well to unit testing. This PR implements the full testing plan across all layers.

Changes

Test infrastructure

  • with_test_app(closure) / with_test_app_configs() helpers that manage TempDir lifetime automatically
  • mock_session() and make_program_state() helpers for creating test sessions with dummy AsyncBridge
  • AsyncBridge::dummy() test constructor in ui-core (behind testing feature flag) for mock bridges without a real debugger
  • Session::new_for_test() constructor for bypassing the real DAP connection
  • render_to_string() helper using ratatui TestBackend for deterministic UI snapshots

Test coverage by layer

Layer Module Tests What's covered
Pure state ui-core::code_view 16 Cursor movement, scroll, selection ranges
Pure state ui-core::file_cache 6 Insert/get/load/clear
Pure state ui-core::session_state 14 State machine transitions
Pure state ui-core::file_picker 9 Cursor navigation, select, refilter
App state tui::app 22 Focus cycling, open_file, breakpoints, REPL history
Input tui::input 36 All key bindings across all modes and focus panes
Syntax tui::syntax 16 Highlighting, build_lines (gutter, markers, search, annotations)
UI rendering tui::ui::snapshot_tests 10 Full-layout insta snapshots for all major UI states
Integration tui::app (event draining) 11 All debugger event types through drain_debugger_events
Integration tui::app (persistence) 2 Breakpoint persist/restore round-trip
Total 163

UI snapshot tests

Uses insta with ratatui's TestBackend for visual regression testing. Snapshots cover: no-session (empty, with configs, with file), running, terminated, help overlay, error status bar, output tab, REPL tab, and breakpoints panel. All snapshots are deterministic (file browser is pre-loaded to prevent reading real git files).

Testing

# Run all tests
cargo test -p tui -p ui-core

# Run just snapshot tests
cargo test -p tui -- snapshot

# Review snapshot changes after UI modifications
cargo insta review

Summary by CodeRabbit

Release Notes

  • Tests

    • Expanded comprehensive test coverage across core functionality to strengthen reliability and catch potential regressions
  • Chores

    • Added testing infrastructure and development dependencies
    • Enhanced remote debugger attachment process with status messages for improved visibility during setup

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 4, 2026

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

This pull request introduces comprehensive test infrastructure and test utilities across the tui and ui-core crates, adding test-only constructors, helper modules, and extensive unit test suites covering app state management, user input handling, syntax highlighting, code view navigation, file caching, and UI rendering.

Changes

Cohort / File(s) Summary
Cargo manifest test dependencies
crates/tui/Cargo.toml, crates/ui-core/Cargo.toml
Added dev-dependencies (tempfile, insta) and introduced a testing feature flag in ui-core for test-only conditional code.
App and session test utilities
crates/tui/src/app.rs, crates/tui/src/session.rs, crates/ui-core/src/async_bridge.rs
Added test-only constructor functions (Session::new_for_test, AsyncBridge::dummy) and comprehensive test helper module (test_helpers) providing builders for App, StateManager, temporary files, mock sessions, and debugger state objects; included test suites validating focus cycling, file operations, breakpoint CRUD, REPL history, debugger event handling, and breakpoint persistence.
Input and UI rendering tests
crates/tui/src/input.rs, crates/tui/src/ui/mod.rs
Added extensive input handling tests covering key event dispatching across all modes/focuses (quitting, help, search, navigation, config cycling, breakpoint toggling, REPL history, output scrolling); added snapshot tests for complete UI layouts using insta baselines.
Core library test modules
crates/ui-core/src/code_view.rs, crates/ui-core/src/file_cache.rs, crates/ui-core/src/file_picker.rs, crates/ui-core/src/session_state.rs, crates/tui/src/syntax.rs
Added test suites for CodeViewState (file operations, cursor movement, scroll visibility, selection); FileCache (get/load/insert/clear semantics); FilePickerState (navigation, filtering, selection); SessionState (state transitions, boolean helpers); SyntaxHighlighter (line highlighting, checkpoint caching, line building with gutter/cursor/breakpoint/selection/evaluation annotations).
Integration test updates
attach.py, crates/debugger/tests/debugger.rs
Updated attach.py to emit DAP server listening status message to stderr; modified test_remote_attach to actively wait for this signal instead of using fixed sleep, and updated breakpoint assertion from line 9 to line 11.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Poem

🐰 A warren of tests now stands tall,
From app to syntax, we cover all,
Mock sessions hop, snapshots align,
Each helper builds confidence line by line,
The code hops forward, more certain and bright!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarises the primary change: adding 163 tests to the tui and ui-core crates. It is specific, descriptive, and accurately reflects the main changeset focus.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/tui-crate-testing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
.mcp.json (1)

3-4: Avoid committing machine-specific MCP endpoint configuration

Line 4 hardcodes a localhost port, which is likely environment-specific and brittle for other contributors. Consider using a local-only config (gitignored) or environment-variable substitution, and keep a checked-in example file for discoverability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.mcp.json around lines 3 - 4, The checked-in .mcp.json contains a hardcoded
machine-specific URL at the forge_extension.url key; replace this with a
non-committed, environment-driven configuration: remove the literal
"http://localhost:39263/mcp" from .mcp.json and instead reference an environment
placeholder or leave the value empty in the committed file (e.g. a placeholder
like {MCP_URL}), add a gitignored local override (e.g. .mcp.local.json) that
developers can populate with their localhost URL, and add a checked-in example
file (e.g. .mcp.example.json) showing how to set forge_extension.url and
documenting the use of an env var (MCP_URL) so runtime code reads
process.env.MCP_URL or a config loader that merges .mcp.local.json.
crates/tui/src/ui/mod.rs (1)

137-162: Consider extracting common setup logic to reduce duplication.

render_to_string and render_to_string_with_configs share nearly identical setup and teardown code. Extracting the common parts into a shared builder or helper would reduce maintenance burden.

♻️ Suggested refactor
+    fn make_test_app(configs: Vec<LaunchConfiguration>, config_names: Vec<String>) -> (tempfile::TempDir, App) {
+        let dir = tempfile::tempdir().expect("tempdir");
+        let state_path = dir.path().join("state.json");
+        let state_manager = state::StateManager::new(&state_path).expect("StateManager");
+        let (wakeup_tx, _) = crossbeam_channel::unbounded();
+
+        let mut app = crate::app::App::new(
+            configs,
+            config_names,
+            0,
+            std::path::PathBuf::from("/tmp/test"),
+            std::path::PathBuf::from("/tmp/test"),
+            state_manager,
+            wakeup_tx,
+            vec![],
+        );
+        app.file_browser_loaded = true;
+        (dir, app)
+    }
+
     fn render_to_string(width: u16, height: u16, f: impl FnOnce(&mut App)) -> String {
-        let dir = tempfile::tempdir().expect("tempdir");
-        let state_path = dir.path().join("state.json");
-        let state_manager = state::StateManager::new(&state_path).expect("StateManager");
-        let (wakeup_tx, _) = crossbeam_channel::unbounded();
-
-        let mut app = crate::app::App::new(
-            vec![],
-            vec![],
-            0,
-            std::path::PathBuf::from("/tmp/test"),
-            std::path::PathBuf::from("/tmp/test"),
-            state_manager,
-            wakeup_tx,
-            vec![],
-        );
-        app.file_browser_loaded = true;
-
+        let (_dir, mut app) = make_test_app(vec![], vec![]);
         f(&mut app);
-
         let backend = TestBackend::new(width, height);
         let mut terminal = Terminal::new(backend).unwrap();
         terminal.draw(|frame| render(&mut app, frame)).unwrap();
         terminal.backend().to_string()
     }

Also applies to: 165-208

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/tui/src/ui/mod.rs` around lines 137 - 162, The two helpers
render_to_string and render_to_string_with_configs duplicate tempdir/state
setup, wakeup channel creation, App construction (crate::app::App::new and
app.file_browser_loaded = true), and TestBackend/Terminal drawing; extract that
common setup into a single helper (e.g., build_test_app or TestAppBuilder) that
takes width/height and any optional config args and returns the ready-to-use App
and a function or TestBackend/Terminal pair for rendering; update
render_to_string and render_to_string_with_configs to call this helper and only
apply their specific changes (invoke the passed closure f, any extra config
handling, and the terminal.draw/render call), keeping references to
state::StateManager, TestBackend, Terminal, and wakeup_tx so callers still
operate on the same objects.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/ui-core/src/file_cache.rs`:
- Around line 72-75: The test get_or_load_returns_none_for_missing_file
currently uses a hard-coded Path::new("/nonexistent/file.py"); change it to
create a temporary directory (e.g., with tempfile::tempdir()), construct a path
inside that tempdir that you do not create (e.g.,
temp_dir.path().join("nonexistent.py")), and pass that path to
FileCache::get_or_load so the missing-file assertion is portable across
platforms and environments.

---

Nitpick comments:
In @.mcp.json:
- Around line 3-4: The checked-in .mcp.json contains a hardcoded
machine-specific URL at the forge_extension.url key; replace this with a
non-committed, environment-driven configuration: remove the literal
"http://localhost:39263/mcp" from .mcp.json and instead reference an environment
placeholder or leave the value empty in the committed file (e.g. a placeholder
like {MCP_URL}), add a gitignored local override (e.g. .mcp.local.json) that
developers can populate with their localhost URL, and add a checked-in example
file (e.g. .mcp.example.json) showing how to set forge_extension.url and
documenting the use of an env var (MCP_URL) so runtime code reads
process.env.MCP_URL or a config loader that merges .mcp.local.json.

In `@crates/tui/src/ui/mod.rs`:
- Around line 137-162: The two helpers render_to_string and
render_to_string_with_configs duplicate tempdir/state setup, wakeup channel
creation, App construction (crate::app::App::new and app.file_browser_loaded =
true), and TestBackend/Terminal drawing; extract that common setup into a single
helper (e.g., build_test_app or TestAppBuilder) that takes width/height and any
optional config args and returns the ready-to-use App and a function or
TestBackend/Terminal pair for rendering; update render_to_string and
render_to_string_with_configs to call this helper and only apply their specific
changes (invoke the passed closure f, any extra config handling, and the
terminal.draw/render call), keeping references to state::StateManager,
TestBackend, Terminal, and wakeup_tx so callers still operate on the same
objects.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9c487afa-88b0-42db-ab6d-05d5b1ecd15d

📥 Commits

Reviewing files that changed from the base of the PR and between f0131c9 and f9a5f49.

⛔ Files ignored due to path filters (11)
  • Cargo.lock is excluded by !**/*.lock
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__breakpoints_in_running_mode.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__help_overlay.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__no_session_empty.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__no_session_with_configs.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__no_session_with_file.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__output_tab_with_lines.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__repl_tab.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__running_mode.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__status_bar_with_error.snap is excluded by !**/*.snap
  • crates/tui/src/ui/snapshots/tui__ui__snapshot_tests__terminated_mode.snap is excluded by !**/*.snap
📒 Files selected for processing (14)
  • .config/wt.toml.new
  • .mcp.json
  • crates/tui/Cargo.toml
  • crates/tui/src/app.rs
  • crates/tui/src/input.rs
  • crates/tui/src/session.rs
  • crates/tui/src/syntax.rs
  • crates/tui/src/ui/mod.rs
  • crates/ui-core/Cargo.toml
  • crates/ui-core/src/async_bridge.rs
  • crates/ui-core/src/code_view.rs
  • crates/ui-core/src/file_cache.rs
  • crates/ui-core/src/file_picker.rs
  • crates/ui-core/src/session_state.rs

Comment on lines +72 to +75
fn get_or_load_returns_none_for_missing_file() {
let mut cache = FileCache::default();
let result = cache.get_or_load(Path::new("/nonexistent/file.py"));
assert_eq!(result, None);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use a tempdir-based missing path to keep this test portable.

Line 74 hard-codes /nonexistent/file.py; using a guaranteed-missing path inside a temp directory is more robust across environments.

💡 Suggested tweak
     #[test]
     fn get_or_load_returns_none_for_missing_file() {
         let mut cache = FileCache::default();
-        let result = cache.get_or_load(Path::new("/nonexistent/file.py"));
+        let dir = tempfile::tempdir().unwrap();
+        let missing = dir.path().join("missing.py");
+        let result = cache.get_or_load(&missing);
         assert_eq!(result, None);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/ui-core/src/file_cache.rs` around lines 72 - 75, The test
get_or_load_returns_none_for_missing_file currently uses a hard-coded
Path::new("/nonexistent/file.py"); change it to create a temporary directory
(e.g., with tempfile::tempdir()), construct a path inside that tempdir that you
do not create (e.g., temp_dir.path().join("nonexistent.py")), and pass that path
to FileCache::get_or_load so the missing-file assertion is portable across
platforms and environments.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/debugger/tests/debugger.rs`:
- Line 151: The test sets breakpoint_line to a non-executable line (10, the "def
foo()" declaration) which won't hit in attach mode; change the breakpoint_line
constant in the test (breakpoint_line) from 10 to 11 so the breakpoint targets
the first executable statement inside foo (the print("Foo") line) to ensure the
debugger receives Paused instead of Ended.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a7eb41f-939d-443f-b1c7-2de69af68807

📥 Commits

Reviewing files that changed from the base of the PR and between f9a5f49 and 0449649.

📒 Files selected for processing (2)
  • attach.py
  • crates/debugger/tests/debugger.rs

Comment thread crates/debugger/tests/debugger.rs Outdated
simonrw added 6 commits April 5, 2026 09:37
Phase 2 & 3 of the TUI testing plan:

- Add test infrastructure: with_test_app(closure) helper that manages
  TempDir lifetime, with_test_app_configs for config cycling tests,
  write_temp_file for disk-backed test fixtures
- Add 22 app state tests: Focus cycling, open_file (load/reset/nonexistent),
  file content caching, breakpoint toggle/add/remove, REPL history
  navigation, start session error, evaluate popup, word under cursor
- Add 36 input handling tests: global keys (q, Ctrl+C, ?, Esc), focus
  cycling (Tab/BackTab/Shift+Tab), bottom tabs (Alt+1/2/3), Ctrl+P/F,
  config cycling with wrap, code view navigation (j/k/g/G/Ctrl+D/U),
  breakpoint toggle (b), visual selection (v), search mode, file picker
  mode, breakpoint input mode, breakpoint panel, REPL focus, output
  focus, evaluate popup, inline eval clear, F5 no-session
Phase 4: Tests for SyntaxHighlighter covering:

- highlight_lines: no syntax (unstyled), Python (styled spans), range
  slicing, empty content, range clamping beyond content
- Checkpoint caching: set_file clears checkpoints, re-highlighting
  reuses cached checkpoints
- build_lines: gutter line numbers, cursor line background, breakpoint
  marker, execution line marker with background, visual selection
  background, inline evaluation annotations (green for values, red
  for errors), search match highlighting with span splitting,
  start_line offset for gutter numbering
Phase 5: Snapshot tests using ratatui TestBackend + insta.

Snapshots cover all major UI states:
- no_session_empty: File browser with no files, no file open
- no_session_with_configs: Config selector (h/l cycling) visible
- no_session_with_file: Code view with Python file loaded
- running_mode: Running state with call stack/breakpoints sidebar
- terminated_mode: Terminated state with restart controls
- help_overlay: Help popup over the normal UI
- status_bar_with_error: Error message displayed in status bar
- output_tab_with_lines: Output panel with stdout/stderr/console
- repl_tab: REPL tab with history and input
- breakpoints_in_running_mode: Breakpoints panel with entries

Test infrastructure:
- render_to_string() and render_to_string_with_configs() helpers
  create deterministic App instances with file_browser_loaded=true
  to prevent reading real git files
- Uses write_temp_file() from app::test_helpers for file content
- All snapshots are deterministic across machines
Phase 7 & 8: Integration tests for drain_debugger_events and
breakpoint persistence.

Infrastructure:
- Add AsyncBridge::dummy() test constructor to ui-core (behind
  testing feature flag) for creating mock bridges without a real
  debugger connection
- Add Session::new_for_test() constructor for creating test sessions
- Add mock_session() and make_program_state() test helpers
- Add 'testing' feature to ui-core crate

Event draining tests (11):
- Paused event: sets mode, updates breakpoints, clears caches,
  jumps cursor to execution line
- Running event: sets mode, clears inline evaluations
- Ended event: sets Terminated mode
- Initialised event: sets Running mode
- Output events: appends to output_lines
- Thread started/exited: adds/removes from threads list
- Error event: sets status_error
- ScopeChange event: clears variable cache, jumps cursor
- No session: drain is a no-op
- Multiple events: processes all in sequence

Breakpoint persistence tests (2):
- persist_and_restore_breakpoints: round-trip through StateManager
- collect_all_breakpoints_merges_ui_and_persisted: verifies merge
  of UI breakpoints with previously persisted ones
…n test_remote_attach

The test_remote_attach test was failing in CI with 'Connection refused'
(os error 111) because it used a fixed 1-second sleep to wait for the
Python debugpy process to start listening. On slower CI runners, this
was insufficient.

Fix:
- Add a readiness marker ('DAP server listening') to attach.py that is
  printed to stderr immediately after debugpy.listen() succeeds
- Replace the naive sleep in the test with a stderr reader thread that
  waits for this marker, matching the pattern used by the server crate's
  wait_for_ready() function
- Update breakpoint line number (9 -> 10) to account for the added
  import line in attach.py
Two fixes for CI failures:

1. Update breakpoint_line from 10 to 11 in test_remote_attach to match
   the actual line of print("Foo") in attach.py after ruff-format
   added blank lines between top-level definitions.

2. Bump tempfile minimum version from "3" to "3.23.0" in ui-core and
   tui dev-dependencies to match the debugger crate's requirement,
   fixing the minimal-versions CI job which was failing because
   tempfile 3.0.2 conflicts with tempfile 3.23.0.
@simonrw simonrw force-pushed the test/tui-crate-testing branch from f84a5e0 to b09a7e2 Compare April 5, 2026 08:37
@simonrw simonrw enabled auto-merge (squash) April 5, 2026 08:38
@simonrw simonrw merged commit c9ae709 into main Apr 5, 2026
14 of 16 checks passed
@simonrw simonrw deleted the test/tui-crate-testing branch April 5, 2026 08:39
@github-actions github-actions bot mentioned this pull request Apr 5, 2026
simonrw pushed a commit that referenced this pull request Apr 6, 2026
## 🤖 New release

* `dap-gui-async-transport`: 0.1.0
* `dap-gui-types`: 0.1.0
* `dap-gui-launch-configuration`: 0.1.0
* `dap-gui-server`: 0.1.0
* `dap-gui-debugger`: 0.1.0
* `dap-gui-fuzzy`: 0.1.0
* `dap-gui-state`: 0.1.0
* `dap-gui-ui-core`: 0.1.0
* `dap-gui-egui`: 0.1.0
* `dap-gui-pcaplog`: 0.1.0
* `dap-tui`: 0.1.0

<details><summary><i><b>Changelog</b></i></summary><p>

## `dap-gui-async-transport`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-async-transport-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Move bytes to workspace dependency to fix minimal-versions CI
- Rename transport2 crate to async-transport
</blockquote>

## `dap-gui-types`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-types-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Add documentation to dap-types crate from DAP specification
- Replace hand-written DAP types in transport with auto-generated
dap-types
- fmt
- Add dap-types crate
</blockquote>

## `dap-gui-launch-configuration`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-launch-configuration-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Merge file browser into main app's no-session view
- Add GUI launch controls: start, stop, and restart debug sessions
- Remove transport crate, sync debugger, and repl crate
- Fix cargo fmt formatting across 7 files
- Robustness improvements for startup procedure
- Add more tests
- Add 30-second timeout for DAP request responses
([#355](#355))
- Create crates/ subdir
</blockquote>

## `dap-gui-server`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-server-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Remove transport crate, sync debugger, and repl crate
- Fix cargo fmt formatting across 7 files
- Robustness improvements for startup procedure
- Add 30-second timeout for DAP request responses
([#355](#355))
- Use mise and fix test issues
- Create crates/ subdir
</blockquote>

## `dap-gui-debugger`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-debugger-v0.1.0)
- 2026-04-05

### Added

- add Event::Error variant to surface background task failures

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))
- start DAP sequence numbers at 1 instead of 0
- replace panic with error propagation in stopped event handler

### Other

- add version fields to path dependencies for release-plz compatibility
- add 163 tests for tui and ui-core crates
([#388](#388))
- scaffold TUI crate with ratatui (Phase 1)
- surface Output and Thread events from DAP
- add missing unit tests for error paths and scope changes
- move command-name mapping into RequestBody and simplify argument
serialisation
- extract send_and_expect_success helper to eliminate boilerplate
- gate testing module behind cfg to exclude from release builds
- Deduplicate DAP session initialization with SessionArgs/StartMode
enums
- Add file:line breakpoint input for remote attach workflows
([#386](#386))
- Rename transport2 crate to async-transport
- Remove transport crate, sync debugger, and repl crate
- Replace hand-written DAP types in transport with auto-generated
dap-types
- Move tokio to workspace dependency to fix minimal-versions CI
- Add 5 GUI improvements: breakpoints, variable tree, syntax
highlighting, async migration, error handling
- Fix cargo fmt formatting across 7 files
- Robustness improvements for startup procedure
- Add more tests
- Fix minimal versions
- Error handling for bad responses
- Shortly hold lock
- Try to get implementation working
- Integrate launch configuration and staged debugger initialization
- Fix clippy lints
- Complete debugger transport integration phases
([#383](#383))
- Clean out old POC crates
- Add testing infrastructure for async debugger (Phase 5)
([#382](#382))
- Implement transport2 integration phases 1 and 2
([#381](#381))
- Add integration plan for debugger + transport2
([#380](#380))
- Fix try_poll_message to handle partial reads across timeouts
([#378](#378))
- Add infrastructure for non-blocking request handling
([#375](#375))
- Add refactoring plan for message receiving architecture
([#374](#374))
- Switch debugger to use TransportConnection instead of Client
([#372](#372))
- Migrate to latest iced version
([#373](#373))
- Refactor debugger background thread to use command pattern
([#371](#371))
- Add Command infrastructure for background thread communication
([#370](#370))
- Add non-blocking event processing foundation
([#367](#367))
- Fix stack frame handling panics in Stopped event
([#362](#362))
- Fix home directory panic in path normalization
([#364](#364))
- Fix runaway background thread termination
([#361](#361))
- Fix race condition in test_remote_attach event handling
([#365](#365))
- Fix poisoned mutex panic in with_internals
([#363](#363))
- Fix panic in Drop implementation
([#360](#360))
- Add 30-second timeout for DAP request responses
([#355](#355))
- Ensure launch program exists
- Use mise and fix test issues
- Create crates/ subdir
</blockquote>

## `dap-gui-fuzzy`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-fuzzy-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Extract fuzzy crate and add file picker to egui GUI
</blockquote>

## `dap-gui-state`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-state-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- no-session polish and robustness (Phase 5)
- Add Lilex font for code view with Cmd+/- font size shortcuts
- fmt
- Persist breakpoints to disk when modified via gutter clicks
- Add more tests
- Create crates/ subdir
</blockquote>

## `dap-gui-ui-core`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-ui-core-v0.1.0)
- 2026-04-05

### Added

- make config_path optional, defaulting to .vscode/launch.json
- add user-facing documentation to CLI argument parser
([#390](#390))

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- add 163 tests for tui and ui-core crates
([#388](#388))
- extract shared ui-core crate from gui and tui
([#387](#387))
</blockquote>

## `dap-gui-egui`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-egui-v0.1.0)
- 2026-04-05

### Added

- add Event::Error variant to surface background task failures

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- extract shared ui-core crate from gui and tui
([#387](#387))
- surface Output and Thread events from DAP
- Deduplicate DAP session initialization with SessionArgs/StartMode
enums
- Add always-visible text search to no-session code viewer
- Merge file browser into main app's no-session view
- Add Cmd+F / Ctrl+F text search in code view
- Add GUI launch controls: start, stop, and restart debug sessions
- Add Lilex font for code view with Cmd+/- font size shortcuts
- Add file-picker startup mode when no breakpoints provided
- Add file:line breakpoint input for remote attach workflows
([#386](#386))
- Rename transport2 crate to async-transport
- Remove transport crate, sync debugger, and repl crate
- Persist breakpoints to disk when modified via gutter clicks
- fmt
- Move tokio to workspace dependency to fix minimal-versions CI
- Fix breakpoint rendering
- Canonicalize all paths early to fix breakpoint gutter display
- Make code window fill full width of the code panel
- Fix breakpoint toggle: persist UI breakpoints across frames and match
by path+line
- Fix code panel scroll stability: use viewport height and only scroll
when needed
- Fix debug server lifetime: keep server handle alive for app duration
- Move CentralPanel into renderer and add status messages for empty
states
- Add 5 GUI improvements: breakpoints, variable tree, syntax
highlighting, async migration, error handling
- Fix cargo fmt formatting across 7 files
- Extract fuzzy crate and add file picker to egui GUI
- Robustness improvements for startup procedure
- Fix variable parsing
- Update controls
- Migrate to latest iced version
([#373](#373))
- Bump versions
- Formatting
- Create crates/ subdir
</blockquote>

## `dap-gui-pcaplog`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-pcaplog-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- Move bytes to workspace dependency to fix minimal-versions CI
- Rename transport2 crate to async-transport
- Remove transport crate, sync debugger, and repl crate
- Use mise and fix test issues
- Create crates/ subdir
</blockquote>

## `dap-tui`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-tui-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- rename main crate to dap-tui again
- add version fields to path dependencies for release-plz compatibility
- set up release pipeline with release-plz and GitHub Actions
([#389](#389))
- add zen mode to maximize code view
- add 163 tests for tui and ui-core crates
([#388](#388))
- extract shared ui-core crate from gui and tui
([#387](#387))
- add inline evaluation annotations in code view (Phase C)
- add visual line selection in code view (Phase B)
- add Ctrl+E evaluate expression popup (Phase A)
- remove modal REPL input, type directly when focused
- no-session polish and robustness (Phase 5)
- interactive breakpoints, REPL, and variable tree (Phase 4)
- connect to debugger and hit breakpoints (Phase 3)
- file browsing with syntax highlighting (Phase 2)
- scaffold TUI crate with ratatui (Phase 1)
- Clean out old POC crates
- Create crates/ subdir
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions github-actions bot mentioned this pull request Apr 6, 2026
simonrw pushed a commit that referenced this pull request Apr 6, 2026
## 🤖 New release

* `dap-gui-async-transport`: 0.1.0
* `dap-gui-config`: 0.1.0
* `dap-gui-types`: 0.1.0
* `dap-gui-launch-configuration`: 0.1.0
* `dap-gui-server`: 0.1.0
* `dap-gui-debugger`: 0.1.0
* `dap-gui-fuzzy`: 0.1.0
* `dap-gui-state`: 0.1.0
* `dap-gui-ui-core`: 0.1.0
* `dap-gui-egui`: 0.1.0
* `dap-gui-pcaplog`: 0.1.0
* `dap-tui`: 0.1.0

<details><summary><i><b>Changelog</b></i></summary><p>

## `dap-gui-async-transport`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-async-transport-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Move bytes to workspace dependency to fix minimal-versions CI
- Rename transport2 crate to async-transport
</blockquote>

## `dap-gui-config`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-config-v0.1.0)
- 2026-04-06

### Added

- add configurable keybindings with TOML config file
([#393](#393))
</blockquote>

## `dap-gui-types`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-types-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Add documentation to dap-types crate from DAP specification
- Replace hand-written DAP types in transport with auto-generated
dap-types
- fmt
- Add dap-types crate
</blockquote>

## `dap-gui-launch-configuration`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-launch-configuration-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Merge file browser into main app's no-session view
- Add GUI launch controls: start, stop, and restart debug sessions
- Remove transport crate, sync debugger, and repl crate
- Fix cargo fmt formatting across 7 files
- Robustness improvements for startup procedure
- Add more tests
- Add 30-second timeout for DAP request responses
([#355](#355))
- Create crates/ subdir
</blockquote>

## `dap-gui-server`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-server-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Remove transport crate, sync debugger, and repl crate
- Fix cargo fmt formatting across 7 files
- Robustness improvements for startup procedure
- Add 30-second timeout for DAP request responses
([#355](#355))
- Use mise and fix test issues
- Create crates/ subdir
</blockquote>

## `dap-gui-debugger`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-debugger-v0.1.0)
- 2026-04-05

### Added

- add Event::Error variant to surface background task failures

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))
- start DAP sequence numbers at 1 instead of 0
- replace panic with error propagation in stopped event handler

### Other

- add version fields to path dependencies for release-plz compatibility
- add 163 tests for tui and ui-core crates
([#388](#388))
- scaffold TUI crate with ratatui (Phase 1)
- surface Output and Thread events from DAP
- add missing unit tests for error paths and scope changes
- move command-name mapping into RequestBody and simplify argument
serialisation
- extract send_and_expect_success helper to eliminate boilerplate
- gate testing module behind cfg to exclude from release builds
- Deduplicate DAP session initialization with SessionArgs/StartMode
enums
- Add file:line breakpoint input for remote attach workflows
([#386](#386))
- Rename transport2 crate to async-transport
- Remove transport crate, sync debugger, and repl crate
- Replace hand-written DAP types in transport with auto-generated
dap-types
- Move tokio to workspace dependency to fix minimal-versions CI
- Add 5 GUI improvements: breakpoints, variable tree, syntax
highlighting, async migration, error handling
- Fix cargo fmt formatting across 7 files
- Robustness improvements for startup procedure
- Add more tests
- Fix minimal versions
- Error handling for bad responses
- Shortly hold lock
- Try to get implementation working
- Integrate launch configuration and staged debugger initialization
- Fix clippy lints
- Complete debugger transport integration phases
([#383](#383))
- Clean out old POC crates
- Add testing infrastructure for async debugger (Phase 5)
([#382](#382))
- Implement transport2 integration phases 1 and 2
([#381](#381))
- Add integration plan for debugger + transport2
([#380](#380))
- Fix try_poll_message to handle partial reads across timeouts
([#378](#378))
- Add infrastructure for non-blocking request handling
([#375](#375))
- Add refactoring plan for message receiving architecture
([#374](#374))
- Switch debugger to use TransportConnection instead of Client
([#372](#372))
- Migrate to latest iced version
([#373](#373))
- Refactor debugger background thread to use command pattern
([#371](#371))
- Add Command infrastructure for background thread communication
([#370](#370))
- Add non-blocking event processing foundation
([#367](#367))
- Fix stack frame handling panics in Stopped event
([#362](#362))
- Fix home directory panic in path normalization
([#364](#364))
- Fix runaway background thread termination
([#361](#361))
- Fix race condition in test_remote_attach event handling
([#365](#365))
- Fix poisoned mutex panic in with_internals
([#363](#363))
- Fix panic in Drop implementation
([#360](#360))
- Add 30-second timeout for DAP request responses
([#355](#355))
- Ensure launch program exists
- Use mise and fix test issues
- Create crates/ subdir
</blockquote>

## `dap-gui-fuzzy`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-fuzzy-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- Extract fuzzy crate and add file picker to egui GUI
</blockquote>

## `dap-gui-state`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-state-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- no-session polish and robustness (Phase 5)
- Add Lilex font for code view with Cmd+/- font size shortcuts
- fmt
- Persist breakpoints to disk when modified via gutter clicks
- Add more tests
- Create crates/ subdir
</blockquote>

## `dap-gui-ui-core`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-ui-core-v0.1.0)
- 2026-04-05

### Added

- make config_path optional, defaulting to .vscode/launch.json
- add user-facing documentation to CLI argument parser
([#390](#390))

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- add 163 tests for tui and ui-core crates
([#388](#388))
- extract shared ui-core crate from gui and tui
([#387](#387))
</blockquote>

## `dap-gui-egui`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-egui-v0.1.0)
- 2026-04-05

### Added

- add Event::Error variant to surface background task failures

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- extract shared ui-core crate from gui and tui
([#387](#387))
- surface Output and Thread events from DAP
- Deduplicate DAP session initialization with SessionArgs/StartMode
enums
- Add always-visible text search to no-session code viewer
- Merge file browser into main app's no-session view
- Add Cmd+F / Ctrl+F text search in code view
- Add GUI launch controls: start, stop, and restart debug sessions
- Add Lilex font for code view with Cmd+/- font size shortcuts
- Add file-picker startup mode when no breakpoints provided
- Add file:line breakpoint input for remote attach workflows
([#386](#386))
- Rename transport2 crate to async-transport
- Remove transport crate, sync debugger, and repl crate
- Persist breakpoints to disk when modified via gutter clicks
- fmt
- Move tokio to workspace dependency to fix minimal-versions CI
- Fix breakpoint rendering
- Canonicalize all paths early to fix breakpoint gutter display
- Make code window fill full width of the code panel
- Fix breakpoint toggle: persist UI breakpoints across frames and match
by path+line
- Fix code panel scroll stability: use viewport height and only scroll
when needed
- Fix debug server lifetime: keep server handle alive for app duration
- Move CentralPanel into renderer and add status messages for empty
states
- Add 5 GUI improvements: breakpoints, variable tree, syntax
highlighting, async migration, error handling
- Fix cargo fmt formatting across 7 files
- Extract fuzzy crate and add file picker to egui GUI
- Robustness improvements for startup procedure
- Fix variable parsing
- Update controls
- Migrate to latest iced version
([#373](#373))
- Bump versions
- Formatting
- Create crates/ subdir
</blockquote>

## `dap-gui-pcaplog`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-pcaplog-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- add version fields to path dependencies for release-plz compatibility
- Move bytes to workspace dependency to fix minimal-versions CI
- Rename transport2 crate to async-transport
- Remove transport crate, sync debugger, and repl crate
- Use mise and fix test issues
- Create crates/ subdir
</blockquote>

## `dap-tui`

<blockquote>

##
[0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-tui-v0.1.0)
- 2026-04-05

### Fixed

- rename workspace crates with dap-gui- prefix for cargo package
compatibility ([#391](#391))

### Other

- rename main crate to dap-tui again
- add version fields to path dependencies for release-plz compatibility
- set up release pipeline with release-plz and GitHub Actions
([#389](#389))
- add zen mode to maximize code view
- add 163 tests for tui and ui-core crates
([#388](#388))
- extract shared ui-core crate from gui and tui
([#387](#387))
- add inline evaluation annotations in code view (Phase C)
- add visual line selection in code view (Phase B)
- add Ctrl+E evaluate expression popup (Phase A)
- remove modal REPL input, type directly when focused
- no-session polish and robustness (Phase 5)
- interactive breakpoints, REPL, and variable tree (Phase 4)
- connect to debugger and hit breakpoints (Phase 3)
- file browsing with syntax highlighting (Phase 2)
- scaffold TUI crate with ratatui (Phase 1)
- Clean out old POC crates
- Create crates/ subdir
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant