agent-orchestrator-kit 0.1.1 → 0.1.3

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 ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.1.3] - 2026-06-14
6
+
7
+ ### Added
8
+ - **`mvp` profile** — demos/spikes: `require_spec_review: false`, up to 3 active changes
9
+ - **`/opsx:quick` command** — propose + apply in one session for MVP workflows
10
+ - **`openspec/config.yaml.example`** from vue3 and mvp profiles on init
11
+ - **Review gate enforcement** — `/opsx:review` writes `review.md`; `/opsx:apply` checks `require_spec_review`
12
+ - **Vue 3 review checklist** in `/opsx:review` (script setup, Pinia, Axios)
13
+ - **Package manager detection** (npm/yarn/pnpm) → updates verifier commands in `orchestrator.yaml`
14
+ - **CI workflow** auto-detects npm / yarn / pnpm
15
+ - **OpenSpec + frontend-agent-skills** hints in init next steps
16
+ - **Profile validation** with warning for unknown profiles
17
+
18
+ ### Fixed
19
+ - Gitignore dedup uses exact line match (not substring) — `.cursor/memory.json` no longer blocks `.cursor`
20
+ - `.claude` added to gitignore on init
21
+ - `sync --target amp` — explicit Amp handling + `.amp/settings.json` bootstrap
22
+
23
+ ## [0.1.2] - 2026-06-14
24
+
25
+ ### Fixed
26
+ - CLI executable bit on `bin/agent-orchestrator.js` (`agent-orchestrator: not found` via npx)
27
+ - Added `agent-orchestrator-kit` bin alias (matches package name for npx)
28
+
29
+ ## [0.1.1] - 2026-06-14
30
+
31
+ ### Added
32
+ - All OpenSpec skills (`openspec-*`, `spec-workflow-openspec`)
33
+ - CI workflow template `.github/workflows/agent-verify.yml`
34
+ - `.agents/amp.settings.json.example` for Amp Code MCP
35
+ - `update` command refreshes all kit-managed skills and CI
36
+ - Sync script auto-creates `.amp/settings.json` from example
37
+
38
+ ### Removed
39
+ - Unused `prompts` dependency
40
+
41
+ ## [0.1.0] - 2026-06-14
42
+
43
+ ### Added
44
+ - Initial release: 5-role orchestration pipeline, `/opsx:*` commands, IDE sync
45
+
46
+ [0.1.3]: https://github.com/makshc2/agent-orchestrator-kit/compare/v0.1.2...v0.1.3
47
+ [0.1.2]: https://github.com/makshc2/agent-orchestrator-kit/compare/v0.1.1...v0.1.2
48
+ [0.1.1]: https://github.com/makshc2/agent-orchestrator-kit/compare/v0.1.0...v0.1.1
49
+ [0.1.0]: https://github.com/makshc2/agent-orchestrator-kit/releases/tag/v0.1.0
package/README.md CHANGED
@@ -38,6 +38,8 @@ npm i -D @fission-ai/openspec
38
38
  npx openspec init
39
39
  ```
40
40
 
41
+ > **Important:** `agent-orchestrator-kit init` does **not** install OpenSpec automatically. Install OpenSpec first (or ensure it exists in the repo), then run kit init.
42
+
41
43
  ### Install the kit
42
44
 
43
45
  ```bash
@@ -50,6 +52,7 @@ With a stack profile:
50
52
  npx agent-orchestrator-kit init --profile vue3
51
53
  npx agent-orchestrator-kit init --profile node
52
54
  npx agent-orchestrator-kit init --profile generic
55
+ npx agent-orchestrator-kit init --profile mvp # demos / spikes — no review gate
53
56
  ```
54
57
 
55
58
  With options:
@@ -111,7 +114,7 @@ your-project/
111
114
  | What | How |
112
115
  |------|-----|
113
116
  | OpenSpec CLI | `npm i -D @fission-ai/openspec && npx openspec init` |
114
- | Stack skills (Vue, etc.) | `npx vue-cursor-skills install` for vue3 profile |
117
+ | Stack skills (Vue, JS, Vite) | `npx frontend-agent-skills install` for vue3 profile |
115
118
  | Project conventions | Create `.agents/project-conventions/SKILL.md` manually |
116
119
  | Domain specs | Live in `openspec/specs/` per project |
117
120
 
@@ -345,17 +348,28 @@ npx agent-orchestrator-kit update
345
348
  | Profile | Stack | Extra (separate install) |
346
349
  |---------|-------|--------------------------|
347
350
  | `generic` | Any | Orchestration + OpenSpec skills only |
348
- | `vue3` | Vue 3 + Vite | + `npx vue-cursor-skills install` |
349
- | `node` | Node.js | + your JS skills as needed |
351
+ | `vue3` | Vue 3 + Vite + JS | + `npx frontend-agent-skills install` |
352
+ | `node` | Node.js | + `npx frontend-agent-skills install --category javascript` |
353
+ | `mvp` | Vue 3 demo/spike | + frontend-agent-skills; use `/opsx:quick`, no review gate |
350
354
 
351
355
  For `vue3`, after kit init also run:
352
356
 
353
357
  ```bash
354
- npx vue-cursor-skills install
355
- rsync -a .cursor/skills/ .agents/skills/
358
+ # Amp (primary — installs directly to .agents/skills/)
359
+ npx frontend-agent-skills install --agent amp --yes
360
+
361
+ # Cursor + Claude Code users — sync local IDE dirs
356
362
  ./scripts/sync-local-agent-skills.sh
357
363
  ```
358
364
 
365
+ Or install for all IDEs at once:
366
+
367
+ ```bash
368
+ npx frontend-agent-skills install --agent all --yes
369
+ ```
370
+
371
+ > **Migrating from `vue-cursor-skills`?** Renamed to `frontend-agent-skills` v2 — same package, old CLI alias still works.
372
+
359
373
  ## Memory MCP — Shared State Between Sessions
360
374
 
361
375
  Each role starts a fresh session. Memory MCP persists orchestration state across sessions so you don't re-explain context every time.
@@ -412,7 +426,7 @@ Amp will run this skill as a subagent when invoked.
412
426
 
413
427
  ```bash
414
428
  npx agent-orchestrator-kit init [options]
415
- --profile <name> Stack profile: generic | vue3 | node | python
429
+ --profile <name> Stack profile: generic | vue3 | node | mvp
416
430
  --lang <code> Agent language: en | uk | ...
417
431
  --name <name> Project name (default: directory name)
418
432
  --force Overwrite existing files
