semantu-agents 1.2.0 → 1.2.2

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/README.md CHANGED
@@ -1,53 +1,110 @@
1
1
  # semantu-agents
2
2
 
3
- Reusable Claude Code skills and hooks for Semantu projects.
3
+ Reusable Claude Code and agent skills for Semantu projects.
4
4
 
5
- Public skills are shipped with the npm package and work everywhere. Private skills require git access to the agents repo.
6
-
7
- ## Project setup
5
+ ## Recommended: Global Install
8
6
 
9
7
  ```bash
10
- npx semantu-agents
8
+ npx semantu-agents global
11
9
  ```
12
10
 
13
- Syncs public skills from npm, tries to clone the agents repo for private skills (skips gracefully without access), patches `package.json` and `.gitignore`, and syncs all skills to `.claude/skills/` and `.agents/skills/`.
11
+ Syncs the npm-packaged public skills to:
12
+
13
+ - `~/.claude/skills`
14
+ - `~/.agents/skills`
15
+
16
+ This is the default recommended setup. It keeps application repos clean and makes the shared skills available across projects. Project repos can still define app-specific skills separately.
17
+
18
+ ## Updating Global Skills
19
+
20
+ For normal users, rerun:
21
+
22
+ ```bash
23
+ npx semantu-agents global
24
+ ```
14
25
 
15
- Add to `package.json` so it runs on setup:
26
+ For contributors with an editable checkout at `~/.agents-src`, run this from anywhere:
16
27
 
17
- ```json
18
- {
19
- "scripts": {
20
- "setup": "npx semantu-agents"
21
- }
22
- }
28
+ ```bash
29
+ npx semantu-agents update
23
30
  ```
24
31
 
25
- ## Global setup
32
+ This updates `~/.agents-src/main`, syncs it to `~/.claude/skills` and `~/.agents/skills`, then restores your previous branch when possible. If `~/.agents-src` has uncommitted changes, commit or stash them first.
33
+
34
+ ## Contributing Skill Changes
35
+
36
+ Install an editable source checkout:
26
37
 
27
38
  ```bash
28
- npx semantu-agents --global
39
+ npx semantu-agents dev
29
40
  ```
30
41
 
31
- Syncs skills to `~/.claude/skills/` and `~/.agents/skills/`. This makes skills available to Claude Code and Codex across all projects without per-repo setup.
42
+ This clones or pulls `github.com:Semantu/agents` into `~/.agents-src`, installs a post-merge hook, and syncs that checkout globally.
32
43
 
33
- ## Editing skills
44
+ Dev mode requires repo access. If cloning fails, ask for access to the Semantu agents repo.
34
45
 
35
- Edit directly in `packages/semantu-agents/skills/`, then commit and push:
46
+ Make changes in the source checkout only:
36
47
 
37
48
  ```bash
38
- cd packages/semantu-agents
49
+ cd ~/.agents-src
39
50
  git checkout -b my-change
40
- # edit skills...
41
- git add -A && git commit -m "improve workflow skill"
51
+ # edit skills/public/... or skills/private/...
52
+ npm run sync
53
+ git add .
54
+ git commit -m "improve workflow skill"
42
55
  git push -u origin my-change
56
+ gh pr create
57
+ ```
58
+
59
+ Do not edit these generated folders directly:
60
+
61
+ - `~/.claude/skills`
62
+ - `~/.agents/skills`
63
+
64
+ They are overwritten by `semantu-agents global`, `semantu-agents sync`, and `semantu-agents update`.
65
+
66
+ The dev post-merge hook runs `node cli.mjs sync` after pulls, so merged changes are synced globally automatically.
67
+
68
+ ## Project Setup
69
+
70
+ Project-local setup is still available for repos that intentionally want checked-out helper files:
71
+
72
+ ```bash
73
+ npx semantu-agents
43
74
  ```
44
75
 
45
- To re-sync after editing:
76
+ Most projects should prefer the global install instead.
77
+
78
+ ## Docs index
79
+
80
+ Print a markdown or JSON index of docs that use YAML frontmatter.
46
81
 
47
82
  ```bash
