feat: centralized FocusMode state machine for TUI input dispatch#60
Merged
yishuiliunian merged 2 commits intomainfrom Apr 1, 2026
Merged
feat: centralized FocusMode state machine for TUI input dispatch#60yishuiliunian merged 2 commits intomainfrom
yishuiliunian merged 2 commits intomainfrom
Conversation
Introduce FocusMode enum (Input / AgentPanel) to replace implicit conditional checks for agent panel navigation. Different modes produce different key behaviors, and the agent list now scrolls when there are more than 5 agents. Key changes: - FocusMode dispatches handle_normal_key into mode-specific handlers - AgentPanel mode: Up/Down navigate agents, Enter drills in, Tab/Esc exit - Typing auto-switches back to Input mode - Scrollable agent list with ↑/↓ indicators - Ctrl+P/N are mode-aware (agent nav in AgentPanel, history in Input) - Stale focused_agent auto-recovers on re-entry - 46 new test cases across 4 test files
yishuiliunian
added a commit
that referenced
this pull request
Apr 2, 2026
…user approval (#60) Align Plan mode with Claude Code's plan-approve-execute pattern: - PlanFile: session-scoped plan file with slug collision retry, path matching for relative/absolute paths, and read with NotFound vs IO error distinction - PlanModeState: atomic snapshot of pre-plan mode/permission/tool-filter, restored on ExitPlanMode via take() — prevents inconsistent partial state - EnterPlanMode: user consent, sub-agent guard, mkdir rollback on failure - ExitPlanMode: validates mode + plan file, reads plan, requests approval via Frontend trait, injects approved plan into tool_result context - Hard enforcement: dual-layer tool filtering (LLM-side via llm_params + runtime-side via tools_check), Write/Edit path-restricted to plan file - System-reminder: wraps non-intercepted tool results with plan mode rules - Fragment: 5-phase workflow (Explore→Design→Review→Write→Approve) - mode.system_prompt_suffix() returns empty for Plan to avoid conflict with Fragment instructions - 26 new tests across 3 files covering PlanFile, Enter/Exit interception, tool filtering, and system-reminder wrapping
yishuiliunian
added a commit
that referenced
this pull request
Apr 2, 2026
…user approval (#61) * chore: ignore * feat: enhance Plan mode with 5-phase workflow, hard enforcement, and user approval (#60) Align Plan mode with Claude Code's plan-approve-execute pattern: - PlanFile: session-scoped plan file with slug collision retry, path matching for relative/absolute paths, and read with NotFound vs IO error distinction - PlanModeState: atomic snapshot of pre-plan mode/permission/tool-filter, restored on ExitPlanMode via take() — prevents inconsistent partial state - EnterPlanMode: user consent, sub-agent guard, mkdir rollback on failure - ExitPlanMode: validates mode + plan file, reads plan, requests approval via Frontend trait, injects approved plan into tool_result context - Hard enforcement: dual-layer tool filtering (LLM-side via llm_params + runtime-side via tools_check), Write/Edit path-restricted to plan file - System-reminder: wraps non-intercepted tool results with plan mode rules - Fragment: 5-phase workflow (Explore→Design→Review→Write→Approve) - mode.system_prompt_suffix() returns empty for Plan to avoid conflict with Fragment instructions - 26 new tests across 3 files covering PlanFile, Enter/Exit interception, tool filtering, and system-reminder wrapping * fix: resolve rustfmt formatting issues in plan mode files
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
FocusModeenum (Input/AgentPanel) to replace implicit conditional checks for agent panel navigation↑ N more/↓ N moreindicators when >5 agentsChanges
New type:
FocusModeinapp/types.rs— orthogonal tofocused_agent(mode = which region, focus = which agent)Input dispatch refactor (
input/mod.rs):handle_normal_keysplit intohandle_agent_panel_key/handle_input_mode_keyDispatch logic (
key_dispatch_ops.rs):enter_agent_panel: validates live agents, recovers stalefocused_agentcycle_agent_focus: auto-exits AgentPanel when no agents remainadjust_agent_scroll: keeps focused agent in visible 5-row windowRendering (
views/agent_panel.rs):↑ N more/↓ N morescroll indicatorspanel_heightuses clamped offset for layout consistencyTests (4 new files):
focus_mode_test.rs— mode transition coveragefocus_panel_keys_test.rs— key behavior per modeenter_panel_test.rs— enter_agent_panel dispatch logiccycle_focus_test.rs— cycling, wrap-around, scroll boundariesTest plan
bazel build //...passesbazel build //... --config=clippyzero warningsbazel test //...— 46/46 pass