@@ -456,6 +470,23 @@ openspec/ # Committed — spec-driven workflow
456
470
 
457
471
  ## Changelog
458
472
 
473
+ ### 0.1.3
474
+ - Fix gitignore dedup (exact line match, not substring)
475
+ - Add `.claude` to gitignore on init
476
+ - `sync --target amp` — explicit Amp handling + settings.json bootstrap
477
+ - OpenSpec + frontend-agent-skills hints in init next steps
478
+ - Profile validation with warning for unknown profiles
479
+ - CI workflow: auto-detect npm / yarn / pnpm
480
+ - Package manager detection → updates verifier commands in orchestrator.yaml
481
+ - `openspec/config.yaml.example` from vue3/mvp profiles
482
+ - Review gate: `review.md` + apply checks `require_spec_review`
483
+ - Vue 3 checklist in `/opsx:review`
484
+ - New `/opsx:quick` command and **mvp** profile for demos/spikes
485
+
486
+ ### 0.1.2
487
+ - Fix CLI: executable bit on `bin/agent-orchestrator.js` (`agent-orchestrator: not found`)
488
+ - Add `agent-orchestrator-kit` bin alias (matches package name for npx)
489
+
459
490
  ### 0.1.1
460
491
  - Added all OpenSpec skills (`openspec-*`, `spec-workflow-openspec`)
461
492
  - Added CI workflow template `.github/workflows/agent-verify.yml`
@@ -10,6 +10,8 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  const KIT_ROOT = join(__dirname, '..');
11
11
  const KIT_VERSION = JSON.parse(readFileSync(join(KIT_ROOT, 'package.json'), 'utf-8')).version;
12
12
 
