Files
flynn/docs/plans/phase1-pr2-command-registry-checklist.md
2026-02-12 22:47:28 -08:00

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 CommandRegistry abstraction 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

  1. 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>;
}
  1. src/commands/registry.ts (new)
  • Implement registration + parse + execute.
  • Use Map for O(1) lookup.

Required methods:

  • register(def: CommandDefinition): void
  • get(nameOrAlias: string): CommandDefinition | undefined
  • list(): CommandDefinition[]
  • isCommand(input: string): boolean
  • parse(input: string): { name: string; args: string[] } | null
  • execute(input: string, ctx: CommandContext): Promise<CommandResult>
  1. 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(...)
  1. src/commands/index.ts (new)
  • Barrel exports.
  1. src/daemon/index.ts (modify)
  • Construct a CommandRegistry at daemon startup.
  • Register built-in commands with required deps.
  • Pass registry into both message routing and gateway handler dependency paths.
  • Add to DaemonContext if needed for future introspection.
  1. src/daemon/routing.ts (modify)
  • In handler, before invoking agent.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?.isCommand behavior.
  • Do not break current /model, /usage, /compact, /reset logic while migrating; either reuse existing code in handlers or keep compatibility shim.
  1. 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.
  1. src/gateway/handlers/index.ts and related handler deps (modify as needed)
  • Thread commandRegistry through constructor/dependency interfaces.
  1. 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

  1. Create typed command contracts and registry.
  2. Add core parse/lookup/execute behavior with strict handling for unknown commands.
  3. Implement built-in command handlers as factories.
  4. Wire registry in daemon bootstrap.
  5. Add channel router fast-path.
  6. Add gateway fast-path.
  7. Add tests for success/fallback/error cases.
  8. 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

  • CommandRegistry supports 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, /reset still 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

  1. Add command discovery/docs endpoint for UI autocomplete.
  2. Add optional command-level permission profiles.
  3. Add skill-registered commands (//skill) on top of registry.