Skip to content

feat(cli): add retort run — multi-CLI team dispatch with .retortconfig routing #487

@JustAGhosT

Description

@JustAGhosT

Summary

Add a retort run command that acts as a unified dispatcher for AI CLI tools (Claude Code, Cursor, Codex, Aider, OpenCode, Windsurf). Instead of users remembering which CLI to open and which context file to load, retort run resolves the right tool from .retortconfig, injects the correct team context, and invokes it.

retort run /team-backend "add payment endpoint"
retort run /orchestrate
retort run /team-frontend --cli cursor     # override preferred CLI
retort run --list-clis                     # show detected CLIs + availability

Motivation

Retort already generates per-tool configs for 15+ AI tools from a single spec. The missing step is runtime dispatch — currently users must:

  1. Know which CLI to use for a given team
  2. Manually open it
  3. Remember to load the right context

retort run closes the loop: spec → config → dispatch.

This also enables the retort-plugins AgentFleetPanel to show agent activity across all CLIs (Claude Code, Codex, Cursor) not just the one that happens to be active.


.retortconfig schema additions

cli:
  preferred: claude          # default CLI for all teams
  fallback: opencode         # if preferred not installed
  team-overrides:
    devops: codex            # use Codex for infra/devops work
    frontend: cursor         # use Cursor for UI work
    data: aider              # use Aider for data/migration work
  auto-detect: true          # scan PATH for available CLIs (default: true)

CLI registry

Internal registry of known AI CLIs, their binary names, and how to invoke slash commands:

CLI Binary Team command pattern Context flag
Claude Code claude claude /team-{id} "{prompt}" --context .claude/
Cursor cursor cursor --cmd "/team-{id} {prompt}" auto (reads .cursor/)
Codex codex codex "{/team-{id}: prompt}" --instructions .github/copilot-instructions.md
Aider aider aider --message "/team-{id}: {prompt}" --read .aider/
OpenCode opencode opencode run /team-{id} "{prompt}" auto
Windsurf windsurf windsurf --task "/team-{id}: {prompt}" auto

Registry lives in .agentkit/engines/node/src/cli-registry.mjs.


Resolution algorithm

1. Parse command: retort run /team-backend "add payment endpoint"
2. Resolve team: look up `backend` in teams.yaml
3. Resolve CLI:
   a. Check .retortconfig cli.team-overrides[backend]
   b. Fall back to .retortconfig cli.preferred
   c. Fall back to .retortconfig cli.fallback
   d. Fall back to first detected CLI in PATH
4. Check availability: which <binary> → error if not found
5. Build invocation: interpolate team + prompt into CLI's command pattern
6. Exec: spawn the CLI, inherit stdio (interactive session)

Detection: retort run --list-clis

Detected AI CLIs:
  ✓ claude        (claude-code v2.1.86)    preferred
  ✓ cursor        (cursor v0.45.0)
  ✗ codex         not found in PATH
  ✓ opencode      (opencode v0.1.14)       fallback
  ✗ aider         not found in PATH
  ✗ windsurf      not found in PATH

Active overrides (.retortconfig):
  frontend → cursor
  devops   → (none configured, using: claude)

Integration with retort-plugins

The retort run --list-clis --json output is consumed by packages/router/src/cli-registry.ts in retort-plugins. The plugin's AskPanel can then offer: "Which CLI do you want to use?" before dispatching a team command.

The AgentFleetPanel shows active agents regardless of which CLI spawned them — because all CLIs write to .claude/state/tasks/ via the shared task protocol (or will once each CLI's Retort config includes a hook that writes task events).


Files

File Change
.agentkit/engines/node/src/cli-registry.mjs New — CLI definitions, detection, invocation builder
.agentkit/engines/node/src/run-command.mjs New — retort run implementation
.agentkit/engines/node/src/cli.mjs Add run to command dispatch
.agentkit/engines/node/src/commands-registry.mjs Add run to VALID_COMMANDS
.agentkit/spec/settings.yaml Document cli: block in schema

Acceptance criteria

  • retort run /team-backend "add payment" invokes the preferred CLI with correct args
  • --cli <name> override works
  • --list-clis shows all CLIs with installed/missing status
  • Team-level overrides in .retortconfig are respected
  • Graceful error if no CLI is installed (retort run without any detected CLI)
  • --dry-run prints the resolved command without executing
  • --json output for machine consumption (used by retort-plugins)
  • Unit tests ≥ 80% coverage (CLI invocation builder, resolution algorithm)

Related

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions