Repository navigation
Architecture review: two shells, one engine — hotspots, drift risks, and refactor roadmap #5
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Description
Activity
looks like AI wrote this issue
Reacted by lance, Boyee2022, dinggong, yukk, Okay Kaçar, Ankan Misra, Macro, yy, JiMMyMatrix, sky wong and 6 more@DevMatei yes, i used https://github.com/Yeachan-Heo/oh-my-claudecode to write the issue down :)
Reacted by 沫沫. and DevMateiReacted by JiMMyMatrixcc 写的审查 cc 的源码
Reacted by 啦啦啦种太阳, Okay Kaçar, du1ge, Goodstudydaydayup, yy, mhwu2017, XuChazz and RuijieZhou-ustcFollow-up with a diagram-first architecture view.
Architecture diagram
Loadingflowchart TD subgraph Bootstrap CLI[src/entrypoints/cli.tsx] INIT[src/entrypoints/init.ts] MAIN[src/main.tsx] LAUNCH[src/replLauncher.tsx] end subgraph InteractiveShell APP[src/components/App.tsx] REPL[src/screens/REPL.tsx] INPUT[src/utils/processUserInput/processUserInput.ts] end subgraph HeadlessShell PRINT[src/cli/print.ts] SIO[src/cli/structuredIO.ts] ASK[src/QueryEngine.ts] end subgraph Bridge BMAIN[src/bridge/bridgeMain.ts] SRUN[src/bridge/sessionRunner.ts] BMSG[src/bridge/bridgeMessaging.ts] RBRIDGE[src/hooks/useReplBridge.tsx] end subgraph SharedEngine QUERY[src/query.ts] ORCH[src/services/tools/toolOrchestration.ts\n+ StreamingToolExecutor] end CLI -->|interactive path| MAIN MAIN --> INIT MAIN --> LAUNCH LAUNCH --> APP APP --> REPL REPL --> INPUT INPUT --> QUERY MAIN -->|headless path| PRINT PRINT --> SIO PRINT --> ASK ASK --> QUERY CLI -->|bridge fast-path| BMAIN BMAIN --> SRUN BMAIN --> BMSG SRUN -->|spawns child CLI in --print --stream-json mode| PRINT RBRIDGE --> REPL RBRIDGE --> BMSG QUERY --> ORCH ORCH --> QUERYFocused review
- The architecture is best understood as two shells around one shared engine, plus a bridge supervisor around headless child sessions.
- The strongest design choice is that interactive, headless, and bridge flows all converge on the same lower turn engine instead of duplicating model/tool execution logic.
- The biggest risk is not the engine itself, but the amount of orchestration still split across
src/main.tsx,src/screens/REPL.tsx,src/cli/print.ts, andsrc/bridge/bridgeMain.ts. - The bridge is important to think of as a supervisor over headless child CLI sessions, not just a UI transport layer, because that determines how behavior drifts and where shared abstractions matter most.
Short version: the engine looks shared and healthy; the shell/supervisor boundaries are where cleanup buys the most.
Follow-up focused specifically on the proposed capability snapshot refactor.
Capability snapshot target diagram
Loadingflowchart TD subgraph CapabilitySources BUILTIN_CMDS[src/commands.ts\nBuilt-in command registry] BUILTIN_TOOLS[src/tools.ts\nBuilt-in tool registry] SKILLS[src/skills/loadSkillsDir.ts] BUNDLED[src/skills/bundledSkills.ts] PLUGINS[src/utils/plugins/loadPluginCommands.ts] WORKFLOWS[workflow commands] MCP_CMDS[MCP commands] MCP_TOOLS[MCP tools] DYNAMIC[dynamic skills] end subgraph SnapshotLayer[Proposed snapshot layer] CS[src/capabilities/buildCommandSnapshot.ts] TS[src/capabilities/buildToolSnapshot.ts] CAPS[src/capabilities/buildCapabilitySnapshot.ts] TYPES[src/capabilities/types.ts] end subgraph ExistingPublicAPIs GETCMDS[getCommands / skill-command views] GETTOOLS[assembleToolPool / getMergedTools] end subgraph Shells REPL[src/screens/REPL.tsx] PRINT[src/cli/print.ts] BRIDGE[src/bridge/sessionRunner.ts -> print mode] end BUILTIN_CMDS --> CS SKILLS --> CS BUNDLED --> CS PLUGINS --> CS WORKFLOWS --> CS MCP_CMDS --> CS DYNAMIC --> CS BUILTIN_TOOLS --> TS MCP_TOOLS --> TS TYPES --> CS TYPES --> TS CS --> CAPS TS --> CAPS CS --> GETCMDS TS --> GETTOOLS GETCMDS --> REPL GETCMDS --> PRINT GETTOOLS --> REPL GETTOOLS --> PRINT PRINT --> BRIDGEWhy this should be the first refactor
- Today the active capability surface is assembled from built-ins, skills, bundled skills, plugins, workflows, MCP, feature flags, permission mode, and runtime state.
- That flexibility is useful, but the resolution logic is distributed enough that it is hard to answer a simple question like: what commands/tools are active right now?
- A snapshot layer is a good first PR because it is high leverage, relatively low risk, and easy to verify with ordering/collision tests.
- The main invariant is simple: this refactor should change where capability resolution lives, not how capability resolution behaves.
Key rule:
src/commands.tsandsrc/tools.tsshould still own built-in definitions; the new snapshot layer should assemble the active surface, not redefine it.up
cc 写的审查 cc 的源码
cool
good
cool
Also found some hidden features - #933
- added a commit that references this issue
on May 11, 2026 - added 4 commits that reference this issue
on May 21, 2026 - added a commit that references this issue
on Jun 3, 2026 - added a commit that references this issue
on Jul 6, 2026
Metadata
Metadata
Assignees
Labels
No labels
TL;DR
After reading the current repository snapshot on March 31, 2026, my main conclusion is:
The simplest mental model is:
src/screens/REPL.tsxsrc/cli/print.tssrc/bridge/bridgeMain.tssrc/QueryEngine.ts+src/query.tsThat foundation is strong. The main risk is drift between the shells and the bridge path.
Current structure
src/entrypoints/cli.tsx,src/entrypoints/init.ts,src/main.tsx,src/replLauncher.tsxsrc/screens/REPL.tsx,src/components/App.tsxsrc/cli/print.ts,src/cli/structuredIO.tssrc/QueryEngine.ts,src/query.tssrc/bridge/bridgeMain.ts,src/bridge/sessionRunner.ts,src/bridge/bridgeMessaging.ts,src/hooks/useReplBridge.tsxRepresentative refs:
src/entrypoints/cli.tsx:28-33, 108-162, 182-208main.tsxorchestration:src/main.tsx:585-760, 1903-1935, 2404-2453, 3761-3798src/screens/REPL.tsx:680-835, 2392-2523, 2855-3055, 3831-4043src/cli/print.ts:455-620, 1471-1510, 2130-2205src/query.ts:219-320, 551-740src/bridge/bridgeMain.ts:141-220, 1980-2057What looks good
1. Shared lower turn engine
The repo does not duplicate the core model/tool execution loop across interactive/headless/bridge. That is the biggest architectural strength.
2. Registry-first command/tool model
Commands and tools are explicitly assembled rather than scattered ad hoc.
Refs:
src/commands.ts:258-346, 449-517src/tools.ts:193-250, 271-327, 345-3893. Real extensibility model
Skills, plugins, workflows, MCP commands, and MCP tools are part of the actual runtime capability model.
Refs:
src/commands.ts:353-398, 449-517, 547-586src/skills/loadSkillsDir.tssrc/utils/plugins/loadPluginCommands.tssrc/tools.ts:345-389Main risks
1. REPL vs headless drift
The biggest structural risk is that there are two large orchestration shells:
src/screens/REPL.tsxsrc/cli/print.tsThey share the lower engine, but a lot of setup/runtime assembly still happens separately.
Likely drift points:
2. Oversized orchestration hotspots
The main files carrying too many boundaries right now are:
src/main.tsxsrc/screens/REPL.tsxsrc/cli/print.tssrc/bridge/bridgeMain.tsThese files mix routing, capability assembly, lifecycle management, task/queue/mailbox handling, and teardown.
3. “Task” means two different things
There appear to be two task domains:
runtime/background execution tasks
src/Task.tssrc/tasks.tssrc/tasks/*file-backed todo/planning task state
src/utils/tasks.tssrc/hooks/useTasksV2.tsRefs:
src/Task.ts:6-29, 44-125src/tasks.ts:17-38src/utils/tasks.ts:69-89, 190-210src/hooks/useTasksV2.ts:20-29, 113-151, 218-2494. Capability resolution is too distributed
The active command/tool surface depends on built-ins, skills, bundled skills, plugins, workflows, MCP, feature flags, permission mode, and runtime state.
That flexibility is good, but the resolution logic is spread across too many places instead of being represented as one clear capability snapshot.
5. App state and tool runtime context are broad
Refs:
src/state/AppStateStore.tssrc/Tool.ts:123-239AppStateandToolUseContextboth look broad enough to become accidental coupling points.Recommended refactor order
ToolUseContextBest immediate next step
If I had to choose one next refactor, it would be:
Why:
Concretely, I would add:
src/capabilities/types.tssrc/capabilities/buildCommandSnapshot.tssrc/capabilities/buildToolSnapshot.tssrc/capabilities/buildCapabilitySnapshot.tsThen make existing APIs in
src/commands.tsandsrc/tools.tsdelegate to those builders while preserving behavior.Critical invariants:
Why this issue exists
This repository already has a real architecture. The problem is not lack of structure; it is that several important boundaries are still implicit:
Making those boundaries explicit would reduce drift and make future maintenance safer.