48
- npm run sync:agents
83
+ npx semantu-agents docs
84
+ npx semantu-agents docs ideas
85
+ npx semantu-agents docs architecture
86
+ npx semantu-agents docs --all
87
+ npx semantu-agents docs --format markdown
88
+ npx semantu-agents docs --all --format json
49
89
  ```
50
90
 
91
+ Supported scopes:
92
+
93
+ - `root` (default) -> `docs/*.md`
94
+ - `architecture` -> `docs/architecture/*.md`
95
+ - `ideas` -> `docs/ideas/*.md`
96
+ - `plans` -> `docs/plans/*.md`
97
+ - `reports` -> `docs/reports/*.md`
98
+
99
+ Notes:
100
+
101
+ - default output is text
102
+ - supported formats: `text`, `markdown`, `json`
103
+ - JSON uses short keys: `f` = file, `s` = summary, `d` = folder
104
+ - `--all` adds a folder column in markdown, or `d` in JSON
105
+ - `--fix` adds an empty `summary` field when frontmatter is missing it
106
+ - missing summaries stay blank; the command does not warn
107
+
51
108
  ## Skill layout
52
109
 
53
110
  ```
package/cli.mjs CHANGED
@@ -1,29 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- /**
4
- * semantu-agents — CLI that syncs public skills from npm and private skills from git.
5
- *
6
- * Usage:
7
- * npx semantu-agents — sync public skills + try git clone for private skills
8
- * npx semantu-agents --global — sync to ~/.claude/ and ~/.agents/ for all projects
9
- *
10
- * Public skills are always available (shipped with the npm package).
11
- * Private skills require git access to github.com:Semantu/agents.
12
- */
13
-
14
- import {cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync} from 'node:fs';
3
+ import {execSync} from 'node:child_process';
4
+ import {cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync} from 'node:fs';
15
5
  import {homedir} from 'node:os';
16
6
  import path from 'node:path';
17
- import {execSync} from 'node:child_process';
18
7
  import {fileURLToPath} from 'node:url';
19
8
 
20
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const args = process.argv.slice(2);
11
+ const command = args[0];
12
+
13
+ const projectRoot = process.cwd();
21
14
  const skillsRepo = 'git@github.com:Semantu/agents.git';
15
+ const DOC_FOLDERS = {
16
+ root: 'docs',
17
+ architecture: path.join('docs', 'architecture'),
18
+ ideas: path.join('docs', 'ideas'),
19
+ plans: path.join('docs', 'plans'),
20
+ reports: path.join('docs', 'reports'),
21
+ };
22
22
 
23
23
  function run(cmd, opts) {
24
24
  return execSync(cmd, {stdio: 'inherit', ...opts});
25
25
  }
26
26
 
