5.8 KiB
5.8 KiB
Phase 1 PR #2 Checklist: Fast-Path Command Registry
Created: 2026-02-12 Owner: Flynn core Status: ready to implement
Goal
Add a deterministic CommandRegistry that handles simple slash commands before AgentOrchestrator, reducing latency/token usage and keeping fallback behavior fully intact.
Initial fast-path commands for this PR:
/help/status/usage/model/compact/reset
PR Boundary
In scope:
- New
CommandRegistryabstraction with typed handlers - Built-in deterministic command handlers
- Fast-path integration in channel routing and gateway agent handler
- Graceful fallback to existing orchestrator flow when unmatched
- Unit + integration tests
Out of scope:
- Runtime plugin command loading
- Command auth/ACL system beyond current session/channel constraints
- Command chaining/pipelines
- Per-command rate limiting
File-by-File Diff Plan
src/commands/types.ts(new)
- Define command contracts.
export interface CommandContext {
channel: string;
senderId: string;
sessionId: string;
rawInput: string;
}
export interface CommandResult {
handled: boolean;
text: string;
}
export interface CommandDefinition {
name: string;
aliases?: string[];
description: string;
execute: (args: string[], ctx: CommandContext) => Promise<CommandResult>;
}
src/commands/registry.ts(new)
- Implement registration + parse + execute.
- Use
Mapfor O(1) lookup.
Required methods:
register(def: CommandDefinition): voidget(nameOrAlias: string): CommandDefinition | undefinedlist(): CommandDefinition[]isCommand(input: string): booleanparse(input: string): { name: string; args: string[] } | nullexecute(input: string, ctx: CommandContext): Promise<CommandResult>
src/commands/builtin/index.ts(new)
- Export command factories to avoid circular deps and enable daemon wiring with dependencies.
Factories:
createHelpCommand(registry: CommandRegistry)createStatusCommand()createUsageCommand()createModelCommand(...)createCompactCommand(...)createResetCommand(...)
src/commands/index.ts(new)
- Barrel exports.
src/daemon/index.ts(modify)
- Construct a
CommandRegistryat daemon startup. - Register built-in commands with required deps.
- Pass registry into both message routing and gateway handler dependency paths.
- Add to
DaemonContextif needed for future introspection.
src/daemon/routing.ts(modify)
- In
handler, before invokingagent.process(...):- detect slash command with registry
- execute command
- if
handled, reply immediately and return - if not handled, continue existing orchestrator path
Important:
- Preserve existing
msg.metadata?.isCommandbehavior. - Do not break current
/model,/usage,/compact,/resetlogic while migrating; either reuse existing code in handlers or keep compatibility shim.
src/gateway/handlers/agent.ts(modify)
- Add equivalent fast-path before agent processing.
- Return command output through existing gateway response events.
- Maintain cancellation/queue behavior unchanged.
src/gateway/handlers/index.tsand related handler deps (modify as needed)
- Thread
commandRegistrythrough constructor/dependency interfaces.
- Tests
src/commands/registry.test.ts(new)src/daemon/routing.test.ts(modify/add cases)src/gateway/handlers/agent.test.ts(modify/add cases)
Implementation Steps
- Create typed command contracts and registry.
- Add core parse/lookup/execute behavior with strict handling for unknown commands.
- Implement built-in command handlers as factories.
- Wire registry in daemon bootstrap.
- Add channel router fast-path.
- Add gateway fast-path.
- Add tests for success/fallback/error cases.
- Run full validation suite.
Validation Commands
pnpm typecheck
pnpm test:run src/commands/registry.test.ts
pnpm test:run src/daemon/routing.test.ts
pnpm test:run src/gateway/handlers/agent.test.ts
pnpm test:run
pnpm lint
pnpm build
Acceptance Criteria
CommandRegistrysupports register/get/list/parse/execute.- Known commands are handled without entering
AgentOrchestrator.process(). - Unknown commands cleanly fall through to existing orchestration flow.
- Existing slash command UX remains unchanged for users.
/model,/usage,/compact,/resetstill function correctly via fast-path.- Gateway and channel routes both support fast-path execution.
- All tests pass; no regressions in existing command behavior.
Quality Gates
- Backward compatibility:
- Existing command parsing and metadata behavior still works.
- Existing TUI/web command flows are not broken.
- Security:
- No shell execution from command names/args in registry core.
- Input length and basic parse validation enforced.
- Handler errors are caught and returned safely.
- Performance:
- Lookup uses O(1) maps.
- No measurable slowdown for non-command messages.
- Reliability:
- Registry failures do not crash daemon startup unexpectedly.
- Unknown command behavior deterministic and tested.
Risks and Mitigations
- Risk: duplicate command logic between old path and new path.
- Mitigation: move existing command branches into reusable built-in handlers, keep thin compatibility shim.
- Risk: divergence between gateway and channel behavior.
- Mitigation: reuse same registry + handler functions; add parity tests for both entrypoints.
- Risk: hidden regressions in slash command edge-cases.
- Mitigation: preserve existing parse semantics and add regression tests.
Suggested Commit Message
feat(commands): add fast-path command registry before orchestrator
Follow-up PRs
- Add command discovery/docs endpoint for UI autocomplete.
- Add optional command-level permission profiles.
- Add skill-registered commands (
//skill) on top of registry.