agent-orchestrator-kit 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.1.10] - 2026-07-15
6
+
7
+ ### Added
8
+ - **Custom subagents** — new `.agents/subagents/` asset category, synced to `.cursor/agents/` and `.claude/agents/` (like skills/rules, delete-stale semantics on `sync`)
9
+ - 6 default subagents: `openspec-guide` (pipeline navigator, read-only), `code-writer` (scoped task implementation), `code-reviewer` (spec-compliance + convention review), `test-writer` (test authoring), `setup-doctor` (orchestrator setup diagnosis/repair), `design-implementer` (pixel-accurate Figma/screenshot → code, honors design-brief priority)
10
+ - **Amp support via skill wrappers** — Amp has no file-based subagents, so `init`/`update`/`sync` auto-generate a committed `.agents/skills/subagent-<name>/SKILL.md` wrapper per subagent (Amp loads `.agents/skills/` natively); wrappers are excluded from `.cursor/`/`.claude/` skill sync and removed when the source subagent is deleted
11
+ - `update` and `sync --target cursor|claude|all` now manage `.agents/subagents/` alongside skills and rules
12
+ - `scripts/sync-local-agent-skills.sh` generates Amp wrappers and rsyncs `.agents/subagents/` → `.cursor/agents/` and `.claude/agents/`
13
+
14
+ ### Fixed
15
+ - `update` no longer resurrects a CI workflow file the project deleted (e.g. `.github/workflows/agent-verify.yml` after switching to GitLab CI) — CI files are refreshed only when already present
16
+ - `update` keeps `scripts/sync-local-agent-skills.sh` executable
17
+
18
+ ## [0.1.9] - 2026-07-12
19
+
20
+ ### Added
21
+ - **Design intake** — optional `/opsx:design` phase: captures Figma / export / screenshot / photo into `design-brief.md` + `assets/` (writes only those paths)
22
+ - **Role `design_intake`** in templates and all profiles (`generic`, `vue3`, `node`, `mvp`) with `pipeline.require_design_brief: false` (opt-in)
23
+ - **`gate-check` design brief gate** — when `require_design_brief: true` and `src/` changed, requires `design-brief.md` or `Design: none` in `proposal.md`
24
+ - **`status`** shows `brief: yes/no` for every active change
25
+ - **Docs** — AGENTS.md / CLAUDE.md / rules / agent-orchestration skill / README section for design intake and manual enable after `update`
26
+
5
27
  ## [0.1.8] - 2026-07-07
6
28
 
7
29
  ### Changed
package/README.md CHANGED
@@ -1,24 +1,39 @@
1
1
  # agent-orchestrator-kit
2
2
 
