Skip to content

feat: debug mode — hypothesis-driven debugging (Cursor-style)#45

Merged
kienbui1995 merged 4 commits intomainfrom
feat/debug-mode
Apr 12, 2026
Merged

feat: debug mode — hypothesis-driven debugging (Cursor-style)#45
kienbui1995 merged 4 commits intomainfrom
feat/debug-mode

Conversation

@kienbui1995
Copy link
Copy Markdown
Owner

@kienbui1995 kienbui1995 commented Apr 12, 2026

Debug Mode

Structured debugging workflow inspired by Cursor's Debug Mode:

4 phases:

  1. hypothesize — generate 3-5 hypotheses about root cause
  2. instrument — add targeted logging/assertions to verify each hypothesis
  3. analyze — compare evidence against hypotheses, identify root cause
  4. fix — apply targeted fix, remove instrumentation, add regression test

Usage: /debug in TUI or agent calls debug tool directly

Why: Standard agent debugging = guess and fix. Debug Mode = evidence-based, systematic, fewer iterations.

30 tools, 192 tests, 0 warnings.

Summary by CodeRabbit

  • New Features
    • Introduced a Debug tool that guides structured debugging workflows (hypothesize, instrument, analyze, fix).
    • Added a /template debug command to generate step-by-step debug prompts.
  • Behavior
    • Debug and Browser are now processed as sequential tools within turn execution.
  • Tests
    • Test expectations updated to include the new Debug tool.

- New 'debug' tool with 4 phases: hypothesize, instrument, analyze, fix
- Guides agent through evidence-based debugging workflow
- TUI '/debug' template activates debug mode in conversation
- Agent generates hypotheses → adds logging → analyzes evidence → targeted fix
- 30 tools total, 192 tests pass, 0 warnings
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a21d12de-890f-4069-8517-e9358b01309a

📥 Commits

Reviewing files that changed from the base of the PR and between e15fd7e and 7ba4fc4.

📒 Files selected for processing (1)
  • mc/crates/mc-core/src/debug.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • mc/crates/mc-core/src/debug.rs

📝 Walkthrough

Walkthrough

Adds a new synchronous "debug" tool: spec, core handler (execute_debug), runtime dispatch changes to treat "debug" (and "browser") as sequential tools, a TUI template, and a test update reflecting the new tool count.

Changes

Cohort / File(s) Summary
Runtime changes
mc/crates/mc-core/src/runtime.rs
run_turn now classifies "debug" and "browser" into the sequential dispatch set; dispatch_tool adds an explicit name == "debug" branch that calls execute_debug instead of routing through the generic tool executor.
Debug handler & export
mc/crates/mc-core/src/debug.rs, mc/crates/mc-core/src/lib.rs
Added execute_debug(input: &serde_json::Value) -> (String, bool) implementing hypothesize, instrument, analyze, fix flows with required-field validation and formatted responses; exported via pub mod debug;. Includes unit tests for error and success cases.
Tool specification
mc/crates/mc-tools/src/spec.rs
Added ToolSpec for "debug" with an input_schema requiring an action enum (hypothesize,instrument,analyze,fix) and conditional fields via allOf/if/then (e.g., bug_description, file, evidence, root_cause).
TUI template
mc/crates/mc-tui/src/commands.rs
Extended /template help text and added "debug" template arm that populates a step-by-step debugging workflow prompt instructing the use of the debug tool.
Tests / Registry
mc/crates/mc-tools/src/registry.rs
Updated test expectation in specs_has_all_tools from 29 → 30 to include the new debug spec.

Sequence Diagram

sequenceDiagram
    participant User as User/TUI
    participant Runtime as Runtime
    participant Registry as Tool Registry
    participant Debug as execute_debug

    User->>Runtime: invoke tool "debug" with input (action + params)
    Runtime->>Registry: identify tool "debug" (sequential)
    Registry->>Runtime: confirm dispatch
    Runtime->>Debug: call execute_debug(input)

    alt action = "hypothesize"
        Debug->>Debug: read `bug_description`
        Debug->>User: return hypothesis message, is_error=false
    else action = "instrument"
        Debug->>Debug: validate `file` and optional `hypotheses`
        alt missing required fields
            Debug->>User: return error message, is_error=true
        else
            Debug->>User: return instrumentation message, is_error=false
        end
    else action = "analyze"
        Debug->>Debug: validate `evidence`
        alt evidence missing
            Debug->>User: return error message, is_error=true
        else
            Debug->>User: return analysis message, is_error=false
        end
    else action = "fix"
        Debug->>Debug: read `root_cause` and `file`
        Debug->>User: return fix message, is_error=false
    else unknown action
        Debug->>User: return "Unknown debug action" error, is_error=true
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble at a curious bug tonight,
I hypothesize, then instrument the light.
I gather evidence and analyze the scene,
I fix the root cause, then run the green.
I hop away singing — the tests are clean.