13
+ const VALID_PROFILES = ['generic', 'vue3', 'node', 'mvp'];
14
+
13
15
  const KIT_SKILL_DIRS = [
14
16
  'agent-orchestration',
15
17
  'openspec-howto',
@@ -29,6 +31,8 @@ const KIT_MANAGED_PATHS = [
29
31
  'scripts/sync-local-agent-skills.sh',
30
32
  ];
31
33
 
34
+ const GITIGNORE_LINES = ['.cursor', '.cursor/memory.json', '.amp/settings.json', '.claude'];
35
+
32
36
  const log = {
33
37
  info: (msg) => console.log(pc.cyan(' →'), msg),
34
38
  ok: (msg) => console.log(pc.green(' ✓'), msg),
@@ -58,20 +62,19 @@ function copyDir(src, dest, opts = {}) {
58
62
  }
59
63
  }
60
64
 
65
+ function gitignoreLines(content) {
66
+ return content.split('\n').map((l) => l.trim()).filter(Boolean);
67
+ }
68
+
61
69
  function mergeGitignore(projectDir, lines) {
62
70
  const gitignorePath = join(projectDir, '.gitignore');
63
- let content = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';
64
- let changed = false;
65
- for (const line of lines) {
66
- if (!content.includes(line)) {
67
- content += `\n${line}`;
68
- changed = true;
69
- }
70
- }
71
- if (changed) {
72
- writeFileSync(gitignorePath, content.trimStart());
73
- log.ok('.gitignore updated');
74
- }
71
+ const raw = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';
72
+ const existing = gitignoreLines(raw);
73
+ const toAdd = lines.filter((line) => !existing.includes(line));
74
+ if (toAdd.length === 0) return;
75
+ const prefix = raw.length > 0 && !raw.endsWith('\n') ? '\n' : '';
76
+ writeFileSync(gitignorePath, raw + prefix + toAdd.join('\n') + '\n');
77
+ log.ok('.gitignore updated');
75
78
  }
76
79
 
77
80
  function resolveTemplate(templateName, profile) {
@@ -89,6 +92,138 @@ function applyPlaceholders(filePath, vars) {
89
92
  writeFileSync(filePath, content);
90
93
  }
91
94
 
95
+ function resolveProfile(profile) {
96
+ if (VALID_PROFILES.includes(profile)) return profile;
97
+ log.warn(`Unknown profile "${profile}". Valid: ${VALID_PROFILES.join(', ')}. Using generic.`);
98
+ return 'generic';
99
+ }
100
+
101
+ function detectPackageManager(projectDir) {
102
+ if (existsSync(join(projectDir, 'pnpm-lock.yaml'))) return 'pnpm';
103
+ if (existsSync(join(projectDir, 'yarn.lock'))) return 'yarn';
104
+ return 'npm';
105
+ }
106
+
107
+ function pmCommands(pm) {
108
+ const map = {
109
+ npm: { install: 'npm ci', lint: 'npm run lint', build: 'npm run build', test: 'npm test' },
110
+ yarn: { install: 'yarn install --frozen-lockfile', lint: 'yarn lint', build: 'yarn build', test: 'yarn test' },
111
+ pnpm: { install: 'pnpm install --frozen-lockfile', lint: 'pnpm run lint', build: 'pnpm run build', test: 'pnpm test' },
112
+ };
113
+ return map[pm] || map.npm;
114
+ }
115
+
116
+ function hasOpenSpec(projectDir) {
117
+ return existsSync(join(projectDir, 'openspec', 'config.yaml'));
118
+ }
119
+
120
+ function installOpenspecConfigExample(projectDir, profile, vars, force) {
121
+ const src = resolveTemplate('openspec-config.yaml.example', profile);
122
+ if (!existsSync(src)) return;
123
+
124
+ const openspecDir = join(projectDir, 'openspec');
125
+ const configPath = join(openspecDir, 'config.yaml');
126
+ const examplePath = join(openspecDir, 'config.yaml.example');
127
+
128
+ mkdirSync(openspecDir, { recursive: true });
129
+
130
+ if (existsSync(configPath) && !force) {
131
+ log.warn('skip (exists): openspec/config.yaml');
132
+ return;
133
+ }
134
+
135
+ if (!existsSync(configPath)) {
136
+ copyFileSync(src, examplePath);
137
+ applyPlaceholders(examplePath, vars);
138
+ log.ok('openspec/config.yaml.example');
139
+ return;
140
+ }
141
+
142
+ if (force) {
143
+ copyFileSync(src, configPath);
144
+ applyPlaceholders(configPath, vars);
145
+ log.ok('openspec/config.yaml');
146
+ }
147
+ }
148
+
149
+ function patchOrchestratorVerifier(projectDir, pm) {
150
+ const orchPath = join(projectDir, '.agents', 'orchestrator.yaml');
151
+ if (!existsSync(orchPath)) return;
152
+
153
+ const cmds = pmCommands(pm);
154
+ let content = readFileSync(orchPath, 'utf-8');
155
+
156
+ content = content.replace(/^(\s*package_manager:\s*).+$/m, `$1${pm}`);
157
+ if (!/^package_manager:/m.test(content)) {
158
+ content = content.replace(
159
+ /^(project:\n(?: .+\n)+)/m,
160
+ `$1\npackage_manager: ${pm}\n`,
161
+ );
162
+ }
163
+
164
+ content = content.replace(/^(\s*lint_command:\s*).+$/m, `$1"${cmds.lint}"`);
165
+ content = content.replace(/^(\s*build_command:\s*).+$/m, `$1"${cmds.build}"`);
166
+ content = content.replace(/^(\s*test_command:\s*).+$/m, `$1"${cmds.test}"`);
167
+
168
+ writeFileSync(orchPath, content);
169
+ }
170
+
171
+ function printNextSteps(profile, projectDir) {
172
+ const pm = detectPackageManager(projectDir);
173
+ const openspecReady = hasOpenSpec(projectDir);
174
+ const lines = [`${pc.bold('Next steps:')}`];
175
+
176
+ if (!openspecReady) {
177
+ lines.push(` 0. Install OpenSpec (required — kit does not install it):`);
178
+ lines.push(` ${pc.cyan('npm i -D @fission-ai/openspec && npx openspec init')}`);
179
+ lines.push(` Then copy ${pc.cyan('openspec/config.yaml.example')} → ${pc.cyan('openspec/config.yaml')} if present`);
180
+ } else {
181
+ lines.push(` 0. OpenSpec detected ✓ — run ${pc.cyan('npx openspec validate --all --strict')} to verify`);
182
+ }
183
+
184
+ lines.push(` 1. Review ${pc.cyan('AGENTS.md')} and ${pc.cyan('.agents/orchestrator.yaml')}`);
185
+ lines.push(` 2. Sync to your IDE:`);
186
+ lines.push(` ${pc.cyan('./scripts/sync-local-agent-skills.sh')}`);
187
+
188
+ if (profile === 'vue3') {
189
+ lines.push(` 3. Install Vue/JS stack skills:`);
190
+ lines.push(` ${pc.cyan('npx frontend-agent-skills install --agent all --yes')}`);
191
+ lines.push(` 4. MCP: copy .mcp.json (Cursor) / .amp/settings.json (Amp) from *.example files`);
192
+ lines.push(` 5. Start your first change:`);
193
+ } else if (profile === 'mvp') {
194
+ lines.push(` 3. For quick demos use ${pc.cyan('/opsx:quick <name>')} (propose + apply, no review gate)`);
195
+ lines.push(` 4. MCP: copy .mcp.json (Cursor) / .amp/settings.json (Amp) from *.example files`);
196
+ lines.push(` 5. Start exploring:`);
197
+ } else {
198
+ lines.push(` 3. MCP: copy .mcp.json (Cursor) / .amp/settings.json (Amp) from *.example files`);
199
+ lines.push(` 4. Start your first change:`);
200
+ }
201
+
202
+ const startCmd = profile === 'mvp' ? '/opsx:quick' : '/opsx:explore';
203
+ lines.push(` ${pc.cyan(startCmd)}`);
204
+
205
+ if (pm !== 'npm') {
206
+ lines.push(` ${pc.dim(`Detected package manager: ${pm} (verifier commands updated in orchestrator.yaml)`)}`);
207
+ }
208
+
209
+ console.log('\n' + lines.join('\n') + '\n');
210
+ }
211
+
212
+ function syncAmp(projectDir) {
213
+ log.info('Amp Code reads .agents/ natively — no skill sync needed');
214
+ mkdirSync(join(projectDir, '.amp'), { recursive: true });
215
+ const ampExample = join(projectDir, '.agents', 'amp.settings.json.example');
216
+ const ampDest = join(projectDir, '.amp', 'settings.json');
217
+ if (existsSync(ampExample) && !existsSync(ampDest)) {
218
+ copyFileSync(ampExample, ampDest);
219
+ log.ok('.amp/settings.json created from example');
220
+ } else if (existsSync(ampDest)) {
221
+ log.ok('.amp/settings.json already present');
222
+ } else {
223
+ log.warn('.amp/settings.json missing — copy from .agents/amp.settings.json.example');
224
+ }
225
+ }
226
+
92
227
  program
93
228
  .name('agent-orchestrator')
94
229
  .description('Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code')
@@ -97,22 +232,25 @@ program
97
232
  program
98
233
  .command('init')
99
234
  .description('Install orchestrator kit into the current project')
100
- .option('--profile <profile>', 'Stack profile: generic | vue3 | node | python', 'generic')
235
+ .option('--profile <profile>', `Stack profile: ${VALID_PROFILES.join(' | ')}`, 'generic')
101
236
  .option('--lang <lang>', 'Agent response language (en | uk | ...)', 'en')
102
237
  .option('--name <name>', 'Project name (defaults to directory name)')
103
238
  .option('--force', 'Overwrite existing files', false)
104
239
  .action((opts) => {
105
240
  const projectDir = process.cwd();
106
241
  const projectName = opts.name || basename(projectDir);
242
+ const profile = resolveProfile(opts.profile);
243
+ const pm = detectPackageManager(projectDir);
107
244
 
108
245
  log.title(`agent-orchestrator init v${KIT_VERSION}`);
109
246
  log.info(`Project: ${projectName}`);
110
- log.info(`Profile: ${opts.profile}`);
247
+ log.info(`Profile: ${profile}`);
111
248
  log.info(`Language: ${opts.lang}`);
249
+ log.info(`Package manager: ${pm}`);
112
250
 
113
251
  const templateDir = join(KIT_ROOT, 'templates');
114
- const profileDir = join(KIT_ROOT, 'profiles', opts.profile);
115
- const vars = { PROJECT_NAME: projectName, LANG: opts.lang, KIT_VERSION };
252
+ const profileDir = join(KIT_ROOT, 'profiles', profile);
253
+ const vars = { PROJECT_NAME: projectName, LANG: opts.lang, KIT_VERSION, PACKAGE_MANAGER: pm };
116
254
 
117
255
  log.title('Installing .agents/');
118
256
  copyDir(join(templateDir, '.agents'), join(projectDir, '.agents'), { overwrite: opts.force });
@@ -141,7 +279,7 @@ program
141
279
 
142
280
  log.title('Installing root files');
143
281
  for (const f of ['AGENTS.md', 'CLAUDE.md']) {
144
- const src = resolveTemplate(f, opts.profile);
282
+ const src = resolveTemplate(f, profile);
145
283
  const dest = join(projectDir, f);
146
284
  if (!opts.force && existsSync(dest)) {
147
285
  log.warn(`skip (exists): ${f}`);
@@ -154,30 +292,26 @@ program
154
292
  }
155
293
  }
156
294
 
157
- const orchSrc = resolveTemplate('orchestrator.yaml', opts.profile);
295
+ const orchSrc = resolveTemplate('orchestrator.yaml', profile);
158
296
  const orchDest = join(projectDir, '.agents', 'orchestrator.yaml');
159
297
  if (!opts.force && existsSync(orchDest)) {
160
298
  log.warn('skip (exists): .agents/orchestrator.yaml');
161
299
  } else if (existsSync(orchSrc)) {
162
300
  copyFileSync(orchSrc, orchDest);
163
301
  applyPlaceholders(orchDest, vars);
302
+ patchOrchestratorVerifier(projectDir, pm);
164
303
  log.ok('.agents/orchestrator.yaml');
165
304
  }
166
305
 
306
+ log.title('OpenSpec config template');
307
+ installOpenspecConfigExample(projectDir, profile, vars, opts.force);
308
+
167
309
  log.title('Updating .gitignore');
168
- mergeGitignore(projectDir, ['.cursor', '.cursor/memory.json', '.amp/settings.json']);
310
+ mergeGitignore(projectDir, GITIGNORE_LINES);
169
311
 
170
312
  log.title('Done');
171
313
  log.ok(`agent-orchestrator-kit v${KIT_VERSION} installed`);
172
- console.log(`
173
- ${pc.bold('Next steps:')}
174
- 1. Review ${pc.cyan('AGENTS.md')} and ${pc.cyan('.agents/orchestrator.yaml')}
175
- 2. Sync to your IDE:
176
- ${pc.cyan('./scripts/sync-local-agent-skills.sh')}
177
- 3. Copy MCP config: .mcp.json (Cursor) / .amp/settings.json (Amp) from *.example files
178
- 4. Start your first change:
179
- ${pc.cyan('/opsx:explore')}
180
- `);
314
+ printNextSteps(profile, projectDir);
181
315
  });
182
316
 
183
317
  program
@@ -208,7 +342,7 @@ program
208
342
 
209
343
  program
210
344
  .command('sync')
211
- .description('Sync .agents/ to local IDE directories (Cursor, Claude Code)')
345
+ .description('Sync .agents/ to local IDE directories (Cursor, Claude Code, Amp)')
212
346
  .option('--target <target>', 'cursor | claude | amp | all', 'all')
213
347
  .action((opts) => {
214
348
  const projectDir = process.cwd();
@@ -217,6 +351,7 @@ program
217
351
 
218
352
  const syncCursor = ['cursor', 'all'].includes(opts.target);
219
353
  const syncClaude = ['claude', 'all'].includes(opts.target);
354
+ const syncAmpTarget = ['amp', 'all'].includes(opts.target);
220
355
 
221
356
  if (syncCursor) {
222
357
  log.info('Syncing .agents/ → .cursor/');
@@ -244,8 +379,14 @@ program
244
379
  }
245
380
  }
246
381
 
382
+ if (syncAmpTarget) {
383
+ syncAmp(projectDir);
384
+ }
385
+
386
+ mergeGitignore(projectDir, GITIGNORE_LINES);
387
+
247
388
  log.ok('Sync complete');
248
- log.warn('.cursor/ and .claude/ are local only — not committed to git');
389
+ log.warn('.cursor/, .claude/, .amp/ are local only — not committed to git');
249
390
  });
250
391
 
251
392
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-orchestrator-kit",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code — spec-driven pipeline with OpenSpec integration",
5
5
  "keywords": [
6
6
  "ai-agent",
@@ -17,20 +17,22 @@
17
17
  "homepage": "https://github.com/makshc2/agent-orchestrator-kit#readme",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "https://github.com/makshc2/agent-orchestrator-kit.git"
20
+ "url": "git+https://github.com/makshc2/agent-orchestrator-kit.git"
21
21
  },
22
22
  "bugs": {
23
23
  "url": "https://github.com/makshc2/agent-orchestrator-kit/issues"
24
24
  },
25
25
  "type": "module",
26
26
  "bin": {
27
- "agent-orchestrator": "./bin/agent-orchestrator.js"
27
+ "agent-orchestrator-kit": "bin/agent-orchestrator.js",
28
+ "agent-orchestrator": "bin/agent-orchestrator.js"
28
29
  },
29
30
  "files": [
30
31
  "bin/",
31
32
  "templates/",
32
33
  "profiles/",
33
34
  "README.md",
35
+ "CHANGELOG.md",
34
36
  "LICENSE"
35
37
  ],
36
38
  "engines": {
@@ -41,7 +43,11 @@
41
43
  "picocolors": "^1.0.0"
42
44
  },
43
45
  "scripts": {
46
+ "prepack": "chmod +x bin/agent-orchestrator.js",
47
+ "prepublishOnly": "npm test",
44
48
  "test": "node --test test/*.test.js",
45
- "link": "npm link"
49
+ "link": "npm link",
50
+ "release:check": "npm test && npm pack --dry-run",
51
+ "release:tag": "git tag v$(node -p \"require('./package.json').version\")"
46
52
  }
47
53
  }