27
+ function output(cmd, opts) {
28
+ return execSync(cmd, {encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], ...opts}).trim();
29
+ }
30
+
27
31
  function cloneOrPull(dir) {
28
32
  if (existsSync(path.join(dir, '.git'))) {
29
33
  console.log('Updating agents repo...');
@@ -34,11 +38,23 @@ function cloneOrPull(dir) {
34
38
  }
35
39
  }
36
40
 
37
- /**
38
- * Sync skills from a source directory into target directories.
39
- * Copies each skill folder individually so public and private merge into
40
- * the same flat target directory.
41
- */
41
+ function cloneIfMissing(dir) {
42
+ if (existsSync(path.join(dir, '.git'))) {
43
+ console.log('Using existing editable agents repo at ~/.agents-src');
44
+ } else {
45
+ console.log('Cloning agents repo...');
46
+ run(`git clone ${skillsRepo} ${dir}`);
47
+ }
48
+ }
49
+
50
+ function globalTargets() {
51
+ const home = homedir();
52
+ return [
53
+ path.join(home, '.claude', 'skills'),
54
+ path.join(home, '.agents', 'skills'),
55
+ ];
56
+ }
57
+
42
58
  function syncSkillsInto(skillsSource, targets) {
43
59
  if (!existsSync(skillsSource)) return;
44
60
 
@@ -48,33 +64,81 @@ function syncSkillsInto(skillsSource, targets) {
48
64
  }
49
65
  }
50
66
 
51
- function setupGlobal() {
52
- const home = homedir();
53
- const targets = [
54
- path.join(home, '.claude', 'skills'),
55
- path.join(home, '.agents', 'skills'),
56
- ];
67
+ function syncFromSource(sourceDir, label = 'source checkout', options = {}) {
68
+ const includePrivate = options.includePrivate ?? true;
69
+ const targets = globalTargets();
70
+ const publicSkills = path.join(sourceDir, 'skills', 'public');
71
+ const privateSkills = path.join(sourceDir, 'skills', 'private');
57
72
 
58
- // 1. Always sync public skills from the npm package
59
- const publicSkills = path.join(__dirname, 'skills', 'public');
60
73
  for (const dest of targets) {
61
74
  rmSync(dest, {recursive: true, force: true});
62
75
  }
63
- syncSkillsInto(publicSkills, targets);
64
- console.log('Synced public skills from npm package');
65
76
 
66
- // 2. Try to clone/pull for private skills
67
- const srcDir = path.join(home, '.agents-src');
68
- try {
69
- cloneOrPull(srcDir);
70
- const privateSkills = path.join(srcDir, 'skills', 'private');
77
+ syncSkillsInto(publicSkills, targets);
78
+ if (includePrivate) {
71
79
  syncSkillsInto(privateSkills, targets);
72
- console.log('Synced private skills from git repo');
73
- } catch {
74
- console.log('Skipped private skills — no git access to agents repo.');
75
80
  }
76
81
 
77
- console.log('\nDone. Skills synced globally to ~/.claude/skills/ and ~/.agents/skills/');
82
+ console.log(`Synced skills from ${label} -> ~/.claude/skills/ and ~/.agents/skills/`);
83
+ }
84
+
85
+ function setupGlobal() {
86
+ syncFromSource(__dirname, 'npm package', {includePrivate: false});
87
+ console.log('\nDone. Public skills synced globally. Run `npx semantu-agents dev` to install an editable source checkout.');
88
+ }
89
+
90
+ function installPostMergeHook(repoDir) {
91
+ const hooksDir = path.join(repoDir, '.git', 'hooks');
92
+ const hookPath = path.join(hooksDir, 'post-merge');
93
+ const hook = `#!/bin/sh
94
+ cd "$(git rev-parse --show-toplevel)" && node cli.mjs sync
95
+ `;
96
+
97
+ mkdirSync(hooksDir, {recursive: true});
98
+ writeFileSync(hookPath, hook, {mode: 0o755});
99
+ console.log('Installed post-merge hook to sync global skills after pulls');
100
+ }
101
+
102
+ function setupDev() {
103
+ const srcDir = path.join(homedir(), '.agents-src');
104
+
105
+ cloneIfMissing(srcDir);
106
+ installPostMergeHook(srcDir);
107
+ syncFromSource(srcDir, '~/.agents-src');
108
+
109
+ console.log('\nDone. Edit skills in ~/.agents-src, run `node cli.mjs sync`, then commit and open a PR.');
110
+ }
111
+
112
+ function syncGlobalFromCurrentCheckout() {
113
+ syncFromSource(__dirname, 'current checkout');
114
+ }
115
+
116
+ function updateDevCheckout() {
117
+ const srcDir = path.join(homedir(), '.agents-src');
118
+
119
+ if (!existsSync(path.join(srcDir, '.git'))) {
120
+ console.log('No editable checkout found at ~/.agents-src.');
121
+ console.log('Run `npx semantu-agents dev` if you have access to github.com:Semantu/agents.');
122
+ process.exit(1);
123
+ }
124
+
125
+ const currentBranch = output('git branch --show-current', {cwd: srcDir});
126
+ const dirty = output('git status --porcelain', {cwd: srcDir});
127
+
128
+ if (dirty) {
129
+ console.log('Cannot update ~/.agents-src because it has uncommitted changes.');
130
+ console.log('Commit, stash, or discard them, then rerun `npx semantu-agents update`.');
131
+ process.exit(1);
132
+ }
133
+
134
+ run('git fetch origin main', {cwd: srcDir});
135
+ run('git switch main', {cwd: srcDir});
136
+ run('git pull --ff-only origin main', {cwd: srcDir});
137
+ syncFromSource(srcDir, '~/.agents-src');
138
+
139
+ if (currentBranch && currentBranch !== 'main') {
140
+ run(`git switch ${currentBranch}`, {cwd: srcDir});
141
+ }
78
142
  }
79
143
 
80
144
  function setupProject() {
@@ -105,7 +169,6 @@ function setupProject() {
105
169
  console.log('Skipped private skills — no git access to agents repo.');
106
170
  }
107
171
 
108
- // 3. Patch package.json scripts
109
172
  const pkgPath = path.join(projectRoot, 'package.json');
110
173
  if (existsSync(pkgPath)) {
111
174
  const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
@@ -128,7 +191,6 @@ function setupProject() {
128
191
  }
129
192
  }
130
193
 
131
- // 4. Patch .gitignore
132
194
  const ignorePath = path.join(projectRoot, '.gitignore');
133
195
  const ignoreEntries = ['packages/', '.claude/', '.agents/'];
134
196
  let ignoreContent = existsSync(ignorePath) ? readFileSync(ignorePath, 'utf8') : '';
@@ -146,7 +208,6 @@ function setupProject() {
146
208
  console.log('Updated .gitignore');
147
209
  }
148
210
 
149
- // 5. Ensure docs directories exist
150
211
  for (const dir of ['docs/ideas', 'docs/plans', 'docs/reports']) {
151
212
  const fullPath = path.join(projectRoot, dir);
152
213
  if (!existsSync(fullPath)) {
@@ -156,12 +217,193 @@ function setupProject() {
156
217
  }
157
218
  }
158
219
 
159
- // --- Main ---
220
+ function parseDocsArgs(inputArgs) {
221
+ const options = {
222
+ format: 'text',
223
+ fix: false,
224
+ all: false,
225
+ scope: 'root',
226
+ dir: projectRoot,
227
+ };
228
+
229
+ for (let i = 0; i < inputArgs.length; i += 1) {
230
+ const arg = inputArgs[i];
231
+
232
+ if (arg === '--all') {
233
+ options.all = true;
234
+ continue;
235
+ }
236
+ if (arg === '--fix') {
237
+ options.fix = true;
238
+ continue;
239
+ }
240
+ if (arg === '--format') {
241
+ options.format = inputArgs[i + 1] || 'markdown';
242
+ i += 1;
243
+ continue;
244
+ }
245
+ if (arg === '--dir') {
246
+ options.dir = path.resolve(projectRoot, inputArgs[i + 1] || '.');
247
+ i += 1;
248
+ continue;
249
+ }
250
+ if (arg === 'json' || arg === 'markdown' || arg === 'text') {
251
+ options.format = arg;
252
+ continue;
253
+ }
254
+ if (arg === 'all') {
255
+ options.all = true;
256
+ continue;
257
+ }
258
+ if (Object.hasOwn(DOC_FOLDERS, arg)) {
259
+ options.scope = arg;
260
+ continue;
261
+ }
262
+ }
263
+
264
+ return options;
265
+ }
266
+
267
+ function listMarkdownFiles(dirPath) {
268
+ if (!existsSync(dirPath)) {
269
+ return [];
270
+ }
271
+
272
+ return readdirSync(dirPath)
273
+ .filter(name => name.endsWith('.md'))
274
+ .filter(name => statSync(path.join(dirPath, name)).isFile())
275
+ .sort()
276
+ .map(name => path.join(dirPath, name));
277
+ }
278
+
279
+ async function ensureSummary(filePath) {
280
+ const {default: matter} = await import('gray-matter');
281
+ const source = readFileSync(filePath, 'utf8');
282
+ const parsed = matter(source);
283
+
284
+ if (typeof parsed.data.summary === 'string') {
285
+ return;
286
+ }
287
+
288
+ writeFileSync(
289
+ filePath,
290
+ matter.stringify(parsed.content, {
291
+ summary: '',
292
+ ...parsed.data,
293
+ }),
294
+ );
295
+ }
296
+
297
+ function escapeCell(value) {
298
+ return String(value || '')
299
+ .replace(/\n+/g, ' ')
300
+ .replace(/\|/g, '\\|')
301
+ .trim();
302
+ }
303
+
304
+ async function loadEntries(scope, options) {
305
+ const {default: matter} = await import('gray-matter');
306
+ const folderPath = path.join(options.dir, DOC_FOLDERS[scope]);
307
+ const files = listMarkdownFiles(folderPath);
308
+
309
+ if (options.fix) {
310
+ for (const file of files) {
311
+ await ensureSummary(file);
312
+ }
313
+ }
314
+
315
+ return files.map(filePath => {
316
+ const parsed = matter(readFileSync(filePath, 'utf8'));
317
+ return {
318
+ folder: scope,
319
+ file: path.basename(filePath),
320
+ summary: typeof parsed.data.summary === 'string' ? parsed.data.summary : '',
321
+ };
322
+ });
323
+ }
324
+
325
+ function renderMarkdown(entries, includeFolder) {
326
+ const header = includeFolder
327
+ ? ['| folder | file | summary |', '|--------|------|---------|']
328
+ : ['| file | summary |', '|------|---------|'];
329
+
330
+ const rows = entries.map(entry =>
331
+ includeFolder
332
+ ? `| ${escapeCell(entry.folder)} | ${escapeCell(entry.file)} | ${escapeCell(entry.summary)} |`
333
+ : `| ${escapeCell(entry.file)} | ${escapeCell(entry.summary)} |`,
334
+ );
335
+
336
+ return [...header, ...rows].join('\n');
337
+ }
338
+
339
+ function renderText(entries, includeFolder) {
340
+ if (includeFolder) {
341
+ const lines = [];
342
+ let currentFolder = null;
343
+
344
+ for (const entry of entries) {
345
+ if (entry.folder !== currentFolder) {
346
+ if (lines.length > 0) {
347
+ lines.push('');
348
+ }
349
+ currentFolder = entry.folder;
350
+ lines.push(entry.folder);
351
+ }
352
+
353
+ lines.push(` ${entry.file}`);
354
+ if (entry.summary) {
355
+ lines.push(` ${entry.summary}`);
356
+ }
357
+ }
358
+
359
+ return lines.join('\n');
360
+ }
361
+
362
+ return entries
363
+ .flatMap(entry =>
364
+ entry.summary ? [entry.file, ` ${entry.summary}`] : [entry.file],
365
+ )
366
+ .join('\n');
367
+ }
368
+
369
+ function renderJson(entries, includeFolder) {
370
+ const rows = entries.map(entry =>
371
+ includeFolder
372
+ ? {d: entry.folder, f: entry.file, s: entry.summary}
373
+ : {f: entry.file, s: entry.summary},
374
+ );
375
+
376
+ return JSON.stringify(rows, null, 2);
377
+ }
378
+
379
+ async function docs(inputArgs) {
380
+ const options = parseDocsArgs(inputArgs);
381
+ const scopes = options.all ? Object.keys(DOC_FOLDERS) : [options.scope];
382
+ const entries = (await Promise.all(scopes.map(scope => loadEntries(scope, options)))).flat();
383
+ const includeFolder = options.all;
384
+
385
+ const output =
386
+ options.format === 'json'
387
+ ? renderJson(entries, includeFolder)
388
+ : options.format === 'markdown'
389
+ ? renderMarkdown(entries, includeFolder)
390
+ : renderText(entries, includeFolder);
391
+
392
+ process.stdout.write(`${output}\n`);
393
+ }
160
394
 
161
395
  const isGlobal = process.argv.includes('--global') || process.argv.includes('-g');
162
396
 
163
- if (isGlobal) {
397
+ if (command === 'docs') {
398
+ await docs(args.slice(1));
399
+ } else if (command === 'global' || isGlobal) {
164
400
  setupGlobal();
401
+ } else if (command === 'dev') {
402
+ setupDev();
403
+ } else if (command === 'sync') {
404
+ syncGlobalFromCurrentCheckout();
405
+ } else if (command === 'update') {
406
+ updateDevCheckout();
165
407
  } else {
166
408
  setupProject();
167
409
  }
package/package.json CHANGED
@@ -1,17 +1,15 @@
1
1
  {
2
2
  "name": "semantu-agents",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Reusable Claude Code skills and hooks for Semantu projects",
5
5
  "type": "module",
6
- "bin": {
7
- "semantu-agents": "cli.mjs"
8
- },
6
+ "bin": "cli.mjs",
9
7
  "files": [
10
8
  "cli.mjs",
11
9
  "skills/public"
12
10
  ],
13
11
  "scripts": {
14
- "sync": "node sync.mjs"
12
+ "sync": "node cli.mjs sync"
15
13
  },
16
14
  "publishConfig": {
17
15
  "access": "public"
@@ -19,5 +17,8 @@
19
17
  "devDependencies": {
20
18
  "@changesets/changelog-github": "^0.5.2",
21
19
  "@changesets/cli": "^2.29.8"
20
+ },
21
+ "dependencies": {
22
+ "gray-matter": "^4.0.3"
22
23
  }
23
24
  }
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: explore
3
+ description: Deeply evaluate a topic with context, 3 viable approaches, tradeoffs, and a recommendation without forcing a full ideation-mode cycle.
4
+ ---
5
+
6
+ # Instructions
7
+
8
+ ## Objective
9
+
10
+ Provide a reusable deep-dive format for `explore <topic>` in any mode, including decomposition of broad topics into concrete decisions.
11
+
12
+ ## Entry gate
13
+
14
+ Run this skill when the user explicitly says `explore <topic>` (or clearly asks to explore a topic in this format).
15
+
16
+ ## Steps
17
+
18
+ 1. Confirm scope only if the topic is ambiguous; otherwise proceed directly.
19
+ 2. Decompose the topic into decision candidates and unknowns.
20
+ 3. For each decision, classify as `must decide now` or `can defer`.
21
+ 4. For each `must decide now` decision, give concise context and assumptions, then provide exactly 3 viable approaches (A-C).
22
+ 5. For each approach, list pros, cons, and risks.
23
+ 6. Recommend one approach (A/B/C) with a one-line rationale.
24
+ 7. If there are multiple decisions, present them in batches of 3 by default (use fewer only when fewer remain or when the user asks for a different batch size). Start with `Decision x-y of N`, and end with `Recap: 1A 2C 3B`; ask for agreement or edits.
25
+ 8. Iterate until consent; no feedback on a decision counts as acceptance after an explicit agreement prompt.
26
+ 9. Recurse only for nested decisions classified as `must decide now`; defer the rest. Default max depth is 2 unless the user asks for deeper drilldown.
27
+ 10. After consent, ask whether to continue the current mode or switch modes.
28
+
29
+ ## Guardrails
30
+
31
+ - Do not force a mode switch by default; this skill can run inside any active mode.
32
+ - Do not create ideation/plan artifacts unless the active mode requires them or the user asks.
33
+ - Keep outputs structured and concise; avoid repeating unchanged context.
34
+ - Do not recurse indefinitely; respect the depth cap and defer non-blocking items.
@@ -7,99 +7,35 @@ description: Explore and compare candidate implementation routes before committi
7
7
 
8
8
  ## Objective
9
9
 
10
- Interactively explore implementation routes and architecture choices with the user through conversation, recording progress in an ideation document.
10
+ Surface unknowns, assumptions, and architecture choices before committing to a plan.
11
11
 
12
12
  ## Entry gate
13
13
 
14
- Run this mode only after the user explicitly confirms ideation mode for the current task.
14
+ Run this mode when the user explicitly chooses ideation, or when workflow routes brainstorming into ideation.
15
15
 
16
16
  ## Steps
17
17
 
18
- ### 1. Understand context
19
-
20
- Spawn one or more subagents to explore the codebase concurrently. Give each subagent a focused research question — e.g. "find all files related to authentication and summarize the current flow", "read the test suite for module X and report what it covers". Do not read large files or trace dependencies directly in the main agent; let subagents do the heavy lifting and report back.
21
-
22
- Synthesize subagent findings into the Context section of the ideation doc. Summarise the problem space and goals back to the user in chat to confirm shared understanding.
23
-
24
- ### 2. Create the ideation document
25
-
26
- Create/update `docs/ideas/<nnn>-<topic>.md` as a progress tracker (NOT the primary output — chat is).
27
-
28
- - For new docs, `<nnn>` MUST be the next available 3-digit prefix in `docs/ideas`.
29
- - Use this structure:
30
-
31
- ```markdown
32
- # <Topic> — Ideation
33
-
34
- ## Context
35
- <problem statement, relevant code references>
36
-
37
- ## Goals
38
- <what we're trying to achieve>
39
-
40
- ## Open Questions
41
- - [ ] Question 1
42
- - [ ] Question 2
43
-
44
- ## Decisions
45
- | # | Decision | Chosen | Rationale |
46
- |---|----------|--------|-----------|
47
-
48
- ## Notes
49
- <scratchpad for explored approaches, discarded ideas>
50
- ```
51
-
52
- ### 3. Identify everything that needs deciding
53
-
54
- Before proposing solutions, discover and list all decision points:
55
- - Open questions about scope and requirements
56
- - Architecture decisions needed
57
- - Technical unknowns requiring investigation
58
- - Constraints and dependencies
59
-
60
- Present this list to the user and ask if anything is missing.
61
-
62
- ### 4. Walk through decisions one at a time
63
-
64
- For each decision point, present in chat:
65
- - **Full context** — relevant code snippets, existing patterns, constraints
66
- - **2–3 approaches** with concrete code examples where helpful
67
- - **Pros/cons** for each approach
68
- - **Recommended path** with reasoning
69
-
70
- **Progress indicator:** Always tell the user where they are — e.g. "Decision 2 of 5" or "Gap 3 of 4" — so they know how many remain before the next mode.
71
-
72
- When assessing the viability of a specific approach requires reading code or checking feasibility, spawn a research subagent for that investigation and incorporate its findings into the discussion. Do not spawn subagents for the creative work of generating approaches — that stays with the main agent.
73
-
74
- Wait for the user's input before moving to the next decision. Do not batch multiple decisions into one message.
75
-
76
- ### 5. Record as you go
77
-
78
- After each decision is made:
79
- - Check off the resolved question in Open Questions
80
- - Add a row to the Decisions table
81
- - Update Notes with any useful context that came up
82
-
83
- ### 6. Check for completeness
84
-
85
- After working through the list, review what remains:
86
- - Are all open questions resolved?
87
- - Are there new questions that surfaced during discussion?
88
- - Does the user want to explore anything further?
89
-
90
- Keep iterating until everything is decided.
18
+ 1. Read relevant code, tests, and docs first.
19
+ 2. Create/update `docs/ideas/<nnn>-<topic>.md`.
20
+ - For new ideation docs, `<nnn>` MUST be the next available 3-digit prefix in `docs/ideas`.
21
+ - Every new ideation doc MUST start with YAML frontmatter containing at least a summary key.
22
+ 3. Discover impacted repo/package test surfaces:
23
+ - Locate changed package roots (root repo and/or `packages/<name>` roots as applicable).
24
+ - For each impacted package, identify quick test commands (target total runtime 1-2 minutes), full/slow test commands, and where each was found (`package.json` scripts first, README fallback).
25
+ - Record unknowns/gaps when no reliable quick regression command exists.
26
+ 4. Build a decision map: list major decisions, unknowns, and research gaps.
27
+ 5. Classify each item as `must decide now` (blocks planning) or `can defer`.
28
+ 6. Use the `explore` skill for each `must decide now` decision/topic.
29
+ 7. Record accepted choices, deferred unknowns, and discovered test surfaces in the ideation doc.
30
+ 8. Continue until blocking decisions reach consent; then ask whether to switch to `plan` mode.
91
31
 
92
32
  ## Guardrails
93
33
 
94
- - **Chat is the primary medium.** The ideation doc tracks progress — it is not the deliverable.
95
34
  - Do not write implementation code in this mode.
96
- - Do not batch multiple unrelated decisions into a single message.
97
- - Do not suggest plan mode until all open questions are resolved and the user confirms nothing is left.
35
+ - Do not convert ideation into a plan unless the user explicitly requests it.
98
36
 
99
37
  ## Exit criteria
100
38
 
101
- - All open questions in the ideation doc are checked off.
102
- - All architecture decisions have a chosen approach recorded.
103
- - User has explicitly confirmed next step. Offer:
104
- - **Plan mode** (default) — continue manually through the workflow.
105
- - **Automatic mode** — switch to automatic mode and run plan → tasks → implementation → review autonomously.
39
+ - Blocking decisions and deferred unknowns are documented.
40
+ - User feedback has narrowed choices.
41
+ - User has explicitly confirmed whether to switch to plan mode or stay in ideation mode.
@@ -14,12 +14,14 @@ Run only after explicit user confirmation to enter implementation mode, with an
14
14
  1. Confirm the approved plan exists on disk at `docs/plans/<nnn>-<topic>.md`. Tool-native plan mode alone is not sufficient.
15
15
  2. If this plan stems from an ideation doc, remove the originating ideation doc in `docs/ideas` when implementation begins.
16
16
  3. Implement one planned phase at a time.
17
- 4. Run the phase validation criteria and record results.
17
+ 4. Run the phase validation criteria and record results, including the quick regression gate for impacted packages (target total runtime 1-2 minutes).
18
18
  5. After a phase is completed, update `docs/plans/<nnn>-<topic>.md` to reflect completed work and mark phase status. This update is mandatory before moving to the next phase.
19
19
  6. Create one commit per phase, including code changes and the phase-completion plan update in the same commit.
20
20
  7. Continue to next phase without pausing only if there are no deviations and no major problems.
21
21
  8. If any deviation/blocker/major risk appears, pause and report.
22
22
 
23
+ Full/slow test suites may be deferred until review by default. Run deferred suites earlier only if the user requests it.
24
+
23
25
  ## Parallel execution
24
26
 
25
27
  When the plan marks phases as parallelizable, use the Task tool (or any available sub-agent spawning tool) to run them concurrently:
@@ -47,6 +49,7 @@ When the plan marks phases as parallelizable, use the Task tool (or any availabl
47
49
  - If the originating ideation doc is ambiguous, pause and ask the user which ideation file to remove.
48
50
  - Do not skip plan updates between completed phases.
49
51
  - Do not switch to review/wrapup implicitly; ask the user to explicitly confirm the next mode.
52
+ - Do not mark a phase complete if its quick regression gate fails.
50
53
 
51
54
  ## Exit criteria
52
55
 
@@ -13,6 +13,7 @@ Run only when the user explicitly confirms plan mode (for example: converting id
13
13
 
14
14
  1. Create/update `docs/plans/<nnn>-<topic>.md`. This on-disk plan file is mandatory.
15
15
  - When creating a new plan doc (including ideation -> plan conversion), `<nnn>` MUST be the next available 3-digit prefix in `docs/plans`.
16
+ - Every new plan doc MUST start with YAML frontmatter containing at least a summary key.
16
17
  2. Focus on chosen route(s), not all explored options.
17
18
  3. **Carry forward all decided features and details from the ideation doc.** Every feature, API surface, design detail, and example that was explored and not explicitly rejected must appear in the plan. No idea can be silently dropped. If unsure whether something was tentatively discussed or firmly decided, ask the user for clarification rather than omitting it.
18
19
  4. Include:
@@ -22,8 +23,14 @@ Run only when the user explicitly confirms plan mode (for example: converting id
22
23
  - Potential pitfalls
23
24
  - Remaining unclear areas/decisions
24
25
  - **Inter-component contracts**: When the architecture has separable parts (layers, modules, packages), make the contracts between them explicit — type definitions, function signatures, shared data structures. These contracts enable parallel implementation in tasks mode.
26
+ - **Test strategy**:
27
+ - impacted repo/package list
28
+ - quick regression gate commands (target total runtime 1-2 minutes) to run after each phase
29
+ - full/slow test commands deferred to review
30
+ - command source notes (`package.json` scripts and/or README)
31
+ - explicit skip/defer rationale for slow suites
25
32
  5. Mention tradeoffs only to explain why chosen paths were selected.
26
- 5. Continuously refine the plan with user feedback until it is explicitly approved for implementation.
33
+ 6. Continuously refine the plan with user feedback until it is explicitly approved for implementation.
27
34
 
28
35
  ## Guardrails
29
36
 
@@ -16,6 +16,7 @@ Run only when the user explicitly confirms review mode.
16
16
  3. Identify what is still missing to make this work more complete.
17
17
  4. Identify gaps or risks in the current implementation.
18
18
  5. Identify likely future work required for fuller completeness.
19
+ 6. Re-run deferred full/slow test suites for all impacted repos/packages from the plan's test strategy, and report pass/fail with any skipped checks and reasons.
19
20
 
20
21
  ## Parallel review via subagents
21
22
 
@@ -102,12 +103,14 @@ The ideation within this section follows the same rules as the ideation skill:
102
103
  - Only convert review findings into iteration content after the user confirms which gaps to address.
103
104
  - For newly uncovered work, always go through ideation first — never skip straight to tasks or implementation.
104
105
  - If the user's response involves clarifying approach or scope, treat this as still in the clarification loop — ask follow-ups for any remaining ambiguity.
106
+ - Do not claim review completion without test evidence for impacted packages (or explicit user-approved skips).
105
107
 
106
108
  ## Exit criteria
107
109
 
108
110
  - Gaps are triaged with explicit user decisions (now vs defer).
109
111
  - If iterating: ideation for all selected gaps is recorded in the plan doc, and user has confirmed next step.
110
112
  - If deferring: ideation docs were created for deferred gaps.
113
+ - Deferred full/slow test suites for impacted packages were executed and reported, or explicitly skipped with user approval.
111
114
  - User has explicitly confirmed whether to:
112
115
  - **Iterate** — proceed to plan the ideated gaps (manually via plan mode, or via automatic mode for plan → tasks → implementation → review)
113
116
  - **Wrapup** — no more work needed, move to wrapup mode
@@ -15,8 +15,12 @@ Run only when the user explicitly confirms tasks mode.
15
15
  2. Define implementation phases.
16
16
  3. Define concrete tasks under each phase.
17
17
  4. Add explicit validation criteria per phase (for example: unit tests, integration tests, build/typecheck commands, targeted runtime checks).
18
- 5. Write detailed test specifications for every phase (see **Test specification** below).
19
- 6. Ensure phases are commit-friendly (one commit per phase).
18
+ 5. For every phase, define:
19
+ - phase-specific tests to add/update when behavior/API changes,
20
+ - a quick regression gate using discovered package test commands (target total runtime 1-2 minutes),
21
+ - full/slow suites deferred to review.
22
+ 6. Write detailed test specifications for every phase (see **Test specification** below).
23
+ 7. Ensure phases are commit-friendly (one commit per phase).
20
24
 
21
25
  ## Parallel execution
22
26
 
@@ -33,6 +37,10 @@ Phases should be designed for maximum parallelism — different agents may imple
33
37
 
34
38
  Every phase must include a **Validation** section that describes the checks an implementing agent must perform and pass before considering the phase complete. Validation is not limited to coded tests — it includes any check that truly proves the work is correct.
35
39
 
40
+ Validation must separate:
41
+ - **Quick phase gate**: checks that should finish in 1-2 minutes total and must pass after each phase.
42
+ - **Full review gate**: slow suites deferred to review unless the user requests earlier execution.
43
+
36
44
  **Types of validation checks** (use whichever are appropriate for the phase):
37
45
  - **Unit/integration tests**: Coded test files with named test cases and concrete assertions.
38
46
  - **Compilation/type-check**: e.g. `npm run compile` passes with no errors.
@@ -9,6 +9,12 @@ description: Enforce the explicit mode cadence (ideation -> plan -> tasks -> imp
9
9
 
10
10
  - Default for any task that touches code or modifies planning/docs.
11
11
 
12
+ ## Shortcut triggers
13
+
14
+ - If the user says `explore <topic>`, run the `explore` skill immediately, even when already inside another mode.
15
+ - `explore` is a deep-dive formatting shortcut, not a mode switch by itself.
16
+ - After finishing an `explore` pass, ask whether to continue the current mode or switch modes.
17
+
12
18
  ## Mode selection at task start
13
19
 
14
20
  - If the user has already explicitly chosen a mode (or explicitly called a mode skill), enter that mode directly.
@@ -51,6 +57,16 @@ These transition gates apply to standard modes. `automatic` mode is an explicit
51
57
  - `review`: emit findings in chat first; after user decisions, update plan with now-work tasks and/or create ideation docs for deferred future work
52
58
  - `wrapup`: convert plan into a final report doc in `docs/reports`, then remove the plan doc after report approval
53
59
 
60
+ ## Frontmatter requirements for docs
61
+
62
+ - Any new doc created under `docs/ideas`, `docs/plans`, `docs/reports`, or `docs/architecture` MUST start with YAML frontmatter.
63
+ - Minimum required frontmatter for new docs:
64
+ ```yaml
65
+ ---
66
+ summary: One or two lines describing the document.
67
+ ---
68
+ ```
69
+
54
70
  ## Global constraints
55
71
 
56
72
  - Tool-native plan modes do NOT replace the on-disk plan file requirement.
@@ -24,6 +24,13 @@ Also treat any user request to prepare/open/update a PR, or draft PR title/body/
24
24
  5. Update `docs/plans/<nnn>-<topic>.md` by appending a `## REVIEW` section at the end with wrapup outcomes and PR-readiness status.
25
25
  6. Convert `docs/plans/<nnn>-<topic>.md` into a report doc in `docs/reports/<nnn>-<topic>.md`.
26
26
  - For this conversion, the report `<nnn>` MUST be the next available 3-digit prefix in `docs/reports` (do not reuse the plan prefix when it conflicts).
27
+ - The report MUST start with YAML frontmatter containing a summary key.
28
+ ```yaml
29
+ ---
30
+ summary: One or two lines describing the final implemented outcome.
31
+ ---
32
+ ```
33
+ - When converting from a plan, rewrite the `summary` so it reflects the completed result and report scope, not the earlier proposed plan.
27
34
  - Update any references to the report path after conversion.
28
35
  7. **Report quality** — see the dedicated section below. The report is a condensed but comprehensive record of everything that was done. It is NOT a brief summary.
29
36
  8. **Remove the plan doc** `docs/plans/<nnn>-<topic>.md` after the report is written. Do not wait until after the PR — the plan must be gone before the final commit.