🚥 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 'feat: debug mode — hypothesis-driven debugging (Cursor-style)' directly and accurately reflects the main change: introducing a new debug mode feature with a hypothesis-driven workflow inspired by Cursor. It is concise, specific, and clearly communicates the primary functionality added in this PR.
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 feat/debug-mode

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

@kienbui1995
Copy link
Copy Markdown
Owner Author

/review

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
mc/crates/mc-tui/src/commands.rs (1)

383-396: ⚠️ Potential issue | 🟡 Minor

Expose debug in the /template help list.

/template now supports debug (Line 396), but the list shown when no args are provided still omits it (Line 384), so users won’t discover it.

💡 Proposed fix
-        app.push("Templates: review, refactor, test, explain, document, optimize, security");
+        app.push("Templates: review, refactor, test, explain, document, optimize, security, debug");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mc/crates/mc-tui/src/commands.rs` around lines 383 - 396, The templates help
list omits the new "debug" template when arg.is_empty() is true; update the
string pushed to the UI (the first app.push call that currently lists
"Templates: review, refactor, test, explain, document, optimize, security") to
include "debug" (e.g., append ", debug" or insert at desired position) so the
/template help output exposes the Debug Mode entry; keep the Usage line as-is
and ensure the change is made near the arg.is_empty() branch in commands.rs
where app.push is called.
🧹 Nitpick comments (2)
mc/crates/mc-core/src/runtime.rs (1)

1704-1719: Validate fix inputs like other debug phases.

fix accepts empty root_cause and file, which weakens the workflow and can cause extra loops. Consider enforcing non-empty values (similar to instrument and analyze).

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

In `@mc/crates/mc-core/src/runtime.rs` around lines 1704 - 1719, The "fix" debug
branch currently allows empty root_cause and file (variables root_cause and file
in the "fix" match arm), so update runtime.rs to validate them the same way as
the instrument/analyze phases: extract with input.get(...).and_then(|v|
v.as_str()).filter(|s| !s.is_empty()) and if either is missing/empty return or
propagate an error (or produce a validation prompt) instead of defaulting to "";
ensure the match arm for "fix" fails fast on missing values and logs/returns a
clear validation error so the prompt is only built when both root_cause and file
are non-empty.
mc/crates/mc-tools/src/spec.rs (1)

391-405: Tighten debug schema with action-specific required fields.

Right now only action is required, but runtime rejects missing file for instrument and missing evidence for analyze. Encoding that in schema (oneOf/if-then) would reduce avoidable tool-call failures.

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

In `@mc/crates/mc-tools/src/spec.rs` around lines 391 - 405, The debug ToolSpec's
input_schema currently only requires "action", causing runtime failures when
action-specific fields are missing; update the ToolSpec with an action-specific
schema (use JSON Schema oneOf or if/then branches) inside the input_schema for
the ToolSpec named "debug" so that: when action == "hypothesize" require
"bug_description"; when action == "instrument" require "file" (and optionally
"hypotheses"); when action == "analyze" require "evidence"; when action == "fix"
require "root_cause" (and "file" if fixes target a file). Modify the
input_schema definition in the ToolSpec block to include these conditional/oneOf
subschemas so the runtime validates required fields per action.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mc/crates/mc-core/src/runtime.rs`:
- Around line 1208-1209: The "debug" tool is registered in runtime
(execute_debug) but run_turn currently doesn't classify "debug" as a sequential
tool, so calls go through the parallel path (ToolRegistry::execute) where no
debug handler exists; update the classification in run_turn to treat "debug" as
sequential (or alternatively add a debug branch in ToolRegistry::execute) so
that execute_debug is reached when name == "debug" and Debug Mode no longer
returns NotFound; reference run_turn and execute_debug (or ToolRegistry::execute
if you choose the alternate fix) when making the change.

