-
Notifications
You must be signed in to change notification settings - Fork 0
feat(cli): add retort run — multi-CLI team dispatch with .retortconfig routing #487
Description
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 + availabilityMotivation
Retort already generates per-tool configs for 15+ AI tools from a single spec. The missing step is runtime dispatch — currently users must:
- Know which CLI to use for a given team
- Manually open it
- 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-clisshows all CLIs with installed/missing status - Team-level overrides in
.retortconfigare respected - Graceful error if no CLI is installed (
retort runwithout any detected CLI) -
--dry-runprints the resolved command without executing -
--jsonoutput for machine consumption (used by retort-plugins) - Unit tests ≥ 80% coverage (CLI invocation builder, resolution algorithm)
Related
- retort-plugins#1 — router package that consumes
--list-clis --json .retortconfigschema (landed PR feat(config): add .retortconfig — agent remapping and opt-in feature flags v1 #479) —cli:block extends existing structureworktree.mjs— similar spawn pattern for reference
🤖 Generated with Claude Code