Refactor: restructure app architecture, simplify internals, and improve UX#8
Merged
Refactor: restructure app architecture, simplify internals, and improve UX#8
Conversation
Signed-off-by: Meng Yan <myan@redhat.com>
- Rename internal/runtime to internal/loop with cleaner API - Move UI components (history, progress, selector, suggest, theme) into internal/app - Consolidate internal/message and internal/messageconv into core - Move internal/client into internal/provider - Move internal/transcript into internal/session/transcript - Move internal/tracker into internal/task/tracker - Move internal/filecache, image, log, markdown into internal/util - Add command_controller.go and view_layout.go - Remove handler_stream.go, handler_tool_progress.go, stream_runtime.go - 253 files changed, 4594 insertions, 5510 deletions Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
- Update architecture docs - Simplify handler_approval, handler_mode, handler_tool - Remove background_task_tracker redundant code - Clean up toolui/run and toolui/state - Remove obsolete tests - 12 files changed, -1385 lines Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…t packages - Rename internal/provider to internal/llm - Rename internal/hooks to internal/hook (singular) - Add internal/app/system package (state, update, view) - Add internal/app/agentinput/state.go - Remove async_hook_queue.go - Update loop, tool, and integration test imports - 98 files changed, 793 insertions, 615 deletions Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Restructure internal/app by extracting cohesive concerns into their own sub-packages: - internal/app/agent: background task tracker, notification queue, state, update handlers, and view rendering for agent sessions - internal/app/user: user input handling (model, init, update, view, tests) replaces the old internal/app/input package - internal/app/output: message output model, update, and view rendering replaces internal/app/view_layout and view_messages Removed packages and files consolidated into the new structure: - internal/app/input (replaced by internal/app/user) - internal/app/agentinput/state.go (merged into internal/app/agent) - internal/app/agent_builder.go, agent_config.go (moved into model.go) - internal/app/loop_builder.go (merged into model_init.go) - internal/app/background_task_tracker[_test].go (moved to agent/) - internal/app/task_notification_queue.go (moved to agent/) - internal/app/view_layout.go, view_messages.go (moved to output/) Also simplifies handler_input.go and handler_task_notifications.go by delegating to the new sub-packages. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…dlers to update_*
Reorganize internal/app with two major structural changes:
1. Move all UI component packages under internal/app/ui/:
agentui, approval, compact, conversation, history, mcpui, memory,
mode, pluginui, providerui, progress, queue, render, searchui,
selector, sessionui, skillui, suggest, theme, toolui
2. Rename handler files to follow update_* convention organized by
input source:
- update_user_*: user input, commands, approval, mode, submit, window
- update_output_*: LLM output events, compact, mcp, memory, plugin,
provider, session
- update_agent_input: agent/task notification handling
- update_system_input: system-level input handling
3. Extract runtime helpers into sub-packages:
- internal/app/agent/runtime.go
- internal/app/output/runtime.go
- internal/app/system/runtime.go
- internal/app/user/runtime.go, queue.go
4. Remove consolidated handler files:
- handler_async_hooks.go, handler_cron.go, handler_input_queue.go,
handler_search.go
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Signed-off-by: Meng Yan <myan@redhat.com>
…UI layer Move theme package from output/theme to ui/theme and selector package from user/selector to ui/selector, keeping shared UI utilities in a common location. Update all import references across render, user, and output packages to reflect the new paths. Remove deleted theme and selector files from their old locations. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Remove the unnecessary RenderTrackerList wrapper from agent/view.go and call render.RenderTrackerList directly in view.go, eliminating an extra layer of indirection. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Major package reorganizations: - ext/ → extension/ (mcp, skill, subagent, command, plugin) - llm/ → provider/ (all LLM provider implementations) - loop/ → runtime/ (main execution loop) - hook/ → kept, core/prompt/ → system/ - ui/selector,theme → app/kit/ (shared UI primitives) Move update handlers into their owning sub-packages: - update_user_* → app/user/ - update_output_* → app/output/ - update_system_input → app/system/ - update_agent_input → app/agent/ Delete removed packages: internal/agent/, internal/hooks/, internal/mcp/, internal/skill/, internal/command/, internal/log/, internal/image/, internal/filecache/, internal/markdown/, internal/plugin/, and app/ui/ remnants. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Move update_user_*, update_output_*, update_system_input, and update_agent_input back to internal/app/ from their sub-packages. Update import paths across the codebase to use internal/util/ prefix consistently for shared utilities. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…e Selector indirection Also inlines updateSearch handler from providerui into app package, removing the providerui→searchui cross-package dependency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…model Moves LLM, Store, CurrentModel, InputTokens, OutputTokens, ThinkingLevel, and ThinkingOverride from providerui.State to the parent model struct. providerui.State now holds only UI concerns (Selector, StatusMessage, FetchingLimits). Adds SetLLM/SetCurrentModel/GetLLM to providerui.Runtime interface so the overlay can write back domain state through callbacks instead of direct field mutation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
- Eliminate providerui→searchui lateral dependency: inline updateSearch in app
- Add compile-time Runtime interface satisfaction checks for all 5 overlays
- Use kit.StartExternalEditor in update_overlays startExternalEditor wrapper
- Move FilterSuggestion to dedicated suggest package, use from update_user_suggest
- Add kit/editor.go and kit/theme_selector.go (relocated from user package)
- Add user/suggest/filter.go (relocated from user/suggest_filter.go)
- Remove dead code: approval preview isExpanded/setMaxVisible methods
- Remove dead code: queue.remove() and its tests
- Fix kit package doc comment ("common" → "kit")
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Meng Yan <myan@redhat.com>
- Remove mcpui.State.Registry field: use mcp.DefaultRegistry directly throughout model.go, model_init.go, hook_firing.go, update_user_command_tool.go - Migrate mcpui editor dependency from memory to kit package - Migrate memory editor to use kit.StartExternalEditor - Delete memory/editor.go (functionality now in kit/editor.go) - Use kit.GetEditor() in cmd/gen/mcp.go - Use kit.RunThemeSelector() in run.go, remove user package import - Delete user/suggest_filter.go and user/theme_selector.go (relocated) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
- Remove unused isExpanded() and setMaxVisible() from approval preview types - Remove unused Queue.remove() method and its tests - Fix kit package doc comment: "common" → "kit" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Move domain state out of UI overlay State structs into the parent model: - mode.State: Operation, SessionPermissions, DisabledTools → model - memory.State: CachedUser, CachedProject → model - sessionui.State: Store, CurrentID, Summary → model - providerui.Runtime: collapse 6 methods into OnProviderChanged callback - Move StartExternalEditor from memory/ to kit/, eliminating mcpui→memory This completes the separation of domain state from overlay UI state, making overlay packages purely concerned with selector/modal UI logic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Signed-off-by: Meng Yan <myan@redhat.com> # Conflicts: # internal/app/update_overlays.go # internal/app/user/memory/runtime.go # internal/app/user/providerui/runtime.go
… access Replace all coremcp.DefaultRegistry and coreplugin.DefaultRegistry usage in mcpui and pluginui packages with constructor-injected registry fields. This makes the dependency explicit, improves testability, and removes hidden coupling to global state. - mcpui.New(reg) / pluginui.New(reg) now require a *Registry parameter - AutoConnect and startConnect are now methods/functions taking the registry - All command handlers receive the registry from the selector parameter - PrepareServerEdit and ApplyServerEdit take an explicit registry parameter - Unexport pluginui.Action to pluginui.action (package-internal type) - Update all callers in app/, cmd/gen/, and test files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…omain state - Extract MCP config editing logic (PrepareServerEdit, ApplyServerEdit, ParseScope, ParseKeyValues) from app/user/mcpui to extension/mcp/edit.go, fixing the cmd/gen → mcpui layer violation and deduplicating parseScope/ parseKeyValues which were copied in both packages - Move Preview types from agentui and skillui into approval package as unexported types (agentPreview, skillPreview), eliminating lateral dependencies between sibling overlay packages - Remove wrapper-only State structs for agentui and searchui, using Model directly to reduce pointless indirection - Extract domain state from overlay State structs (mode, memory, session) to the parent app model where it belongs - Split monolithic output.Runtime interface into focused sub-interfaces (ConversationMutator, StreamController, ToolSideEffects, TurnManager) Signed-off-by: Meng Yan <yanmxa@gmail.com> Signed-off-by: Meng Yan <myan@redhat.com>
…ain state - Move mode/ from user/ to internal/app/mode/ — it holds modal prompts and plan mode state, not an overlay selector - Move history/ and suggest/ from user/ to internal/app/kit/ — they are pure utilities, not overlay packages - Extract plan domain state (planEnabled, planTask, planStore) from mode.State to the parent app model, leaving mode.State with only modal prompt UI components - Fix searchui hidden dependency: Enter() now accepts *provider.Store instead of creating its own, matching the injection pattern used by all other overlay packages - Fix duplicate comment in approval/model.go Signed-off-by: Meng Yan <yanmxa@gmail.com> Signed-off-by: Meng Yan <myan@redhat.com>
…rm bridge files - Convert approval.Model from pointer to value type (removes nil guards) - Convert HandleTextareaUpdate from free function to method on user.Model - Rename queue.go to input_queue.go to disambiguate from queue/ sub-package - Extract agent config methods into model_agent_config.go - Extract permission bridge code into update_output_perm_bridge.go Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…ation - Add kit.ListNav: shared cursor/scroll/search component for list selectors - Add kit.SaveLevel: shared project/user scope enum - Refactor agentui.Model to use kit.ListNav and kit.SaveLevel - Refactor skillui.Model to use kit.ListNav and kit.SaveLevel - Simplify renderOverlaySelector using overlaySelectors() loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
- toolui: replace manual navigation + SaveLevel with kit.ListNav + kit.SaveLevel - mcpui: replace manual list-level navigation with kit.ListNav fields - sessionui: replace manual navigation with kit.ListNav - Simplify delegateToActiveModal using overlaySelectors() loop Eliminates ~200 lines of duplicated cursor/scroll/search boilerplate. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
The pending permission bridge request is agent-session state, not top-level model state. It is set when agentPermissionMsg arrives (which only happens after agentSess is initialized) and consumed in handlePermBridgeResponse. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…toolexec (execution) The tool selector overlay (user-facing UI) and tool execution state (agent-output concern) were bundled in one package. Separating them aligns with the three-source MVU architecture: user/toolui handles the selector overlay, output/toolexec holds execution state and the ExecuteApproved entry point. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
… output/toolexec (execution)" This reverts commit 09ffa18.
…ime, rename files - Add Reset(), RecordSubmission(), RestoreImages(), HasContent(), PendingImages() methods to user.Model for state encapsulation - Inline queue/ package into user package as Queue type on user.Model, remove inputQueue from central model - Move showTasks toggle from user.Model to central model (view concern) - Add searchui/runtime.go with Update() and Runtime interface - Rename user/init.go → new.go, user/runtime.go → update_textarea.go Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Signed-off-by: Meng Yan <myan@redhat.com>
…or conversation preservation - Rename command_controller.go → slash_command.go - Flip from blocklist to allowlist: only compact/fork/resume/plan/loop/init/tokenlimit are preserved in conversation history. All other commands (builtin, skill, custom) default to not polluting the conversation flow. - Simplify HandleSubmit: remove insertConversationMessage, ShouldPreserveBeforeCommandExecution, preAppended tracking. Always pre-append preserved commands, rollback if not a valid command. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…xtras, richer injection
- Conditional tools guidelines: tools-git.txt only included when IsGit=true
- Deferred tools now list one-line descriptions instead of bare names
- Coordinator guidance condensed from 112 to 42 lines
- Extra layers use semantic names ("coordinator", "skill-invocation") instead of index-based
- base.txt enriched with output control, error handling, multi-turn behavior
- Agents listing structured with separate "Use when:" and "Tools:" lines, sorted
- Subagents with Agent/Skill tools now inherit capabilities sections
- Environment info includes GOARCH
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Meng Yan <myan@redhat.com>
…uidelines - base.txt: merge Professional objectivity + Proactiveness → Behavior section, inline code reference example, tighten all sections (-46% → 30 lines) - generic.txt: remove redundant "NEVER commit" (covered by tools-git.txt) - tools-core.txt: condense examples, tighten key rules (-33% → 23 lines) - tools-questions.txt: reduce 3 examples to compact description (-83% → 7 lines) - Add IsSubagent flag to Config: excludes tools-questions and tools-tasks for subagent prompts; tools-tasks also excluded in plan mode - Subagent readonly prompt: 9.5KB → 5.0KB (-48%) - Main session prompt: 12.4KB → 9.2KB (-26%) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…nsolidate layers - Merge generic.txt into base.txt, delete generic.txt - Merge 3 capabilities layers (skills, agents, deferred) → 1 - Merge 2 instructions layers (user, project) → 1 - Provider layer only added if provider-specific file exists - Layer count: 12 → 8 (identity, provider?, environment, instructions, session-summary, capabilities, guidelines, mode, extra) - Update priority doc in system.go Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
…tem prompt Compaction summary is now a regular user message, not session-level state. Remove Summary/SummaryBlobID/HasSummary from transcript types, PatchSummary, BlobReader, SaveSessionMemory/LoadSessionMemory, GetSummary/SetSummary from session.Service. Trim planmode and tools-core prompts, cache CompactPrompt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
- Move task execution rules from base.txt to tools-core.txt (correct layer) - Compress coordinator.txt (~30% smaller, same content) - Add conversation format description to compact.txt - Consolidate git safety rules in tools-git.txt (8 NEVER rules → 1 list) - Remove unused LoadMemory() from system/memory.go - Extract hardcoded compact max tokens to named constant (2048 → 4096) - Update golden test files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Meng Yan <myan@redhat.com>
Signed-off-by: Meng Yan <myan@redhat.com>
… docs - Show input/output token counts with context percentage on the right side status bar next to model name - Replace inline token usage indicator with warning-only display at >50% - Add OutputTokens to OperationModeParams and wire through view layer - Stop agent session when switching providers - Ensure agent session started before skill invocations - Simplify agent continuation: inline resolveLiveTaskID and resolveContinuationTargetForMessage wrappers - Simplify tracker_view pending task rendering - Clean up hub/format.go merge loop and schema.go tool registration - Add docs/extension.md documenting skill/agent/command architecture Signed-off-by: Meng Yan <myan@redhat.com>
|
Important Review skippedToo many files! This PR contains 296 files, which is 146 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (296)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
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
Major refactoring of the app layer and internal packages for clearer architecture and maintainability.
Architecture & Package Structure
UI & UX Improvements
Code Simplification
System Prompt
Documentation
Bug Fixes