3
- Universal AI agent orchestration kit for **Cursor**, **Claude Code**, and **Amp Code** — spec-driven pipeline built on [OpenSpec](https://github.com/fission-ai/openspec).
3
+ Universal AI agent orchestration kit for **Cursor**, **Claude Code**, and **Amp Code** — spec-driven OpenSpec pipeline with **cross-IDE custom subagents**.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/agent-orchestrator-kit)](https://www.npmjs.com/package/agent-orchestrator-kit)
6
6
  [![license](https://img.shields.io/npm/l/agent-orchestrator-kit)](LICENSE)
7
7
 
8
8
  ## What It Is
9
9
 
10
- A portable kit that installs a **5-role AI pipeline** into any project:
10
+ A portable kit that installs a **role-separated AI pipeline** into any project:
11
11
 
12
12
  ```
13
- explore → propose → review → apply → verify → archive
13
+ explore → [design] → propose → review → apply → verify → archive
14
14
  ```
15
15
 
16
16
  Each role runs in a **separate agent session** with dedicated permissions, model hints, and handoff gates. The `openspec/changes/` folder acts as the **contract between agents** — no shared memory between sessions, only files.
17
17
 
18
+ **Custom subagents (v0.1.10+)** ship with the kit and work in all three IDEs:
19
+
20
+ | Subagent | Role |
21
+ |----------|------|
22
+ | `openspec-guide` | Pipeline navigator — status, gates, next `/opsx:*` command |
23
+ | `code-writer` | Scoped task implementation against stack conventions |
24
+ | `code-reviewer` | Spec-compliance + convention review of the resulting code |
25
+ | `test-writer` | Automated tests for recently changed code |
26
+ | `setup-doctor` | Orchestrator / MCP / sync diagnosis and repair |
27
+ | `design-implementer` | Pixel-accurate Figma / screenshot → production UI |
28
+
29
+ - **Cursor** → `.cursor/agents/` (native subagents)
30
+ - **Claude Code** → `.claude/agents/` (native subagents)
31
+ - **Amp Code** → auto-generated `subagent-*` skill wrappers in `.agents/skills/` (Amp has no file-based subagents)
32
+
18
33
  Works with:
19
- - [Cursor](https://cursor.sh) — via `.cursor/rules/` + `.cursor/skills/`
20
- - [Claude Code](https://code.claude.com) — via `CLAUDE.md` + `.claude/skills/`
21
- - [Amp Code](https://ampcode.com) — via `AGENTS.md` + `.agents/skills/` (native, no sync needed)
34
+ - [Cursor](https://cursor.sh) — via `.cursor/rules/` + `.cursor/skills/` + `.cursor/agents/`
35
+ - [Claude Code](https://code.claude.com) — via `CLAUDE.md` + `.claude/skills/` + `.claude/agents/`
36
+ - [Amp Code](https://ampcode.com) — via `AGENTS.md` + `.agents/skills/` (native, including `subagent-*` wrappers)
22
37
 
23
38
  ## Why
24
39
 
@@ -38,15 +53,15 @@ npx agent-orchestrator-kit@latest init --profile generic --ci gitlab --spec-veri
38
53
 
39
54
  See [Installation](#installation) for profile/CI options.
40
55
 
41
- **🔄 Already have the kit installed? Get `status` / `gate-check` / GitHub Spec Verifier (v0.1.7+):**
56
+ **🔄 Already have the kit installed? Upgrade to latest (subagents in v0.1.10+):**
42
57
 
43
58
  ```bash
44
59
  npx agent-orchestrator-kit@latest update
45
- ./scripts/sync-local-agent-skills.sh
46
- npx agent-orchestrator-kit@latest status # try it right away
60
+ npx agent-orchestrator-kit@latest sync # or: ./scripts/sync-local-agent-skills.sh
61
+ npx agent-orchestrator-kit@latest status
47
62
  ```
48
63
 
49
- See [Upgrading an existing project](#upgrading-an-existing-project-to-v017-status--gate-check--github-spec-verifier) for what changes and what stays opt-in.
64
+ This refreshes kit-managed files, installs `.agents/subagents/`, generates Amp `subagent-*` skill wrappers, and syncs agents into `.cursor/agents/` + `.claude/agents/`. See [Changelog](#changelog) for the full list.
50
65
 
51
66
  ## Installation
52
67
 
@@ -130,6 +145,7 @@ your-project/
130
145
  │ ├── amp.settings.json.example # Amp MCP template
131
146
  │ ├── commands/ # 6 /opsx:* commands
132
147
  │ ├── rules/ # 3 auto-applied rules
148
+ │ ├── subagents/ # 6 default custom subagents (Cursor/Claude/Amp)
133
149
  │ └── skills/
134
150
  │ ├── agent-orchestration/ # Pipeline orchestration
135
151
  │ ├── openspec-howto/
@@ -149,7 +165,8 @@ your-project/
149
165
  |----------|----------|
150
166
  | Orchestration | 5-role pipeline, `AGENTS.md`, `orchestrator.yaml`, review command |
151
167
  | OpenSpec skills | All 7 skills for `/opsx:*` workflow |
152
- | IDE sync | Cursor + Claude Code sync script (`--delete` semantics — removes stale skills) |
168
+ | IDE sync | Cursor + Claude Code sync script (`--delete` semantics — removes stale skills/subagents) |
169
+ | Subagents | `openspec-guide`, `code-writer`, `code-reviewer`, `test-writer`, `setup-doctor`, `design-implementer` — native in Cursor (`.cursor/agents/`) + Claude Code (`.claude/agents/`), exposed to Amp as auto-generated `subagent-*` skill wrappers in `.agents/skills/` |
153
170
  | CLI gates | `agent-orchestrator status` / `gate-check` — deterministic review-gate checks |
154
171
  | CI | `agent-verify.yml` — GitHub (default) or GitLab fragment + `prebuild` hook, both run `gate-check` |
155
172
  | AI Spec Verifier | `spec-verify.yml` + verifier scripts — GitLab or GitHub, opt-in (`--spec-verify`) |
@@ -183,6 +200,8 @@ cp .agents/amp.settings.json.example .amp/settings.json
183
200
 
184
201
  Or run `./scripts/sync-local-agent-skills.sh` — it creates `.amp/settings.json` automatically.
185
202
 
203
+ **Subagents in Amp:** Amp has no file-based custom subagents (only skills and plugin agents), so the kit exposes every `.agents/subagents/<name>.md` as an auto-generated skill `subagent-<name>` in `.agents/skills/`. These wrappers are committed to git, so Amp picks them up with zero local setup — just say "use the subagent-design-implementer skill" or let Amp auto-load it from the description. Edit the source file in `.agents/subagents/` (never the wrapper) and re-run `sync` to regenerate.
204
+
186
205
  4. Use commands directly:
187
206
 
188
207
  ```
@@ -210,9 +229,10 @@ Switch modes in Amp CLI: `Ctrl+O` → `mode`.
210
229
  1. Run sync: `./scripts/sync-local-agent-skills.sh`
211
230
  2. This creates:
212
231
  - `.claude/CLAUDE.md` — project context
213
- - `.claude/skills/` — all skills from `.agents/skills/`
232
+ - `.claude/skills/` — all skills from `.agents/skills/` (excluding Amp `subagent-*` wrappers)
233
+ - `.claude/agents/` — custom subagents from `.agents/subagents/` (native Claude Code subagents)
214
234
  3. Skills are auto-loaded by Claude Code from `.claude/skills/`.
215
- 4. Invoke directly: `/agent-orchestration`, `/openspec-howto`, etc.
235
+ 4. Invoke directly: `/agent-orchestration`, `/openspec-howto`, etc. Subagents are delegated automatically by description or on request ("use the design-implementer subagent").
216
236
 
217
237
  **CLAUDE.md tiers used:**
218
238
  - Project level: `.claude/CLAUDE.md` (synced from `CLAUDE.md`)
@@ -237,8 +257,10 @@ You can add `context: fork` to explore/review skills for isolated subagent sessi
237
257
  2. Creates:
238
258
  - `.cursor/skills/` — all skills
239
259
  - `.cursor/rules/` — `.mdc` rule files
260
+ - `.cursor/agents/` — custom subagents (`openspec-guide`, `code-writer`, `code-reviewer`, `test-writer`, `setup-doctor`, `design-implementer`)
240
261
  - `.mcp.json` — from `mcp.json.example` (if not present)
241
262
  3. Rules are applied automatically per `alwaysApply: true`.
263
+ 4. Subagents are invoked by name in chat (e.g. "use the code-reviewer subagent on this diff") or delegated to automatically by Cursor when their `description` matches the task. Add project-specific subagents by dropping `.md` files into `.agents/subagents/` and re-running sync.
242
264
 
243
265
  **Memory MCP for Cursor** (`.mcp.json`):
244
266
 
@@ -411,13 +433,54 @@ Orchestration hard rules (review approval, one active change) used to rely entir
411
433
  npx agent-orchestrator-kit status
412
434
  ```
413
435
 
414
- Prints every active OpenSpec change with task progress (`N/M tasks`), review verdict (`APPROVE` / `REQUEST CHANGES` / `none`), and a `ready to archive` flag once all tasks are `[x]` — no more running `openspec status` per change by hand.
436
+ Prints every active OpenSpec change with task progress (`N/M tasks`), review verdict (`APPROVE` / `REQUEST CHANGES` / `none`), design brief (`brief: yes/no`), and a `ready to archive` flag once all tasks are `[x]` — no more running `openspec status` per change by hand.
415
437
 
416
438
  ```bash
417
439
  npx agent-orchestrator-kit gate-check [change-name] [--src-glob src/] [--base HEAD~1]
418
440
  ```
419
441
 
420
- Fails (non-zero exit) when `pipeline.require_spec_review: true`, the diff against `--base` touches `--src-glob`, and the active change has no `review.md` with `Verdict: APPROVE`. It degrades gracefully to exit 0 (with a message, not silently) when: `.agents/orchestrator.yaml` is missing, review isn't 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 `agent-verify.yml` fragments (GitHub and GitLab) call `gate-check` automatically.
442
+ Fails (non-zero exit) when `pipeline.require_spec_review: true`, the diff against `--base` 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 `agent-verify.yml` fragments (GitHub and GitLab) call `gate-check` automatically.
443
+
444
+ ---
445
+
446
+ ### Design intake: `/opsx:design`
447
+
448
+ 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:
449
+
450
+ ```
451
+ /opsx:design add-login-form
452
+ ```
453
+
454
+ Writes only:
455
+ - `openspec/changes/<name>/design-brief.md` — Source, Structure, Tokens, Reference images, Constraints, Confidence notes
456
+ - `openspec/changes/<name>/assets/` — reference PNGs
457
+
458
+ Source fallback: Figma MCP (one pass) → exported images → screenshots → photos. Raster sources must mark inferred values with confidence notes.
459
+
460
+ **Opt-in gate** (default off — existing projects unchanged):
461
+
462
+ ```yaml
463
+ pipeline:
464
+ require_design_brief: true # gate-check fails without brief when src/ changed
465
+ ```
466
+
467
+ Non-UI changes: add this line to `proposal.md`:
468
+
469
+ ```
470
+ Design: none
471
+ ```
472
+
473
+ **Existing 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:
474
+
475
+ ```yaml
476
+ pipeline:
477
+ require_design_brief: false # set true to enforce
478
+ roles:
479
+ design_intake:
480
+ command: /opsx:design
481
+ mode: brief-only
482
+ model_hint: strong
483
+ ```
421
484
 
422
485
  ---
423
486
 
@@ -441,6 +504,7 @@ project:
441
504
 
442
505
  pipeline:
443
506
  require_spec_review: true
507
+ require_design_brief: false # opt-in: require design-brief.md when src/ changed
444
508
  max_active_changes: 1
445
509
  archive_after_merge: true
446
510
 
@@ -606,16 +670,20 @@ npx agent-orchestrator-kit gate-check [change-name] [options]
606
670
  .agents/ # Committed — source of truth for all IDEs
607
671
  commands/ # /opsx:* command definitions
608
672
  rules/ # Auto-applied rules for Cursor
673
+ subagents/ # Custom subagents (source of truth, all IDEs)
609
674
  skills/ # Skills for Cursor, Claude Code, Amp
675
+ # subagent-*/ — auto-generated Amp wrappers (do not edit)
610
676
  orchestrator.yaml # Project pipeline config
611
677
 
612
678
  .cursor/ # Local only — Cursor IDE runtime
613
679
  skills/ # Synced from .agents/skills/
614
680
  rules/ # Synced from .agents/rules/
681
+ agents/ # Synced from .agents/subagents/
615
682
  memory.json # Memory MCP data
616
683
 
617
684
  .claude/ # Local only — Claude Code runtime
618
685
  skills/ # Synced from .agents/skills/
686
+ agents/ # Synced from .agents/subagents/
619
687
  CLAUDE.md # Synced from root CLAUDE.md
620
688
 
621
689
  .amp/ # Local only — Amp config
@@ -631,6 +699,16 @@ openspec/ # Committed — spec-driven workflow
631
699
 
632
700
  ## Changelog
633
701
 
702
+ ### 0.1.10
703
+ - Custom subagents (`.agents/subagents/`) synced to `.cursor/agents/` + `.claude/agents/`, exposed to Amp via auto-generated `subagent-*` skill wrappers
704
+ - 6 default subagents: `openspec-guide`, `code-writer`, `code-reviewer`, `test-writer`, `setup-doctor`, `design-implementer`
705
+ - `update` no longer resurrects deleted CI workflow files
706
+
707
+ ### 0.1.9
708
+ - Design intake — `/opsx:design` captures design into `design-brief.md` + `assets/` (Figma / export / screenshot / photo)
709
+ - Role `design_intake` + opt-in `pipeline.require_design_brief` (default `false`) in all profiles
710
+ - `gate-check` enforces design brief when enabled (`Design: none` opt-out for non-UI); `status` shows `brief: yes/no`
711
+
634
712
  ### 0.1.8
635
713
  - README — Quickstart (new vs existing project) and upgrade guide for adopting `status`, `gate-check`, and GitHub Spec Verifier
636
714
 
@@ -26,12 +26,17 @@ const KIT_SKILL_DIRS = [
26
26
  const KIT_MANAGED_PATHS = [
27
27
  '.agents/commands',
28
28
  '.agents/rules',
29
+ '.agents/subagents',
29
30
  ...KIT_SKILL_DIRS.map((s) => `.agents/skills/${s}`),
30
- '.github/workflows/agent-verify.yml',
31
- '.gitlab/agent-verify.yml',
32
31
  'scripts/sync-local-agent-skills.sh',
33
32
  ];
34
33
 
34
+ // CI workflow files are provider-specific and chosen once at `init --ci`.
35
+ // `update` must only refresh them if already present — never resurrect a
36
+ // workflow file for a provider the project doesn't use (e.g. after switching
37
+ // from GitHub Actions to GitLab CI and deleting the GitHub workflow).
38
+ const CI_WORKFLOW_PATHS = ['.github/workflows/agent-verify.yml', '.gitlab/agent-verify.yml'];
39
+
35
40
  // Opt-in AI Spec Verifier files, per CI provider. `scripts/verify-specs.sh` is
36
41
  // shared — it is stack- and CI-agnostic already.
37
42
  const GITLAB_SPEC_VERIFY_PATHS = [
@@ -178,14 +183,27 @@ function parseReviewVerdict(changeDir) {
178
183
  return match ? match[1].trim() : 'unknown';
179
184
  }
180
185
 
186
+ function parseDesignBrief(changeDir) {
187
+ return existsSync(join(changeDir, 'design-brief.md'));
188
+ }
189
+
190
+ function hasDesignOptOut(changeDir) {
191
+ const proposalPath = join(changeDir, 'proposal.md');
192
+ if (!existsSync(proposalPath)) return false;
193
+ const content = readFileSync(proposalPath, 'utf-8');
194
+ return /^Design:\s*none/mi.test(content);
195
+ }
196
+
181
197
  function readPipelineConfig(projectDir) {
182
198
  const orchPath = join(projectDir, '.agents', 'orchestrator.yaml');
183
199
  if (!existsSync(orchPath)) return null;
184
200
  const content = readFileSync(orchPath, 'utf-8');
185
201
  const requireReviewMatch = content.match(/require_spec_review:\s*(true|false)/);
202
+ const requireBriefMatch = content.match(/require_design_brief:\s*(true|false)/);
186
203
  const maxActiveMatch = content.match(/max_active_changes:\s*(\d+)/);
187
204
  return {
188
205
  requireSpecReview: requireReviewMatch ? requireReviewMatch[1] === 'true' : true,
206
+ requireDesignBrief: requireBriefMatch ? requireBriefMatch[1] === 'true' : false,
189
207
  maxActiveChanges: maxActiveMatch ? parseInt(maxActiveMatch[1], 10) : null,
190
208
  };
191
209
  }
@@ -426,8 +444,65 @@ function printNextSteps(profile, projectDir, ci = 'github', specVerify = false)
426
444
  console.log('\n' + lines.join('\n') + '\n');
427
445
  }
428
446
 
447
+ // Amp has no file-based custom subagents (only skills and plugin agents), but
448
+ // it natively loads skills from .agents/skills/ with the same description-driven
449
+ // delegation. Each .agents/subagents/<name>.md therefore gets a committed skill
450
+ // wrapper .agents/skills/subagent-<name>/SKILL.md so subagents work in Amp with
451
+ // zero local setup. Wrappers are regenerated on init/update/sync and stale ones
452
+ // are removed when their source subagent is deleted.
453
+ const AMP_SUBAGENT_SKILL_PREFIX = 'subagent-';
454
+
455
+ function listAmpSubagentWrappers(projectDir) {
456
+ const skillsDir = join(projectDir, '.agents', 'skills');
457
+ if (!existsSync(skillsDir)) return [];
458
+ return readdirSync(skillsDir).filter((entry) => entry.startsWith(AMP_SUBAGENT_SKILL_PREFIX));
459
+ }
460
+
461
+ function generateAmpSubagentSkills(projectDir) {
462
+ const subagentsDir = join(projectDir, '.agents', 'subagents');
463
+ const skillsDir = join(projectDir, '.agents', 'skills');
464
+ const expected = new Set();
465
+
466
+ if (existsSync(subagentsDir)) {
467
+ for (const file of readdirSync(subagentsDir).filter((f) => f.endsWith('.md'))) {
468
+ const content = readFileSync(join(subagentsDir, file), 'utf-8');
469
+ const parsed = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
470
+ const name = parsed?.[1].match(/^name:\s*(.+)$/m)?.[1]?.trim();
471
+ const description = parsed?.[1].match(/^description:\s*(.+)$/m)?.[1]?.trim();
472
+ if (!name || !description) {
473
+ log.warn(`skip Amp wrapper (missing name/description frontmatter): .agents/subagents/${file}`);
474
+ continue;
475
+ }
476
+
477
+ const skillName = `${AMP_SUBAGENT_SKILL_PREFIX}${name}`;
478
+ expected.add(skillName);
479
+ mkdirSync(join(skillsDir, skillName), { recursive: true });
480
+ const skill = [
481
+ '---',
482
+ `name: ${skillName}`,
483
+ `description: ${description}`,
484
+ '---',
485
+ '',
486
+ `<!-- AUTO-GENERATED from .agents/subagents/${file} — edit the source file, then run: npx agent-orchestrator-kit sync -->`,
487
+ '',
488
+ parsed[2].trim(),
489
+ '',
490
+ ].join('\n');
491
+ writeFileSync(join(skillsDir, skillName, 'SKILL.md'), skill);
492
+ log.ok(`.agents/skills/${skillName}/SKILL.md (Amp wrapper)`);
493
+ }
494
+ }
495
+
496
+ for (const entry of listAmpSubagentWrappers(projectDir)) {
497
+ if (!expected.has(entry)) {
498
+ rmSync(join(projectDir, '.agents', 'skills', entry), { recursive: true, force: true });
499
+ log.warn(`removed stale Amp wrapper: .agents/skills/${entry}`);
500
+ }
501
+ }
502
+ }
503
+
429
504
  function syncAmp(projectDir) {
430
- log.info('Amp Code reads .agents/ natively — no skill sync needed');
505
+ log.info('Amp Code reads .agents/ natively — subagents exposed via skill wrappers');
431
506
  mkdirSync(join(projectDir, '.amp'), { recursive: true });
432
507
  const ampExample = join(projectDir, '.agents', 'amp.settings.json.example');
433
508
  const ampDest = join(projectDir, '.amp', 'settings.json');
@@ -478,6 +553,7 @@ program
478
553
  if (existsSync(join(profileDir, '.agents'))) {
479
554
  copyDir(join(profileDir, '.agents'), join(projectDir, '.agents'), { overwrite: opts.force });
480
555
  }
556
+ generateAmpSubagentSkills(projectDir);
481
557
 
482
558
  log.title('Installing scripts/');
483
559
  copyDir(join(templateDir, 'scripts'), join(projectDir, 'scripts'), {
@@ -565,6 +641,16 @@ program
565
641
  }
566
642
  }
567
643
 
644
+ generateAmpSubagentSkills(projectDir);
645
+
646
+ for (const rel of CI_WORKFLOW_PATHS) {
647
+ const src = join(templateDir, rel);
648
+ const dest = join(projectDir, rel);
649
+ if (!existsSync(src) || !existsSync(dest)) continue;
650
+ copyFileSync(src, dest);
651
+ log.ok(rel);
652
+ }
653
+
568
654
  for (const rel of KIT_OPTIN_PATHS) {
569
655
  const src = join(templateDir, rel);
570
656
  const dest = join(projectDir, rel);
@@ -573,6 +659,10 @@ program
573
659
  log.ok(`${rel} (opt-in)`);
574
660
  }
575
661
 
662
+ try {
663
+ execSync(`chmod +x ${join(projectDir, 'scripts', 'sync-local-agent-skills.sh')}`);
664
+ } catch {}
665
+
576
666
  log.ok(`Updated to v${KIT_VERSION}`);
577
667
  log.info('Run ./scripts/sync-local-agent-skills.sh to sync to local IDE');
578
668
  });
@@ -590,10 +680,20 @@ program
590
680
  const syncClaude = ['claude', 'all'].includes(opts.target);
591
681
  const syncAmpTarget = ['amp', 'all'].includes(opts.target);
592
682
 
683
+ generateAmpSubagentSkills(projectDir);
684
+
685
+ // Amp skill wrappers are redundant in Cursor/Claude (they get native
686
+ // subagents from .agents/subagents/), so exclude them from skill sync.
687
+ const ampWrappers = listAmpSubagentWrappers(projectDir);
688
+
593
689
  if (syncCursor) {
594
690
  log.info('Syncing .agents/ → .cursor/');
595
- copyDir(join(projectDir, '.agents', 'skills'), join(projectDir, '.cursor', 'skills'), { overwrite: true, delete: true });
691
+ copyDir(join(projectDir, '.agents', 'skills'), join(projectDir, '.cursor', 'skills'), { overwrite: true, delete: true, skip: ampWrappers });
692
+ for (const wrapper of ampWrappers) {
693
+ rmSync(join(projectDir, '.cursor', 'skills', wrapper), { recursive: true, force: true });
694
+ }
596
695
  copyDir(join(projectDir, '.agents', 'rules'), join(projectDir, '.cursor', 'rules'), { overwrite: true, delete: true });
696
+ copyDir(join(projectDir, '.agents', 'subagents'), join(projectDir, '.cursor', 'agents'), { overwrite: true, delete: true });
597
697
 
598
698
  const mcpExample = join(projectDir, '.agents', 'mcp.json.example');
599
699
  const mcpDest = join(projectDir, '.mcp.json');
@@ -605,7 +705,11 @@ program
605
705
 
606
706
  if (syncClaude) {
607
707
  log.info('Syncing .agents/ → .claude/');
608
- copyDir(join(projectDir, '.agents', 'skills'), join(projectDir, '.claude', 'skills'), { overwrite: true, delete: true });
708
+ copyDir(join(projectDir, '.agents', 'skills'), join(projectDir, '.claude', 'skills'), { overwrite: true, delete: true, skip: ampWrappers });
709
+ for (const wrapper of ampWrappers) {
710
+ rmSync(join(projectDir, '.claude', 'skills', wrapper), { recursive: true, force: true });
711
+ }
712
+ copyDir(join(projectDir, '.agents', 'subagents'), join(projectDir, '.claude', 'agents'), { overwrite: true, delete: true });
609
713
 
610
714
  const claudeMd = join(projectDir, 'CLAUDE.md');
611
715
  const claudeDir = join(projectDir, '.claude');
@@ -643,6 +747,7 @@ program
643
747
  const changeDir = join(projectDir, 'openspec', 'changes', name);
644
748
  const progress = parseTasksProgress(changeDir);
645
749
  const verdict = parseReviewVerdict(changeDir);
750
+ const hasBrief = parseDesignBrief(changeDir);
646
751
  const progressStr = progress ? `${progress.done}/${progress.total} tasks` : 'no tasks.md';
647
752
  const verdictStr = verdict || 'none';
648
753
  const readyToArchive = Boolean(progress && progress.total > 0 && progress.done === progress.total);
@@ -650,6 +755,7 @@ program
650
755
  console.log(`\n${pc.bold(name)}`);
651
756
  console.log(` tasks: ${progressStr}`);
652
757
  console.log(` review: ${verdictStr}`);
758
+ console.log(` brief: ${hasBrief ? 'yes' : 'no'}`);
653
759
  if (readyToArchive) log.ok('ready to archive');
654
760
  }
655
761
  console.log('');
@@ -670,7 +776,7 @@ program
670
776
  return;
671
777
  }
672
778
 
673
- if (!config.requireSpecReview) {
779
+ if (!config.requireSpecReview && !config.requireDesignBrief) {
674
780
  log.ok('review not required (pipeline.require_spec_review: false)');
675
781
  return;
676
782
  }
@@ -709,15 +815,28 @@ program
709
815
  return;
710
816
  }
711
817
 
712
- const verdict = parseReviewVerdict(changeDir);
713
- if (verdict && /^APPROVE/i.test(verdict)) {
818
+ if (config.requireSpecReview) {
819
+ const verdict = parseReviewVerdict(changeDir);
820
+ if (!(verdict && /^APPROVE/i.test(verdict))) {
821
+ log.err(`review gate failed — change "${target}" has ${verdict ? `verdict "${verdict}"` : 'no review.md'}`);
822
+ log.err(`Run /opsx:review ${target} and get an explicit APPROVE before apply/merge.`);
823
+ process.exitCode = 1;
824
+ return;
825
+ }
714
826
  log.ok(`review gate passed — ${target}: APPROVE`);
715
- return;
827
+ } else {
828
+ log.ok('review not required (pipeline.require_spec_review: false)');
716
829
  }
717
830
 
718
- log.err(`review gate failed — change "${target}" has ${verdict ? `verdict "${verdict}"` : 'no review.md'}`);
719
- log.err(`Run /opsx:review ${target} and get an explicit APPROVE before apply/merge.`);
720
- process.exitCode = 1;
831
+ if (config.requireDesignBrief) {
832
+ if (parseDesignBrief(changeDir) || hasDesignOptOut(changeDir)) {
833
+ log.ok(`design brief gate passed — ${target}`);
834
+ } else {
835
+ log.err(`design brief gate failed — change "${target}" has no design-brief.md`);
836
+ log.err(`Run /opsx:design ${target} (or add "Design: none" to proposal.md for non-UI changes).`);
837
+ process.exitCode = 1;
838
+ }
839
+ }
721
840
  });
722
841
 
723
842
  program.parse();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-orchestrator-kit",
3
- "version": "0.1.8",
4
- "description": "Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code — spec-driven pipeline with OpenSpec integration",
3
+ "version": "0.1.10",
4
+ "description": "Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code — spec-driven OpenSpec pipeline with cross-IDE custom subagents (openspec-guide, code-writer, code-reviewer, test-writer, setup-doctor, design-implementer)",
5
5
  "keywords": [
6
6
  "ai-agent",
7
7
  "cursor",
@@ -10,6 +10,9 @@
10
10
  "openspec",
11
11
  "sdd",
12
12
  "agent-orchestration",
13
+ "subagents",
14
+ "custom-subagents",
15
+ "design-to-code",
13
16
  "developer-tools"
14
17
  ],
15
18
  "author": "Maksim Shevyakov <makshc2>",
@@ -7,6 +7,7 @@ project:
7
7
 
8
8
  pipeline:
9
9
  require_spec_review: true
10
+ require_design_brief: false
10
11
  max_active_changes: 1
11
12
  archive_after_merge: true
12
13
 
@@ -15,6 +16,10 @@ roles:
15
16
  command: /opsx:explore
16
17
  mode: read-only
17
18
  model_hint: fast
19
+ design_intake:
20
+ command: /opsx:design
21
+ mode: brief-only
22
+ model_hint: strong
18
23
  architect:
19
24
  command: /opsx:propose
20
25
  mode: specs-only
@@ -11,6 +11,7 @@ package_manager: npm
11
11
 
12
12
  pipeline:
13
13
  require_spec_review: false
14
+ require_design_brief: false
14
15
  max_active_changes: 3
15
16
  archive_after_merge: false
16
17
  quick_mode_enabled: true
@@ -20,6 +21,11 @@ roles:
20
21
  command: /opsx:explore
21
22
  mode: read-only
22
23
  model_hint: fast
24
+ design_intake:
25
+ command: /opsx:design
26
+ mode: brief-only
27
+ model_hint: strong
28
+ notes: "In quick mode, the same session may create the brief before propose+apply"
23
29
  architect:
24
30
  command: /opsx:propose
25
31
  mode: specs-only
@@ -10,6 +10,7 @@ package_manager: npm
10
10
 
11
11
  pipeline:
12
12
  require_spec_review: true
13
+ require_design_brief: false
13
14
  max_active_changes: 1
14
15
  archive_after_merge: true
15
16
 
@@ -18,6 +19,10 @@ roles:
18
19
  command: /opsx:explore
19
20
  mode: read-only
20
21
  model_hint: fast
22
+ design_intake:
23
+ command: /opsx:design
24
+ mode: brief-only
25
+ model_hint: strong
21
26
  architect:
22
27
  command: /opsx:propose
23
28
  mode: specs-only
@@ -10,6 +10,7 @@ package_manager: npm
10
10
 
11
11
  pipeline:
12
12
  require_spec_review: true
13
+ require_design_brief: false
13
14
  max_active_changes: 1
14
15
  archive_after_merge: true
15
16
 
@@ -18,6 +19,10 @@ roles:
18
19
  command: /opsx:explore
19
20
  mode: read-only
20
21
  model_hint: fast
22
+ design_intake:
23
+ command: /opsx:design
24
+ mode: brief-only
25
+ model_hint: strong
21
26
  architect:
22
27
  command: /opsx:propose
23
28
  mode: specs-only
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: /opsx-design
3
+ id: opsx-design
4
+ category: Workflow
5
+ description: Capture design from any source into a durable design brief for an OpenSpec change
6
+ ---
7
+
8
+ Capture design into a durable brief for an OpenSpec change. One-shot intake from Figma, exports, screenshots, or photos — then apply never needs live design tools.
9
+
10
+ **IMPORTANT: You must NEVER edit any file in `src/` or any source code. You may write only `openspec/changes/<name>/design-brief.md` and files under `openspec/changes/<name>/assets/`.**
11
+
12
+ **Input**: Optionally specify a change name (e.g., `/opsx:design add-login-form`). If omitted, auto-select if one active change exists, otherwise list and ask. If the change does not exist yet, create the change directory when writing the brief (after explore chose the name).
13
+
14
+ ---
15
+
16
+ ## Steps
17
+
18
+ ### 1. Select the change
19
+
20
+ If name provided — use it. Otherwise:
21
+ - Run `openspec list --json` to list active changes.
22
+ - Auto-select if only one exists.
23
+ - Ask the user if ambiguous.
24
+
25
+ Announce: "Design intake for change: **<name>**"
26
+
27
+ ### 2. Choose source (fallback ladder)
28
+
29
+ Use the first available source; do not climb the ladder twice:
30
+
31
+ 1. **Figma MCP** — one pass only (`get_design_context` / screenshot / metadata). Capture everything needed immediately; never call Figma again during later apply.
32
+ 2. **Exported images** — PNG/SVG already in the repo or attached by the user.
33
+ 3. **Screenshots** — UI captures (desktop/mobile).
34
+ 4. **Photos** — physical mockups or whiteboard photos.
35
+
36
+ Ask the user for the source if unclear. Prefer Figma when a `figma.com` URL is given.
37
+
38
+ ### 3. Capture into assets/
39
+
40
+ Save reference images under `openspec/changes/<name>/assets/`:
41
+ - Prefer compressed PNG; ~1–2 images per breakpoint
42
+ - Do not commit raw video, PSD, or huge originals
43
+ - Name files clearly: `desktop.png`, `mobile.png`, `hero-detail.png`
44
+
45
+ ### 4. Write design-brief.md
46
+
47
+ Create or overwrite `openspec/changes/<name>/design-brief.md` using this template:
48
+
49
+ ```markdown
50
+ # Design Brief
51
+
52
+ **Change:** <name>
53
+ **Captured:** <ISO date>
54
+
55
+ ## Source
56
+
57
+ - Type: Figma | export | screenshot | photo
58
+ - URL / path: <figma URL or file path>
59
+ - File key / node ids: <if Figma>
60
+ - Capture date: <ISO date>
61
+ - Notes: <auth, branch, frame names>
62
+
63
+ ## Structure
64
+
65
+ - Layout hierarchy (sections, regions, key components)
66
+ - Responsive breakpoints if known
67
+ - Navigation / interaction notes relevant to implementation
68
+
69
+ ## Tokens
70
+
71
+ - Colors: <hex or token names>
72
+ - Typography: <families, sizes, weights>
73
+ - Spacing: <scale or measured gaps>
74
+ - Radii / shadows / borders: <as observed>
75
+
76
+ ## Reference images
77
+
78
+ - `assets/<file>` — <what it shows>
79
+
80
+ ## Constraints
81
+
82
+ - Must match: <hard constraints from design>
83
+ - Out of scope / approximate OK: <soft areas>
84
+ - Non-UI change? If this change has no UI, put `Design: none` in `proposal.md` instead of this brief.
85
+
86
+ ## Confidence notes
87
+
88
+ - Measured / from Figma: <list>
89
+ - Inferred (screenshot/photo): mark each inferred value with a confidence marker, e.g. `~8px (medium confidence)` or `color ≈ #1a1a1a (low confidence)`
90
+ ```
91
+
92
+ ### 5. Confidence markers for raster sources
93
+
94
+ When the source is a **screenshot** or **photo** (not Figma MCP / vector export):
95
+ - Do not present guessed spacing, colors, or type sizes as facts
96
+ - Mark every inferred token/value with a confidence note in **Confidence notes** and inline in **Tokens** where useful
97
+ - Prefer ranges or approximations over fake precision
98
+
99
+ ### 6. Handoff
100
+
101
+ Output a short summary:
102
+
103
+ ```
104
+ ## Design Intake Complete
105
+
106
+ **Change:** <name>
107
+ **Brief:** openspec/changes/<name>/design-brief.md
108
+ **Assets:** N file(s) under assets/
109
+
110
+ ### Next
111
+ - Continue with `/opsx:propose <name>` if artifacts are missing
112
+ - Or `/opsx:apply <name>` — Implementer must use the brief, not live Figma MCP
113
+ ```
114
+
115
+ For non-UI changes: do not invent a brief. Tell the Architect to add a line `Design: none` in `proposal.md` so `gate-check` can opt out when `require_design_brief: true`.
116
+
117
+ ---
118
+
119
+ ## Guardrails
120
+
121
+ - **Never** edit source code or `src/`
122
+ - **Never** edit `tasks.md`, `review.md`, or other OpenSpec artifacts except creating the change folder if needed for the brief
123
+ - **May write only** `openspec/changes/<name>/design-brief.md` and `openspec/changes/<name>/assets/*`
124
+ - **Never** rely on a second Figma MCP pass later — store everything in the brief now
125
+ - **Never** tell apply sessions to open live Figma; point them at the brief + assets
126
+ - Keep `assets/` small (compressed PNG, few files)
127
+ - Ask for clarification only if the source is missing or unreadable
@@ -5,10 +5,11 @@ alwaysApply: true
5
5
 
6
6
  # Agent Orchestration Rules
7
7
 
8
- This project uses a spec-driven 5-role pipeline. Read `.agents/orchestrator.yaml` for config.
8
+ This project uses a spec-driven role pipeline. Read `.agents/orchestrator.yaml` for config.
9
9
 
10
10
  ## Role Commands
11
11
  - `/opsx:explore` → read-only thinking, no code
12
+ - `/opsx:design <name>` → writes only `design-brief.md` + `assets/` (optional design intake)
12
13
  - `/opsx:propose <name>` → creates `openspec/changes/<name>/` artifacts only
13
14
  - `/opsx:review <name>` → read-only spec review, writes `review.md`, outputs Approve or Request Changes
14
15
  - `/opsx:apply <name>` → writes `src/`, marks `tasks.md [x]` (blocked if no review when `require_spec_review: true`)
@@ -18,13 +19,17 @@ This project uses a spec-driven 5-role pipeline. Read `.agents/orchestrator.yaml
18
19
  ## Session Rules
19
20
  - One active change at a time (unless mvp profile: up to 3)
20
21
  - Each role = new chat session (except `/opsx:quick` combines propose+apply)
21
- - No code in explore or review sessions
22
+ - No code in explore, design, or review sessions
23
+ - Design Intake may write only `openspec/changes/<name>/design-brief.md` and `assets/`
22
24
  - No apply without review when `pipeline.require_spec_review: true` — check `review.md` or Approve in context
25
+ - When `require_design_brief: true` and the change touches UI — need `design-brief.md`, or `Design: none` in `proposal.md` for non-UI
26
+ - Apply uses the design brief, not live Figma MCP
23
27
  - After apply: build + lint before PR
24
28
  - After merge: run `/opsx:archive` (when `archive_after_merge: true`)
25
29
 
26
30
  ## Never
27
31
  - Mix propose and apply in one session
28
- - Edit `src/` during explore or review
32
+ - Edit `src/` during explore, design, or review
29
33
  - Skip spec review before apply
34
+ - Call live Figma MCP during apply when a design brief exists
30
35
  - Leave changes un-archived after merge
@@ -5,7 +5,7 @@ alwaysApply: true
5
5
 
6
6
  # OpenSpec Workflow (/opsx)
7
7
 
8
- `/opsx:explore`, `/opsx:propose`, `/opsx:apply`, `/opsx:archive`, `/opsx:sync`, `/opsx:review`, `/opsx:quick` — AI workflow commands, not source code.
8
+ `/opsx:explore`, `/opsx:design`, `/opsx:propose`, `/opsx:apply`, `/opsx:archive`, `/opsx:sync`, `/opsx:review`, `/opsx:quick` — AI workflow commands, not source code.
9
9
 
10
10
  ## File Locations
11
11
 
@@ -15,12 +15,14 @@ alwaysApply: true
15
15
  | Skills | `.agents/skills/` |
16
16
  | Specs (source of truth) | `openspec/specs/` |
17
17
  | Active changes | `openspec/changes/` |
18
+ | Design brief | `openspec/changes/<name>/design-brief.md` + `assets/` |
18
19
  | Project config | `openspec/config.yaml` |
19
20
  | Orchestration config | `.agents/orchestrator.yaml` |
20
21
 
21
22
  ## Command → Skill Mapping
22
23
 
23
24
  - `/opsx:explore` → skill `openspec-explore` (thinking only)
25
+ - `/opsx:design <name>` → command `opsx-design` (writes design-brief.md + assets/)
24
26
  - `/opsx:propose <name>` → skill `openspec-propose`
25
27
  - `/opsx:review <name>` → command `opsx-review` (read-only, writes review.md)
26
28
  - `/opsx:apply` → skill `openspec-apply-change`
@@ -3,7 +3,7 @@ name: agent-orchestration
3
3
  description: >
4
4
  Spec-driven AI agent pipeline orchestration built on OpenSpec. Load when deciding which
5
5
  role/command to use, how to handoff between phases, which model to pick, or when a session
6
- should stop and a new one start. Commands: /opsx:explore, /opsx:propose, /opsx:review,
6
+ should stop and a new one start. Commands: /opsx:explore, /opsx:design, /opsx:propose, /opsx:review,
7
7
  /opsx:apply, /opsx:archive, /opsx:quick.
8
8
  disable-model-invocation: false
9
9
  allowed-tools: Bash, Read
@@ -17,13 +17,16 @@ is the primary source of wasted tokens and failed implementations.
17
17
  ## Pipeline
18
18
 
19
19
  ```
20
- explore → propose → review → apply → verify → archive
20
+ explore → [design] → propose → review → apply → verify → archive
21
21
  ```
22
22
 
23
+ `[design]` is optional (`/opsx:design`) — capture UI into `design-brief.md` + `assets/` so apply does not depend on live Figma.
24
+
23
25
  **MVP profile** (`require_spec_review: false`):
24
26
  ```
25
27
  explore → quick (propose+apply) → verify → archive (optional)
26
28
  ```
29
+ In quick mode the same session may create the design brief before propose+apply.
27
30
 
28
31
  Read `.agents/orchestrator.yaml` for project-specific config (language, flags, MCP, review gate).
29
32
 
@@ -32,6 +35,7 @@ Read `.agents/orchestrator.yaml` for project-specific config (language, flags, M
32
35
  | Role | Command | Mode | Model hint | Allowed output |
33
36
  |------|---------|------|------------|----------------|
34
37
  | Explorer | `/opsx:explore` | read-only | fast | chat only |
38
+ | Design Intake | `/opsx:design <name>` | brief-only | strong | `design-brief.md`, `assets/` |
35
39
  | Architect | `/opsx:propose <name>` | specs-only | strong | `openspec/changes/` |
36
40
  | Spec Reviewer | `/opsx:review <name>` | read-only | medium | `review.md`, Approve / Request Changes |
37
41
  | Implementer | `/opsx:apply <name>` | code | strong | `src/`, `tasks.md [x]` |
@@ -40,6 +44,19 @@ Read `.agents/orchestrator.yaml` for project-specific config (language, flags, M
40
44
 
41
45
  ## Handoff Protocol
42
46
 
47
+ ### explore → design (optional)
48
+ Exit Explorer into Design Intake when:
49
+ - Change has UI and a Figma URL, export, screenshot, or photo is available
50
+ - kebab-case change name chosen
51
+
52
+ Start Design Intake with:
53
+ ```
54
+ /opsx:design <name>
55
+ ```
56
+
57
+ ### design → propose
58
+ Exit Design Intake when `design-brief.md` (+ `assets/`) is written. Non-UI changes: skip design and put `Design: none` in `proposal.md` when `require_design_brief: true`.
59
+
43
60
  ### explore → propose
44
61
  Exit Explorer when:
45
62
  - Problem is stated in 3–5 sentences
@@ -57,7 +74,6 @@ Context from explore:
57
74
  - Non-goals: ...
58
75
  - Draft acceptance: ...
59
76
  ```
60
-
61
77
  ### propose → review
62
78
  Exit Architect when:
63
79
  ```bash
@@ -74,7 +90,7 @@ Before apply, check `.agents/orchestrator.yaml`:
74
90
 
75
91
  If Request Changes — fix artifacts, re-run `/opsx:review`.
76
92
 
77
- This is no longer only a chat convention: `agent-orchestrator-kit gate-check` runs in CI (both `agent-verify.yml` fragments) and fails the pipeline if `src/` changed without an approved `review.md` — a forgotten or skipped review is caught at merge time, not just at apply time.
93
+ This is no longer only a chat convention: `agent-orchestrator-kit gate-check` runs in CI (both `agent-verify.yml` fragments) and fails the pipeline if `src/` changed without an approved `review.md` — a forgotten or skipped review is caught at merge time, not just at apply time. When `require_design_brief: true`, the same command also requires `design-brief.md` (or `Design: none` in `proposal.md`).
78
94
 
79
95
  ### apply → verify
80
96
  Exit Implementer when:
@@ -82,6 +98,7 @@ Exit Implementer when:
82
98
  - `npm run build` (or project build cmd) exits 0
83
99
  - `npm run lint` exits 0
84
100
  - Commit ready
101
+ - UI work followed `design-brief.md` — do **not** open live Figma MCP in the apply session
85
102
 
86
103
  ### verify → archive
87
104
  After PR merged + CI green:
@@ -93,7 +110,7 @@ After PR merged + CI green:
93
110
 
94
111
  **Start of each session:**
95
112
  1. Announce role: "Starting Spec Reviewer session for change: <name>"
96
- 2. Run `agent-orchestrator-kit status` (or `openspec list`) — confirm active change limit (`max_active_changes` in orchestrator.yaml) and see task/review progress for every active change at a glance
113
+ 2. Run `agent-orchestrator-kit status` (or `openspec list`) — confirm active change limit (`max_active_changes` in orchestrator.yaml) and see task/review/brief progress for every active change at a glance
97
114
  3. Read `orchestrator.yaml` for project config and review gate
98
115
 
99
116
  **During session:**
@@ -111,6 +128,7 @@ After PR merged + CI green:
111
128
  | Phase | Use case | Recommended |
112
129
  |-------|----------|-------------|
113
130
  | explore | Q&A, brainstorm | fast (rush/flash) |
131
+ | design | Vision / layout capture | strong (vision-capable) |
114
132
  | propose | Architecture decisions | strong (opus/sonnet) |
115
133
  | review | Artifact analysis | medium or strong |
116
134
  | apply complex | Multi-file refactor | strong |
@@ -146,6 +164,7 @@ At start of new session: read relevant entities to restore context without re-ex
146
164
  |-------------|--------|
147
165
  | Explore + propose in one chat | Architect has stale exploration context |
148
166
  | Apply without review | ~60% chance of rework |
167
+ | Live Figma MCP in apply session | Token/quota loss; context not durable across sessions |
149
168
  | All tasks in one apply session | Context overload; model drifts |
150
169
  | No archive after merge | Next propose has stale domain specs |
151
170
  | Strong model on lint fixes | 5–10x cost with no quality gain |
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: code-reviewer
3
+ description: Reviews a code diff for OpenSpec spec-compliance and project stack conventions — checks the change against openspec/specs/ and the active change's proposal/design/tasks, not against security or general bug-hunting concerns (use the Bugbot or Security Review subagents for that). Use proactively after implementation, before opening a PR/MR, or whenever the user asks for a review against the spec.
4
+ ---
5
+
6
+ You are a read-only reviewer. You never edit files. Your review is advisory — it does **not** replace the required `/opsx:review` spec-review session (that gate is on the proposal before apply; you review the resulting code after apply).
7
+
8
+ Steps:
9
+
10
+ 1. Determine the diff: `git diff` against the target branch, or the files the user points you to.
11
+ 2. Identify the active OpenSpec change (`openspec list --json`, or ask if ambiguous). Read `openspec/changes/<name>/proposal.md`, `design.md`, and every touched `specs/*/spec.md`.
12
+ 3. Check spec compliance: does the diff implement every ADDED/MODIFIED requirement in the delta specs? Does it avoid touching anything marked out of scope? Flag missing or extra behavior explicitly, quoting the requirement.
13
+ 4. Check stack conventions from `.agents/orchestrator.yaml` (`project.stack`) — e.g. for `vue3`: Composition API only, `<script setup>`, no Options API, Pinia via `storeToRefs`, Axios via the project's shared instance/interceptors, no business logic left in templates.
14
+ 5. Check task hygiene: does `tasks.md` reflect what was actually implemented (no task marked `[x]` without matching code, no implemented work left unchecked)?
15
+
16
+ Output format:
17
+
18
+ ```
19
+ ## Code Review: <change-name>
20
+
21
+ **Spec compliance:** Compliant | Gaps found
22
+ - ...
23
+
24
+ **Convention issues**
25
+ - Critical: ...
26
+ - Warning: ...
27
+ - Suggestion: ...
28
+
29
+ **Verdict:** Ready for MR | Needs changes before MR
30
+ ```
31
+
32
+ Be specific — cite file and line/region for every issue. If everything is fine, say so briefly instead of inventing nitpicks.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: code-writer
3
+ description: Implementation specialist. Writes production-ready code in src/ for one clearly-scoped task at a time, following the project's declared stack conventions (see .agents/orchestrator.yaml project.stack) and existing file/naming patterns. Use proactively during /opsx:apply for a well-defined task, or whenever the user asks to implement a specific, narrow piece of code.
4
+ ---
5
+
6
+ You implement one scoped unit of work at a time. You are not the OpenSpec pipeline owner — you do not choose the change, decide architecture, or mark `tasks.md` checkboxes complete; report back what you changed and let the calling session confirm and check it off.
7
+
8
+ Before writing code:
9
+
10
+ 1. Read `.agents/orchestrator.yaml` → `project.stack` and `roles.implementer.notes` to know which stack skills apply (e.g. `vue-core`, `vue-pinia`, `vue-axios`, `vue-router`, `vue-composables` for `stack: vue3`; adapt to whatever stack is declared otherwise).
11
+ 2. If working from an OpenSpec change, read the specific task in `openspec/changes/<name>/tasks.md` plus the relevant section of `design.md` and `specs/*/spec.md` — implement exactly what is scoped, nothing more.
12
+ 3. Look at 2-3 existing files of the same kind (component, composable, store, API module) already in the codebase and match their structure, naming, and idioms before introducing anything new.
13
+
14
+ While writing code:
15
+
16
+ - Keep the diff minimal and scoped to the task — no drive-by refactors, no unrelated formatting changes.
17
+ - No comments that narrate obvious code; only comment non-obvious intent, trade-offs, or constraints.
18
+ - Match the project's existing patterns for state management, HTTP calls, and component structure rather than inventing new ones.
19
+ - If the task is ambiguous or the codebase has no established pattern to follow, stop and ask instead of guessing.
20
+
21
+ When done, report: files changed, a one-line summary per file, and anything the calling session should double-check (edge cases, follow-up tasks, tests you did not write).
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: design-implementer
3
+ description: Pixel-accurate design-to-code specialist. Translates Figma designs, screenshots, or design briefs into production UI code with maximum visual fidelity — layout, spacing, typography, colors, states, and responsive behavior. Use proactively whenever the user provides a Figma link, a screenshot/mockup image, or asks to implement, port, or match a design.
4
+ ---
5
+
6
+ You translate visual designs into production UI code with maximum fidelity. Accuracy beats speed: a design that is 95% right is a failed task — get spacing, typography, colors, radii, shadows, and states exact.
7
+
8
+ ## Source of truth — strict priority order
9
+
10
+ 1. **Design brief first.** If an active OpenSpec change has `openspec/changes/<name>/design-brief.md` + `assets/`, that is your only design source. Do NOT call live Figma MCP when a brief exists — this is a hard pipeline rule.
11
+ 2. **Figma MCP** (Cursor: `get_design_context`, `get_screenshot`; load the figma-design-to-code skill first if available). Use only when no design brief exists. Extract exact values — never eyeball a Figma frame.
12
+ 3. **Screenshot/image only.** Read the image carefully. Measure proportions from the image; state explicitly which values are inferred (exact px, fonts) so the user can correct them.
13
+
14
+ ## Workflow
15
+
16
+ 1. **Extract the spec before writing any code.** Build a token table from the source: colors (exact hex), font family/size/weight/line-height per text style, spacing values, border radii, shadows, breakpoints. For Figma, prefer design tokens/variables over raw hex.
17
+ 2. **Map to the project's system — never hardcode what already exists.** Check the project's existing tokens first (CSS variables, SCSS variables, framework theme — e.g. `quasar.variables.scss`, Tailwind config). Reuse existing UI components (check `src/components/` and the UI framework's components) instead of rebuilding them. Only introduce new tokens/components when nothing matches, and say so.
18
+ 3. **Implement.** Follow the project's stack conventions from `.agents/orchestrator.yaml` (`project.stack`). Match existing component structure and naming. Implement all states visible or implied in the design: hover, focus, active, disabled, empty, loading, error. Handle responsive behavior — if the design shows one viewport, apply the project's existing responsive patterns and note the assumption.
19
+ 4. **Verify against the reference.** Render the result (dev server + browser/screenshot when available) and compare side by side with the source image: alignment, spacing rhythm, font rendering, color accuracy. Fix discrepancies before reporting. If you cannot render, do a line-by-line self-review of the extracted spec table against your code.
20
+
21
+ ## Rules
22
+
23
+ - Never approximate a color, spacing, or font size when the exact value is available in the source.
24
+ - Never invent design decisions not present in the source; if something is ambiguous (missing state, unclear breakpoint), list it as an open question instead of guessing silently.
25
+ - Asset handling: export/copy image and icon assets into the project's existing assets location; prefer SVG for icons; never hotlink Figma URLs.
26
+ - Accessibility is part of fidelity: semantic elements, alt text, focus states, sufficient contrast — flag contrast failures in the source design rather than silently shipping them.
27
+
28
+ When done, report: the token/spec table you extracted, what was reused vs newly created, states implemented, and any open questions or deviations from the source.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: openspec-guide
3
+ description: OpenSpec pipeline navigator. Reports the state of an active change (tasks progress, review verdict, design brief, archive-readiness), explains why a gate (gate-check / verify-openspec-pr) is failing, and tells the user exactly which /opsx:* command to run next. Use proactively whenever the user asks "what's the status of X", "why is the gate failing", "what do I run next", or seems unsure which pipeline phase they are in.
4
+ ---
5
+
6
+ You are a read-only guide for the OpenSpec + agent-orchestrator-kit pipeline (`explore → [design] → propose → review → apply → verify → archive`).
7
+
8
+ **Never edit files.** You only read and explain. If the user wants to act on your findings (write a proposal, implement a task, etc.), tell them which `/opsx:*` command to run in a fresh session — do not do it yourself.
9
+
10
+ On every invocation:
11
+
12
+ 1. Read `.agents/orchestrator.yaml` — note `pipeline.require_spec_review`, `pipeline.require_design_brief`, `pipeline.max_active_changes`, and `pipeline.archive_after_merge`.
13
+ 2. Run `openspec list --json` (or `agent-orchestrator status` if the CLI is available) to see active changes.
14
+ 3. If the user named a change, run `openspec status --change "<name>" --json` and read `openspec/changes/<name>/tasks.md` and `review.md` directly for ground truth.
15
+ 4. Map what you find to the correct next command:
16
+ - No `proposal.md` yet → `/opsx:propose <name>`
17
+ - `require_design_brief: true`, UI-touching change, no `design-brief.md`, no `Design: none` in `proposal.md` → `/opsx:design <name>`
18
+ - `proposal.md` exists but no `review.md` with `Verdict: APPROVE` → `/opsx:review <name>` (must run in a separate read-only session)
19
+ - `review.md` says APPROVE but `tasks.md` has unchecked `- [ ]` items → `/opsx:apply <name>`
20
+ - All tasks `[x]` and review approved → ready to archive, suggest `/opsx:archive <name>` (or note that GitLab/GitHub CI auto-archives after merge if `archive_after_merge: true`)
21
+ 5. If a CI gate (`gate-check`, `verify-openspec-pr`) is failing, reproduce the check locally (`npx agent-orchestrator-kit gate-check <name>`, `npm run verify:openspec:pr`) and quote the exact failing reason from its output — don't guess.
22
+ 6. If `pipeline.max_active_changes` is exceeded, say so explicitly and name which changes are over the limit.
23
+
24
+ Keep answers short and concrete: current phase, one-line reason, exact next command. Do not summarize the whole pipeline unless asked.
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: setup-doctor
3
+ description: Diagnoses and fixes agent-orchestrator-kit setup problems — failing `verify:agents`/`gate-check`, missing .mcp.json or .amp/settings.json, out-of-sync .cursor/ or .claude/ directories, stale kit_version. Use proactively whenever verify:agents or CI setup checks fail, MCP/skills/subagents seem missing in the IDE, or the user asks to fix, set up, or update the orchestrator.
4
+ ---
5
+
6
+ You diagnose and repair the *orchestrator's own* setup — not the project's business logic. Never touch `src/` or `openspec/changes/` content; only `.agents/`, `.cursor/`, `.claude/`, `.amp/`, `.mcp.json`, and root config files the kit manages.
7
+
8
+ Diagnosis steps:
9
+
10
+ 1. Run `npm run verify:agents` (or the project's equivalent) and read every failing check line by line — don't summarize, quote them.
11
+ 2. Run `npx agent-orchestrator-kit status` and `npx agent-orchestrator-kit gate-check` to see pipeline-level gate state.
12
+ 3. Check `.agents/orchestrator.yaml` → `kit_version` against the installed package version; flag drift.
13
+ 4. Check that `.mcp.json` / `.amp/settings.json` exist (copy from their `.example` files if missing) and that the `memory` MCP server is configured with `MEMORY_FILE_PATH: .cursor/memory.json`.
14
+ 5. Check `.cursor/skills/`, `.cursor/rules/`, `.cursor/agents/` (and `.claude/` equivalents) are present and not stale relative to `.agents/` — if stale, this is fixed by running `sync`, not by hand-editing.
15
+
16
+ Fix, in this priority order, applying only safe/reversible changes:
17
+
18
+ - Missing local IDE files → run `./scripts/sync-local-agent-skills.sh` or `npx agent-orchestrator-kit sync --target all`
19
+ - Stale kit-managed files → run `npx agent-orchestrator-kit update`, then re-sync
20
+ - Missing `.mcp.json`/`.amp/settings.json` → copy from the `.example` file
21
+ - Missing cache directories (`.agents/cache/handoffs`, `.agents/cache/checkpoints`) → create them with `.gitkeep`
22
+
23
+ Never attempt fixes that require credentials or external side effects you don't have (npm login/publish, `sudo`, pushing to protected branches, rotating CI/CD variables) — instead tell the user the exact command they need to run themselves.
24
+
25
+ Report: what you fixed, what still needs the user's action (with exact commands), and re-run `verify:agents` at the end to confirm.
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: test-writer
3
+ description: Writes and updates automated tests for recently changed or newly implemented code, using the project's testing stack (e.g. Vitest + Vue Test Utils for vue3 projects). Use proactively right after implementing a feature or fixing a bug, or whenever the user asks to add or update tests.
4
+ ---
5
+
6
+ You write tests for code that already exists — you do not implement features. If the code you're asked to test doesn't exist yet, say so and ask for it to be implemented first (or hand off to the `code-writer` subagent).
7
+
8
+ Steps:
9
+
10
+ 1. Find what changed: `git diff --name-only` against the target branch, or the files the user names.
11
+ 2. For each changed source file, find its existing test file (co-located or in a mirrored test directory) or determine where a new one belongs, following the project's existing test file naming/location convention.
12
+ 3. Read `.agents/orchestrator.yaml` → `verifier.test_command` to know how tests are run in this project.
13
+ 4. Write tests following AAA structure (Arrange, Act, Assert). For Vue 3 projects: use Vue Test Utils `mount`/`shallowMount`, mock Pinia stores and Axios calls, test component behavior and composable outputs — not implementation details (internal refs, private state).
14
+ 5. Cover: the happy path, at least one edge case, and any error/rejection path that the changed code explicitly handles.
15
+ 6. Run the test command (from `verifier.test_command`) and report pass/fail. If tests fail, fix your own test code first; only flag the source code as broken if you're confident the test is correct and the implementation genuinely violates the expected behavior.
16
+
17
+ Do not test trivial getters/setters, third-party library internals, or purely visual styling. Report which files you added/changed and the final test run result.
@@ -8,9 +8,11 @@ Every feature follows the same cycle regardless of stack or IDE.
8
8
  ## Pipeline
9
9
 
10
10
  ```
11
- explore → propose → review → apply → verify → archive
11
+ explore → [design] → propose → review → apply → verify → archive
12
12
  ```
13
13
 
14
+ `[design]` is optional — run `/opsx:design` when the change has UI and you need a durable design brief (Figma, screenshot, or photo). Skip for non-UI work; use `Design: none` in `proposal.md` when `require_design_brief: true`.
15
+
14
16
  Each phase runs in a **separate agent session** with a dedicated role, model hint, and permissions.
15
17
  Never mix phases in one chat — this is the single most important rule.
16
18
 
@@ -19,6 +21,7 @@ Never mix phases in one chat — this is the single most important rule.
19
21
  | Role | Command | Mode | Model hint |
20
22
  |------|---------|------|------------|
21
23
  | Explorer | `/opsx:explore` | read-only | fast |
24
+ | Design Intake | `/opsx:design <name>` | writes `design-brief.md` + `assets/` only | strong |
22
25
  | Architect | `/opsx:propose <name>` | writes `openspec/changes/` only | strong |
23
26
  | Spec Reviewer | `/opsx:review <name>` | read-only | medium/strong |
24
27
  | Implementer | `/opsx:apply <name>` | writes `src/` | strong |
@@ -28,13 +31,13 @@ Verifier runs on **GitHub Actions** (default) or **GitLab** via `prebuild` → `
28
31
 
29
32
  With `init --ci gitlab --spec-verify` or `init --ci github --spec-verify`, an **AI Spec Verifier** also runs on MRs/PRs changing `src/`: an Amp agent checks the changed code against `openspec/specs/` and a **BLOCKED verdict fails the pipeline** (gate `spec-verify-blocking` in `.agents/orchestrator.yaml`).
30
33
 
31
- Both CI fragments also run `agent-orchestrator-kit gate-check` — a deterministic check that fails the pipeline when `src/` changed but the active change has no `review.md` with `Verdict: APPROVE` (when `require_spec_review: true`). Run `agent-orchestrator-kit status` at the start of any session to see task progress, review verdict, and archive readiness for every active change without querying `openspec` per change.
34
+ Both CI fragments also run `agent-orchestrator-kit gate-check` — a deterministic check that fails the pipeline when `src/` changed but the active change has no `review.md` with `Verdict: APPROVE` (when `require_spec_review: true`), and optionally requires `design-brief.md` (when `require_design_brief: true`, unless `proposal.md` has `Design: none`). Run `agent-orchestrator-kit status` at the start of any session to see task progress, review verdict, design brief, and archive readiness for every active change without querying `openspec` per change.
32
35
 
33
36
  ## Hard Rules
34
37
 
35
38
  - **One active change per developer** at a time.
36
39
  - **No apply without spec-review approval** (explicit Approve in chat).
37
- - **No code edits** during explore or spec-review sessions.
40
+ - **No code edits** during explore, design-intake, or spec-review sessions.
38
41
  - **Archive after every merge** (`/opsx:archive`).
39
42
  - **Always run local build/lint** before opening a PR.
40
43
 
@@ -42,7 +45,9 @@ Both CI fragments also run `agent-orchestrator-kit gate-check` — a determinist
42
45
 
43
46
  | Transition | Gate |
44
47
  |------------|------|
45
- | explore → propose | Decision brief written; change name chosen |
48
+ | explore → design | UI change needs a brief; change name chosen |
49
+ | explore → propose | Decision brief written; change name chosen (skip design if non-UI) |
50
+ | design → propose | `design-brief.md` (+ `assets/`) written |
46
51
  | propose → review | `openspec validate --strict` passes ✓ |
47
52
  | review → apply | Reviewer writes explicit **Approve** — enforced in CI by `gate-check` |
48
53
  | apply → verify | All `tasks.md` checkboxes `[x]`; local build OK |
@@ -53,9 +58,10 @@ Both CI fragments also run `agent-orchestrator-kit gate-check` — a determinist
53
58
  | Role | Attach (`@`) |
54
59
  |------|-------------|
55
60
  | Explorer | `@openspec/specs/` + relevant `@src/` subtree |
56
- | Architect | `@openspec/config.yaml` + explore brief |
61
+ | Design Intake | design source (Figma URL / images) + `@openspec/changes/<name>/` |
62
+ | Architect | `@openspec/config.yaml` + explore brief (+ `@design-brief.md` if present) |
57
63
  | Reviewer | entire `@openspec/changes/<name>/` |
58
- | Implementer | `@openspec/changes/<name>/tasks.md` |
64
+ | Implementer | `@openspec/changes/<name>/tasks.md` + `@openspec/changes/<name>/design-brief.md` |
59
65
 
60
66
  ## Configuration
61
67
 
@@ -24,6 +24,7 @@ Use `/skill-name` or let Claude auto-load based on context.
24
24
 
25
25
  ```
26
26
  /opsx:explore — think through ideas (read-only, no code)
27
+ /opsx:design — capture design into design-brief.md + assets/ (optional)
27
28
  /opsx:propose — create change artifacts
28
29
  /opsx:review — spec review (read-only, no code)
29
30
  /opsx:apply — implement tasks
@@ -34,7 +35,8 @@ Use `/skill-name` or let Claude auto-load based on context.
34
35
 
35
36
  - Check `.agents/orchestrator.yaml` for project-specific pipeline config.
36
37
  - One active change at a time — run `openspec list` to confirm.
37
- - No code edits in explore or review mode.
38
+ - No code edits in explore, design, or review mode.
39
+ - Design Intake writes only `design-brief.md` and `assets/` — never `src/`.
38
40
  - After completing apply: run build/lint before declaring done.
39
41
  - Use `openspec validate --all --strict` to verify change artifacts.
40
42
 
@@ -43,6 +45,7 @@ Use `/skill-name` or let Claude auto-load based on context.
43
45
  | What | Where |
44
46
  |------|-------|
45
47
  | Active changes | `openspec/changes/` |
48
+ | Design brief | `openspec/changes/<name>/design-brief.md` + `assets/` |
46
49
  | Specs (source of truth) | `openspec/specs/` |
47
50
  | Project config | `openspec/config.yaml` |
48
51
  | Orchestration config | `.agents/orchestrator.yaml` |
@@ -9,6 +9,7 @@ package_manager: npm
9
9
 
10
10
  pipeline:
11
11
  require_spec_review: true
12
+ require_design_brief: false
12
13
  max_active_changes: 1
13
14
  archive_after_merge: true
14
15
 
@@ -17,6 +18,10 @@ roles:
17
18
  command: /opsx:explore
18
19
  mode: read-only
19
20
  model_hint: fast
21
+ design_intake:
22
+ command: /opsx:design
23
+ mode: brief-only
24
+ model_hint: strong
20
25
  architect:
21
26
  command: /opsx:propose
22
27
  mode: specs-only
@@ -21,18 +21,59 @@ echo ""
21
21
  echo "sync-local-agent-skills"
22
22
  echo "-----------------------"
23
23
 
24
+ # ── Amp subagent skill wrappers ────────────────────────────────────────
25
+ # Amp has no file-based subagents; it loads skills from .agents/skills/.
26
+ # Generate a skill wrapper per subagent so they work in Amp too.
27
+ if [ -d .agents/subagents ]; then
28
+ echo ""
29
+ info "Generating Amp skill wrappers from .agents/subagents/"
30
+
31
+ for old in .agents/skills/subagent-*; do
32
+ [ -d "$old" ] && rm -rf "$old"
33
+ done
34
+
35
+ for sub in .agents/subagents/*.md; do
36
+ [ -f "$sub" ] || continue
37
+ NAME="$(awk '/^---$/{c++; next} c==1 && /^name:/{sub(/^name:[ \t]*/,""); print; exit}' "$sub")"
38
+ DESC="$(awk '/^---$/{c++; next} c==1 && /^description:/{sub(/^description:[ \t]*/,""); print; exit}' "$sub")"
39
+ if [ -z "$NAME" ] || [ -z "$DESC" ]; then
40
+ warn "skip (no name/description): $sub"
41
+ continue
42
+ fi
43
+ DIR=".agents/skills/subagent-${NAME}"
44
+ mkdir -p "$DIR"
45
+ {
46
+ echo "---"
47
+ echo "name: subagent-${NAME}"
48
+ echo "description: ${DESC}"
49
+ echo "---"
50
+ echo ""
51
+ echo "<!-- AUTO-GENERATED from ${sub} — edit the source file, then re-run this script -->"
52
+ echo ""
53
+ awk '/^---$/{c++; next} c>=2{print}' "$sub"
54
+ } > "$DIR/SKILL.md"
55
+ ok "$DIR/SKILL.md"
56
+ done
57
+ fi
58
+
24
59
  # ── Cursor ─────────────────────────────────────────────────────────────
25
60
  echo ""
26
61
  info "Syncing → .cursor/ (Cursor)"
27
- mkdir -p .cursor/skills .cursor/rules
62
+ mkdir -p .cursor/skills .cursor/rules .cursor/agents
28
63
 
29
- rsync -a --delete .agents/skills/ .cursor/skills/
64
+ rsync -a --delete --exclude 'subagent-*' .agents/skills/ .cursor/skills/
65
+ rm -rf .cursor/skills/subagent-*
30
66
  ok ".cursor/skills/"
31
67
 
32
68
  for rule in .agents/rules/*.mdc; do
33
69
  [ -f "$rule" ] && cp "$rule" .cursor/rules/ && ok ".cursor/rules/$(basename "$rule")"
34
70
  done
35
71
 
72
+ if [ -d .agents/subagents ]; then
73
+ rsync -a --delete .agents/subagents/ .cursor/agents/
74
+ ok ".cursor/agents/"
75
+ fi
76
+
36
77
  if [ ! -f .mcp.json ] && [ -f .agents/mcp.json.example ]; then
37
78
  cp .agents/mcp.json.example .mcp.json
38
79
  ok ".mcp.json created from example"
@@ -43,11 +84,17 @@ fi
43
84
  # ── Claude Code ────────────────────────────────────────────────────────
44
85
  echo ""
45
86
  info "Syncing → .claude/ (Claude Code)"
46
- mkdir -p .claude/skills
87
+ mkdir -p .claude/skills .claude/agents
47
88
 
48
- rsync -a --delete .agents/skills/ .claude/skills/
89
+ rsync -a --delete --exclude 'subagent-*' .agents/skills/ .claude/skills/
90
+ rm -rf .claude/skills/subagent-*
49
91
  ok ".claude/skills/"
50
92
 
93
+ if [ -d .agents/subagents ]; then
94
+ rsync -a --delete .agents/subagents/ .claude/agents/
95
+ ok ".claude/agents/"
96
+ fi
97
+
51
98
  if [ -f CLAUDE.md ]; then
52
99
  cp CLAUDE.md .claude/CLAUDE.md
53
100
  ok ".claude/CLAUDE.md"
@@ -55,7 +102,7 @@ fi
55
102
 
56
103
  # ── Amp Code ───────────────────────────────────────────────────────────
57
104
  echo ""
58
- info "Amp Code reads .agents/ directly — no sync needed"
105
+ info "Amp Code reads .agents/ directly — subagents exposed via skill wrappers"
59
106
  mkdir -p .amp
60
107
  if [ ! -f .amp/settings.json ] && [ -f .agents/amp.settings.json.example ]; then
61
108
  cp .agents/amp.settings.json.example .amp/settings.json