agent-orchestrator-kit
v0.18.0
Published
Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code — spec-driven OpenSpec pipeline, conductor subagents, durable session handoff, factory gates and MCP setup, cloud-agent handoff, and optional local Figma PAT setup
Maintainers
Readme
agent-orchestrator-kit
Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code — spec-driven OpenSpec pipeline with cross-IDE custom subagents.
What It Is
A portable kit that installs a role-separated AI pipeline into any project:
explore → [design] → propose → review → apply → verify → archiveEach role runs in a separate agent session. The parent /opsx:* session is a conductor: it restores state, spawns the routed specialist, verifies its report, and does not perform specialist work itself. OpenSpec files remain the requirements/tasks source of truth; Memory MCP and openspec/changes/<name>/handoff.md index phase state and the next command.
Figma PAT setup — local .agents/figma.local.env + MCP launcher (token never in chat / committed MCP JSON). See Figma token.
Custom subagents ship with the kit and work in all three IDEs:
| Subagent | Role |
|----------|------|
| openspec-guide | Pipeline navigator — status, gates, next /opsx:* command |
| code-writer | Scoped task implementation against stack conventions |
| code-reviewer | Spec-compliance + convention review of the resulting code |
| test-writer | Automated tests for recently changed code |
| setup-doctor | Orchestrator / MCP / sync diagnosis and repair |
| design-implementer | Pixel-accurate Figma / screenshot → production UI |
| codebase-explorer | Read-only repository investigation for explore |
| design-intake | Design source → durable brief + assets |
| spec-architect | Proposal, design, delta specs, and tasks |
| spec-reviewer | Pre-apply artifact gate + review.md |
| spec-archiver | Delta merge and completed-change archive |
| session-handoff | Restore/persist Memory + handoff.md + expanded next-thread prompt |
Delegation is differentiated per phase (lean model): thinking-heavy phases spawn a mandatory specialist, apply is parent-driven, archive is a deterministic CLI:
| Phase / signal | Delegation |
|----------------|------------|
| Status / gates / next command | openspec-guide |
| Session start restore / session exit persist | parent-driven CLI (handoff --restore / handoff <name>); session-handoff is a fallback only |
| Kit / MCP / sync repair | setup-doctor |
| Explore repository research | codebase-explorer (mandatory) |
| Design / propose / spec review | design-intake / spec-architect / spec-reviewer (mandatory) |
| Apply | parent implements from tasks.md + apply-notes.md; code-writer / test-writer optional for ≥ 2 independent tasks or explicit request; design-implementer for design-brief/Figma tasks |
| Pre-PR code review | code-reviewer |
| Archive | npx agent-orchestrator-kit archive <name> (CLI — no subagent; spec-archiver is a fallback when the CLI is unavailable) |
- Cursor →
.cursor/agents/(native subagents) - Claude Code →
.claude/agents/(native subagents) - Amp Code → auto-generated
subagent-*skill wrappers in.agents/skills/; each wrapper requires the parent to spawn an isolated subagent, never execute it in the main thread
Works with:
- Cursor — via
.cursor/rules/+.cursor/skills/+.cursor/agents/ - Claude Code — via
CLAUDE.md+.claude/skills/+.claude/agents/ - Amp Code — via
AGENTS.md+.agents/skills/(native, includingsubagent-*wrappers)
Why
Without role separation, AI agents tend to mix thinking with implementation, skip spec review, and accumulate context debt across one long chat. This kit enforces the discipline at the filesystem level: each role has explicit allowed files, a checklist, and a handoff gate before the next role starts.
The AGENTS.md / CLAUDE.md files tell each IDE exactly what the roles are, so you don't repeat yourself every session.
Quickstart
🆕 New project:
npm i -D @fission-ai/openspec && npx openspec init
npx agent-orchestrator-kit@latest init --profile generic # default: GitHub Actions CI
./scripts/sync-local-agent-skills.shGitLab-hosted project with the opt-in AI Spec Verifier (needs the Amp CLI, AMP_API_KEY, and a GitLab token in CI):
npx agent-orchestrator-kit@latest init --profile generic --ci gitlab --spec-verifySee Installation for profile/CI options.
🔄 Already have the kit installed? Upgrade to latest (v0.18.0 makes the /opsx:propose conductor thin — it no longer researches the repo before or after the spec-architect spawn — and adds two deterministic checks: gate-check --review warns when a change's artifacts outgrow the size budget, and gate-check --review-md checks review.md against the /opsx:review schema; spec-architect and spec-reviewer also get reading rules):
npx agent-orchestrator-kit@latest update
npx agent-orchestrator-kit@latest sync # or: ./scripts/sync-local-agent-skills.sh
npx agent-orchestrator-kit@latest mcp-setup # optional — GitHub/GitLab from origin + browser
npx agent-orchestrator-kit@latest figma-setup # optional — local Figma token
npx agent-orchestrator-kit@latest hooks-setup # optional — pre-commit review gate
npx agent-orchestrator-kit@latest statusThis refreshes kit-managed files, installs .agents/subagents/, generates Amp subagent-* skill wrappers, and syncs agents into .cursor/agents/ + .claude/agents/. See Changelog for the full list.
Installation
Prerequisites
- Node.js ≥ 18
- OpenSpec installed in the project:
npm i -D @fission-ai/openspec
npx openspec initImportant:
agent-orchestrator-kit initdoes not install OpenSpec automatically. Install OpenSpec first (or ensure it exists in the repo), then run kit init.
Install the kit
npx agent-orchestrator-kit initWith a stack profile:
npx agent-orchestrator-kit init --profile vue3
npx agent-orchestrator-kit init --profile node
npx agent-orchestrator-kit init --profile generic
npx agent-orchestrator-kit init --profile mvp # demos / spikes — no review gateWith options:
npx agent-orchestrator-kit init \
--profile vue3 \
--name "My Project" \
--lang ukFor GitLab-hosted projects (verify via prebuild hook — no GitHub Actions):
npx agent-orchestrator-kit init --ci gitlabThis installs .gitlab/agent-verify.yml, injects verify:openspec and PM-aware prebuild into package.json. When DevOps runs npm run build (or yarn/pnpm build), npm lifecycle runs prebuild first → npx openspec validate --all --strict executes automatically.
Optional dev-controlled CI before DevOps setup: copy templates/.gitlab-ci.starter.yml.example from the kit to .gitlab-ci.yml and adjust stages as needed.
Skip CI files entirely:
npx agent-orchestrator-kit init --ci noneDefault remains GitHub Actions (--ci github).
Sync to local IDEs
After init (and after every update):
./scripts/sync-local-agent-skills.shThis copies .agents/ to your local IDE directories (not committed to git).
What Gets Installed
your-project/
├── AGENTS.md
├── CLAUDE.md
├── .github/workflows/agent-verify.yml # CI (default --ci github)
├── .github/workflows/spec-verify.yml # AI Spec Verifier (--ci github --spec-verify, opt-in)
├── .gitlab/agent-verify.yml # CI fragment (--ci gitlab)
├── .gitlab/spec-verify.yml # AI Spec Verifier (--ci gitlab --spec-verify, opt-in)
├── openspec/config.yaml.example # only when openspec/config.yaml does not exist yet
├── .agents/
│ ├── orchestrator.yaml
│ ├── mcp.json.example # Cursor / Claude Code MCP template (.mcp.json)
│ ├── amp.settings.json.example # Amp MCP template (.amp/settings.json)
│ ├── figma.local.env.example # + github/gitlab.local.env.example (token templates)
│ ├── commands/ # /opsx:* role commands
│ ├── rules/ # auto-applied orchestration rules
│ ├── subagents/ # 12 stage/custom subagents (Cursor/Claude/Amp)
│ └── skills/
│ ├── agent-orchestration/ # Pipeline orchestration
│ ├── openspec-howto/
│ ├── openspec-explore/
│ ├── openspec-propose/
│ ├── openspec-apply-change/
│ ├── openspec-archive-change/
│ ├── openspec-sync-specs/
│ └── spec-workflow-openspec/
├── scripts/sync-local-agent-skills.sh
├── scripts/{memory,figma,github,gitlab,browser}-mcp-launcher.cjs # stdio MCP launchers (always)
├── scripts/cursor-spend-hook.cjs + cursor-spend-collect.cjs # Cursor spend capture (always)
├── scripts/pre-commit-gate-check.sh # installed unconnected; wire with hooks-setup / --hooks
├── scripts/post-pr-verdict-github.sh # always copied; used only by the GitHub Spec Verifier
├── scripts/verify-specs.sh + post-mr-verdict.sh # (--spec-verify, opt-in)
├── .mcp.json # seeded from mcp.json.example if missing (memory + figma; mcp-setup adds VCS/browser); no secrets, committing is fine
├── .amp/settings.json # local only — seeded from amp.settings.json.example the same way
└── .cursor/hooks.json + .cursor/memory.json # local only — spend hook entries + Memory MCP storeIncluded in kit
| Category | Contents |
|----------|----------|
| Orchestration | Role-separated pipeline (explore → design → propose → review → apply → verify → archive), AGENTS.md, orchestrator.yaml, review command |
| OpenSpec skills | All 7 skills for /opsx:* workflow |
| IDE sync | Cursor + Claude Code sync script (--delete semantics — removes stale skills/subagents/commands) |
| Subagents | 12 exclusive routes: guide/setup/session-handoff, explore/design/propose/review/archive stage agents, and apply implementation/test/code-review agents — native in Cursor + Claude Code, isolated Amp subagent-* wrappers |
| CLI gates | npx agent-orchestrator-kit status / gate-check / archive / handoff / metrics / memory-setup — deterministic review-gate, archive, session-handoff, and change metrics (always via npx; see cli-via-npm.mdc) |
| CI | agent-verify.yml — GitHub (default) or GitLab fragment + prebuild hook, both run gate-check |
| AI Spec Verifier | spec-verify.yml + verifier scripts — GitLab or GitHub, opt-in (--spec-verify) |
| MCP templates | .agents/mcp.json.example (Cursor / Claude Code .mcp.json) and .agents/amp.settings.json.example (Amp) — five stdio launchers: memory, figma, github, gitlab, browser |
Not included (install separately)
| What | How |
|------|-----|
| OpenSpec CLI | npm i -D @fission-ai/openspec && npx openspec init |
| Stack skills (Vue, JS, Vite) | npx frontend-agent-skills install for vue3 profile |
| Project conventions | Create .agents/project-conventions/SKILL.md manually |
| Domain specs | Live in openspec/specs/ per project |
Git-committed: .agents/ + AGENTS.md + CLAUDE.md + scripts/ + .github/
Local only (not committed): .cursor/ .claude/ .amp/
IDE Integration
Amp Code (primary — zero config)
Amp reads .agents/skills/ and AGENTS.md natively — no sync needed.
CLI note: Amp shells often lack global openspec / agent-orchestrator-kit on PATH (exit 127). Agents must use npx … / npm run … — see always-apply rule .agents/rules/cli-via-npm.mdc.
- Install the kit →
AGENTS.mdis created automatically. - Amp picks up skills from
.agents/skills/on session start. - Copy Amp MCP config (on first sync):
cp .agents/amp.settings.json.example .amp/settings.jsonOr run ./scripts/sync-local-agent-skills.sh — it creates .amp/settings.json automatically.
Subagents in Amp: the kit exposes every .agents/subagents/<name>.md as an auto-generated subagent-<name> skill. The conductor MUST run the wrapper as an isolated subagent with fresh context and MUST NOT execute its body in the main thread. Edit only the source file and re-run sync to regenerate wrappers.
- Use commands directly:
/opsx:explore
/opsx:propose add-feature-name
/opsx:review add-feature-name
/opsx:apply add-feature-name
/opsx:archive
/opsx:sync add-feature-name # agent-driven merge of the change's delta specs into openspec/specs/ without archivingModel hints per role (Amp modes):
| Role | Recommended Amp mode |
|------|---------------------|
| explore | rush |
| propose | smart or deep |
| review | smart |
| apply (complex) | smart or deep |
| apply (simple task) | rush |
Switch modes in Amp CLI: Ctrl+O → mode.
Claude Code
- Run sync:
./scripts/sync-local-agent-skills.sh - This creates:
.claude/CLAUDE.md— project context.claude/skills/— all skills from.agents/skills/(excluding Ampsubagent-*wrappers).claude/agents/— custom subagents from.agents/subagents/(native Claude Code subagents).claude/commands/opsx/—/opsx:*commands from.agents/commands/
- Skills are auto-loaded by Claude Code from
.claude/skills/. The.agents/rules/*.mdcfiles are synced only to Cursor (.cursor/rules/); Claude Code reaches them through the references inCLAUDE.md/AGENTS.md. - Invoke
/opsx:*or the orchestration skill. The conductor delegates using the mandatory phase/signal routing table rather than relying on description-only selection.
CLAUDE.md tiers used:
- Project level:
.claude/CLAUDE.md(synced fromCLAUDE.md) - Personal (optional):
~/.claude/CLAUDE.mdfor preferences
Claude Code subagent config (optional, in skill frontmatter):
---
name: openspec-explore
context: fork
agent: Explore
allowed-tools: Read, Bash
---You can add context: fork to explore/review skills for isolated subagent sessions.
Cursor
- Run sync:
./scripts/sync-local-agent-skills.sh - Creates:
.cursor/skills/— all skills.cursor/rules/—.mdcrule files.cursor/agents/— all 12 custom/stage subagents.mcp.json— frommcp.json.example(if not present)
- Rules are applied automatically per
alwaysApply: true. /opsx:*sessions use the mandatory conductor routing table to spawn subagents. Add project-specific subagents in.agents/subagents/, add an exclusive route, and re-run sync.
Memory + optional Figma MCP for Cursor (.mcp.json):
{
"mcpServers": {
"memory": {
"command": "node",
"args": ["scripts/memory-mcp-launcher.cjs"]
},
"figma": {
"command": "node",
"args": ["scripts/figma-mcp-launcher.cjs"]
}
}
}Token lives in .agents/figma.local.env — see Figma token.
The Pipeline in Detail
Role 1: Explorer — /opsx:explore
Mode: read-only. Cannot edit any files. Model: fast/cheap. Purpose: Understand the problem. Surface options. Choose a direction.
The conductor spawns codebase-explorer for repository investigation and stays read-only.
Exit criteria (before starting Architect):
- Problem stated in 3–5 sentences
- 2–3 solution options + recommendation
- kebab-case change name chosen
- Non-goals listed
/opsx:explore How should we handle bulk camera export?Role 2: Architect — /opsx:propose <name>
Mode: writes openspec/changes/<name>/ only. Cannot touch src/.
Model: strong reasoning.
Purpose: Create all change artifacts: proposal, design, tasks, delta specs.
The conductor spawns spec-architect; it does not write artifacts in the parent session. It is a thin conductor: it does not research the repo itself, passes the decision brief by path, and after the report only runs the exit gate below without re-reading the artifacts.
Exit gate:
npx openspec validate <name> --strict --type change # must be ✓
npx agent-orchestrator-kit gate-check --review <name> # Tier 1 pre-gate: exit 0 before /opsx:review/opsx:propose add-bulk-camera-exportRole 3: Spec Reviewer — /opsx:review <name>
Mode: read-only. No code edits. Model: medium or strong. Purpose: Review artifacts. Output Approve ✓ or Request Changes ✗.
Review is two-tiered. Tier 1 is deterministic: npx agent-orchestrator-kit gate-check --review <name> runs strict OpenSpec validation, the task-contract lint, and structural checks (Non-goals / Acceptance criteria in proposal.md, non-empty delta-spec sections); it also warns when the artifacts outgrow the size budget. If Tier 1 fails, the verdict is REQUEST CHANGES without spawning anyone. Only on a Tier 1 pass does the conductor spawn spec-reviewer (not code-reviewer) for Tier 2 judgment and verify its review.md with gate-check --review-md <name>. On APPROVE the reviewer also writes apply-notes.md (≤ 20 lines of constraints and pitfalls for the implementer).
Tier 2 checks (judgment only — no duplication of Tier 1):
- Consistency proposal ↔ design ↔ tasks
- No scope creep vs Non-goals
- No conflicts with existing domain specs
- Tasks self-sufficient for a blind implementer (Files / Do / Done-when)
/opsx:review add-bulk-camera-exportOnly after explicit APPROVE can apply start.
Role 4: Implementer — /opsx:apply <name>
Mode: conductor; routed specialists write src/ and tests. Only the conductor marks tasks.md [x] after a verified Status: done report.
Model: strong. Use fast for simple mechanical tasks.
Purpose: Implement tasks. One session = 1–3 tasks (not all 15 at once).
Exit gate:
npm run build # must pass
npm run lint # must pass/opsx:apply add-bulk-camera-exportRole 5: Verifier — CI (automatic)
GitHub (default --ci github): installed at .github/workflows/agent-verify.yml:
- run: npx openspec validate --all --strict
- run: npm run lint --if-present
- run: npm run build --if-present
- run: npm test --if-presentGitLab (--ci gitlab): verify runs through the package manager build lifecycle — no GitHub Actions:
"verify:openspec": "npx openspec validate --all --strict",
"prebuild": "npm run verify:openspec"When CI or a developer runs npm run build, npm executes prebuild first. DevOps pipelines that already call npm run build get OpenSpec validate with zero config changes.
Optional: include .gitlab/agent-verify.yml in .gitlab-ci.yml for full lint/build/test verify before DevOps owns the root CI file. See kit templates/.gitlab-ci.starter.yml.example.
Blocks merge if any gate fails.
Both consumer CI templates (templates/.github/workflows/agent-verify.yml and templates/.gitlab/agent-verify.yml, installed as agent-verify.yml) also run npx agent-orchestrator-kit gate-check — see Deterministic gates below. It never fails the pipeline for projects without .agents/orchestrator.yaml. (The kit's own repository CI runs only openspec validate + npm test.)
AI Spec Verifier (GitLab or GitHub, opt-in)
npx agent-orchestrator-kit init --ci gitlab --spec-verify
npx agent-orchestrator-kit init --ci github --spec-verifyInstalls an AI verification layer on top of the deterministic gates: on every merge/pull request that changes src/, an Amp agent reads openspec/specs/, checks the changed code against every relevant requirement, posts a PASS / BLOCKED comment to the MR/PR, and fails the pipeline on BLOCKED — specs become an enforceable merge contract, not just documentation.
Installed files (GitLab):
| File | Purpose |
|------|---------|
| .gitlab/spec-verify.yml | CI fragment — hidden .spec-verify-base + blocking spec-verify job (MR + src/**/* only) |
| scripts/verify-specs.sh | Collects changed files + specs, builds prompt (project context from openspec/config.yaml), calls amp -x, writes artifacts/verdict.json |
| scripts/post-mr-verdict.sh | Posts the verdict as an MR comment via GitLab API |
Installed files (GitHub):
| File | Purpose |
|------|---------|
| .github/workflows/spec-verify.yml | Workflow triggered on pull_request for src/** — same verdict evaluation, permissions: pull-requests: write |
| scripts/verify-specs.sh | Same script as GitLab — stack-agnostic, reused as-is |
| scripts/post-pr-verdict-github.sh | Posts the verdict as a PR comment via gh pr comment |
The flag also adds spec-verify-blocking to roles.verifier.gates in .agents/orchestrator.yaml.
Setup after install (GitLab):
- Include the fragment from
.gitlab-ci.yml:
include:
- local: '.gitlab/spec-verify.yml'- Add CI/CD variables (Settings → CI/CD → Variables, masked):
AMP_API_KEY,GITLAB_VERIFIER_TOKEN(project access token withapiscope).
Setup after install (GitHub): the workflow runs automatically on pull_request — just add the repo secret AMP_API_KEY (Settings → Secrets and variables → Actions). GITHUB_TOKEN is provided by Actions automatically.
Verdict schema (artifacts/verdict.json): pass, score (0–100), summary, findings[] with severity (error fails the job), spec, requirement, message, file. The script degrades gracefully — no src/ changes, no specs, missing amp CLI, or missing AMP_API_KEY produce a skipped passing verdict and never block the pipeline. Secrets are never logged; .env/key/token files are excluded from prompts.
Warning-only rollout (Phase 1): uncomment allow_failure: true (GitLab) or continue-on-error: true (GitHub) to keep the pipeline green while the team builds trust in verdicts, then remove it to enforce blocking (Phase 2).
update refreshes the spec-verify files only in projects that already installed them — the feature stays opt-in.
Deterministic gates: status / gate-check
Orchestration hard rules (review approval, one active change) used to rely entirely on the agent remembering to check them in chat. Two CLI commands make them checkable and CI-enforceable:
npx agent-orchestrator-kit statusPrints an archive_after_merge: <true|false> policy line under the title (when .agents/orchestrator.yaml exists), then every active OpenSpec change with task progress (N/M tasks), review verdict (APPROVE / REQUEST CHANGES / none), design brief (brief: yes/no), a ready to archive flag once all tasks are [x], and an MCP health section (launcher / env / live config — never prints token values). VCS tools that do not match git remote origin show as skipped (no origin match).
npx agent-orchestrator-kit gate-check [change-name] [--src-glob src/] [--base HEAD~1] [--staged]Fails (non-zero exit) when pipeline.require_spec_review: true, the diff against --base (or staged files with --staged) touches --src-glob, and the active change has no review.md with Verdict: APPROVE. When pipeline.require_design_brief: true and src/ changed, it also requires design-brief.md (or a Design: none line in proposal.md for non-UI changes). It degrades gracefully to exit 0 (with a message, not silently) when: .agents/orchestrator.yaml is missing, neither review nor design brief is required, the diff can't be computed (e.g. shallow clone), or nothing under --src-glob changed. It also warns (never fails) when active changes exceed pipeline.max_active_changes. Both consumer agent-verify.yml templates (GitHub and GitLab, installed by init --ci) call gate-check automatically. Pre-commit uses --staged so it checks the index, not HEAD~1.
npx agent-orchestrator-kit gate-check --tasks <change-name>Lints the task contract in tasks.md: every task needs Files: / Do: / Done-when:, no vague phrasing (as needed, if necessary, …), and every Files: path must exist unless prefixed new file:. Behavior follows pipeline.task_contract in orchestrator.yaml: warn (default) exits 0 with warnings, strict exits 1 on violations, off skips the lint.
npx agent-orchestrator-kit gate-check --review <change-name> [--json]Deterministic Tier 1 of the review phase: strict OpenSpec validation, the task-contract lint, Non-goals / Acceptance criteria sections in proposal.md, non-empty ADDED/MODIFIED/REMOVED sections in delta specs, and the same heading checks archive --sync enforces (a MODIFIED/REMOVED title must exist in the main spec, an ADDED title must not). Human-readable stdout, or --json for a {pass, errors[]} report.
It also measures proposal.md, design.md, tasks.md and the delta specs in bytes and reports artifact budget: … when tasks.md is over 60 000 B or their total is over 150 000 B, with the advice to split the change into slices. pipeline.artifact_budget sets the mode: warn (default) prints a warning and keeps the exit code, strict makes it an error (exit 1), off skips the measurement.
npx agent-orchestrator-kit gate-check --review-md <change-name> [--json]Checks review.md against the /opsx:review schema after Tier 2: exactly one Verdict: line (APPROVE or REQUEST CHANGES), a Previous findings heading, on REQUEST CHANGES non-empty Checklist, Findings (Blocker / Major / Minor) and Required Before Apply, on APPROVE an apply-notes.md of at most 20 lines. A Tier 1 record (**Source:** gate-check, no Checklist) only has to be REQUEST CHANGES. Exit 1 with the error list, or --json for a {pass, errors[]} report. /opsx:review runs it after the spec-reviewer report instead of checking the headings by hand.
Pre-commit review gate (optional)
gate-check already exists; it is not wired to git commit unless you opt in. The kit never writes .git/hooks/ directly.
npx agent-orchestrator-kit hooks-setup
# or: npx agent-orchestrator-kit init --hooks- If
.husky/exists, a marked linesh scripts/pre-commit-gate-check.shis appended to.husky/pre-commit(idempotent; existing content is kept).core.hooksPathis not changed. - Otherwise the kit writes committed
.githooks/pre-commitand runsgit config core.hooksPath .githooks. Ifcore.hooksPathis already set to something else, the command refuses and prints a manual line to add. - Lefthook: add
sh scripts/pre-commit-gate-check.shto your pre-commit job yourself (no auto-write). initwithout--hooksstill installsscripts/pre-commit-gate-check.shas a managed file, unconnected.- Disable: remove the marked line from
.husky/pre-commit, orgit config --unset core.hooksPath. - MVP (
require_spec_review: false): the hook is a no-op (exit 0). - Keep
agent-orchestrator-kitin the project's devDependencies sonpx agent-orchestrator-kiton every commit does not cold-fetch from the registry.
Run hooks-setup on each machine (git config is local), same as figma-setup.
Optional MCP: GitHub, GitLab, browser
Same pattern as Figma: stdio launcher + gitignored env + committed .example. Tokens never go in chat or committed MCP JSON.
npx agent-orchestrator-kit mcp-setupDetection uses git remote get-url origin (https and ssh). --ci is ignored.
| Origin hostname | Installed VCS MCP |
|-----------------|-------------------|
| github.com | GitHub only |
| gitlab.com or hostname contains gitlab (self-hosted) | GitLab only; GITLAB_API_URL=https://<hostname>/api/v4 |
| missing / unrecognized | no VCS MCP (status shows skipped) |
Browser MCP (@playwright/mcp) is always added unless you pass --no-browser. Override detection with --vcs github or --vcs gitlab.
npx agent-orchestrator-kit mcp-setup --vcs gitlab --no-browserThen put tokens only in the gitignored files (never in chat):
| Path | Git |
|------|-----|
| .agents/github.local.env | ignored |
| .agents/gitlab.local.env | ignored |
| .agents/*.local.env.example | committed |
| scripts/*-mcp-launcher.cjs | committed |
Cursor, Claude Code, and Amp all spawn the same launchers. Committed examples list all five servers (memory, figma, github, gitlab, browser); live .mcp.json / .amp/settings.json receive only the detected VCS plus browser.
npx agent-orchestrator-kit status prints MCP health (ok / not configured / skipped) without token values.
Design intake: /opsx:design
Optional phase between explore and propose (or before apply) that captures design into a durable artifact so implement sessions do not depend on live Figma MCP:
/opsx:design add-login-formWrites only:
openspec/changes/<name>/design-brief.md— Source, Structure, Tokens, Reference images, Constraints, Confidence notesopenspec/changes/<name>/assets/— reference PNGs
Source fallback: Figma MCP (one pass) → exported images → screenshots → photos. Raster sources must mark inferred values with confidence notes.
Opt-in gate (default off — existing projects unchanged):
pipeline:
require_design_brief: true # gate-check fails without brief when src/ changedNon-UI changes: add this line to proposal.md:
Design: noneExisting projects after update: the command file opsx-design.md is installed automatically. Your orchestrator.yaml is never overwritten — add the role and flag manually if you want the gate:
pipeline:
require_design_brief: false # set true to enforce
roles:
design_intake:
command: /opsx:design
mode: brief-only
model_hint: strongArchive — terminal first, /opsx:archive as fallback
After the PR is merged and CI is green, archive from a terminal — no chat needed:
npx agent-orchestrator-kit archive add-bulk-camera-export --syncAfter a green apply (the Implementer closes, every task in tasks.md is [x], ## Blocked is none), handoff <name> prints exactly this line instead of a next-session prompt; run it once the PR is merged. /opsx:archive <name> stays as a fallback for when a terminal or CI was not available.
Archive is a deterministic CLI, not an agent workflow:
npx agent-orchestrator-kit archive <name> [--sync | --no-sync --force] [--if-ready] [--collect]It first runs Gate 0 and refuses a folder that already looks archived (archivedAt set in the change metrics.json, or Next command: none in handoff.md; for a re-opened copy clear the marker and re-run), then checks the gates (APPROVE in review.md when required, all tasks [x], target folder free), merges delta specs into openspec/specs/ (--sync: ADDED append, MODIFIED replace, REMOVED delete), moves the change to openspec/changes/archive/YYYY-MM-DD-<name>, and runs npx openspec validate --all --strict with a full rollback on failure (main specs restored, new spec files deleted, move reverted). With delta specs present you must decide: --sync merges, --no-sync --force archives without merging, and no flag refuses with exit 1. It finishes by writing the final handoff.md (next_command: none), updating memory, appending an Archiver session, and printing the same human metrics summary as metrics <name>. Archive collects the locked client (Cursor hook / Amp threads / Claude JSONL) in [pending.startedAt, now] plus leftover of the previous session — the same leftover-then-collect flow as persist. --collect still runs every adapter. Unique ## Metrics in the change handoff.md still counts as Archiver self-report; leftover apply numbers that match the previous session are ignored. /opsx:archive is the chat fallback: a thin wrapper that calls this CLI, shows its output, and on a refusal prints it and stops; the spec-archiver subagent remains only as a fallback when the CLI is unavailable.
--if-ready is the CI mode of the same command. It prints one skip: <reason> line, exits 0 and changes nothing when pipeline.archive_after_merge is false, the change already looks archived (Gate 0), or it is not ready — the same blockers status prints (tasks incomplete, no review.md, …; a missing tasks.md counts as not ready). Otherwise it archives like a normal run, and real failures (an existing target folder, a delta-spec sync conflict, a failed validation) still exit 1. Without --if-ready a manual archive ignores archive_after_merge.
CI archive (opt-in)
A terminal stays the default. The CI templates (agent-verify.yml: GitHub job archive, GitLab job agent-archive) also contain an archive job that is off until you opt in:
- Set the repository variable (GitLab: CI/CD variable)
AOK_ARCHIVE_ON_MERGE=true. Without it the job is skipped. - Add the secret (GitLab: masked CI/CD variable)
AOK_ARCHIVE_TOKEN— a token whose user may push to the protected default branch (a branch-protection bypass). On GitHub the job falls back to the workflow token, which can push only to an unprotected branch. - Keep
pipeline.archive_after_merge: truein.agents/orchestrator.yaml(themvpprofile setsfalse).
On a push to the default branch the job waits for verify, runs archive <name> --sync --if-ready for every openspec/changes/<name>/, and pushes one chore(openspec): archive merged change [skip ci] commit with the moved change and its finalized metrics.json; [skip ci] keeps that push from starting another run.
Known caveats: a Cursor sessionEnd hook can append leftover usage to a local metrics.json after the last persist, which then conflicts with the CI commit (keep the archived copy when you resolve it); two merges in quick succession can make the first push fail as non-fast-forward (the next push to the default branch archives again, or archive from a terminal); the job runs the published npx agent-orchestrator-kit, so it needs a kit version that has --if-ready.
Configuration
Edit .agents/orchestrator.yaml after init:
project:
name: "My Project"
agent_language: uk # response language for agents
pipeline:
require_spec_review: true
require_design_brief: false # opt-in: require design-brief.md when src/ changed
max_active_changes: 1
archive_after_merge: true # policy flag: `status` shows it; `archive --if-ready` and the opt-in CI job honour it; a manual archive ignores it
task_contract: warn # tasks.md lint mode for gate-check: warn | strict | off
artifact_budget: warn # change size budget for gate-check --review: warn | strict | off (a missing key means warn)
src_glob: "src/" # paths gate-check treats as product code (default for --src-glob)
verifier:
lint_command: "npm run lint"
build_command: "npm run build"
test_command: "npm test" # optionalUpdate
When a new version of the kit is released:
npx agent-orchestrator-kit update
./scripts/sync-local-agent-skills.shupdate only touches kit-managed files (commands, rules, skills). It never overwrites:
orchestrator.yamlopenspec/config.yamlopenspec/specs/openspec/changes/- Any project-conventions skills
Existing openspec/config.yaml: update never touches it, and init skips openspec/config.yaml.example when openspec/config.yaml already exists (for example after npx openspec init). Add the proposal rule by hand, under rules.proposal, so openspec instructions proposal tells the architect about the Tier 1 headings:
rules:
proposal:
- "Always include the exact level-2 headings '## Non-goals' and '## Acceptance criteria' (gate-check --review Tier 1 rejects the proposal without them)."Double-quote every rule: an unquoted item that contains : makes OpenSpec drop the whole list for that artifact, and an unquoted # silently cuts the rule short (YAML reads the rest as a comment). A fresh init --profile node or init --profile generic installs openspec/config.yaml.example with these rules from templates/openspec-config.yaml.example; init --force overwrites an existing openspec/config.yaml.
Upgrading from older versions
No re-init is needed — update + sync is the whole upgrade path:
npx agent-orchestrator-kit@latest update
npx agent-orchestrator-kit@latest sync # or: ./scripts/sync-local-agent-skills.sh
npx agent-orchestrator-kit@latest status- CI files are refreshed only where they already exist:
updaterewrites.github/workflows/agent-verify.yml/.gitlab/agent-verify.ymland the opt-inspec-verify.yml+ verifier scripts when the project has them, and never creates a workflow for a provider you did not choose. - Adding the AI Spec Verifier to a project that never had it is a separate opt-in — run it once, then add the
AMP_API_KEYsecret:npx agent-orchestrator-kit@latest init --ci github --spec-verify # or --ci gitlab updatenever edits your CI root file. Ifgate-checkdoes not seem to run on GitLab, check that.gitlab-ci.ymlstillincludes.gitlab/agent-verify.yml(GitHub Actions picks up.github/workflows/*.ymlautomatically).
Profiles
| Profile | Stack | Extra (separate install) |
|---------|-------|--------------------------|
| generic | Any | Orchestration + OpenSpec skills only. init still writes the detected JS package-manager commands (npm/yarn/pnpm lint / build / test) into verifier.* of orchestrator.yaml — non-Node projects edit those three commands after init |
| vue3 | Vue 3 + Vite + JS | + npx frontend-agent-skills install |
| node | Node.js | + npx frontend-agent-skills install --category javascript |
| mvp | Vue 3 demo/spike | + frontend-agent-skills; use /opsx:quick, no review gate |
For vue3, after kit init also run:
# Amp (primary — installs directly to .agents/skills/)
npx frontend-agent-skills install --agent amp --yes
# Cursor + Claude Code users — sync local IDE dirs
./scripts/sync-local-agent-skills.shOr install for all IDEs at once:
npx frontend-agent-skills install --agent all --yesMigrating from
vue-cursor-skills? Renamed tofrontend-agent-skillsv2 — same package, old CLI alias still works.
Figma token (optional)
Personal Access Token for design intake (/opsx:design) and the optional Framelink figma-developer-mcp server. Never paste the token into AI chat.
Setup (each developer, once)
npx agent-orchestrator-kit figma-setup
# open .agents/figma.local.env in the IDE and set:
# FIGMA_ACCESS_TOKEN=figd_...
npx agent-orchestrator-kit figma-statusThen restart Cursor / Claude Code / Amp.
| Path | Purpose | Git |
|------|---------|-----|
| .agents/figma.local.env | Your token (FIGMA_ACCESS_TOKEN) | ignored |
| .agents/figma.local.env.example | Template | committed |
| scripts/figma-mcp-launcher.cjs | Starts MCP with token from the env file | committed |
| .mcp.json → figma | Points at the launcher (no secret inline) | committed OK |
Create a token: Figma → Settings → Security → Personal access tokens (file content read as needed).
CLI
npx agent-orchestrator-kit figma-setup
npx agent-orchestrator-kit figma-status
npx agent-orchestrator-kit figma-fetch --url "https://www.figma.com/design/FILE_KEY/Name?node-id=1-2" \
--out openspec/changes/<name>/assets/figma-nodes.json
# large frames: limit tree depth
npx agent-orchestrator-kit figma-fetch --file FILE_KEY --nodes 1:2 --depth 2 --out figma-nodes.jsonfigma-fetch uses the Figma REST API (X-Figma-Token) and writes JSON for design-brief capture. Live Figma is for design-intake only — apply uses design-brief.md.
Upgrade existing projects
npx agent-orchestrator-kit@latest update
npx agent-orchestrator-kit figma-setup
./scripts/sync-local-agent-skills.shMemory MCP — Shared State Between Sessions
Each role starts a fresh session. OpenSpec artifacts remain the source of truth; Memory MCP and openspec/changes/<name>/handoff.md are the phase index used to resume without re-explanation.
Standard entities to save:
Change:add-bulk-export status: spec-approved, tasks: 0/7, last_role: reviewer, review: APPROVE
Decision:export-format chosen: xlsx, reason: matches existing reports
Handoff:add-bulk-export next_role: implementer, next_command: /opsx:apply add-bulk-export,
session_count: 2, summary: ..., blocked: noneSession boundaries are parent-driven (no routine subagent): every /opsx:* session restores via npx agent-orchestrator-kit handoff --restore (the CLI briefing already reads memory.json and handoff.md), falling back to reading handoff.md directly if the CLI fails. At exit the parent itself writes handoff.md, runs npx agent-orchestrator-kit handoff <name> (upserts .cursor/memory.json with an absolute path), and pastes the CLI stdout prompt. The session-handoff subagent is spawned only when the CLI path fails; Memory MCP is an optional mirror. The prompt is self-contained — Amp often skips Memory MCP, so the next thread must be able to work from the pasted text alone. Never configure Memory with a relative MEMORY_FILE_PATH; use scripts/memory-mcp-launcher.cjs (npx agent-orchestrator-kit memory-setup). The next phase always starts in a new chat. The canonical Session Start / Exit protocol lives in one place — .agents/rules/session-handoff.mdc — and the /opsx:* commands reference it instead of duplicating it.
Change decisions (decisions.md)
Session decisions accumulate in git-tracked, append-only openspec/changes/<name>/decisions.md. That file is the canon visible in a PR/MR; Memory Decision:* is a file → Memory mirror only.
npx agent-orchestrator-kit handoff add-bulk-export
# appends dated bullets from handoff.md ## Decisions (skips duplicates; same topic + new text → new row)
npx agent-orchestrator-kit handoff add-bulk-export --restore
# prints decisions from the git file (or `decisions: none` if the file does not exist)Decisions: none does not create the file. Re-running persist with the same handoff does not duplicate rows. A later revision of the same topic is a new line; the old line stays. update does not migrate historical Memory entities into the file.
Cloud agent handoff (Phase 3)
Every persist writes a ## Runtime section to openspec/changes/<name>/handoff.md:
## Runtime
- runtime: local|cloud
- agent_id: <id|none>Detection is a fixed chain (no TTY / CURSOR_AGENT magic): --runtime → env AOK_RUNTIME → CLOUD_ENV_MARKERS (starts with CURSOR_BACKGROUND_AGENT) → existing ## Runtime in the file → local. agent_id uses --agent-id → AOK_AGENT_ID → existing value → none. Invalid --runtime (not local or cloud) exits non-zero. Legacy files without Runtime stay valid; the next persist appends the section.
Configure a cloud agent once:
AOK_RUNTIME=cloud
AOK_AGENT_ID=<vm-or-run-id>--cloud-check is a separate branch of handoff, never part of persist (persist has just rewritten handoff.md, so the tree is always dirty at that point). It verifies (1) git status --porcelain -- openspec/changes/<name>/ is empty and (2) the current branch has an upstream with no unpushed commits. Verdict: cloud + any failure = non-zero; local + the same failure = warning + exit 0; clean = exit 0. The CLI never runs git commit or git push.
Cloud Session Exit order:
npx agent-orchestrator-kit handoff <name> --runtime cloud
git add openspec/changes/<name>/
git commit
git push
npx agent-orchestrator-kit handoff <name> --cloud-check # require exit 0Persist with runtime: cloud prints those four steps on stderr; stdout stays the pure /opsx: next-thread prompt. Local persist is unchanged.
Change metrics
Every change accumulates git-tracked openspec/changes/<name>/metrics.json — the data source for planning the next feature: how long each phase took, how many sessions it needed, what it cost.
Schema v2 stores compact sourceIds, sourceTotals, and byModel per session instead of sessions[].sources. This is BREAKING for readers of the old event arrays. v1 files are normalized in memory without rewriting; run npx agent-orchestrator-kit metrics <name> --migrate for a schema-only rewrite that preserves existing numeric fields and aggregates.
## Metricsself-report — Session Exit fillshandoff.mdwithplatform,model,input_tokens,output_tokens,cost_usd,amp_credits,spend_source(unknownwhen missing). Persist reads that section;metrics.jsonis the source of truth for what landed. CLI flags do not rewrite the section.session.model— source product id wins when any collected source has a model;--model/## Metrics: model/AOK_MODELapply only when sources have no model. Never a Closed role.- Session start —
handoff --restorewrites apendingmarker (startedAt, expected role). - Session end —
handoff <name>closes the pending session. Its collect lower bound is--started-atorpending.startedAtminus 120 seconds; without either it is the previousendedAt, orcreatedAtfor the first session, with no open-ended scan. Amp usage totals and fresh Cost are authoritative; Claude JSONL is deduplicated bymessage.id, includes subagents, and accepts cwd descendants. Claude uses a versioned Anthropic list-price estimate with cache split; Amp without Cost uses the same model table or the $3/$15 fallback. Estimates never enter billedcostUsd. - Archive — successful
archive <name>always creates or finalizesmetrics.json, setsarchivedAt, appends an Archiver session, collects the locked client (Cursor hook / Amp export+usage / Claude JSONL) in[pending.startedAt, now]plus leftover of the previous session, and prints the same human summary asmetrics <name>.--collectstill runs all three adapters. Leftover apply## Metricsthat repeats the previous session is ignored so those tokens are not counted twice. sessionEndleftover —scripts/cursor-spend-collect.cjsalso reads the newestopenspec/changes/archive/*-<name>/metrics.jsonwhen the active change folder is gone, so a late hook after archive still attaches.stop/afterAgentResponserun the same leftover after a successful jsonl append. Whenlast.threadIdis non-empty, leftover keeps only rows whoseconversationIdmatches that id (empty/nullthreadId stays time-only). In a multi-root window leftover walks every candidate that hasopenspec/changes, reading that root’s jsonl. Aggregates writecostUsdEstimatedwith 4 decimal places. Eachphases.<phase>storesstartedAt/endedAt/leadTimeMsfrom that phase’s sessions;durationMsstays the work-time sum and does not clonetotals.leadTimeMs.- Leftover without
--collect— Scopes tolast.platformand Amp thread identity fromthreadIdorsourceIds. Sessions without a thread id are capped atendedAt + 120s; identified sessions may continue to the next pending boundary. Fresh Amp usage totals, Models, and Cost replace cached values. - Cursor
conversationId— restore writesCURSOR_CONVERSATION_IDintopending.threadId; Cursor collect and sessionEnd leftover skip rows whoseconversationIddoes not match when a filter id is present (last.threadIdon leftover). - Canonical role —
session.roleandpending.rolestore the first known token (Explorer,Architect,Spec Reviewer,Implementer,Archiver,Design Intake); Closed role inhandoff.mdMAY keep a sentence after—. - Platform —
--platform→## Metrics: platform→AOK_PLATFORM→ pending client from--restore→ host env (Amp / Cursor / Claude Code) → collected sources (cursor|claude|amponly). Invalid--platformfails before persist/move. - Locked client —
--restorerecordspending.platformand Amppending.threadIdbefore phase work. Persist follows that client’s flow even if persist runs in another shell (noAMP_*/CURSOR_*). Amp:amp threads exportplusamp threads usage --details(AOK_AMP_BIN) and localthreads/*.json. Export suppliesmodel/ tokens /agentMode; usage supplies billed$. If Amp runs tools over a pipe (/dev/null), thread id comes fromamp threads list, not stalesession.jsonlastThreadId. When env and Amp parent do not win, restore locks a freshsession.jsonlastThreadIdasamp-session-last. Cursor: spend hook file. Claude:~/.claude/projects.--collectstill runs all three adapters. - Cursor spend hook (optional) — Cursor never writes token usage to disk, so the kit can install
scripts/cursor-spend-hook.cjsplus.cursor/hooks.jsonentries (stop/subagentStop/afterAgentResponse) ininit/update/sync/mcp-setup: the hook appends each turn's tokens to gitignored.agents/spend/cursor-usage.jsonl. After a successfulstop/afterAgentResponseappend the hook runs leftover (fail-open, no stdout). Hook and collect resolve the consumer in a multi-root window (not the first cwd with.agentsoropenspec). Persist auto-reads that file when the locked client is Cursor. Persist and restore do not self-heal the hook.sessionEndstill runsscripts/cursor-spend-collect.cjs. Restart Cursor once after the first install.statusshows aSpend capturesection. Claude JSONL remains a fallback. Amp web/CLI spend is taken fromamp threads export(tokens, model,agentMode) andamp threads usage(billed USD).
Aggregates are recomputed on every write: per-phase totals (startedAt, endedAt, leadTimeMs from that phase’s sessions, durationMs = sum of session work time — not totals.leadTimeMs and not endedAt − startedAt, tokens, costUsd, costUsdEstimated, costUsdTotal to 4 decimals, sessions, roles, models) plus overall totals (sessions, cloudSessions, durationMs = sum of session work time, leadTimeMs = wall clock from first session start to last session end), spend (USD only), and separate by platform / by model tables. Numbers are null-honest: a metric nobody reported stays null, never a fake 0. No single total that adds Amp credits to USD. costUsdTotal is the one USD figure per change, phase, platform, model, and session: each session contributes its billed costUsd when present, otherwise its costUsdEstimated, so a change that ran on Amp (billed) plus Cursor and Claude (estimated) sums all three platforms instead of showing only the billed part. Amp credits never enter it. The human cost: line prints it as $21.08 ($14.48 billed + ~$6.60 est.).
Fill ## Metrics in handoff.md before persist (unknown is fine; do not invent 0):
## Metrics
- platform: cursor
- model: cursor-grok-4.6
- input_tokens: 128000
- output_tokens: 9400
- cost_usd: unknown
- amp_credits: unknown
- spend_source: self-reportnpx agent-orchestrator-kit handoff add-thing
npx agent-orchestrator-kit handoff add-thing --collect # optional: Claude JSONL / Amp threads / Cursor hook
npx agent-orchestrator-kit metrics add-thing # human summary: phases, tokens, cost, roles / models
npx agent-orchestrator-kit metrics add-thing --json # raw metrics.json (works for archived changes too)
npx agent-orchestrator-kit metrics add-thing --summary-json # compact dashboard contract
npx agent-orchestrator-kit metrics add-thing --migrate # rewrite v1 → v2 without numeric recompute
npx agent-orchestrator-kit archive add-thing --sync # finalize + the same tables as metricsFor dashboards
Use only phases.<phase>.startedAt, endedAt, and durationMs for phase boundaries and duration. Use totals.leadTimeMs only for the whole change. Git log MUST NOT be used for phase boundaries; the kit does not provide per-phase commit counts. metrics <name> --summary-json returns only aggregate totals, phases, and spend maps, without sessions or commits. For the headline cost use spend.costUsdTotal (and phases.<phase>.costUsdTotal, spendByPlatform.<platform>.costUsdTotal, spendByModel[].costUsdTotal): costUsd alone is only the billed part and costUsdEstimated alone is only the estimated part, so picking one of them drops every platform that reported the other.
Recording is on by default and never a persist/archive/gate-check gate; opt out per persist with --no-metrics. Persist and archive collect the locked client without --collect; --collect runs every adapter. Flags (--model, --platform, --input-tokens, …) override session totals in metrics.json and do not rewrite the ## Metrics section.
Skill inventory
.agents/orchestrator.yaml carries a machine-readable skills: section (kit / stack / external) instead of hardcoded skill names in the CLI:
skills:
kit:
- agent-orchestration
- openspec-howto
# ... remaining kit skills
stack: [] # vue3: vue-core, vue-pinia, vue-axios, vue-router
external: "" # vue3/node: frontend-agent-skillsnpx agent-orchestrator-kit status prints Skill health after MCP health (ok / missing / stale) for kit + stack skills and Amp subagent-* wrappers. The section is warn-only: missing or stale skills never change the exit code. Repair with the existing commands — sync (stale IDE copies), update (missing kit files), or a manual stack install:
npx frontend-agent-skills install --agent all --yesThe CLI never auto-installs external skill packages. .agents/orchestrator.yaml is outside kit-managed paths, so update does not refresh skills.kit — after a kit skill is added or removed, edit that list by hand (or re-init with --force).
Amp Code — Deep Integration Notes
Amp is the primary target of this kit. It reads .agents/skills/ and AGENTS.md without any sync step — your team commits .agents/ and everyone gets the same orchestration behavior automatically.
Amp-specific features used:
| Feature | How the kit uses it |
|---------|-------------------|
| AGENTS.md at the repo root | Roles, hard rules, and routing pointers (.agents/rules/) read on every session |
| .agents/skills/ | All orchestration + domain skills |
| .amp/settings.json (amp.mcpServers) | Memory MCP via scripts/memory-mcp-launcher.cjs; seeded from .agents/amp.settings.json.example by init / sync |
| Subagents | Conductor routing + isolated subagent-* wrappers |
| Amp modes (rush/smart/deep) | Per-role model hints in AGENTS.md |
Amp generated wrapper (.agents/skills/subagent-codebase-explorer/SKILL.md):
---
name: subagent-codebase-explorer
description: Read-only repository research specialist...
---
CRITICAL (Amp / Cursor / Claude): Parent MUST spawn this skill as an isolated subagent with fresh context.
Do not execute it in the main thread. If spawn is unavailable, STOP and report blocked.The conductor invokes the wrapper in isolation and consumes only its structured report.
Team workflow with Amp:
- Commit
.agents/to git. - Team members clone — skills available immediately.
- No
sync-local-agent-skills.shneeded for Amp users. - Cursor/Claude Code users run sync once after clone.
CLI Reference
npx agent-orchestrator-kit init [options]
--profile <name> Stack profile: generic | vue3 | node | mvp
--lang <code> Agent language: en | uk | ...
--name <name> Project name (default: directory name)
--ci <provider> CI provider: gitlab | github | none (default: github)
--spec-verify Install AI Spec Verifier blocking gate (GitLab or GitHub)
--hooks Opt-in: install pre-commit gate-check hook (husky-first)
--force Overwrite existing files
npx agent-orchestrator-kit update
Updates kit-managed files, preserves project overlay
npx agent-orchestrator-kit sync [options]
--target <ide> cursor | claude | amp | all (default: all)
Copies .agents/ to local IDE directories, removing skills/rules no longer
present in .agents/. Also seeds local files it never overwrites: creates an
empty .cursor/memory.json, seeds .mcp.json / .amp/settings.json from the
.example files and upserts the memory server entry, writes the spend-hook
entries into .cursor/hooks.json, merges .gitignore, and copies CLAUDE.md to
.claude/CLAUDE.md. Existing user content in those files is kept.
npx agent-orchestrator-kit status
Show the archive_after_merge policy line, progress, review verdict, archive-readiness, MCP health, and Skill health
(warn-only; missing/stale skills do not fail the command)
npx agent-orchestrator-kit gate-check [change-name] [options]
--src-glob <glob> Source path filter used to detect code changes; a comma- or
space-separated list is passed to git as separate pathspecs
(default: pipeline.src_glob from orchestrator.yaml, else src/)
--base <ref> Git ref to diff against (default: HEAD~1)
--staged Check staged files (git diff --cached) instead of --base
--tasks <name> Lint task contracts (Files / Do / Done-when)
--review <name> Deterministic Tier 1 review (optional --json)
--review-md <name> Check review.md against the /opsx:review schema (optional --json)
Exit non-zero when require_spec_review is true, src/ changed, and the
active change has no review.md with Verdict: APPROVE. Graceful no-op
otherwise (missing config, review not required, no relevant diff).
npx agent-orchestrator-kit hooks-setup
Opt-in pre-commit gate (husky-first, else core.hooksPath=.githooks)
npx agent-orchestrator-kit mcp-setup [--vcs github|gitlab] [--no-browser]
Install GitHub/GitLab (from origin) and browser MCP launchers
npx agent-orchestrator-kit figma-setup
Create local .agents/figma.local.env from the example, refresh the launcher,
and add the figma MCP entry to .mcp.json / .amp/settings.json (never prints the token)
npx agent-orchestrator-kit figma-status
Report whether a local Figma token is configured (never prints the token)
npx agent-orchestrator-kit figma-fetch [options]
--url <url> Figma design URL (file key + optional node-id)
--file <key> Figma file key
--nodes <ids> Comma-separated node ids (1:2 or 1-2)
--depth <n> Limit node tree depth (use for large frames; omit = full tree)
--out <path> Output JSON path (default: figma-nodes.json)
Fetch Figma file/nodes JSON via the REST API using the local token
npx agent-orchestrator-kit memory-setup
Install the memory MCP launcher and rewrite Cursor/Amp configs to use an
absolute MEMORY_FILE_PATH
npx agent-orchestrator-kit archive <name> [--sync | --no-sync --force] [options]
--model <name> LLM product id recorded on the Archiver session
--platform <id> cursor | claude | amp
--input-tokens <n> / --output-tokens <n> / --total-tokens <n>
Token spend for the Archiver session (total defaults to in+out)
--cost-usd <usd> Cost of the Archiver session in USD
--collect Collect all spend adapters (default: locked client only)
--if-ready CI mode: print "skip: <reason>" and exit 0 (nothing changed) when
archive_after_merge is false, the change already looks archived
(Gate 0) or is not ready; real failures still exit 1
Refuse an already archived folder (Gate 0), gate-check a completed change, optionally merge delta specs, move to
openspec/changes/archive/YYYY-MM-DD-<name>, validate, write final handoff,
and print the change-wide metrics summary.
npx agent-orchestrator-kit handoff [change-name] [options]
--restore Print the restore briefing instead of persisting
(also records the session start into metrics.json)
--closed-role <role> Closed role for persist
--next-command <command> Next /opsx:* command
--next-role <role> Next role or subagent name
--summary <text> Persisted summary (also fills Done when Done is empty)
--done <text> Done section
--decisions <text> Decisions section
--blocked <text> Blocked section
--attach <text> Attach section
--spawn <text> Subagents to spawn
--constraints <text> Constraints section
--status <status> Change status observation
--tasks <progress> Task progress n/m
--review <verdict> Review verdict
--session-count <n> Handoff session_count
--runtime <value> local | cloud (invalid values exit non-zero)
--agent-id <id> Cloud agent identifier (default: none)
--cloud-check Verify change artifacts are committed and pushed
(cloud: non-zero on failure; local: warning, exit 0)
--started-at <iso> Session start override when --restore was not run
--model <name> LLM product id (metrics.json); never a Closed role
--platform <id> cursor | claude | amp
--input-tokens <n> / --output-tokens <n> / --total-tokens <n>
Token spend for this session (total defaults to in+out)
--cost-usd <usd> Session cost in USD
--collect Also run local spend adapters (off by default)
--no-metrics Skip recording this session into metrics.json
After a green apply (Implementer, every task [x], Blocked none) stdout is the
single archive command line instead of a next-session prompt.
npx agent-orchestrator-kit metrics [change-name] [options]
--json Print raw metrics.json
--summary-json Print compact aggregate JSON for dashboards
--migrate Rewrite metrics.json using the current schema without
recomputing numbers (v1 → v2)
--collect Backfill the last session from local spend adapters
without adding a new session
Show recorded session metrics for a change (active or archived):
time per phase, sessions, tokens, cost, roles, models, lead time.Directory Reference
.agents/ # Committed — source of truth for all IDEs
commands/ # /opsx:* command definitions
rules/ # Auto-applied rules for Cursor
subagents/ # Custom subagents (source of truth, all IDEs)
skills/ # Skills for Cursor, Claude Code, Amp
# subagent-*/ — auto-generated Amp wrappers (do not edit)
orchestrator.yaml # Project pipeline config
.cursor/ # Local only — Cursor IDE runtime
skills/ # Synced from .agents/skills/
rules/ # Synced from .agents/rules/
agents/ # Synced from .agents/subagents/
commands/ # Synced from .agents/commands/ (flat — /opsx-apply)
memory.json # Memory MCP data
.claude/ # Local only — Claude Code runtime
skills/ # Synced from .agents/skills/
agents/ # Synced from .agents/subagents/
commands/opsx/ # Synced from .agents/commands/ (namespaced — /opsx:apply)
CLAUDE.md # Synced from root CLAUDE.md
.amp/ # Local only — Amp config
settings.json # MCP servers (manual or via amp mcp add)
AGENTS.md # Committed — read natively by Amp; CLAUDE.md is the Claude Code entry point
CLAUDE.md # Committed — synced to .claude/CLAUDE.md
openspec/ # Committed — spec-driven workflow
config.yaml # Project context for AI
specs/ # Source of truth after archive
changes/ # Active work; <name>/handoff.md + metrics.json index session stateRoadmap
The kit moves toward an Agentic Factory in four phases. One phase = one OpenSpec change; the next phase does not start until the previous change is archived.
add-factory-gates-and-mcp— local review gate on commit and Figma-style MCP launchers (GitHub / GitLab / browser). Implemented:hooks-setup,mcp-setup,gate-check --staged, MCP health instatus.add-factory-memory-and-skills— git-canonical decisions with Memory MCP as a mirror, plus a machine skill inventory. Implemented: append-onlydecisions.md, Skill health instatus.add-cloud-agent-handoff— session artifacts exist only on git-tracked paths. Implemented:## Runtimeinhandoff.md,--runtime/--agent-id/--cloud-check, cloud Session Exit.- Phase 4 (
add-factory-control-plane) is an opt-in platform decision, not the next sprint. Phase bounds and non-goals:openspec/specs/agentic-factory-roadmap/spec.md.
Changelog
0.18.0
- Thin
/opsx:proposeconductor: the parent does not research the repo. It reads the decision brief (by path),statusandhandoff --restore, spawnsspec-architectwithin 5 tool calls, and after the report makes at most 3 tool calls without re-reading the artifacts on a green gate. - Artifact size budget in
gate-check --review: a warning whentasks.mdis over 60 000 B orproposal.md+design.md+tasks.md+ delta specs are over 150 000 B, with the advice to split the change into slices.pipeline.artifact_budget: warn | strict | offsets the mode (def
