@hegemonart/get-design-done 1.59.2 → 1.59.4
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +56 -0
- package/SKILL.md +2 -0
- package/agents/design-advisor.md +1 -1
- package/agents/design-context-checker-gate.md +0 -1
- package/agents/design-context-checker.md +0 -1
- package/agents/design-context-reviewer-gate.md +0 -1
- package/agents/design-context-reviewer.md +0 -1
- package/agents/design-integration-checker-gate.md +0 -1
- package/agents/design-integration-checker.md +0 -1
- package/agents/design-plan-checker.md +0 -1
- package/agents/design-verifier-gate.md +0 -1
- package/agents/design-verifier.md +0 -1
- package/agents/prototype-gate.md +0 -1
- package/agents/quality-gate-runner.md +0 -1
- package/figma-plugin/README.md +61 -0
- package/figma-plugin/code.ts +36 -0
- package/figma-plugin/manifest.json +12 -0
- package/figma-plugin/package-lock.json +35 -0
- package/figma-plugin/package.json +12 -0
- package/figma-plugin/src/export-variables.ts +144 -0
- package/figma-plugin/src/payload-schema.ts +250 -0
- package/figma-plugin/tsconfig.json +16 -0
- package/figma-plugin/ui.html +44 -0
- package/hooks/gdd-intel-trigger.js +3 -3
- package/package.json +6 -1
- package/reference/DEPRECATIONS.md +3 -3
- package/reference/live-mode-integration.md +1 -1
- package/reference/registry.json +1 -1
- package/reference/skill-metadata.md +4 -4
- package/reference/skill-placeholders.md +2 -2
- package/scripts/build-skills.cjs +146 -0
- package/scripts/generate-skill-frontmatter.cjs +243 -0
- package/scripts/lib/manifest/scaffolder.cjs +1 -1
- package/scripts/lib/manifest/schemas/skills.schema.json +1 -1
- package/scripts/lib/manifest/skills.json +1 -1
- package/scripts/lib/new-addendum.cjs +1 -1
- package/scripts/skill-templates/README.md +90 -0
- package/scripts/skill-templates/add-backlog/SKILL.md +48 -0
- package/scripts/skill-templates/analyze-dependencies/SKILL.md +95 -0
- package/scripts/skill-templates/apply-reflections/SKILL.md +109 -0
- package/scripts/skill-templates/apply-reflections/apply-reflections-procedure.md +170 -0
- package/scripts/skill-templates/audit/SKILL.md +79 -0
- package/scripts/skill-templates/bandit-reset/SKILL.md +91 -0
- package/scripts/skill-templates/bandit-status/SKILL.md +94 -0
- package/scripts/skill-templates/benchmark/SKILL.md +65 -0
- package/scripts/skill-templates/bootstrap-ds/SKILL.md +43 -0
- package/scripts/skill-templates/brief/SKILL.md +145 -0
- package/scripts/skill-templates/budget/SKILL.md +45 -0
- package/scripts/skill-templates/cache-manager/SKILL.md +66 -0
- package/scripts/skill-templates/cache-manager/cache-policy.md +126 -0
- package/scripts/skill-templates/check-update/SKILL.md +98 -0
- package/scripts/skill-templates/compare/SKILL.md +82 -0
- package/scripts/skill-templates/compare/compare-rubric.md +171 -0
- package/scripts/skill-templates/complete-cycle/SKILL.md +81 -0
- package/scripts/skill-templates/connections/SKILL.md +71 -0
- package/scripts/skill-templates/connections/connections-onboarding.md +608 -0
- package/scripts/skill-templates/context/SKILL.md +137 -0
- package/scripts/skill-templates/continue/SKILL.md +24 -0
- package/scripts/skill-templates/darkmode/SKILL.md +76 -0
- package/scripts/skill-templates/darkmode/darkmode-audit-procedure.md +258 -0
- package/scripts/skill-templates/debug/SKILL.md +41 -0
- package/scripts/skill-templates/debug/debug-feedback-loops.md +119 -0
- package/scripts/skill-templates/design/SKILL.md +118 -0
- package/scripts/skill-templates/design/design-procedure.md +304 -0
- package/scripts/skill-templates/discuss/SKILL.md +96 -0
- package/scripts/skill-templates/do/SKILL.md +45 -0
- package/scripts/skill-templates/explore/SKILL.md +118 -0
- package/scripts/skill-templates/explore/explore-procedure.md +267 -0
- package/scripts/skill-templates/export/SKILL.md +30 -0
- package/scripts/skill-templates/extract-learnings/SKILL.md +114 -0
- package/scripts/skill-templates/fast/SKILL.md +91 -0
- package/scripts/skill-templates/figma-extract/SKILL.md +64 -0
- package/scripts/skill-templates/figma-write/SKILL.md +50 -0
- package/scripts/skill-templates/graphify/SKILL.md +49 -0
- package/scripts/skill-templates/health/SKILL.md +99 -0
- package/scripts/skill-templates/health/health-mcp-detection.md +44 -0
- package/scripts/skill-templates/health/health-skill-length-report.md +69 -0
- package/scripts/skill-templates/help/SKILL.md +60 -0
- package/scripts/skill-templates/instinct/SKILL.md +111 -0
- package/scripts/skill-templates/list-assumptions/SKILL.md +61 -0
- package/scripts/skill-templates/list-pins/SKILL.md +27 -0
- package/scripts/skill-templates/live/SKILL.md +98 -0
- package/scripts/skill-templates/locale/SKILL.md +51 -0
- package/scripts/skill-templates/map/SKILL.md +89 -0
- package/scripts/skill-templates/migrate/SKILL.md +70 -0
- package/scripts/skill-templates/migrate-context/SKILL.md +123 -0
- package/scripts/skill-templates/new-addendum/SKILL.md +81 -0
- package/scripts/skill-templates/new-cycle/SKILL.md +37 -0
- package/scripts/skill-templates/new-project/SKILL.md +53 -0
- package/scripts/skill-templates/new-skill/SKILL.md +90 -0
- package/scripts/skill-templates/next/SKILL.md +68 -0
- package/scripts/skill-templates/note/SKILL.md +48 -0
- package/scripts/skill-templates/openrouter-status/SKILL.md +86 -0
- package/scripts/skill-templates/optimize/SKILL.md +97 -0
- package/scripts/skill-templates/override/SKILL.md +86 -0
- package/scripts/skill-templates/paper-write/SKILL.md +54 -0
- package/scripts/skill-templates/pause/SKILL.md +77 -0
- package/scripts/skill-templates/peer-cli-add/SKILL.md +88 -0
- package/scripts/skill-templates/peer-cli-add/peer-cli-protocol.md +161 -0
- package/scripts/skill-templates/peer-cli-customize/SKILL.md +89 -0
- package/scripts/skill-templates/peers/SKILL.md +96 -0
- package/scripts/skill-templates/pencil-write/SKILL.md +54 -0
- package/scripts/skill-templates/pin/SKILL.md +37 -0
- package/scripts/skill-templates/plan/SKILL.md +105 -0
- package/scripts/skill-templates/plan/plan-procedure.md +278 -0
- package/scripts/skill-templates/plant-seed/SKILL.md +48 -0
- package/scripts/skill-templates/pr-branch/SKILL.md +32 -0
- package/scripts/skill-templates/progress/SKILL.md +107 -0
- package/scripts/skill-templates/quality-gate/SKILL.md +90 -0
- package/scripts/skill-templates/quality-gate/threat-modeling.md +101 -0
- package/scripts/skill-templates/quick/SKILL.md +44 -0
- package/scripts/skill-templates/reapply-patches/SKILL.md +32 -0
- package/scripts/skill-templates/recall/SKILL.md +75 -0
- package/scripts/skill-templates/reflect/SKILL.md +85 -0
- package/scripts/skill-templates/reflect/procedures/capability-gap-scan.md +119 -0
- package/scripts/skill-templates/report-issue/SKILL.md +53 -0
- package/scripts/skill-templates/report-issue/report-issue-procedure.md +119 -0
- package/scripts/skill-templates/resume/SKILL.md +93 -0
- package/scripts/skill-templates/review-backlog/SKILL.md +46 -0
- package/scripts/skill-templates/review-decisions/SKILL.md +42 -0
- package/scripts/skill-templates/roi/SKILL.md +54 -0
- package/scripts/skill-templates/rollout-status/SKILL.md +35 -0
- package/scripts/skill-templates/router/SKILL.md +89 -0
- package/scripts/skill-templates/router/capability-gap-emitter.md +65 -0
- package/scripts/skill-templates/router/router-pick-emitter.md +78 -0
- package/scripts/skill-templates/router/router-rules.md +84 -0
- package/scripts/skill-templates/settings/SKILL.md +87 -0
- package/scripts/skill-templates/ship/SKILL.md +48 -0
- package/scripts/skill-templates/sketch/SKILL.md +78 -0
- package/scripts/skill-templates/sketch-wrap-up/SKILL.md +92 -0
- package/scripts/skill-templates/skill-manifest/SKILL.md +79 -0
- package/scripts/skill-templates/spike/SKILL.md +67 -0
- package/scripts/skill-templates/spike-wrap-up/SKILL.md +86 -0
- package/scripts/skill-templates/start/SKILL.md +67 -0
- package/scripts/skill-templates/start/start-procedure.md +115 -0
- package/scripts/skill-templates/state/SKILL.md +106 -0
- package/scripts/skill-templates/stats/SKILL.md +51 -0
- package/scripts/skill-templates/style/SKILL.md +71 -0
- package/scripts/skill-templates/style/style-doc-procedure.md +150 -0
- package/scripts/skill-templates/synthesize/SKILL.md +94 -0
- package/scripts/skill-templates/timeline/SKILL.md +66 -0
- package/scripts/skill-templates/todo/SKILL.md +64 -0
- package/scripts/skill-templates/turn-closeout/SKILL.md +95 -0
- package/scripts/skill-templates/undo/SKILL.md +31 -0
- package/scripts/skill-templates/unlock-decision/SKILL.md +54 -0
- package/scripts/skill-templates/unpin/SKILL.md +31 -0
- package/scripts/skill-templates/update/SKILL.md +56 -0
- package/scripts/skill-templates/using-gdd/SKILL.md +78 -0
- package/scripts/skill-templates/verify/SKILL.md +113 -0
- package/scripts/skill-templates/verify/verify-procedure.md +511 -0
- package/scripts/skill-templates/warm-cache/SKILL.md +81 -0
- package/scripts/skill-templates/watch-authorities/SKILL.md +82 -0
- package/scripts/skill-templates/zoom-out/SKILL.md +26 -0
- package/sdk/cli/commands/build.ts +2 -2
- package/sdk/cli/index.js +2 -2
- package/sdk/cli/index.ts +1 -1
- package/skills/README.md +22 -14
- package/skills/help/SKILL.md +28 -55
- package/skills/new-skill/SKILL.md +5 -5
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
/**
|
|
4
|
+
* generate-skill-frontmatter.cjs — Phase 46 (Skill UX Polish).
|
|
5
|
+
*
|
|
6
|
+
* scripts/lib/manifest/skills.json is the single source of truth for the
|
|
7
|
+
* universal skill frontmatter fields (description, argument-hint, tools,
|
|
8
|
+
* user-invocable, disable-model-invocation). This script regenerates the
|
|
9
|
+
* frontmatter block of every scripts/skill-templates/<name>/SKILL.md from that manifest,
|
|
10
|
+
* preserving the markdown body and any non-managed frontmatter lines verbatim.
|
|
11
|
+
*
|
|
12
|
+
* Direction is forward (manifest -> source frontmatter); build-skills.cjs then
|
|
13
|
+
* propagates scripts/skill-templates -> skills/ + dist/claude-code/. A CI drift gate
|
|
14
|
+
* (--check) keeps committed frontmatter == generated.
|
|
15
|
+
*
|
|
16
|
+
* Modes:
|
|
17
|
+
* (no flag) regenerate scripts/skill-templates/<name>/SKILL.md frontmatter from skills.json
|
|
18
|
+
* --check exit 1 if any committed frontmatter differs from generated (no writes)
|
|
19
|
+
* --extract reverse: read current source frontmatter -> rewrite skills.json
|
|
20
|
+
* (seed/refresh the SoT from ground truth; idempotent with forward)
|
|
21
|
+
*
|
|
22
|
+
* Managed keys (emitted in this canonical order, only when present):
|
|
23
|
+
* name, description, argument-hint, tools, user-invocable, disable-model-invocation
|
|
24
|
+
* Everything else (color, model, writes:, ...) is carried verbatim in the record's
|
|
25
|
+
* `extra_frontmatter` array and re-emitted after the managed block.
|
|
26
|
+
*
|
|
27
|
+
* Exit: 0 ok / 1 drift (--check) / 2 error.
|
|
28
|
+
*/
|
|
29
|
+
const fs = require('fs');
|
|
30
|
+
const path = require('path');
|
|
31
|
+
|
|
32
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
33
|
+
const SRC = path.join(ROOT, 'scripts', 'skill-templates');
|
|
34
|
+
const SKILLS_JSON = path.join(ROOT, 'scripts', 'lib', 'manifest', 'skills.json');
|
|
35
|
+
|
|
36
|
+
// Managed frontmatter keys <-> manifest record keys, in canonical emit order.
|
|
37
|
+
const MANAGED = [
|
|
38
|
+
{ fm: 'name', rec: 'name', kind: 'name' },
|
|
39
|
+
{ fm: 'description', rec: 'description', kind: 'qstr' },
|
|
40
|
+
{ fm: 'argument-hint', rec: 'argument_hint', kind: 'qstr' },
|
|
41
|
+
{ fm: 'tools', rec: 'tools', kind: 'bare' },
|
|
42
|
+
{ fm: 'user-invocable', rec: 'user_invocable', kind: 'bool' },
|
|
43
|
+
{ fm: 'disable-model-invocation', rec: 'disable_model_invocation', kind: 'bool' },
|
|
44
|
+
];
|
|
45
|
+
const MANAGED_FM = new Set(MANAGED.map((m) => m.fm));
|
|
46
|
+
|
|
47
|
+
function fail(msg) {
|
|
48
|
+
process.stderr.write(`generate-skill-frontmatter: ${msg}\n`);
|
|
49
|
+
process.exit(2);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function listSkillDirs() {
|
|
53
|
+
if (!fs.existsSync(SRC)) fail(`source dir not found: ${SRC}`);
|
|
54
|
+
return fs
|
|
55
|
+
.readdirSync(SRC, { withFileTypes: true })
|
|
56
|
+
.filter((e) => e.isDirectory() && fs.existsSync(path.join(SRC, e.name, 'SKILL.md')))
|
|
57
|
+
.map((e) => e.name)
|
|
58
|
+
.sort((a, b) => a.localeCompare(b));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Split a SKILL.md into { fmLines, body }. fmLines excludes the --- fences. */
|
|
62
|
+
function splitFrontmatter(text, id) {
|
|
63
|
+
const norm = text.replace(/\r\n/g, '\n');
|
|
64
|
+
if (!norm.startsWith('---\n')) fail(`${id}: SKILL.md does not start with a --- frontmatter fence`);
|
|
65
|
+
const end = norm.indexOf('\n---\n', 4);
|
|
66
|
+
if (end === -1) fail(`${id}: unterminated frontmatter`);
|
|
67
|
+
const fmBlock = norm.slice(4, end + 1); // include trailing \n of last fm line
|
|
68
|
+
const body = norm.slice(end + 5); // after "\n---\n"
|
|
69
|
+
const fmLines = fmBlock.replace(/\n$/, '').split('\n');
|
|
70
|
+
return { fmLines, body };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function unquote(v) {
|
|
74
|
+
const t = v.trim();
|
|
75
|
+
if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) {
|
|
76
|
+
return t.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
77
|
+
}
|
|
78
|
+
return t;
|
|
79
|
+
}
|
|
80
|
+
function quote(s) {
|
|
81
|
+
return '"' + String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Parse one skill's frontmatter lines into an enriched record. */
|
|
85
|
+
function recordFromFrontmatter(id, fmLines) {
|
|
86
|
+
const rec = { name: id };
|
|
87
|
+
const extra = [];
|
|
88
|
+
let i = 0;
|
|
89
|
+
while (i < fmLines.length) {
|
|
90
|
+
const line = fmLines[i];
|
|
91
|
+
const m = /^([A-Za-z][\w-]*):(.*)$/.exec(line);
|
|
92
|
+
if (!m) {
|
|
93
|
+
// stray non-key line at top level — preserve verbatim
|
|
94
|
+
extra.push(line);
|
|
95
|
+
i += 1;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const key = m[1];
|
|
99
|
+
const rawVal = m[2];
|
|
100
|
+
// gather continuation lines (indented or list items or blank-within-block)
|
|
101
|
+
const block = [line];
|
|
102
|
+
let j = i + 1;
|
|
103
|
+
while (j < fmLines.length && /^(\s+\S|\s*-\s|\s*$)/.test(fmLines[j]) && !/^[A-Za-z][\w-]*:/.test(fmLines[j])) {
|
|
104
|
+
block.push(fmLines[j]);
|
|
105
|
+
j += 1;
|
|
106
|
+
}
|
|
107
|
+
const managed = MANAGED.find((mm) => mm.fm === key);
|
|
108
|
+
if (managed && block.length === 1) {
|
|
109
|
+
const v = rawVal.trim();
|
|
110
|
+
if (managed.kind === 'name') {
|
|
111
|
+
if (v !== `gdd-${id}`) rec.frontmatter_name = v;
|
|
112
|
+
} else if (managed.kind === 'bool') {
|
|
113
|
+
rec[managed.rec] = v === 'true';
|
|
114
|
+
} else if (managed.kind === 'qstr') {
|
|
115
|
+
rec[managed.rec] = unquote(v);
|
|
116
|
+
} else {
|
|
117
|
+
rec[managed.rec] = v; // bare (tools)
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
extra.push(...block);
|
|
121
|
+
}
|
|
122
|
+
i = j;
|
|
123
|
+
}
|
|
124
|
+
if (extra.length) rec.extra_frontmatter = extra;
|
|
125
|
+
return rec;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Emit the frontmatter block (without --- fences) for a record.
|
|
130
|
+
*
|
|
131
|
+
* Order-preserving: `name` always leads, then the managed keys are emitted in
|
|
132
|
+
* the record's own insertion order (which --extract captures from the original
|
|
133
|
+
* file order), then any non-managed lines verbatim. This keeps forward
|
|
134
|
+
* generation a byte-for-byte fixed point on the committed tree, so existing
|
|
135
|
+
* frontmatter-snapshot baselines never churn. New skills authored directly in
|
|
136
|
+
* skills.json get whatever key order their record uses.
|
|
137
|
+
*/
|
|
138
|
+
function frontmatterFromRecord(rec) {
|
|
139
|
+
const out = [`name: ${rec.frontmatter_name || `gdd-${rec.name}`}`];
|
|
140
|
+
const byRec = new Map(MANAGED.filter((m) => m.kind !== 'name').map((m) => [m.rec, m]));
|
|
141
|
+
for (const key of Object.keys(rec)) {
|
|
142
|
+
const m = byRec.get(key);
|
|
143
|
+
if (!m) continue; // name / frontmatter_name / extra_frontmatter / registered_in_phase / aliases / ...
|
|
144
|
+
const v = rec[key];
|
|
145
|
+
if (v === undefined || v === null) continue;
|
|
146
|
+
if (m.kind === 'bool') out.push(`${m.fm}: ${v ? 'true' : 'false'}`);
|
|
147
|
+
else if (m.kind === 'qstr') out.push(`${m.fm}: ${quote(v)}`);
|
|
148
|
+
else out.push(`${m.fm}: ${v}`);
|
|
149
|
+
}
|
|
150
|
+
if (Array.isArray(rec.extra_frontmatter)) out.push(...rec.extra_frontmatter);
|
|
151
|
+
return out.join('\n');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function readSkillsJson() {
|
|
155
|
+
return JSON.parse(fs.readFileSync(SKILLS_JSON, 'utf8'));
|
|
156
|
+
}
|
|
157
|
+
function recordMap(json) {
|
|
158
|
+
const map = new Map();
|
|
159
|
+
for (const r of json.skills || []) map.set(r.name, r);
|
|
160
|
+
return map;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Build the regenerated SKILL.md text for one skill from its record. */
|
|
164
|
+
function renderSkill(id, rec) {
|
|
165
|
+
const abs = path.join(SRC, id, 'SKILL.md');
|
|
166
|
+
const { body } = splitFrontmatter(fs.readFileSync(abs, 'utf8'), id);
|
|
167
|
+
return `---\n${frontmatterFromRecord(rec)}\n---\n${body}`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function modeForward(check) {
|
|
171
|
+
const json = readSkillsJson();
|
|
172
|
+
const map = recordMap(json);
|
|
173
|
+
const dirs = listSkillDirs();
|
|
174
|
+
const drift = [];
|
|
175
|
+
let written = 0;
|
|
176
|
+
for (const id of dirs) {
|
|
177
|
+
const rec = map.get(id);
|
|
178
|
+
if (!rec) {
|
|
179
|
+
if (check) { drift.push(`${id} (missing from skills.json)`); continue; }
|
|
180
|
+
fail(`${id}: present in scripts/skill-templates but missing from skills.json — add a record (run --extract)`);
|
|
181
|
+
}
|
|
182
|
+
const abs = path.join(SRC, id, 'SKILL.md');
|
|
183
|
+
const cur = fs.readFileSync(abs, 'utf8').replace(/\r\n/g, '\n');
|
|
184
|
+
const next = renderSkill(id, rec);
|
|
185
|
+
if (cur === next) continue;
|
|
186
|
+
if (check) drift.push(id);
|
|
187
|
+
else { fs.writeFileSync(abs, next); written += 1; }
|
|
188
|
+
}
|
|
189
|
+
// records in skills.json with no source dir (e.g. not yet authored) are tolerated
|
|
190
|
+
if (check) {
|
|
191
|
+
if (drift.length) {
|
|
192
|
+
process.stderr.write(
|
|
193
|
+
`generate-skill-frontmatter --check: ${drift.length} skill(s) drift from skills.json:\n ${drift.slice(0, 20).join('\n ')}\n` +
|
|
194
|
+
`Run \`npm run generate:skill-frontmatter\` then \`npm run build:skills\`.\n`,
|
|
195
|
+
);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
process.stdout.write(`generate-skill-frontmatter --check: OK — ${dirs.length} skills match skills.json.\n`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
process.stdout.write(`generate-skill-frontmatter: regenerated ${written}/${dirs.length} skill frontmatter block(s).\n`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function modeExtract() {
|
|
205
|
+
const existing = fs.existsSync(SKILLS_JSON) ? readSkillsJson() : { schema_version: 1, skills: [] };
|
|
206
|
+
const prevMap = recordMap(existing);
|
|
207
|
+
const dirs = listSkillDirs();
|
|
208
|
+
const skills = [];
|
|
209
|
+
for (const id of dirs) {
|
|
210
|
+
const { fmLines } = splitFrontmatter(fs.readFileSync(path.join(SRC, id, 'SKILL.md'), 'utf8'), id);
|
|
211
|
+
const rec = recordFromFrontmatter(id, fmLines);
|
|
212
|
+
// preserve curated fields that live only in the manifest (not frontmatter)
|
|
213
|
+
const prev = prevMap.get(id);
|
|
214
|
+
if (prev && prev.registered_in_phase != null) rec.registered_in_phase = prev.registered_in_phase;
|
|
215
|
+
if (prev && prev.aliases != null) rec.aliases = prev.aliases;
|
|
216
|
+
skills.push(rec);
|
|
217
|
+
}
|
|
218
|
+
const out = { schema_version: existing.schema_version || 1 };
|
|
219
|
+
if (existing.note) out.note = existing.note;
|
|
220
|
+
out.skills = skills;
|
|
221
|
+
fs.writeFileSync(SKILLS_JSON, JSON.stringify(out, null, 2) + '\n');
|
|
222
|
+
process.stdout.write(`generate-skill-frontmatter --extract: wrote ${skills.length} enriched records to skills.json.\n`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function main(argv) {
|
|
226
|
+
const args = argv.slice(2);
|
|
227
|
+
if (args.includes('--extract')) return modeExtract();
|
|
228
|
+
return modeForward(args.includes('--check'));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (require.main === module) main(process.argv);
|
|
232
|
+
|
|
233
|
+
module.exports = {
|
|
234
|
+
splitFrontmatter,
|
|
235
|
+
recordFromFrontmatter,
|
|
236
|
+
frontmatterFromRecord,
|
|
237
|
+
renderSkill,
|
|
238
|
+
unquote,
|
|
239
|
+
quote,
|
|
240
|
+
MANAGED,
|
|
241
|
+
MANAGED_FM,
|
|
242
|
+
main,
|
|
243
|
+
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* scripts/lib/manifest/scaffolder.cjs — Phase 50 (Authoring Contract v3).
|
|
4
4
|
*
|
|
5
5
|
* Pure, dependency-free generator behind the `/gdd:new-skill` scaffolder skill.
|
|
6
|
-
* The SKILL.md (skill-templates/new-skill/SKILL.md) drives the interactive
|
|
6
|
+
* The SKILL.md (scripts/skill-templates/new-skill/SKILL.md) drives the interactive
|
|
7
7
|
* prompts; this module is the deterministic core it (and the test suite) call.
|
|
8
8
|
*
|
|
9
9
|
* Exports:
|
|
@@ -319,7 +319,7 @@
|
|
|
319
319
|
},
|
|
320
320
|
{
|
|
321
321
|
"name": "new-skill",
|
|
322
|
-
"description": "Scaffolds a new Phase-28.5 + Phase-50-compliant skill: gathers a name, a multi-paragraph v3 description, a lifecycle stage, an allowed-tools list, and optional composes_with neighbours, then writes skill-templates/<name>/SKILL.md from the pure generator. Use when adding a brand-new gdd skill and you want the frontmatter, length cap, and v3 description form correct from the first commit. Activates for requests involving authoring a skill, scaffolding a command, creating a new SKILL.md, or adding a slash command.",
|
|
322
|
+
"description": "Scaffolds a new Phase-28.5 + Phase-50-compliant skill: gathers a name, a multi-paragraph v3 description, a lifecycle stage, an allowed-tools list, and optional composes_with neighbours, then writes scripts/skill-templates/<name>/SKILL.md from the pure generator. Use when adding a brand-new gdd skill and you want the frontmatter, length cap, and v3 description form correct from the first commit. Activates for requests involving authoring a skill, scaffolding a command, creating a new SKILL.md, or adding a slash command.",
|
|
323
323
|
"argument_hint": "<skill-name>",
|
|
324
324
|
"tools": "Read, Write, Bash, AskUserQuestion",
|
|
325
325
|
"user_invocable": true,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* scripts/lib/new-addendum.cjs — Phase 54 (Composable Reference Addendums), REG-01.
|
|
4
4
|
*
|
|
5
5
|
* Pure, dependency-free generator behind the `/gdd:new-addendum <kind> <name>`
|
|
6
|
-
* scaffolder skill (skill-templates/new-addendum/SKILL.md). The SKILL.md drives
|
|
6
|
+
* scaffolder skill (scripts/skill-templates/new-addendum/SKILL.md). The SKILL.md drives
|
|
7
7
|
* the prompts; this module is the deterministic core it (and the test suite)
|
|
8
8
|
* call. Mirrors scripts/lib/manifest/scaffolder.cjs (the Phase 50 skill
|
|
9
9
|
* scaffolder): same ReDoS-safe NAME_RE, same throw-on-invalid contract, same
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# `scripts/skill-templates/` - Editable Skill Source (Single Source of Truth)
|
|
2
|
+
|
|
3
|
+
This directory is the **only** place to edit skill content. Every `SKILL.md` and sibling
|
|
4
|
+
doc here is the editable truth - the per-skill prose, examples, procedure files
|
|
5
|
+
(`*-procedure.md`, `*-rules.md`, emitters, etc.) all live here.
|
|
6
|
+
|
|
7
|
+
The user-facing `skills/` directory at the repo root is a **build artifact**, not source.
|
|
8
|
+
It is **committed** (since v1.58.1, NOT gitignored) and regenerated from this directory:
|
|
9
|
+
|
|
10
|
+
- on `npm install` (via the `prepare` lifecycle script) - so contributor clones rebuild it from source
|
|
11
|
+
- on `npm pack` / `npm publish` (via `prepack`) - so the published tarball ships pre-built skills
|
|
12
|
+
- on demand via `node scripts/build-skills.cjs`, with the `build:skills:check` drift gate (CI)
|
|
13
|
+
failing the build whenever the committed `skills/` no longer matches `scripts/skill-templates/`
|
|
14
|
+
|
|
15
|
+
It stays in git because the Claude Code marketplace install path git-clones the plugin
|
|
16
|
+
**without** running `npm install`, so `./skills/` must already exist post-clone. v1.58.0
|
|
17
|
+
briefly gitignored it and broke that path; v1.58.1 restored it as a committed, drift-gated
|
|
18
|
+
build output.
|
|
19
|
+
|
|
20
|
+
End users installing `@hegemonart/get-design-done` from the npm registry receive a tarball
|
|
21
|
+
with `skills/` already built; no build step runs on their machine.
|
|
22
|
+
|
|
23
|
+
## Why two directories, not one
|
|
24
|
+
|
|
25
|
+
Claude Code reads `./skills/<slug>/SKILL.md` raw. If we kept `{{command_prefix}}` placeholders
|
|
26
|
+
in the file Claude reads, the literal text `{{command_prefix}}` would show up in the prompt.
|
|
27
|
+
So the editable templates need to live separately from the rendered output.
|
|
28
|
+
|
|
29
|
+
The previous layout (Phase 42) put templates under `source/skills/` AND committed the
|
|
30
|
+
rendered `skills/` alongside. That meant 232 tracked files for 116 distinct skills with
|
|
31
|
+
identical content modulo a single placeholder substitution. Pure git churn.
|
|
32
|
+
|
|
33
|
+
v1.58.0 fixes this: templates are tracked once at `scripts/skill-templates/`, the rendered output
|
|
34
|
+
is generated on demand.
|
|
35
|
+
|
|
36
|
+
## Source-of-truth split (what lives where)
|
|
37
|
+
|
|
38
|
+
| Concern | Source of truth | How it reaches `skills/` |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| **Body content** (everything below the frontmatter) | `scripts/skill-templates/<slug>/SKILL.md` | `scripts/build-skills.cjs` walks `scripts/skill-templates/`, applies per-harness placeholder substitution, writes to `skills/` |
|
|
41
|
+
| **Universal frontmatter** (`name`, `description`, `argument-hint`, `tools`, `user-invocable`, `disable-model-invocation`) | `scripts/lib/manifest/skills.json` | `scripts/generate-skill-frontmatter.cjs` writes the managed block into `scripts/skill-templates/<slug>/SKILL.md`, then `build:skills` copies it onward |
|
|
42
|
+
| **Non-managed frontmatter** (e.g. `color`, `model`, custom keys) | `scripts/skill-templates/<slug>/SKILL.md` itself (preserved verbatim) | carried through both generators unchanged |
|
|
43
|
+
|
|
44
|
+
The forward direction is **`skills.json` -> `scripts/skill-templates/` -> `skills/`**.
|
|
45
|
+
Treat that direction as canonical; the `--extract` mode of `generate-skill-frontmatter.cjs` exists
|
|
46
|
+
only to seed the manifest from current sources when reconciling drift.
|
|
47
|
+
|
|
48
|
+
## Editing protocol
|
|
49
|
+
|
|
50
|
+
1. **Edit body** -> modify `scripts/skill-templates/<slug>/SKILL.md` (anything below the frontmatter delimiter).
|
|
51
|
+
2. **Edit universal frontmatter** -> modify `scripts/lib/manifest/skills.json`, then run
|
|
52
|
+
`npm run generate:skill-frontmatter`.
|
|
53
|
+
3. **Edit non-managed frontmatter** -> modify `scripts/skill-templates/<slug>/SKILL.md` directly; the generator
|
|
54
|
+
preserves it.
|
|
55
|
+
4. **Regenerate the built surface** -> `npm run build:skills`. This rewrites the committed
|
|
56
|
+
`skills/<slug>/SKILL.md` byte-for-byte from the templates; commit the regenerated `skills/`
|
|
57
|
+
alongside your template edit so the `build:skills:check` drift gate stays green.
|
|
58
|
+
5. **Verify the build** -> `npm run build:skills:check` (CI gate) confirms compile determinism
|
|
59
|
+
and that the on-disk `skills/` matches what `scripts/skill-templates/` would generate.
|
|
60
|
+
|
|
61
|
+
## Placeholders
|
|
62
|
+
|
|
63
|
+
Four substitution slots are supported by `scripts/lib/build/factory.cjs`:
|
|
64
|
+
|
|
65
|
+
- `{{command_prefix}}` - slash-command prefix (`/gdd:` for Claude, `/gdd-` for Codex, etc.)
|
|
66
|
+
- `{{model}}` - human-readable model phrase ("your configured Claude model", etc.)
|
|
67
|
+
- `{{config_file}}` - per-harness config path (`.claude/settings.json`, `.codex/config.toml`, ...)
|
|
68
|
+
- `{{ask_instruction}}` - "ask Claude Code", "ask Codex", etc.
|
|
69
|
+
|
|
70
|
+
Plus conditional blocks: `<!-- harness-only: claude,codex -->BODY<!-- /harness-only -->` keeps
|
|
71
|
+
`BODY` only when the active harness id is in the listed set.
|
|
72
|
+
|
|
73
|
+
Escape with `\{{ ... }}` to emit a literal `{{...}}` in the output (never substituted).
|
|
74
|
+
|
|
75
|
+
Full grammar + the per-harness substitution table: `reference/skill-placeholders.md`.
|
|
76
|
+
|
|
77
|
+
## What npm ships
|
|
78
|
+
|
|
79
|
+
`package.json` `files` lists `skills/` (the built surface); `scripts/skill-templates/` is repo-only and
|
|
80
|
+
is **not** distributed via npm. The `prepack` lifecycle runs `npm run build:skills` so the tarball
|
|
81
|
+
always contains a freshly-built `skills/`.
|
|
82
|
+
|
|
83
|
+
## Cross-references
|
|
84
|
+
|
|
85
|
+
- `scripts/build-skills.cjs` - the multi-harness orchestrator that compiles this directory.
|
|
86
|
+
- `scripts/lib/build/factory.cjs` - the pure transformer applied per-harness.
|
|
87
|
+
- `scripts/lib/manifest/README.md` - explains why `skills.json` is the universal-frontmatter SoT.
|
|
88
|
+
- `scripts/generate-skill-frontmatter.cjs` - manifest -> source-frontmatter generator (with
|
|
89
|
+
`--check` drift gate and `--extract` reverse mode).
|
|
90
|
+
- `reference/skill-placeholders.md` - placeholder grammar + per-harness substitution table.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-add-backlog
|
|
3
|
+
description: "Park a design idea for a future cycle. Writes to .design/backlog/BACKLOG.md."
|
|
4
|
+
argument-hint: "[text]"
|
|
5
|
+
tools: Read, Write, AskUserQuestion
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# {{command_prefix}}add-backlog
|
|
10
|
+
|
|
11
|
+
**Role:** Long-term parking lot for design ideas. Backing store: `.design/backlog/BACKLOG.md`.
|
|
12
|
+
|
|
13
|
+
## Step 1 - Get text
|
|
14
|
+
|
|
15
|
+
If `$ARGUMENTS` is empty, ask the user: "What should be added to the backlog?"
|
|
16
|
+
|
|
17
|
+
## Step 2 - Append
|
|
18
|
+
|
|
19
|
+
Create `.design/backlog/` directory and `BACKLOG.md` with `# Design Backlog` header if missing.
|
|
20
|
+
|
|
21
|
+
Derive `<title>` = first 60 characters of the text (strip newlines). Append:
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
## <title>
|
|
25
|
+
**Added**: YYYY-MM-DD
|
|
26
|
+
**Status**: parked
|
|
27
|
+
|
|
28
|
+
<full text>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
━━━ Backlog entry parked ━━━
|
|
37
|
+
Title: <title>
|
|
38
|
+
Status: parked
|
|
39
|
+
Promote later via: {{command_prefix}}review-backlog
|
|
40
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Constraints
|
|
44
|
+
|
|
45
|
+
- Do not modify files outside `.design/backlog/`.
|
|
46
|
+
- Do not set status to anything other than `parked` here - `{{command_prefix}}review-backlog` owns status transitions.
|
|
47
|
+
|
|
48
|
+
## ADD-BACKLOG COMPLETE
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-analyze-dependencies
|
|
3
|
+
description: "Queries the intel store to surface token fan-out, component call-graphs, decision traceability, and circular dependency detection. Requires .design/intel/ to exist (run build-intel.cjs first)."
|
|
4
|
+
tools: Bash, Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# {{command_prefix}}analyze-dependencies
|
|
8
|
+
|
|
9
|
+
**Role:** Surface dependency relationships, token usage spread, component graphs, and decision traceability using `.design/intel/`. All queries are O(1) reads against pre-built JSON slices - no file greps. See `./reference/heuristics.md` for the underlying dependency-analysis heuristics (fan-out thresholds, orphan-token criteria, cycle-detection bias).
|
|
10
|
+
|
|
11
|
+
## Pre-flight
|
|
12
|
+
|
|
13
|
+
Verify the intel store exists:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ls .design/intel/files.json 2>/dev/null && echo "ready" || echo "missing"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If missing, print:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Intel store not found. Build it first:
|
|
23
|
+
node scripts/build-intel.cjs --force
|
|
24
|
+
Then re-run {{command_prefix}}analyze-dependencies.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage modes
|
|
28
|
+
|
|
29
|
+
- `{{command_prefix}}analyze-dependencies` - run all four analyses and print a combined report
|
|
30
|
+
- `{{command_prefix}}analyze-dependencies tokens` - token fan-out only
|
|
31
|
+
- `{{command_prefix}}analyze-dependencies components` - component call-graph only
|
|
32
|
+
- `{{command_prefix}}analyze-dependencies decisions` - decision traceability only
|
|
33
|
+
- `{{command_prefix}}analyze-dependencies circular` - circular dependency detection only
|
|
34
|
+
|
|
35
|
+
## Analysis 1 - Token fan-out
|
|
36
|
+
|
|
37
|
+
Surfaces tokens referenced in many files + orphans (referenced exactly once).
|
|
38
|
+
|
|
39
|
+
1. Read `.design/intel/tokens.json`; group by `token` value; count distinct `file` values.
|
|
40
|
+
2. Sort descending; print top-20 with token / file count / category columns.
|
|
41
|
+
3. Append orphans list (token + file:line of the single reference).
|
|
42
|
+
|
|
43
|
+
Header: `━━━ Token fan-out ━━━` … `(top 20 shown)` … `Orphaned tokens (referenced in exactly 1 file):` … footer rule.
|
|
44
|
+
|
|
45
|
+
## Analysis 2 - Component call-graph
|
|
46
|
+
|
|
47
|
+
Surfaces widely-referenced components and the files referencing each.
|
|
48
|
+
|
|
49
|
+
1. Read `.design/intel/components.json`; group by `component` name; count distinct `file` values.
|
|
50
|
+
2. Sort descending; print top-20 with component / references / files columns.
|
|
51
|
+
3. If `components <Name>` is passed, print only that component's referencing files (one per line).
|
|
52
|
+
|
|
53
|
+
Header: `━━━ Component call-graph ━━━` … footer rule.
|
|
54
|
+
|
|
55
|
+
## Analysis 3 - Decision traceability
|
|
56
|
+
|
|
57
|
+
Maps decisions to skill/agent files that cite them.
|
|
58
|
+
|
|
59
|
+
1. Read `.design/intel/decisions.json` (decision IDs D-01, D-02, …).
|
|
60
|
+
2. Read `.design/intel/symbols.json` for heading anchors; `.design/intel/dependencies.json` for @-reference chains.
|
|
61
|
+
3. For each decision, cross-reference which files cite the ID.
|
|
62
|
+
4. Print per-decision block: `D-NN <description>` then a 6-space-indented `Referenced by: <file:line>, …` line (or `(no explicit references found)`).
|
|
63
|
+
5. Footer: `Total: N decisions tracked, M with file references`.
|
|
64
|
+
|
|
65
|
+
Empty-state: `No decisions indexed. Run node scripts/build-intel.cjs after creating .design/DESIGN-CONTEXT.md.`
|
|
66
|
+
|
|
67
|
+
## Analysis 4 - Circular dependency detection
|
|
68
|
+
|
|
69
|
+
Detects cycles in the `@`-reference graph (File A → File B → File A). DFS with path-tracking detects back-edges; algorithm + adjacency-map shape detailed in `./reference/heuristics.md` §"Dependency-cycle detection".
|
|
70
|
+
|
|
71
|
+
1. Read `.design/intel/graph.json`; build adjacency map from `edges`.
|
|
72
|
+
2. Run DFS with path-tracking; collect back-edges as cycles.
|
|
73
|
+
3. Print each cycle with the node sequence + `<- CYCLE` marker on the closing node.
|
|
74
|
+
4. Footer: `Total cycles: N` (or `All clear — no circular dependencies detected.`).
|
|
75
|
+
|
|
76
|
+
## Combined report
|
|
77
|
+
|
|
78
|
+
When run without a mode argument, print all four analyses in sequence separated by blank lines, prefixed with:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
━━━ Dependency Analysis ━━━
|
|
82
|
+
Intel store: .design/intel/
|
|
83
|
+
Generated: <timestamp from files.json>
|
|
84
|
+
Files indexed: <count>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Required reading (conditional)
|
|
88
|
+
|
|
89
|
+
@.design/intel/tokens.json (if present)
|
|
90
|
+
@.design/intel/components.json (if present)
|
|
91
|
+
@.design/intel/dependencies.json (if present)
|
|
92
|
+
@.design/intel/decisions.json (if present)
|
|
93
|
+
@.design/intel/graph.json (if present)
|
|
94
|
+
|
|
95
|
+
## ANALYZE-DEPENDENCIES COMPLETE
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-apply-reflections
|
|
3
|
+
description: "Review and selectively apply proposals from .design/reflections/<cycle-slug>.md. Diffs each proposal, prompts user to accept/skip/edit, then writes changes."
|
|
4
|
+
argument-hint: "[--cycle <slug>] [--filter <FRONTMATTER|REFERENCE|BUDGET|QUESTION|GLOBAL-SKILL>] [--dry-run]"
|
|
5
|
+
tools: Read, Write, Edit, Bash, Glob
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# {{command_prefix}}apply-reflections
|
|
9
|
+
|
|
10
|
+
Interactive proposal review loop. Reads `.design/reflections/<cycle-slug>.md`, walks each numbered proposal, and applies accepted ones to the appropriate target file. Nothing is applied without explicit user confirmation.
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
### 1. Resolve reflections file
|
|
15
|
+
|
|
16
|
+
- If `--cycle <slug>` given: load `.design/reflections/<slug>.md`
|
|
17
|
+
- Else: glob `.design/reflections/*.md`, sort by modified time descending, load the most recent
|
|
18
|
+
- If no file found: error "No reflections found. Run `{{command_prefix}}reflect` first."
|
|
19
|
+
- Print: "Reviewing reflections: <filename>"
|
|
20
|
+
|
|
21
|
+
### 2. Parse proposals
|
|
22
|
+
|
|
23
|
+
Scan file for lines matching `### Proposal N — [TYPE] ...`. Extract each proposal block (Why / Change / Risk).
|
|
24
|
+
|
|
25
|
+
If `--filter <TYPE>` given: skip proposals whose type tag doesn't match.
|
|
26
|
+
|
|
27
|
+
Print: "Found N proposals (N after filter)."
|
|
28
|
+
|
|
29
|
+
### 3. Review loop
|
|
30
|
+
|
|
31
|
+
For each proposal (in order):
|
|
32
|
+
|
|
33
|
+
Print the full proposal block:
|
|
34
|
+
```
|
|
35
|
+
─────────────────────────────────────────
|
|
36
|
+
Proposal N/TOTAL — [TYPE] Title
|
|
37
|
+
Risk: low|medium
|
|
38
|
+
|
|
39
|
+
Why: ...
|
|
40
|
+
Change: ...
|
|
41
|
+
─────────────────────────────────────────
|
|
42
|
+
(a) apply (s) skip (e) edit (q) quit
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
If `--dry-run`: print `[dry-run — would prompt here]` and continue to next proposal without prompting.
|
|
46
|
+
|
|
47
|
+
Based on user choice:
|
|
48
|
+
- **a** - apply (see Apply Logic below)
|
|
49
|
+
- **s** - mark proposal as `**Reviewed: skipped**` in the reflections file; continue
|
|
50
|
+
- **e** - show the Change text, ask user to provide edited version, then apply the edited version
|
|
51
|
+
- **q** - stop processing; print "Stopped at proposal N. Resume with `{{command_prefix}}apply-reflections --cycle <slug>`."
|
|
52
|
+
|
|
53
|
+
### 4. Apply Logic by Proposal Type
|
|
54
|
+
|
|
55
|
+
After the user chooses `a` (apply) or `e` (edit-then-apply), branch on the proposal's bracketed type tag and follow the per-type apply procedure in `./apply-reflections-procedure.md` - one numbered procedure each for `[FRONTMATTER]`, `[REFERENCE]`, `[BUDGET]`, `[QUESTION]`, `[GLOBAL-SKILL]`. All branches end with `**Applied**: <date>` appended to the proposal block in the reflections file.
|
|
56
|
+
|
|
57
|
+
### 5. Summary
|
|
58
|
+
|
|
59
|
+
After all proposals processed (or `q`):
|
|
60
|
+
```
|
|
61
|
+
─────────────────────────────────────────
|
|
62
|
+
Apply-reflections complete
|
|
63
|
+
Applied: N
|
|
64
|
+
Skipped: N
|
|
65
|
+
Remaining: N (run again to continue)
|
|
66
|
+
─────────────────────────────────────────
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## [INCUBATOR]
|
|
70
|
+
|
|
71
|
+
Incubator drafts authored by `scripts/lib/incubator-author.cjs` (Phase 29-04) appear as a distinct proposal class. For each draft under `.design/reflections/incubator/<slug>/`, use `scripts/lib/apply-reflections/incubator-proposals.cjs`:
|
|
72
|
+
|
|
73
|
+
1. `discoverIncubatorDrafts()` → list pending drafts.
|
|
74
|
+
2. `renderProposal(draft)` → show full body + diff + origin signals.
|
|
75
|
+
3. User chooses **accept** | **reject** | **defer** | **edit**.
|
|
76
|
+
4. **accept** - scope-guard runs FIRST (`validateScope` from `scripts/validate-incubator-scope.cjs`); `applyAccept` then promotes draft → `agents/<slug>.md` or `skills/<slug>/SKILL.md` and appends a registry entry. Single-step per D-04.
|
|
77
|
+
5. **reject** - `applyReject` removes the incubator subdir.
|
|
78
|
+
6. **defer** - no-op; draft re-surfaces next run.
|
|
79
|
+
7. **edit** - `applyEdit` opens `$EDITOR`; re-prompt user on close.
|
|
80
|
+
|
|
81
|
+
**Stage-1 gate.** At session start, call `checkStage1Gate()`. If `thresholdMet && !optInRecorded`, display the opt-in prompt once. NEVER auto-flip per D-01 - recording opt-in requires explicit user confirmation via `recordOptIn()`. Full procedure: `./apply-reflections-procedure.md` §[INCUBATOR].
|
|
82
|
+
|
|
83
|
+
## [KFM-CANDIDATE]
|
|
84
|
+
|
|
85
|
+
KFM-catalogue proposals authored by `scripts/lib/reflector-kfm-proposer.cjs` (Phase 30.5-03 D-05) appear as a 6th proposal class. Drafts at `.design/reflections/incubator/kfm-<slug>/CATALOGUE-ENTRY.md`; pre-filled 11-field schema with `TODO:` placeholders for `pattern` + `fix`. Two upstream signals share the surface (D-06): `capability_gap` clusters (≥3, no existing match) + `kfm-candidate` events (whitelist-matched articles, 1-shot). User chooses **accept** | **reject** | **defer** | **edit**. `applyAccept` appends to `reference/known-failure-modes.md` + `reference/registry.json` (`origin: incubator-kfm`); `applyReject` removes the incubator subdir; `applyDefer` stamps `deferred_until`; `applyEdit` returns the draft path for `$EDITOR`. Full procedure: `./apply-reflections-procedure.md` §[KFM-CANDIDATE].
|
|
86
|
+
|
|
87
|
+
## [INSTINCT]
|
|
88
|
+
|
|
89
|
+
Atomic instinct units emitted by `design-reflector` (and surfaced from `{{command_prefix}}extract-learnings`) appear as a distinct proposal class, alongside `[INCUBATOR]` and `[KFM-CANDIDATE]`. Each unit is a fenced `yaml` block under the reflector's `## Atomic instincts` section, shaped per `reference/instinct-format.md` (`id`, `trigger`, `confidence`, `domain`, `scope`, `project_id`, `source`, `cycles_seen`, `first_seen`, `last_seen`, plus a short body). A unit is a proposal, never a stored fact - nothing lands until the user accepts it.
|
|
90
|
+
|
|
91
|
+
Mirror the `[INCUBATOR]` flow:
|
|
92
|
+
|
|
93
|
+
1. Discover the units: parse every `yaml` block under `## Atomic instincts` in the reflections file. Skip malformed blocks (warn on stderr, keep going).
|
|
94
|
+
2. For each unit: show the parsed `trigger`, `domain`, `confidence`, and body so the user sees what would be stored.
|
|
95
|
+
3. Prompt: `(a) accept (r) reject (d) defer (e) edit (q) quit`.
|
|
96
|
+
|
|
97
|
+
**Per-action behavior:**
|
|
98
|
+
|
|
99
|
+
1. **accept** - call `scripts/lib/instinct-store.cjs` `add(unit, { scope, baseDir })` with the unit at its emitted `confidence`. The store owns de-duplication and `cycles_seen` bookkeeping. On success print `Stored instinct <id> (<domain>, confidence <n>).` and append `**Applied**: <date>` to the proposal block.
|
|
100
|
+
2. **reject** - do not store the unit. Append `**Reviewed: rejected**` to the reflections file.
|
|
101
|
+
3. **defer** - no-op; the unit re-surfaces next run. Append `**Reviewed: deferred**`.
|
|
102
|
+
4. **edit** - let the user adjust `trigger`, `confidence`, or `domain`, then accept the edited unit through the same `add(...)` call. Default `scope: 'project'` (write `global` only when the unit's frontmatter says so); never edit `.design/instincts/instincts.json` directly, and promote to global via the separate gated `{{command_prefix}}instinct promote`.
|
|
103
|
+
|
|
104
|
+
## Do Not
|
|
105
|
+
|
|
106
|
+
- Do not apply any proposal without the user explicitly choosing `a` or `e`.
|
|
107
|
+
- Do not modify source code files (`.ts`, `.tsx`, `.css`, `.js`) - only agent files, reference files, budget.json, discussant questions, global skills, and incubator drafts.
|
|
108
|
+
- Do not re-run the reflector - this skill only applies existing proposals.
|
|
109
|
+
- Do not bypass the scope guard or auto-flip Stage-1 - both are non-negotiable per D-05 / D-01.
|