---

Outside diff comments:
In `@mc/crates/mc-tui/src/commands.rs`:
- Around line 383-396: The templates help list omits the new "debug" template
when arg.is_empty() is true; update the string pushed to the UI (the first
app.push call that currently lists "Templates: review, refactor, test, explain,
document, optimize, security") to include "debug" (e.g., append ", debug" or
insert at desired position) so the /template help output exposes the Debug Mode
entry; keep the Usage line as-is and ensure the change is made near the
arg.is_empty() branch in commands.rs where app.push is called.

---

Nitpick comments:
In `@mc/crates/mc-core/src/runtime.rs`:
- Around line 1704-1719: The "fix" debug branch currently allows empty
root_cause and file (variables root_cause and file in the "fix" match arm), so
update runtime.rs to validate them the same way as the instrument/analyze
phases: extract with input.get(...).and_then(|v| v.as_str()).filter(|s|
!s.is_empty()) and if either is missing/empty return or propagate an error (or
produce a validation prompt) instead of defaulting to ""; ensure the match arm
for "fix" fails fast on missing values and logs/returns a clear validation error
so the prompt is only built when both root_cause and file are non-empty.

In `@mc/crates/mc-tools/src/spec.rs`:
- Around line 391-405: The debug ToolSpec's input_schema currently only requires
"action", causing runtime failures when action-specific fields are missing;
update the ToolSpec with an action-specific schema (use JSON Schema oneOf or
if/then branches) inside the input_schema for the ToolSpec named "debug" so
that: when action == "hypothesize" require "bug_description"; when action ==
"instrument" require "file" (and optionally "hypotheses"); when action ==
"analyze" require "evidence"; when action == "fix" require "root_cause" (and
"file" if fixes target a file). Modify the input_schema definition in the
ToolSpec block to include these conditional/oneOf subschemas so the runtime
validates required fields per action.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 092baf62-5463-4577-80ac-f7077a6341ab

📥 Commits

Reviewing files that changed from the base of the PR and between e753c73 and 7f951b6.

📒 Files selected for processing (4)
  • mc/crates/mc-core/src/runtime.rs
  • mc/crates/mc-tools/src/registry.rs
  • mc/crates/mc-tools/src/spec.rs
  • mc/crates/mc-tui/src/commands.rs

1. Add 'debug' and 'browser' to sequential tool list (was going
   through parallel path where no handler exists — critical bug)
2. Add 'debug' to /template help list
3. Validate root_cause and file in debug 'fix' action

192 tests, 0 warnings.
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 (1)
mc/crates/mc-core/src/runtime.rs (1)

1640-1732: Consider moving Debug Mode into its own mc-core module.

This handler is already feature-sized, and runtime.rs is doing a lot of orchestration work already. Extracting execute_debug into something like mc-core/src/debug.rs would keep dispatch here thin and make the new workflow easier to evolve and test.

Based on learnings: When adding a new core feature: create module in mc-core/src/{feature}.rs, integrate into ConversationRuntime in runtime.rs, export from mc-core/src/lib.rs, add to config if needed, add slash command in TUI

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

