refactor(cli): split command routing and modularize RPC handlers

Restructure CLI entry point and RPC handler registration to improve maintainability:

- Introduce command registry pattern with CommandDefinition interface for consistent command structure
- Extract individual command modules (claude, codex, daemon, doctor, gemini, auth, connect, etc.)
- Move RPC handlers into separate feature modules (bash, files, git, directories, ripgrep, difftastic, slashCommands)
- Create shared RPC types and response helpers (rpcTypes.ts, rpcResponses.ts)
- Move SpawnSessionOptions and SpawnSessionResult to rpcTypes for proper type organization
- Simplify index.ts to minimal entrypoint using command registry
- Update imports in apiMachine.ts and daemon/run.ts to use rpcTypes module

This enables:
- Better code organization by feature/command
- Easier testing of individual commands
- Safer RPC handler registration without side effects
- Clearer separation of concerns between routing and business logic
This commit is contained in:
weishu
2026-01-03 17:29:05 +08:00
parent 680a37071e
commit aa0c3f2f0d
30 changed files with 1287 additions and 1117 deletions
+48
View File
@@ -0,0 +1,48 @@
import chalk from 'chalk'
import { authAndSetupMachineIfNeeded } from '@/ui/auth'
import { initializeToken } from '@/ui/tokenInit'
import { maybeAutoStartServer } from '@/utils/autoStartServer'
import type { CommandDefinition } from './types'
export const codexCommand: CommandDefinition = {
name: 'codex',
requiresRuntimeAssets: true,
run: async ({ commandArgs }) => {
try {
const { runCodex } = await import('@/codex/runCodex')
const options: {
startedBy?: 'daemon' | 'terminal'
codexArgs?: string[]
permissionMode?: 'default' | 'read-only' | 'safe-yolo' | 'yolo'
} = {}
const unknownArgs: string[] = []
for (let i = 0; i < commandArgs.length; i++) {
const arg = commandArgs[i]
if (arg === '--started-by') {
options.startedBy = commandArgs[++i] as 'daemon' | 'terminal'
} else if (arg === '--yolo' || arg === '--dangerously-bypass-approvals-and-sandbox') {
options.permissionMode = 'yolo'
unknownArgs.push(arg)
} else {
unknownArgs.push(arg)
}
}
if (unknownArgs.length > 0) {
options.codexArgs = unknownArgs
}
await initializeToken()
await maybeAutoStartServer()
await authAndSetupMachineIfNeeded()
await runCodex(options)
} catch (error) {
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error')
if (process.env.DEBUG) {
console.error(error)
}
process.exit(1)
}
}
}