@@ -0,0 +1,47 @@
1
+ # Agent Orchestration — {{PROJECT_NAME}} (MVP)
2
+
3
+ > Powered by [agent-orchestrator-kit](https://github.com/makshc2/agent-orchestrator-kit) v{{KIT_VERSION}} — **mvp profile**
4
+
5
+ Lightweight AI pipeline for **demos, spikes, and hypothesis testing**. Full spec review is optional.
6
+
7
+ ## Pipeline
8
+
9
+ ```
10
+ explore → quick (propose + apply) → verify → archive (optional)
11
+ ```
12
+
13
+ Or full path when needed:
14
+
15
+ ```
16
+ explore → propose → apply → verify
17
+ ```
18
+
19
+ ## Roles
20
+
21
+ | Role | Command | When |
22
+ |------|---------|------|
23
+ | Explorer | `/opsx:explore` | Scope unclear |
24
+ | Quick | `/opsx:quick <name>` | Demo / spike / 1–3 files |
25
+ | Architect | `/opsx:propose <name>` | Need full artifacts |
26
+ | Implementer | `/opsx:apply <name>` | Continue existing change |
27
+ | Verifier | local build/lint | Before demo handoff |
28
+
29
+ ## Hard Rules (MVP)
30
+
31
+ - **`require_spec_review: false`** — no review gate
32
+ - Up to **3 active changes** in parallel
33
+ - **Archive optional** for throwaway demos
34
+ - Still run **build + lint** before declaring done
35
+ - Switch to **vue3/generic profile** when promoting demo to production
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ /opsx:quick add-demo-widget
41
+ # or
42
+ /opsx:explore → /opsx:quick <name>
43
+ ```
44
+
45
+ ## Configuration
46
+
47
+ See `.agents/orchestrator.yaml` — `profile: mvp`, `quick_mode_enabled: true`.
@@ -0,0 +1,36 @@
1
+ # MVP Profile
2
+
3
+ Fast AI pipeline for **demos, prototypes, and hypothesis testing**.
4
+
5
+ ```bash
6
+ npx agent-orchestrator-kit init --profile mvp --lang uk --name "My Demo"
7
+ ```
8
+
9
+ ## Differences from vue3/generic
10
+
11
+ | Setting | vue3 | mvp |
12
+ |---------|------|-----|
13
+ | `require_spec_review` | true | **false** |
14
+ | `max_active_changes` | 1 | **3** |
15
+ | `archive_after_merge` | true | **false** |
16
+ | Primary command | `/opsx:propose` | **`/opsx:quick`** |
17
+ | Delta specs | required | optional |
18
+
19
+ ## Recommended stack setup
20
+
21
+ ```bash
22
+ npm i -D @fission-ai/openspec
23
+ npx openspec init
24
+ # copy openspec/config.yaml.example → openspec/config.yaml
25
+
26
+ npx frontend-agent-skills install --agent all --yes
27
+ ./scripts/sync-local-agent-skills.sh
28
+ ```
29
+
30
+ ## When to graduate to vue3 profile
31
+
32
+ - Feature goes to production
33
+ - Team needs spec review gate
34
+ - Multi-day changes with delta specs
35
+
36
+ Update `.agents/orchestrator.yaml` manually or re-init with `--profile vue3` (preserves openspec/).
@@ -0,0 +1,17 @@
1
+ schema: spec-driven
2
+
3
+ context: |
4
+ Проєкт: {{PROJECT_NAME}} — MVP / demo / hypothesis testing.
5
+ Стек: Vue 3 (Composition API, <script setup>), Pinia, Vite, Axios.
6
+ Мова агента: {{LANG}}.
7
+ Режим: швидкі ітерації — proposal + tasks достатньо; delta specs опційні.
8
+
9
+ rules:
10
+ proposal:
11
+ - Коротко: проблема, scope, non-goals (≤ 15 рядків)
12
+ - Acceptance criteria — 3–5 перевірних пунктів
13
+ tasks:
14
+ - 3–7 атомарних задач
15
+ - Останній пункт: build + lint
16
+ specs:
17
+ - Опційно для MVP — пропускай якщо change тривіальний
@@ -0,0 +1,60 @@
1
+ version: 1
2
+ kit_version: "{{KIT_VERSION}}"
3
+
4
+ project:
5
+ name: "{{PROJECT_NAME}}"
6
+ profile: mvp
7
+ stack: vue3
8
+ agent_language: "{{LANG}}"
9
+
10
+ package_manager: npm
11
+
12
+ pipeline:
13
+ require_spec_review: false
14
+ max_active_changes: 3
15
+ archive_after_merge: false
16
+ quick_mode_enabled: true
17
+
18
+ roles:
19
+ explorer:
20
+ command: /opsx:explore
21
+ mode: read-only
22
+ model_hint: fast
23
+ architect:
24
+ command: /opsx:propose
25
+ mode: specs-only
26
+ model_hint: strong
27
+ quick:
28
+ command: /opsx:quick
29
+ mode: specs-and-code
30
+ model_hint: strong
31
+ notes: "Propose + apply in one session for demos and spikes"
32
+ implementer:
33
+ command: /opsx:apply
34
+ mode: code
35
+ model_hint: strong
36
+ spec_reviewer:
37
+ enabled: false
38
+ verifier:
39
+ type: local
40
+ gates:
41
+ - lint
42
+ - build
43
+
44
+ handoff:
45
+ explore_to_propose: decision_brief
46
+ propose_to_apply: validate_or_quick
47
+ apply_to_verify: all_tasks_checked
48
+
49
+ memory:
50
+ enabled: true
51
+ file: .cursor/memory.json
52
+
53
+ mcp:
54
+ baseline:
55
+ - memory
56
+
57
+ verifier:
58
+ lint_command: "npm run lint"
59
+ build_command: "npm run build"
60
+ test_command: ""
@@ -6,6 +6,8 @@ project:
6
6
  stack: node
7
7
  agent_language: "{{LANG}}"
8
8
 
9
+ package_manager: npm
10
+
9
11
  pipeline:
10
12
  require_spec_review: true
11
13
  max_active_changes: 1
@@ -1,14 +1,36 @@
1
1
  # Vue 3 Profile
2
2
 
3
- After `agent-orchestrator-kit init --profile vue3`, also install Vue-specific skills:
3
+ After `agent-orchestrator-kit init --profile vue3`, install stack skills from [frontend-agent-skills](https://www.npmjs.com/package/frontend-agent-skills):
4
4
 
5
5
  ```bash
6
- npx vue-cursor-skills install
7
- rsync -a --delete .cursor/skills/ .agents/skills/
6
+ # OpenSpec (if not in repo yet)
7
+ npm i -D @fission-ai/openspec && npx openspec init
8
+ cp openspec/config.yaml.example openspec/config.yaml # generated by kit init
9
+
10
+ # Amp — installs directly to .agents/skills/ (no rsync needed)
11
+ npx frontend-agent-skills install --agent amp --yes
12
+
13
+ # Cursor / Claude Code — sync local IDE dirs after install
8
14
  ./scripts/sync-local-agent-skills.sh
9
15
  ```
10
16
 
11
- This adds: `vue-core`, `vue-pinia`, `vue-router`, `vue-axios`, `vue-architecture`, `vue-composables`, `vite`, and debug skills.
17
+ Or install for all IDEs at once:
18
+
19
+ ```bash
20
+ npx frontend-agent-skills install --agent all --yes
21
+ ```
22
+
23
+ Selective install:
24
+
25
+ ```bash
26
+ npx frontend-agent-skills install --agent amp --category vue --yes
27
+ npx frontend-agent-skills install --agent amp --category javascript --yes
28
+ npx frontend-agent-skills list
29
+ ```
30
+
31
+ This adds Vue skills (`vue-core`, `vue-pinia`, `vue-router`, `vue-axios`, `vue-architecture`, `vue-composables`, `vue-debug`, …), `vite`, and JavaScript skills (`javascript-core`, `javascript-dom`, `javascript-debug`, …).
32
+
33
+ > **Migrating from `vue-cursor-skills`?** Renamed in v2.0.0 — same skills, clearer name. Old CLI alias still works.
12
34
 
13
35
  ## Recommended OpenSpec config.yaml additions
14
36
 
@@ -0,0 +1,21 @@
1
+ schema: spec-driven
2
+
3
+ context: |
4
+ Проєкт: {{PROJECT_NAME}} — Vue 3 SPA.
5
+ Стек: Vue 3 (Composition API, <script setup>), Pinia, Vue Router, Axios, Vite.
6
+ Мова агента: {{LANG}}.
7
+ Код: production-ready, без Options API, без зайвих коментарів.
8
+
9
+ rules:
10
+ proposal:
11
+ - Пиши українською (якщо agent_language: uk)
12
+ - Завжди включай Non-goals та Acceptance criteria
13
+ design:
14
+ - Посилайся на існуючі патерни в src/
15
+ - Описуй зміни на рівні компонентів, stores, API
16
+ tasks:
17
+ - Розбивай на задачі до ~2 годин
18
+ - Останній пункт: build + lint без помилок
19
+ specs:
20
+ - Delta format: ADDED / MODIFIED / REMOVED
21
+ - Кожна вимога — мінімум один Scenario
@@ -6,6 +6,8 @@ project:
6
6
  stack: vue3
7
7
  agent_language: "{{LANG}}"
8
8
 
9
+ package_manager: npm
10
+
9
11
  pipeline:
10
12
  require_spec_review: true
11
13
  max_active_changes: 1
@@ -20,6 +20,19 @@ Implement tasks from an OpenSpec change.
20
20
 
21
21
  Always announce: "Using change: <name>" and how to override (e.g., `/opsx:apply <other>`).
22
22
 
23
+ 1.5. **Check review gate**
24
+
25
+ Read `.agents/orchestrator.yaml` → `pipeline.require_spec_review`.
26
+
27
+ If `true` (default for generic/vue3/node):
28
+ - Look for `openspec/changes/<name>/review.md` with `Verdict: APPROVE`
29
+ - OR explicit **APPROVE ✓** from `/opsx:review <name>` in this session (user pasted verdict)
30
+ - OR Memory MCP entity `Change:<name>` with `status: spec-approved`
31
+ - If none found → **STOP**. Tell user:
32
+ > "Spec review required. Run `/opsx:review <name>` in a separate read-only session, then start a new apply session after **Approve ✓`."
33
+
34
+ If `false` (mvp profile) or user confirms quick/demo mode → proceed.
35
+
23
36
  2. **Check status to understand the schema**
24
37
  ```bash
25
38
  openspec status --change "<name>" --json
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: /opsx-quick
3
+ id: opsx-quick
4
+ category: Workflow
5
+ description: Fast path for MVP/demo — propose artifacts and apply in one session (skips review gate)
6
+ ---
7
+
8
+ Quick mode for **small changes, demos, and hypothesis testing**. Combines propose + apply in one session.
9
+
10
+ **Use when:**
11
+ - Spike / proof-of-concept / demo UI
12
+ - 1–3 files, clear scope
13
+ - `pipeline.require_spec_review: false` in `.agents/orchestrator.yaml` (mvp profile)
14
+
15
+ **Do NOT use when:**
16
+ - Multi-file refactor, API contract changes, production features
17
+ - Team requires spec review (`require_spec_review: true`)
18
+
19
+ ---
20
+
21
+ **Input**: Change name (kebab-case) or description. Example: `/opsx:quick add-export-button`
22
+
23
+ **Steps**
24
+
25
+ 1. **Check orchestrator config**
26
+
27
+ Read `.agents/orchestrator.yaml`:
28
+ - If `pipeline.require_spec_review: true` → warn user and ask to confirm skip OR use full pipeline (`/opsx:propose` → `/opsx:review` → `/opsx:apply`)
29
+ - If `false` or `profile: mvp` → proceed
30
+
31
+ 2. **Create change (minimal artifacts)**
32
+
33
+ ```bash
34
+ openspec new change "<name>"
35
+ ```
36
+
37
+ Create **lightweight** artifacts (no delta specs unless user asks):
38
+ - `proposal.md` — problem, scope, non-goals (5–10 lines)
39
+ - `tasks.md` — 3–7 atomic tasks with checkboxes
40
+ - `design.md` — optional, skip if trivial
41
+
42
+ Skip `specs/` delta for MVP unless behavior must be documented.
43
+
44
+ 3. **Validate**
45
+
46
+ ```bash
47
+ openspec validate <name> --strict --type change
48
+ ```
49
+
50
+ 4. **Apply immediately**
51
+
52
+ Follow `/opsx:apply` steps for the same change:
53
+ - Read tasks.md
54
+ - Implement 1–3 tasks per pass
55
+ - Mark `[x]`
56
+ - Run build/lint from `orchestrator.yaml` verifier commands
57
+
58
+ 5. **Exit**
59
+
60
+ - If demo done and no merge planned → optionally skip archive
61
+ - If merging → run `/opsx:archive` after CI green
62
+
63
+ ---
64
+
65
+ **Guardrails**
66
+ - Max ~3 hours of work — if bigger, switch to full pipeline
67
+ - Still run build/lint before declaring done
68
+ - Do not skip OpenSpec entirely — at minimum proposal + tasks
69
+ - For vue3: use vue-core, vue-pinia skills during implementation
@@ -74,6 +74,13 @@ Evaluate each item. Mark ✓ or ✗:
74
74
  - [ ] ADDED/MODIFIED/REMOVED sections used correctly
75
75
  - [ ] No conflicts with main `openspec/specs/`
76
76
 
77
+ **Vue 3** (when `project.stack: vue3` in `.agents/orchestrator.yaml`)
78
+ - [ ] Components use `<script setup>` + Composition API (no Options API)
79
+ - [ ] State via Pinia setup stores (`defineStore` + composable style)
80
+ - [ ] HTTP via Axios service/composable patterns (not raw fetch scattered)
81
+ - [ ] Tasks reference concrete component/store paths under `src/`
82
+ - [ ] No scope creep into unrelated UI refactors
83
+
77
84
  ### 5. Output verdict
78
85
 
79
86
  #### If all ✓ (or only minor notes):
@@ -93,6 +100,31 @@ Evaluate each item. Mark ✓ or ✗:
93
100
  **Ready for implementation.** Run `/opsx:apply <name>` to proceed.
94
101
  ```
95
102
 
103
+ Also **write review record** (gates apply when `require_spec_review: true`):
104
+
105
+ Create or update `openspec/changes/<name>/review.md`:
106
+
107
+ ```markdown
108
+ # Spec Review
109
+
110
+ **Change:** <name>
111
+ **Date:** <ISO date>
112
+ **Verdict:** APPROVE
113
+
114
+ ## Checklist summary
115
+ - Proposal: ✓
116
+ - Design: ✓
117
+ - Tasks: ✓
118
+ - Delta specs: ✓
119
+
120
+ ## Notes
121
+ <optional notes>
122
+ ```
123
+
124
+ For **REQUEST CHANGES**, write the same file with `Verdict: REQUEST CHANGES` and issues list.
125
+
126
+ This is the **only file** you may write during review (not `src/`, not `tasks.md` checkboxes).
127
+
96
128
  #### If any ✗:
97
129
 
98
130
  ```
@@ -119,7 +151,7 @@ Fix the above, then re-run `/opsx:review <name>`.
119
151
  ## Guardrails
120
152
 
121
153
  - **Never** edit source code, `src/`, or `tasks.md` checkboxes
122
- - **Never** create new files (only read)
154
+ - **May write only** `openspec/changes/<name>/review.md` (verdict record for apply gate)
123
155
  - **Never** run apply commands
124
156
  - Ask for clarification only if a critical artifact is missing or unreadable
125
157
  - If proposal is ambiguous on scope, flag as ✗ — do not assume intent
@@ -10,17 +10,18 @@ This project uses a spec-driven 5-role pipeline. Read `.agents/orchestrator.yaml
10
10
  ## Role Commands
11
11
  - `/opsx:explore` → read-only thinking, no code
12
12
  - `/opsx:propose <name>` → creates `openspec/changes/<name>/` artifacts only
13
- - `/opsx:review <name>` → read-only spec review, outputs Approve or Request Changes
14
- - `/opsx:apply <name>` → writes `src/`, marks `tasks.md [x]`
13
+ - `/opsx:review <name>` → read-only spec review, writes `review.md`, outputs Approve or Request Changes
14
+ - `/opsx:apply <name>` → writes `src/`, marks `tasks.md [x]` (blocked if no review when `require_spec_review: true`)
15
+ - `/opsx:quick <name>` → MVP: propose + apply in one session (when `require_spec_review: false`)
15
16
  - `/opsx:archive` → merges delta specs, moves change to archive
16
17
 
17
18
  ## Session Rules
18
- - One active change at a time
19
- - Each role = new chat session
19
+ - One active change at a time (unless mvp profile: up to 3)
20
+ - Each role = new chat session (except `/opsx:quick` combines propose+apply)
20
21
  - No code in explore or review sessions
21
- - No apply without explicit **Approve** from review
22
+ - No apply without review when `pipeline.require_spec_review: true` — check `review.md` or Approve in context
22
23
  - After apply: build + lint before PR
23
- - After merge: always run `/opsx:archive`
24
+ - After merge: run `/opsx:archive` (when `archive_after_merge: true`)
24
25
 
25
26
  ## Never
26
27
  - Mix propose and apply in one session
@@ -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` — AI workflow commands, not source code.
8
+ `/opsx:explore`, `/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
 
@@ -22,8 +22,9 @@ alwaysApply: true
22
22
 
23
23
  - `/opsx:explore` → skill `openspec-explore` (thinking only)
24
24
  - `/opsx:propose <name>` → skill `openspec-propose`
25
- - `/opsx:review <name>` → command `opsx-review` (read-only)
25
+ - `/opsx:review <name>` → command `opsx-review` (read-only, writes review.md)
26
26
  - `/opsx:apply` → skill `openspec-apply-change`
27
+ - `/opsx:quick <name>` → command `opsx-quick` (mvp: propose + apply)
27
28
  - `/opsx:archive` → skill `openspec-archive-change`
28
29
  - `/opsx:sync` → skill `openspec-sync-specs`
29
30
 
@@ -4,7 +4,7 @@ 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
6
  should stop and a new one start. Commands: /opsx:explore, /opsx:propose, /opsx:review,
7
- /opsx:apply, /opsx:archive.
7
+ /opsx:apply, /opsx:archive, /opsx:quick.
8
8
  disable-model-invocation: false
9
9
  allowed-tools: Bash, Read
10
10
  ---
@@ -20,7 +20,12 @@ is the primary source of wasted tokens and failed implementations.
20
20
  explore → propose → review → apply → verify → archive
21
21
  ```
22
22
 
23
- Read `.agents/orchestrator.yaml` for project-specific config (language, flags, MCP).
23
+ **MVP profile** (`require_spec_review: false`):
24
+ ```
25
+ explore → quick (propose+apply) → verify → archive (optional)
26
+ ```
27
+
28
+ Read `.agents/orchestrator.yaml` for project-specific config (language, flags, MCP, review gate).
24
29
 
25
30
  ## Roles & Commands
26
31
 
@@ -28,9 +33,10 @@ Read `.agents/orchestrator.yaml` for project-specific config (language, flags, M
28
33
  |------|---------|------|------------|----------------|
29
34
  | Explorer | `/opsx:explore` | read-only | fast | chat only |
30
35
  | Architect | `/opsx:propose <name>` | specs-only | strong | `openspec/changes/` |
31
- | Spec Reviewer | `/opsx:review <name>` | read-only | medium | Approve / Request Changes |
36
+ | Spec Reviewer | `/opsx:review <name>` | read-only | medium | `review.md`, Approve / Request Changes |
32
37
  | Implementer | `/opsx:apply <name>` | code | strong | `src/`, `tasks.md [x]` |
33
- | Verifier | CI scripts | | | exit codes |
38
+ | Quick (MVP) | `/opsx:quick <name>` | specs+code | strong | `openspec/changes/` + `src/` |
39
+ | Verifier | CI / local scripts | — | — | exit codes |
34
40
 
35
41
  ## Handoff Protocol
36
42
 
@@ -60,7 +66,12 @@ openspec status --change "<name>" # applyRequires artifacts all d
60
66
  ```
61
67
 
62
68
  ### review → apply
63
- Exit Reviewer only when verdict is explicit **APPROVE ✓**.
69
+ Exit Reviewer only when verdict is explicit **APPROVE ✓** and `review.md` written.
70
+
71
+ Before apply, check `.agents/orchestrator.yaml`:
72
+ - `require_spec_review: true` → apply MUST find `review.md` with `Verdict: APPROVE` or Approve in session
73
+ - `require_spec_review: false` → apply allowed directly (mvp / quick mode)
74
+
64
75
  If Request Changes — fix artifacts, re-run `/opsx:review`.
65
76
 
66
77
  ### apply → verify
@@ -80,8 +91,8 @@ After PR merged + CI green:
80
91
 
81
92
  **Start of each session:**
82
93
  1. Announce role: "Starting Spec Reviewer session for change: <name>"
83
- 2. Check `openspec list` — confirm max 1 active change
84
- 3. Read `orchestrator.yaml` for project config
94
+ 2. Check `openspec list` — confirm active change limit (`max_active_changes` in orchestrator.yaml)
95
+ 3. Read `orchestrator.yaml` for project config and review gate
85
96
 
86
97
  **During session:**
87
98
  - Stay in role — do not drift into next phase
@@ -121,7 +132,8 @@ At start of new session: read relevant entities to restore context without re-ex
121
132
 
122
133
  - [ ] explore session closed before propose started
123
134
  - [ ] `openspec validate --strict` passed before review
124
- - [ ] explicit **Approve** received before apply
135
+ - [ ] explicit **Approve** received before apply (when `require_spec_review: true`)
136
+ - [ ] `review.md` with `Verdict: APPROVE` exists (when review required)
125
137
  - [ ] all tasks `[x]` + build OK before PR
126
138
  - [ ] `/opsx:archive` run after merge
127
139
 
@@ -51,9 +51,10 @@ openspec/
51
51
 
52
52
  Для CLI, валідації, іменування changes і типових сценаріїв — читай skill **`openspec-howto`**.
53
53
 
54
- ## Vue skills + Amp
54
+ ## Frontend skills + Amp
55
55
 
56
- При встановленні `vue-cursor-skills`:
57
- - дзеркалюй `.cursor/skills/` `.agents/skills/`
56
+ При встановленні [frontend-agent-skills](https://www.npmjs.com/package/frontend-agent-skills) (`vue-cursor-skills` — старий alias):
57
+ - для Amp: `npx frontend-agent-skills install --agent amp --yes` (напряму в `.agents/skills/`)
58
+ - для Cursor/Claude: `./scripts/sync-local-agent-skills.sh` після install
58
59
  - **не** налаштовуй SpecKit
59
60
  - якщо в проєкті є `openspec/` — дотримуйся OpenSpec workflow
@@ -14,18 +14,69 @@ jobs:
14
14
  - uses: actions/setup-node@v4
15
15
  with:
16
16
  node-version: 20
17
- cache: npm
18
17
 
19
- - run: npm ci
18
+ - name: Detect package manager
19
+ id: pm
20
+ run: |
21
+ if [ -f pnpm-lock.yaml ]; then
22
+ echo "manager=pnpm" >> "$GITHUB_OUTPUT"
23
+ elif [ -f yarn.lock ]; then
24
+ echo "manager=yarn" >> "$GITHUB_OUTPUT"
25
+ else
26
+ echo "manager=npm" >> "$GITHUB_OUTPUT"
27
+ fi
28
+
29
+ - name: Enable corepack (pnpm)
30
+ if: steps.pm.outputs.manager == 'pnpm'
31
+ run: corepack enable
32
+
33
+ - name: Install dependencies (npm)
34
+ if: steps.pm.outputs.manager == 'npm'
35
+ run: npm ci
36
+
37
+ - name: Install dependencies (yarn)
38
+ if: steps.pm.outputs.manager == 'yarn'
39
+ run: yarn install --frozen-lockfile
40
+
41
+ - name: Install dependencies (pnpm)
42
+ if: steps.pm.outputs.manager == 'pnpm'
43
+ run: pnpm install --frozen-lockfile
20
44
 
21
45
  - name: OpenSpec validate
22
46
  run: npx openspec validate --all --strict
23
47
 
24
- - name: Lint
48
+ - name: Lint (npm)
49
+ if: steps.pm.outputs.manager == 'npm'
25
50
  run: npm run lint --if-present
26
51
 
27
- - name: Build
52
+ - name: Lint (yarn)
53
+ if: steps.pm.outputs.manager == 'yarn'
54
+ run: yarn lint
55
+
56
+ - name: Lint (pnpm)
57
+ if: steps.pm.outputs.manager == 'pnpm'
58
+ run: pnpm run lint
59
+
60
+ - name: Build (npm)
61
+ if: steps.pm.outputs.manager == 'npm'
28
62
  run: npm run build --if-present
29
63
 
30
- - name: Test
64
+ - name: Build (yarn)
65
+ if: steps.pm.outputs.manager == 'yarn'
66
+ run: yarn build
67
+
68
+ - name: Build (pnpm)
69
+ if: steps.pm.outputs.manager == 'pnpm'
70
+ run: pnpm run build
71
+
72
+ - name: Test (npm)
73
+ if: steps.pm.outputs.manager == 'npm'
31
74
  run: npm test --if-present
75
+
76
+ - name: Test (yarn)
77
+ if: steps.pm.outputs.manager == 'yarn'
78
+ run: yarn test
79
+
80
+ - name: Test (pnpm)
81
+ if: steps.pm.outputs.manager == 'pnpm'
82
+ run: pnpm test
@@ -5,6 +5,8 @@ project:
5
5
  name: "{{PROJECT_NAME}}"
6
6
  agent_language: "{{LANG}}"
7
7
 
8
+ package_manager: npm
9
+
8
10
  pipeline:
9
11
  require_spec_review: true
10
12
  max_active_changes: 1
@@ -71,7 +71,7 @@ GITIGNORE=".gitignore"
71
71
  CHANGED=0
72
72
 
73
73
  for line in ".cursor" ".cursor/memory.json" ".amp/settings.json" ".claude"; do
74
- if ! grep -qF "$line" "$GITIGNORE" 2>/dev/null; then
74
+ if ! grep -qxF "$line" "$GITIGNORE" 2>/dev/null; then
75
75
  echo "$line" >> "$GITIGNORE"
76
76
  ok "Added '$line' to .gitignore"
77
77
  CHANGED=1