In `@mc/crates/mc-core/src/runtime.rs` around lines 1640 - 1732, The execute_debug
handler is large and should be extracted into its own module named debug: create
a new module debug that exposes a pub fn execute_debug(input:
&serde_json::Value) -> (String, bool) (migrating the entire match body), then
replace the inline implementation in runtime.rs with a thin dispatch that calls
debug::execute_debug; update the crate root to pub mod debug / pub use
debug::execute_debug so the function is exported, wire the ConversationRuntime
dispatch to call the new function, and update any config/TUI slash-command
registration and tests that referenced the old inline handler to point to the
new module.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mc/crates/mc-core/src/runtime.rs`:
- Around line 1661-1717: The runtime's execute_debug branches ("instrument",
"analyze", "fix") enforce required fields (file, hypotheses/evidence/root_cause)
but the registered debug ToolSpec still only marks action as required; update
the ToolSpec registration for the "debug" tool in mc/crates/mc-tools/src/spec.rs
(ToolSpec for debug) to reflect per-action required parameters: require "file"
for action="instrument" and action="fix", require "hypotheses" (or mark its
expected type) for "instrument", require "evidence" for action="analyze", and
require "root_cause" for action="fix" so the schema matches execute_debug's
validations and prevents the model from invoking the tool without those fields.

---

Nitpick comments:
In `@mc/crates/mc-core/src/runtime.rs`:
- Around line 1640-1732: The execute_debug handler is large and should be
extracted into its own module named debug: create a new module debug that
exposes a pub fn execute_debug(input: &serde_json::Value) -> (String, bool)
(migrating the entire match body), then replace the inline implementation in
runtime.rs with a thin dispatch that calls debug::execute_debug; update the
crate root to pub mod debug / pub use debug::execute_debug so the function is
exported, wire the ConversationRuntime dispatch to call the new function, and
update any config/TUI slash-command registration and tests that referenced the
old inline handler to point to the new module.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: cddb14c3-4e6a-4cdc-ae01-22fbebe50265

📥 Commits

Reviewing files that changed from the base of the PR and between 7f951b6 and 5605c60.

📒 Files selected for processing (2)
  • mc/crates/mc-core/src/runtime.rs
  • mc/crates/mc-tui/src/commands.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • mc/crates/mc-tui/src/commands.rs

1. Extract execute_debug to mc-core/src/debug.rs (was inline in runtime.rs)
2. Add 4 unit tests for debug module
3. Tighten ToolSpec schema with per-action required fields (allOf/if-then)
4. Export debug module from mc-core/src/lib.rs

196 tests (4 new), 0 warnings.
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 (1)
mc/crates/mc-core/src/debug.rs (1)

1-2: Mark execute_debug as #[must_use].

This is a public function returning a value, so it should carry the repo-required annotation.

♻️ Proposed fix
 /// Structured debug mode — guides agent through hypothesis-driven debugging.
+#[must_use]
 pub fn execute_debug(input: &serde_json::Value) -> (String, bool) {
Based on learnings: "Add `#[must_use]` attribute on all public functions returning values"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mc/crates/mc-core/src/debug.rs` around lines 1 - 2, The public function
execute_debug returns a value but lacks the required must_use annotation; add
the #[must_use] attribute directly above the pub fn execute_debug(...)
declaration so callers get a compiler warning if the returned (String, bool)
tuple is ignored, preserving the function signature and visibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mc/crates/mc-core/src/debug.rs`:
- Around line 6-9: The code currently sets bug to "unknown bug" when
input.get("bug_description") is missing; instead, make the "bug_description"
required by checking input.get("bug_description").and_then(|v| v.as_str()) and
returning an error (or propagating a failure) if it's None rather than using
unwrap_or; update the branch that sets the variable named bug in
mc/crates/mc-core/src/debug.rs so the "hypothesize" path fails fast when
bug_description is absent and include a clear error message referencing the
missing "bug_description".

---

Nitpick comments:
In `@mc/crates/mc-core/src/debug.rs`:
- Around line 1-2: The public function execute_debug returns a value but lacks
the required must_use annotation; add the #[must_use] attribute directly above
the pub fn execute_debug(...) declaration so callers get a compiler warning if
the returned (String, bool) tuple is ignored, preserving the function signature
and visibility.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: cd0310ea-f7b4-464e-8e00-4f59c66f340b

📥 Commits

Reviewing files that changed from the base of the PR and between 5605c60 and e15fd7e.

📒 Files selected for processing (4)
  • mc/crates/mc-core/src/debug.rs
  • mc/crates/mc-core/src/lib.rs
  • mc/crates/mc-core/src/runtime.rs
  • mc/crates/mc-tools/src/spec.rs
✅ Files skipped from review due to trivial changes (2)
  • mc/crates/mc-core/src/lib.rs
  • mc/crates/mc-tools/src/spec.rs

- Add #[must_use] to execute_debug
- Require bug_description for hypothesize (was defaulting to 'unknown bug')
- Add test for missing bug_description

197 tests, 0 warnings.
@kienbui1995 kienbui1995 self-assigned this Apr 12, 2026
@kienbui1995 kienbui1995 merged commit a9c2f74 into main Apr 12, 2026
9 checks passed
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