Sketch of a Claude Code port of openai/symphony — a daemon-style orchestrator that polls an issue tracker, dispatches isolated worker agents per issue, and reconciles state across ticks. Tracker-agnostic by design: the project's CLAUDE.md documents how to talk to whatever tracker is in use (GitHub Issues, Gitea, tracker CLI, Linear, etc.); the plugin reads those instructions rather than shipping per-tracker adapters. Includes: - /symphony-init for first-time setup (detects gh/gitea/tracker, writes the tracker section into project CLAUDE.md, drops WORKFLOW.md, offers to schedule the tick) - /symphony-tick fired by /schedule cron entries (idempotent, silent, never prompts) - per-issue worker agent in isolated worktrees - on-disk state in .symphony/state.json (survives cron cold starts) Known divergences from the spec are documented in the plugin CLAUDE.md (no streaming agent telemetry; no codex.* knobs; hooks run inside the worker rather than the orchestrator). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.8 KiB
name, description
| name | description |
|---|---|
| symphony-init | First-time setup for the Symphony plugin in a project. Detects the issue tracker, writes a tracker integration section into the project's CLAUDE.md, drops a starter WORKFLOW.md, and optionally schedules the orchestrator tick. Use when the user runs /symphony-init or asks to "set up Symphony" / "configure Symphony for this repo". Idempotent — re-running detects existing config and offers updates rather than overwriting. |
Symphony — project initialization
You are running an interactive setup. The user wants Symphony configured for this repo with as little hand-holding as possible. Detect first, ask second. Never ask a question you can answer by probing the environment.
Detection pass (silent, no questions)
Run these checks in parallel before asking anything:
Tracker probes
gh auth statusexit 0 → GitHub Issues available. Rungh repo view --json nameWithOwnerto record the repo.mcp__gitea__get_mereachable → Gitea MCP available. Note the user's orgs.[ -d .tracker ] && [ -f .tracker/config.toml ]→ localtrackerCLI is in use. Thetracker-usageskill is the canonical reference.[ -f .linear/config ]orLINEAR_API_KEYset → Linear configured.
If exactly one tracker is detected, default to it and confirm with the user before writing. If multiple, list them and ask. If none, ask which the project will use.
Existing-config probes
[ -f ./WORKFLOW.md ]→ already initialized at least partially. Read it; show the user a diff of proposed changes rather than overwriting.[ -f ./CLAUDE.md ]and grep for an existing## Issue tracker(or similar) section → don't duplicate; offer to update in place.[ -d .symphony ]→ state directory already exists; leave it alone.cron list(via/schedule) → check whether/symphony-tickis already scheduled.
Project shape probes (used to prefill WORKFLOW.md hooks)
package.json→npm installinbefore_run.pyproject.toml→uv syncinbefore_run.Cargo.toml→cargo fetch.go.mod→go mod download.- Default branch name from
git symbolic-ref refs/remotes/origin/HEAD.
Interview (only what detection couldn't answer)
Ask in one batch where possible. Suggested order:
- Tracker — only if detection didn't yield exactly one. Prefer
AskUserQuestionso the user picks from a list. - Active states — names used for "ready to be picked up" issues.
Suggest defaults per tracker:
- github:
open(filtered by labelreadyorin-progressif the user uses labels) - gitea:
open - tracker: read from
.tracker/config.tomlif present - linear:
Todo,In Progress
- github:
- Terminal states — names that mean "done, don't touch". Defaults:
- github / gitea:
closed - linear:
Done,Cancelled,Duplicate
- github / gitea:
- Concurrency cap — default
3. Mention the user can change this in WORKFLOW.md later without re-running init. - Branch naming — pattern for worker branches. Default
{{ issue.identifier }}(orissue-{{ issue.id }}if the tracker has no human identifier). - Schedule cadence — default every 5 minutes. Offer to skip and have the user
run
/symphony-tickmanually.
Keep the interview short. Anything that has a sensible default should default.
Write phase
-
Tracker section in
./CLAUDE.md— append (or update in place if it already exists) a section under heading## Issue trackerdocumenting:-
Which tracker the project uses.
-
The exact commands to list active issues, get one issue, transition state, and comment on an issue. Use real commands the worker can run, not descriptions. Examples:
## Issue tracker This project uses GitHub Issues (repo: `acme/widgets`). Symphony workers should: - **List active**: `gh issue list --repo acme/widgets --state open --json number,title,body,labels,state,updatedAt` - **Get one**: `gh issue view <number> --repo acme/widgets --json state,title,body,labels` - **Transition**: we use labels — `gh issue edit <number> --repo acme/widgets --add-label in-review --remove-label ready` - **Comment**: `gh issue comment <number> --repo acme/widgets --body "..."` Active label set: `ready`, `in-progress`. Terminal: closed issues.
If the project's CLAUDE.md doesn't exist yet, create it with just this section. Do not invent other content.
-
-
./WORKFLOW.md— copy from the plugin'stemplates/WORKFLOW.md, with detected values substituted (tracker.kind, active_states, terminal_states, concurrency cap, hook commands appropriate to the project's build system). If aWORKFLOW.mdalready exists, show the diff and ask before overwriting. -
.symphony/— create the directory with an emptystate.json:{ "running": {}, "retry_attempts": {}, "claimed": [], "completed": [], "totals": { "ticks": 0 } }. -
.gitignore— append.symphony/state.jsonand.symphony/logs/if not already ignored. The state file is local-runtime, not source.
Schedule offer
If the user opted in to scheduling, invoke the schedule skill to create a routine
that fires /symphony-tick at the chosen cadence. Confirm with the user before
creating; do not silently schedule.
Final summary
End with a 4-line summary:
Tracker: github (acme/widgets)
Workflow: ./WORKFLOW.md (3 concurrent, retry cap 10m)
Schedule: /symphony-tick every 5m (cron id: <id>)
Next: run /symphony-tick once now to verify, or wait for cron
Re-run behavior
If WORKFLOW.md and a CLAUDE.md tracker section both already exist:
- Detect drift (e.g. user changed tracker, repo moved orgs).
- Show what would change. Apply only with confirmation.
- Never delete
.symphony/state.json— losing it strands in-flight workers.