@hegemonart/get-design-done 1.48.0 → 1.50.0
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 +8 -2
- package/CHANGELOG.md +93 -0
- package/README.md +4 -0
- package/SKILL.md +2 -1
- package/agents/design-auditor.md +37 -4
- package/agents/design-context-builder.md +2 -0
- package/agents/design-debt-crawler.md +36 -5
- package/agents/design-executor.md +2 -0
- package/agents/design-fixer.md +4 -1
- package/agents/design-planner.md +2 -0
- package/agents/design-reflector.md +2 -0
- package/agents/design-research-synthesizer.md +2 -0
- package/agents/design-verifier.md +7 -15
- package/dist/claude-code/.claude/skills/audit/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/brief/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/compare/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/connections/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/darkmode/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/design/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/discover/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/do/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/explore/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/fast/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/health/SKILL.md +2 -2
- package/dist/claude-code/.claude/skills/live/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/new-skill/SKILL.md +90 -0
- package/dist/claude-code/.claude/skills/plan/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/progress/SKILL.md +9 -1
- package/dist/claude-code/.claude/skills/quick/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/scan/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/ship/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/verify/SKILL.md +1 -1
- package/hooks/gdd-design-quality-check.js +340 -0
- package/hooks/hooks.json +9 -0
- package/package.json +12 -2
- package/reference/anti-slop-rubric.md +173 -0
- package/reference/audit-scoring.md +4 -0
- package/reference/debt-categories.md +20 -1
- package/reference/registry.json +28 -0
- package/reference/reviewer-confidence-gate.md +108 -0
- package/reference/skill-authoring-contract.md +97 -15
- package/reference/skill-graph.md +118 -0
- package/reference/visual-tells.md +383 -0
- package/scripts/lib/confidence-route.cjs +60 -0
- package/scripts/lib/manifest/scaffolder.cjs +261 -0
- package/scripts/lib/manifest/schemas/skills.schema.json +14 -0
- package/scripts/lib/manifest/skills.json +26 -18
- package/scripts/lib/worktree-resolve.cjs +221 -0
- package/sdk/mcp/gdd-state/server.js +37 -4
- package/sdk/mcp/gdd-state/tools/shared.ts +61 -0
- package/skills/audit/SKILL.md +1 -1
- package/skills/brief/SKILL.md +1 -1
- package/skills/compare/SKILL.md +1 -1
- package/skills/connections/SKILL.md +1 -1
- package/skills/darkmode/SKILL.md +1 -1
- package/skills/design/SKILL.md +1 -1
- package/skills/discover/SKILL.md +1 -1
- package/skills/do/SKILL.md +1 -1
- package/skills/explore/SKILL.md +1 -1
- package/skills/fast/SKILL.md +1 -1
- package/skills/health/SKILL.md +2 -2
- package/skills/live/SKILL.md +1 -1
- package/skills/new-skill/SKILL.md +90 -0
- package/skills/plan/SKILL.md +1 -1
- package/skills/progress/SKILL.md +9 -1
- package/skills/quick/SKILL.md +1 -1
- package/skills/scan/SKILL.md +1 -1
- package/skills/ship/SKILL.md +1 -1
- package/skills/verify/SKILL.md +1 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* scripts/lib/worktree-resolve.cjs — Phase 49 (Quick Anti-Slop Floor).
|
|
4
|
+
*
|
|
5
|
+
* Redirect `.design/` and `.planning/` writes to the MAIN repo root when GDD
|
|
6
|
+
* runs inside a git WORKTREE. A worktree has its own ephemeral checkout dir; a
|
|
7
|
+
* naive `process.cwd()`-relative `.design/STATE.md` write would land inside the
|
|
8
|
+
* throwaway worktree and get lost (or leak) when the worktree is removed. We
|
|
9
|
+
* detect the worktree, resolve the main repo root, and point artifact writes
|
|
10
|
+
* there so state survives across worktree lifecycles.
|
|
11
|
+
*
|
|
12
|
+
* Detection: `git rev-parse --git-dir` and `--git-common-dir` DIFFER inside a
|
|
13
|
+
* linked worktree (git-dir is `<main>/.git/worktrees/<name>`, common-dir is
|
|
14
|
+
* `<main>/.git`); in the main checkout they are EQUAL. The main repo root is the
|
|
15
|
+
* PARENT of the common git dir.
|
|
16
|
+
*
|
|
17
|
+
* Pure + dependency-free except for spawning `git`, and the `git` call is fully
|
|
18
|
+
* injectable via an `exec` parameter so tests run without a real worktree. NEVER
|
|
19
|
+
* throws: when git is unavailable (no repo, git not on PATH) every resolver
|
|
20
|
+
* degrades gracefully to the caller's `cwd`, so non-git consumers are unaffected.
|
|
21
|
+
*
|
|
22
|
+
* No top-level `Date.now()` / `Math.random()` — the only module-level mutable
|
|
23
|
+
* state is the one-shot `noticeOnce` flag, intentionally per-process.
|
|
24
|
+
*
|
|
25
|
+
* CommonJS so it ships in the npm package and loads from `.cjs` callers and the
|
|
26
|
+
* dual-mode `.ts`/`.js` MCP servers alike.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const { spawnSync } = require('node:child_process');
|
|
30
|
+
const path = require('node:path');
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Default `exec`: synchronously run `git <args...>` in `cwd` and return its
|
|
34
|
+
* trimmed stdout. Returns null on ANY failure (git missing, non-zero exit,
|
|
35
|
+
* not a repo) so callers can treat "no git" as "not a worktree".
|
|
36
|
+
*
|
|
37
|
+
* @param {string[]} args git arguments, e.g. ['rev-parse', '--git-dir']
|
|
38
|
+
* @param {string} cwd working directory to run git in
|
|
39
|
+
* @returns {string | null} trimmed stdout, or null on failure
|
|
40
|
+
*/
|
|
41
|
+
function defaultExec(args, cwd) {
|
|
42
|
+
try {
|
|
43
|
+
const res = spawnSync('git', args, {
|
|
44
|
+
cwd,
|
|
45
|
+
encoding: 'utf8',
|
|
46
|
+
windowsHide: true,
|
|
47
|
+
});
|
|
48
|
+
if (!res || res.status !== 0 || typeof res.stdout !== 'string') return null;
|
|
49
|
+
const out = res.stdout.trim();
|
|
50
|
+
return out.length ? out : null;
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Normalize an injectable `exec` into a uniform `(args, cwd) => string|null`.
|
|
58
|
+
*
|
|
59
|
+
* The injectable form callers/tests pass is `(cmd, args) => string` where `cmd`
|
|
60
|
+
* is the literal `'git'` and `args` is the argv array (matching the prompt
|
|
61
|
+
* contract). We adapt it here and swallow throws into null so a test exec that
|
|
62
|
+
* throws models "git unavailable" exactly like the real one returning null.
|
|
63
|
+
*
|
|
64
|
+
* @param {undefined | ((cmd: string, args: string[]) => string)} exec
|
|
65
|
+
* @param {string} cwd
|
|
66
|
+
* @returns {(args: string[]) => string | null}
|
|
67
|
+
*/
|
|
68
|
+
function makeRunner(exec, cwd) {
|
|
69
|
+
if (typeof exec === 'function') {
|
|
70
|
+
return (args) => {
|
|
71
|
+
try {
|
|
72
|
+
const out = exec('git', args);
|
|
73
|
+
if (typeof out !== 'string') return null;
|
|
74
|
+
const trimmed = out.trim();
|
|
75
|
+
return trimmed.length ? trimmed : null;
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return (args) => defaultExec(args, cwd);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Resolve the absolute git-dir and git-common-dir for `cwd`.
|
|
86
|
+
*
|
|
87
|
+
* `git rev-parse` prints these relative to `cwd` in some setups and absolute in
|
|
88
|
+
* others; we resolve both against `cwd` so comparison and parent-of logic is
|
|
89
|
+
* always done on absolute, normalized paths.
|
|
90
|
+
*
|
|
91
|
+
* @returns {{ gitDir: string, commonDir: string } | null} null when not a repo
|
|
92
|
+
*/
|
|
93
|
+
function gitDirs(run, cwd) {
|
|
94
|
+
const gitDirRaw = run(['rev-parse', '--git-dir']);
|
|
95
|
+
if (gitDirRaw == null) return null;
|
|
96
|
+
const commonDirRaw = run(['rev-parse', '--git-common-dir']);
|
|
97
|
+
if (commonDirRaw == null) return null;
|
|
98
|
+
const gitDir = path.resolve(cwd, gitDirRaw);
|
|
99
|
+
const commonDir = path.resolve(cwd, commonDirRaw);
|
|
100
|
+
return { gitDir, commonDir };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* True when `cwd` sits inside a linked git WORKTREE (git-dir !== git-common-dir).
|
|
105
|
+
* False in the main checkout, and false (degrade gracefully) when git is
|
|
106
|
+
* unavailable or `cwd` is not inside any repo.
|
|
107
|
+
*
|
|
108
|
+
* @param {string} [cwd=process.cwd()]
|
|
109
|
+
* @param {(cmd: string, args: string[]) => string} [exec] injectable git runner
|
|
110
|
+
* @returns {boolean}
|
|
111
|
+
*/
|
|
112
|
+
function isWorktree(cwd = process.cwd(), exec) {
|
|
113
|
+
const run = makeRunner(exec, cwd);
|
|
114
|
+
const dirs = gitDirs(run, cwd);
|
|
115
|
+
if (dirs == null) return false;
|
|
116
|
+
return dirs.gitDir !== dirs.commonDir;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Resolve the MAIN repo root for `cwd`.
|
|
121
|
+
*
|
|
122
|
+
* - In a worktree: the parent of the git-common-dir (`<main>/.git` -> `<main>`).
|
|
123
|
+
* - In the main checkout: the toplevel (`git rev-parse --show-toplevel`).
|
|
124
|
+
* - git unavailable / not a repo: falls back to `path.resolve(cwd)`.
|
|
125
|
+
*
|
|
126
|
+
* Never throws.
|
|
127
|
+
*
|
|
128
|
+
* @param {string} [cwd=process.cwd()]
|
|
129
|
+
* @param {(cmd: string, args: string[]) => string} [exec] injectable git runner
|
|
130
|
+
* @returns {string} absolute main repo root
|
|
131
|
+
*/
|
|
132
|
+
function resolveRepoRoot(cwd = process.cwd(), exec) {
|
|
133
|
+
const run = makeRunner(exec, cwd);
|
|
134
|
+
const dirs = gitDirs(run, cwd);
|
|
135
|
+
if (dirs == null) {
|
|
136
|
+
// Not a repo / git unavailable — degrade to cwd.
|
|
137
|
+
return path.resolve(cwd);
|
|
138
|
+
}
|
|
139
|
+
if (dirs.gitDir !== dirs.commonDir) {
|
|
140
|
+
// Worktree: the main repo root is the parent of the common `.git` dir.
|
|
141
|
+
// common-dir is typically `<main>/.git`; its dirname is `<main>`. Guard the
|
|
142
|
+
// (unusual) bare-repo case where common-dir has no `.git` basename by only
|
|
143
|
+
// climbing when the basename looks like a git dir.
|
|
144
|
+
const base = path.basename(dirs.commonDir);
|
|
145
|
+
if (base === '.git' || base.endsWith('.git')) {
|
|
146
|
+
return path.dirname(dirs.commonDir);
|
|
147
|
+
}
|
|
148
|
+
// Bare/relocated git dir: best effort — fall through to toplevel below.
|
|
149
|
+
}
|
|
150
|
+
// Main checkout (or odd common-dir shape): prefer the toplevel.
|
|
151
|
+
const top = run(['rev-parse', '--show-toplevel']);
|
|
152
|
+
if (top != null) return path.resolve(cwd, top);
|
|
153
|
+
// Last resort: parent of the git dir, else cwd.
|
|
154
|
+
const base = path.basename(dirs.commonDir);
|
|
155
|
+
if (base === '.git' || base.endsWith('.git')) return path.dirname(dirs.commonDir);
|
|
156
|
+
return path.resolve(cwd);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Absolute `.design` root in the MAIN repo (worktree-safe).
|
|
161
|
+
*
|
|
162
|
+
* @param {string} [cwd=process.cwd()]
|
|
163
|
+
* @param {(cmd: string, args: string[]) => string} [exec]
|
|
164
|
+
* @returns {string}
|
|
165
|
+
*/
|
|
166
|
+
function resolveDesignRoot(cwd = process.cwd(), exec) {
|
|
167
|
+
return path.join(resolveRepoRoot(cwd, exec), '.design');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Absolute `.planning` root in the MAIN repo (worktree-safe).
|
|
172
|
+
*
|
|
173
|
+
* @param {string} [cwd=process.cwd()]
|
|
174
|
+
* @param {(cmd: string, args: string[]) => string} [exec]
|
|
175
|
+
* @returns {string}
|
|
176
|
+
*/
|
|
177
|
+
function resolvePlanningRoot(cwd = process.cwd(), exec) {
|
|
178
|
+
return path.join(resolveRepoRoot(cwd, exec), '.planning');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** One-shot guard so the redirect notice prints at most once per process. */
|
|
182
|
+
let NOTICE_EMITTED = false;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Emit a single one-line stderr notice — exactly once per process — announcing
|
|
186
|
+
* that worktree redirection is in effect. Subsequent calls are no-ops, so a
|
|
187
|
+
* caller can invoke this freely on every redirect without spamming stderr.
|
|
188
|
+
*
|
|
189
|
+
* @param {string} targetRoot the resolved MAIN repo root writes are redirected to
|
|
190
|
+
* @param {(line: string) => void} [write] injectable sink (default process.stderr)
|
|
191
|
+
* @returns {boolean} true if THIS call emitted the notice, false if already emitted
|
|
192
|
+
*/
|
|
193
|
+
function noticeOnce(targetRoot, write) {
|
|
194
|
+
if (NOTICE_EMITTED) return false;
|
|
195
|
+
NOTICE_EMITTED = true;
|
|
196
|
+
const line = `worktree detected -> .design/.planning redirected to ${targetRoot}\n`;
|
|
197
|
+
try {
|
|
198
|
+
if (typeof write === 'function') {
|
|
199
|
+
write(line);
|
|
200
|
+
} else {
|
|
201
|
+
process.stderr.write(line);
|
|
202
|
+
}
|
|
203
|
+
} catch {
|
|
204
|
+
/* never let a logging failure break a write path */
|
|
205
|
+
}
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Test-only: reset the one-shot notice flag. Not part of the public contract. */
|
|
210
|
+
function _resetNoticeForTests() {
|
|
211
|
+
NOTICE_EMITTED = false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
module.exports = {
|
|
215
|
+
isWorktree,
|
|
216
|
+
resolveRepoRoot,
|
|
217
|
+
resolveDesignRoot,
|
|
218
|
+
resolvePlanningRoot,
|
|
219
|
+
noticeOnce,
|
|
220
|
+
_resetNoticeForTests,
|
|
221
|
+
};
|
|
@@ -35,7 +35,7 @@ __export(server_exports, {
|
|
|
35
35
|
runStdio: () => runStdio
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(server_exports);
|
|
38
|
-
var
|
|
38
|
+
var import_node_fs5 = require("node:fs");
|
|
39
39
|
var import_node_path3 = require("node:path");
|
|
40
40
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
41
41
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
@@ -1799,6 +1799,8 @@ async function transition(path2, toStage) {
|
|
|
1799
1799
|
|
|
1800
1800
|
// sdk/mcp/gdd-state/tools/shared.ts
|
|
1801
1801
|
var import_node_path2 = __toESM(require("node:path"));
|
|
1802
|
+
var import_node_fs4 = require("node:fs");
|
|
1803
|
+
var import_node_module2 = require("node:module");
|
|
1802
1804
|
|
|
1803
1805
|
// sdk/event-stream/index.ts
|
|
1804
1806
|
var import_node_os2 = require("node:os");
|
|
@@ -2012,9 +2014,40 @@ function getSessionId() {
|
|
|
2012
2014
|
if (CACHED_SESSION_ID === null) CACHED_SESSION_ID = makeSessionId();
|
|
2013
2015
|
return CACHED_SESSION_ID;
|
|
2014
2016
|
}
|
|
2017
|
+
function _findRepoRoot2() {
|
|
2018
|
+
let dir = process.cwd();
|
|
2019
|
+
for (let i = 0; i < 8; i++) {
|
|
2020
|
+
if ((0, import_node_fs4.existsSync)(import_node_path2.default.join(dir, "package.json"))) return dir;
|
|
2021
|
+
const parent = import_node_path2.default.dirname(dir);
|
|
2022
|
+
if (parent === dir) break;
|
|
2023
|
+
dir = parent;
|
|
2024
|
+
}
|
|
2025
|
+
return process.cwd();
|
|
2026
|
+
}
|
|
2027
|
+
var _worktree = (() => {
|
|
2028
|
+
try {
|
|
2029
|
+
const root = _findRepoRoot2();
|
|
2030
|
+
const candidate = import_node_path2.default.resolve(root, "scripts/lib/worktree-resolve.cjs");
|
|
2031
|
+
if (!(0, import_node_fs4.existsSync)(candidate)) return null;
|
|
2032
|
+
const req = (0, import_node_module2.createRequire)(import_node_path2.default.join(root, "package.json"));
|
|
2033
|
+
return req(candidate);
|
|
2034
|
+
} catch {
|
|
2035
|
+
return null;
|
|
2036
|
+
}
|
|
2037
|
+
})();
|
|
2015
2038
|
function resolveStatePath() {
|
|
2016
2039
|
const override = process.env["GDD_STATE_PATH"];
|
|
2017
2040
|
if (typeof override !== "string" || override.length === 0) {
|
|
2041
|
+
if (_worktree !== null) {
|
|
2042
|
+
try {
|
|
2043
|
+
const designRoot = _worktree.resolveDesignRoot();
|
|
2044
|
+
if (_worktree.isWorktree()) {
|
|
2045
|
+
_worktree.noticeOnce(import_node_path2.default.dirname(designRoot));
|
|
2046
|
+
}
|
|
2047
|
+
return import_node_path2.default.join(designRoot, "STATE.md");
|
|
2048
|
+
} catch {
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2018
2051
|
return ".design/STATE.md";
|
|
2019
2052
|
}
|
|
2020
2053
|
if (import_node_path2.default.isAbsolute(override)) {
|
|
@@ -2734,12 +2767,12 @@ function here() {
|
|
|
2734
2767
|
const entry = process.argv[1];
|
|
2735
2768
|
if (typeof entry === "string" && entry.length > 0) {
|
|
2736
2769
|
const entryDir = (0, import_node_path3.dirname)((0, import_node_path3.resolve)(entry));
|
|
2737
|
-
if ((0,
|
|
2770
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path3.join)(entryDir, "tools", "index.ts"))) {
|
|
2738
2771
|
return entryDir;
|
|
2739
2772
|
}
|
|
2740
2773
|
}
|
|
2741
2774
|
const candidate = (0, import_node_path3.resolve)(process.cwd(), expectedRel);
|
|
2742
|
-
if ((0,
|
|
2775
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path3.join)(candidate, "tools", "index.ts"))) {
|
|
2743
2776
|
return candidate;
|
|
2744
2777
|
}
|
|
2745
2778
|
return candidate;
|
|
@@ -2748,7 +2781,7 @@ function loadTools() {
|
|
|
2748
2781
|
const baseDir = here();
|
|
2749
2782
|
return TOOL_MODULES.map((m) => {
|
|
2750
2783
|
const absPath = (0, import_node_path3.join)(baseDir, "tools", m.schemaPath);
|
|
2751
|
-
const raw = (0,
|
|
2784
|
+
const raw = (0, import_node_fs5.readFileSync)(absPath, "utf8");
|
|
2752
2785
|
const parsed = JSON.parse(raw);
|
|
2753
2786
|
const rawInput = parsed.properties?.input;
|
|
2754
2787
|
const inputSchema = rawInput !== void 0 && typeof rawInput === "object" ? rawInput : { type: "object" };
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
// {success:false, error} — handlers never propagate exceptions."
|
|
13
13
|
|
|
14
14
|
import path from 'node:path';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
15
17
|
import {
|
|
16
18
|
ValidationError,
|
|
17
19
|
OperationFailedError,
|
|
@@ -50,6 +52,49 @@ export function getSessionId(): string {
|
|
|
50
52
|
return CACHED_SESSION_ID;
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Worktree redirect (Phase 49). When GDD runs inside a git WORKTREE, a naive
|
|
57
|
+
* `process.cwd()`-relative `.design/STATE.md` write lands in the ephemeral
|
|
58
|
+
* worktree and is lost when it is removed. `scripts/lib/worktree-resolve.cjs`
|
|
59
|
+
* resolves the MAIN repo root and points STATE writes there.
|
|
60
|
+
*
|
|
61
|
+
* Soft-loaded via createRequire (mirrors sdk/event-stream/writer.ts): tsc's
|
|
62
|
+
* Node16 module mode classifies this .ts as CJS output, so `import.meta` is
|
|
63
|
+
* unavailable — we anchor createRequire on the repo-root package.json found by
|
|
64
|
+
* walking up from cwd. If the helper is unreachable (a test subprocess running
|
|
65
|
+
* far above the plugin tree), every resolver degrades to a null shim and the
|
|
66
|
+
* default falls back to the legacy relative path. Production callers always run
|
|
67
|
+
* inside the plugin tree.
|
|
68
|
+
*/
|
|
69
|
+
interface WorktreeResolver {
|
|
70
|
+
resolveDesignRoot: (cwd?: string) => string;
|
|
71
|
+
isWorktree: (cwd?: string) => boolean;
|
|
72
|
+
noticeOnce: (targetRoot: string) => boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function _findRepoRoot(): string {
|
|
76
|
+
let dir = process.cwd();
|
|
77
|
+
for (let i = 0; i < 8; i++) {
|
|
78
|
+
if (existsSync(path.join(dir, 'package.json'))) return dir;
|
|
79
|
+
const parent = path.dirname(dir);
|
|
80
|
+
if (parent === dir) break;
|
|
81
|
+
dir = parent;
|
|
82
|
+
}
|
|
83
|
+
return process.cwd();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const _worktree: WorktreeResolver | null = (() => {
|
|
87
|
+
try {
|
|
88
|
+
const root = _findRepoRoot();
|
|
89
|
+
const candidate = path.resolve(root, 'scripts/lib/worktree-resolve.cjs');
|
|
90
|
+
if (!existsSync(candidate)) return null;
|
|
91
|
+
const req = createRequire(path.join(root, 'package.json'));
|
|
92
|
+
return req(candidate) as WorktreeResolver;
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
})();
|
|
97
|
+
|
|
53
98
|
/**
|
|
54
99
|
* Resolve the target STATE.md path from the environment, with a
|
|
55
100
|
* PATH-TRAVERSAL guard (Plan 33.5-03, D-08).
|
|
@@ -69,6 +114,22 @@ export function getSessionId(): string {
|
|
|
69
114
|
export function resolveStatePath(): string {
|
|
70
115
|
const override = process.env['GDD_STATE_PATH'];
|
|
71
116
|
if (typeof override !== 'string' || override.length === 0) {
|
|
117
|
+
// No override: resolve STATE.md under the worktree-aware `.design` root
|
|
118
|
+
// (Phase 49). Outside a worktree this equals the legacy `<cwd>/.design`
|
|
119
|
+
// (when cwd is the repo root) so behavior is unchanged; inside a worktree
|
|
120
|
+
// the design root points at the MAIN repo so state is not lost. The notice
|
|
121
|
+
// fires at most once per process, only on an actual worktree redirect.
|
|
122
|
+
if (_worktree !== null) {
|
|
123
|
+
try {
|
|
124
|
+
const designRoot = _worktree.resolveDesignRoot();
|
|
125
|
+
if (_worktree.isWorktree()) {
|
|
126
|
+
_worktree.noticeOnce(path.dirname(designRoot));
|
|
127
|
+
}
|
|
128
|
+
return path.join(designRoot, 'STATE.md');
|
|
129
|
+
} catch {
|
|
130
|
+
// Fall through to the legacy relative default on any resolver fault.
|
|
131
|
+
}
|
|
132
|
+
}
|
|
72
133
|
return '.design/STATE.md';
|
|
73
134
|
}
|
|
74
135
|
|
package/skills/audit/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-audit
|
|
3
|
-
description: "Run a design audit by spawning design-auditor, design-integration-checker, and (optionally) design-verifier + design-reflector agents, then printing a consolidated 6-pillar score summary. Use when the user wants to score the current design, retroactively verify a completed cycle, or quickly re-check after a fix."
|
|
3
|
+
description: "Run a design audit by spawning design-auditor, design-integration-checker, and (optionally) design-verifier + design-reflector agents, then printing a consolidated 6-pillar score summary. Use when the user wants to score the current design, retroactively verify a completed cycle, or quickly re-check after a fix. Activates for requests involving scoring an existing design, retroactively reviewing quality, or re-checking after a fix."
|
|
4
4
|
argument-hint: "[--retroactive] [--quick] [--no-reflect]"
|
|
5
5
|
tools: Read, Write, Task, Glob, Bash
|
|
6
6
|
---
|
package/skills/brief/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-brief
|
|
3
|
-
description: "Stage 1 of 5 design intake that captures problem statement, audience, constraints, success metrics, and scope into .design/BRIEF.md, and bootstraps .design/STATE.md if missing. Use when starting a new design cycle and before /gdd:explore."
|
|
3
|
+
description: "Stage 1 of 5 design intake that captures problem statement, audience, constraints, success metrics, and scope into .design/BRIEF.md, and bootstraps .design/STATE.md if missing. Use when starting a new design cycle and before /gdd:explore. Activates for requests involving capturing a problem statement, defining audience and constraints, or starting a new design brief."
|
|
4
4
|
argument-hint: "[--re-brief to redo intake on existing project]"
|
|
5
5
|
tools: Read, Write, AskUserQuestion, mcp__gdd_state__frontmatter_update, mcp__gdd_state__set_status, mcp__gdd_state__update_progress, mcp__gdd_state__get
|
|
6
6
|
---
|
package/skills/compare/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-compare
|
|
3
|
-
description: "Compute the delta between the `DESIGN.md` baseline (from scan) and the `DESIGN-VERIFICATION.md` result (from verify), reporting per-category score delta, anti-pattern delta (resolved vs new), must-have pass/fail change, and design drift (regressions without covering tasks in `DESIGN-PLAN.md`). Use after `verify` to measure whether a design pipeline cycle actually improved the design. Writes `.design/COMPARE-REPORT.md`."
|
|
3
|
+
description: "Compute the delta between the `DESIGN.md` baseline (from scan) and the `DESIGN-VERIFICATION.md` result (from verify), reporting per-category score delta, anti-pattern delta (resolved vs new), must-have pass/fail change, and design drift (regressions without covering tasks in `DESIGN-PLAN.md`). Use after `verify` to measure whether a design pipeline cycle actually improved the design. Writes `.design/COMPARE-REPORT.md`. Activates for requests involving diffing a design baseline against verification output, or a before-after design delta."
|
|
4
4
|
argument-hint: ""
|
|
5
5
|
user-invocable: true
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-connections
|
|
3
|
-
description: "Interactive onboarding wizard for the 33 external integrations the pipeline supports - probes all (`figma`, `refero`, `preview`, `storybook`, `chromatic`, `graphify`, `pinterest`, `claude-design`, `paper-design`, `pencil-dev`, `21st-dev`, `magic-patterns`, `lazyweb`, `mobbin`, `slack`, `discord`, `linear`, `jira`, `notion`, `lottie`, `rive`, `framer`, `penpot`, `webflow`, `v0-dev`, `plasmic`, `builder-io`, `launchdarkly`, `statsig`, `growthbook`, `usertesting`, `maze`, `hotjar`), recommends based on project type, walks the user through setup (auto-run MCP install or copy-command fallback), writes results to `STATE.md <connections>`. Use after `/gdd:new-project` or whenever the user wants to add, inspect, or skip a connection. Re-runnable anytime."
|
|
3
|
+
description: "Interactive onboarding wizard for the 33 external integrations the pipeline supports - probes all (`figma`, `refero`, `preview`, `storybook`, `chromatic`, `graphify`, `pinterest`, `claude-design`, `paper-design`, `pencil-dev`, `21st-dev`, `magic-patterns`, `lazyweb`, `mobbin`, `slack`, `discord`, `linear`, `jira`, `notion`, `lottie`, `rive`, `framer`, `penpot`, `webflow`, `v0-dev`, `plasmic`, `builder-io`, `launchdarkly`, `statsig`, `growthbook`, `usertesting`, `maze`, `hotjar`), recommends based on project type, walks the user through setup (auto-run MCP install or copy-command fallback), writes results to `STATE.md <connections>`. Use after `/gdd:new-project` or whenever the user wants to add, inspect, or skip a connection. Re-runnable anytime. Activates for requests involving setting up external integrations, probing Figma or preview or storybook, or onboarding tools."
|
|
4
4
|
argument-hint: "[list | <connection-name> | --auto]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, ToolSearch
|
package/skills/darkmode/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-darkmode
|
|
3
|
-
description: "Audit a project's dark mode implementation - detects architecture (CSS custom props, Tailwind `dark:` prefix, or JS class toggle), runs architecture-specific contrast / token-override / anti-pattern / meta-property checks, and writes a prioritized fix list to `.design/DARKMODE-AUDIT.md`. Use when the user wants to verify dark mode quality without re-running the full design pipeline. Read-only - no score writeback to `DESIGN.md`."
|
|
3
|
+
description: "Audit a project's dark mode implementation - detects architecture (CSS custom props, Tailwind `dark:` prefix, or JS class toggle), runs architecture-specific contrast / token-override / anti-pattern / meta-property checks, and writes a prioritized fix list to `.design/DARKMODE-AUDIT.md`. Use when the user wants to verify dark mode quality without re-running the full design pipeline. Read-only - no score writeback to `DESIGN.md`. Activates for requests involving auditing dark mode, checking dark-theme contrast, or dark-mode anti-patterns."
|
|
4
4
|
argument-hint: ""
|
|
5
5
|
user-invocable: true
|
|
6
6
|
---
|
package/skills/design/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design
|
|
3
|
-
description: "Stage 4 of 5 orchestrator that reads DESIGN-PLAN.md, partitions tasks by wave + parallel-safe flag, and spawns design-executor agents with the appropriate isolation (worktree for parallel batches, in-place for sequential tail). Use when DESIGN-PLAN.md is approved and ready for implementation."
|
|
3
|
+
description: "Stage 4 of 5 orchestrator that reads DESIGN-PLAN.md, partitions tasks by wave + parallel-safe flag, and spawns design-executor agents with the appropriate isolation (worktree for parallel batches, in-place for sequential tail). Use when DESIGN-PLAN.md is approved and ready for implementation. Activates for requests involving implementing UI, building components, or turning a plan into working interface code."
|
|
4
4
|
argument-hint: "[--auto] [--parallel] [--variants N]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
tools: Read, Write, Bash, Grep, Glob, Task, AskUserQuestion, mcp__gdd_state__get, mcp__gdd_state__transition_stage, mcp__gdd_state__update_progress, mcp__gdd_state__set_status, mcp__gdd_state__add_blocker, mcp__gdd_state__resolve_blocker, mcp__gdd_state__checkpoint
|
package/skills/discover/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: discover
|
|
3
|
-
description: "Stage 1.5 of 4 orchestrator that probes Figma / Refero / Pinterest connections, spawns design-context-builder (auto-detect + interview) and (via lazy gate) design-context-checker (6-dimension validator), producing .design/DESIGN-CONTEXT.md. Use after /gdd:scan when a fast-path context build is wanted instead of the full /gdd:explore."
|
|
3
|
+
description: "Stage 1.5 of 4 orchestrator that probes Figma / Refero / Pinterest connections, spawns design-context-builder (auto-detect + interview) and (via lazy gate) design-context-checker (6-dimension validator), producing .design/DESIGN-CONTEXT.md. Use after /gdd:scan when a fast-path context build is wanted instead of the full /gdd:explore. Activates for requests involving detecting an existing design system, inventorying tokens and components, or onboarding a brownfield repo."
|
|
4
4
|
argument-hint: "[--auto]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
---
|
package/skills/do/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-do
|
|
3
|
-
description: "Natural-language design task router. Parses your intent, maps to the right gdd command(s), confirms before executing."
|
|
3
|
+
description: "Natural-language design task router. Parses your intent, maps to the right gdd command(s), confirms before executing. Activates for requests involving a natural-language design request, routing intent to the right command, or not knowing which skill to use."
|
|
4
4
|
argument-hint: "<natural language description>"
|
|
5
5
|
tools: Read, Write, AskUserQuestion
|
|
6
6
|
---
|
package/skills/explore/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-explore
|
|
3
|
-
description: "Stage 2 of 5 - unified exploration merging inventory grep + design interview. Probes 6 connections, scans the codebase, conducts the AskUserQuestion interview, and writes .design/DESIGN.md + DESIGN-DEBT.md + DESIGN-CONTEXT.md. Use after /gdd:brief to map the existing system and lock decisions before planning."
|
|
3
|
+
description: "Stage 2 of 5 - unified exploration merging inventory grep + design interview. Probes 6 connections, scans the codebase, conducts the AskUserQuestion interview, and writes .design/DESIGN.md + DESIGN-DEBT.md + DESIGN-CONTEXT.md. Use after /gdd:brief to map the existing system and lock decisions before planning. Activates for requests involving researching design direction, gathering references, or exploring visual options."
|
|
4
4
|
argument-hint: "[--skip-interview] [--skip-scan]"
|
|
5
5
|
tools: Read, Write, Bash, Grep, Glob, Task, AskUserQuestion, mcp__gdd_state__get, mcp__gdd_state__transition_stage, mcp__gdd_state__probe_connections, mcp__gdd_state__update_progress, mcp__gdd_state__set_status, mcp__gdd_state__add_blocker, mcp__gdd_state__checkpoint, mcp__gdd_state__add_decision
|
|
6
6
|
---
|
package/skills/fast/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-fast
|
|
3
|
-
description: "Trivial inline design task. No subagents, no planning documents, no pipeline stages. Just do the thing described."
|
|
3
|
+
description: "Trivial inline design task. No subagents, no planning documents, no pipeline stages. Just do the thing described. Activates for requests involving a single quick design fix, a one-shot change, or a fast targeted edit."
|
|
4
4
|
argument-hint: "<task description>"
|
|
5
5
|
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
6
6
|
disable-model-invocation: true
|
package/skills/health/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-health
|
|
3
|
-
description: "Reports .design/ artifact health - staleness, missing files, token drift, broken state transitions."
|
|
3
|
+
description: "Reports .design/ artifact health - staleness, missing files, token drift, broken state transitions. Activates for requests involving checking .design artifact health, staleness, token drift, or broken state transitions."
|
|
4
4
|
tools: Read, Bash, Glob, Grep, mcp__gdd_state__get
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
---
|
|
@@ -90,7 +90,7 @@ After the health table, surface the Phase 28.5 skill-authoring contract drift si
|
|
|
90
90
|
- `Skill-length: <total> total | <clean> clean | <warnings> warn (>=100) | <blockers> block (>=250)`
|
|
91
91
|
- If blockers > 0: list each blocker as a row `- <name> (<lines> lines)`. Else: print `All skills within contract.`
|
|
92
92
|
|
|
93
|
-
Thresholds: warn >=100, block >=250 (D-01). Strict description-format off by default (D-02). See `./health-skill-length-report.md` for the JSON shape and threshold rationale.
|
|
93
|
+
Thresholds: warn >=100, block >=250 (D-01). Strict description-format off by default (D-02). Then add two compact Phase 50 lines from `scripts/lib/manifest/skills.json`: `Skills: <n>/<total> in v3 description form` (descriptions matching `/Activates for requests involving/i`) and `Composition: <edges> edges | <cycles> cycles` (`composes_with`/`next_skills` fan-out; cycles via `scripts/validate-composition-graph.cjs` when present, else `0`). See `./health-skill-length-report.md` for the JSON shape and threshold rationale.
|
|
94
94
|
|
|
95
95
|
## Do Not
|
|
96
96
|
|
package/skills/live/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-live
|
|
3
|
-
description: "Live in-browser design mode. The user picks a DOM element on a running dev server (via the Claude Preview MCP), the agent generates N design variants in one batch, they hot-swap in place through HMR or preview_eval using a data-gdd-variant marker, the user accepts or discards, and the whole pick-generate-accept loop persists to .design/live-sessions so it survives a crash or resume. Use when the user wants to iterate on the look of a live component against a real running server, asks to try variants on a page, or runs the live command with a url; falls back to a screenshot-only degraded mode on harnesses without MCP support."
|
|
3
|
+
description: "Live in-browser design mode. The user picks a DOM element on a running dev server (via the Claude Preview MCP), the agent generates N design variants in one batch, they hot-swap in place through HMR or preview_eval using a data-gdd-variant marker, the user accepts or discards, and the whole pick-generate-accept loop persists to .design/live-sessions so it survives a crash or resume. Use when the user wants to iterate on the look of a live component against a real running server, asks to try variants on a page, or runs the live command with a url; falls back to a screenshot-only degraded mode on harnesses without MCP support. Activates for requests involving in-browser design iteration, picking an element on a dev server, or generating variants with hot-swap."
|
|
4
4
|
argument-hint: "[--variants N] [--resume <session-id>] [url]"
|
|
5
5
|
tools: Read, Write, Edit, Bash, Glob, Grep, Task
|
|
6
6
|
user-invocable: true
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-new-skill
|
|
3
|
+
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 source/skills/<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."
|
|
4
|
+
argument-hint: "<skill-name>"
|
|
5
|
+
tools: Read, Write, Bash, AskUserQuestion
|
|
6
|
+
user-invocable: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /gdd:new-skill
|
|
10
|
+
|
|
11
|
+
**Role:** Interactively scaffold a contract-compliant skill. Gather the fields, then write `source/skills/<name>/SKILL.md` from the pure generator at `scripts/lib/manifest/scaffolder.cjs`. This skill writes ONE source file. It does NOT touch `scripts/lib/manifest/skills.json` and does NOT run the build; it prints the exact follow-up commands instead.
|
|
12
|
+
|
|
13
|
+
Read `reference/skill-authoring-contract.md` first for the length cap, the frontmatter required fields, and the v3 description form.
|
|
14
|
+
|
|
15
|
+
## Prompt strategy (clack with a fallback)
|
|
16
|
+
|
|
17
|
+
Mirror the installer pattern in `scripts/install.cjs`: try `@clack/prompts` lazily, and degrade to `AskUserQuestion` (or plain text) when it is absent. Use this probe at the start:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
node -e "try { require.resolve('@clack/prompts'); console.log('clack'); } catch { console.log('fallback'); }"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- `clack`: drive `clack.text`, `clack.select`, and `clack.confirm` from a short Node script.
|
|
24
|
+
- `fallback`: ask the same questions with `AskUserQuestion` (one prompt per field), or read plain answers.
|
|
25
|
+
|
|
26
|
+
Either way the answers feed the same record builder. Never block waiting on a TTY in a non-interactive run; fall back to `AskUserQuestion`.
|
|
27
|
+
|
|
28
|
+
## Step 1 - Gather the fields
|
|
29
|
+
|
|
30
|
+
1. **name**: the slug from `$ARGUMENTS` if present, else ask. Must match `^[a-z0-9][a-z0-9-._]*$`. Reject `source/skills/<name>/` collisions.
|
|
31
|
+
2. **description**: a multi-paragraph v3 form. Sentence one is what the skill does. Sentence two is `Use when <triggers>`. Sentence three is `Activates for requests involving <kw1>, <kw2>, <kw3>.` Keep it 20 to 1024 chars.
|
|
32
|
+
3. **lifecycle stage**: pick one of brief / explore / plan / verify / ship / figma / token / report (free text allowed). This seeds the composition suggestions.
|
|
33
|
+
4. **tools**: a comma list (for example `Read, Write, Bash`). Empty means inherit-all.
|
|
34
|
+
5. **composes_with**: auto-suggest neighbours, then confirm. Compute the suggestion list:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
node -e "
|
|
38
|
+
const s = require('./scripts/lib/manifest/scaffolder.cjs');
|
|
39
|
+
const m = require('./scripts/lib/manifest/skills.json');
|
|
40
|
+
console.log(JSON.stringify(s.suggestComposesWith(process.argv[1], m.skills)));
|
|
41
|
+
" "<name>"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Present the suggestions; let the user accept, edit, or clear them.
|
|
45
|
+
|
|
46
|
+
## Step 2 - Length pre-check
|
|
47
|
+
|
|
48
|
+
Before writing, estimate the body length. If the planned body would exceed about 100 lines, warn the user (the authoring contract warns at 100 and blocks at 250) and suggest extracting domain content into a co-located `source/skills/<name>/<topic>.md` reference. The generated skeleton is small; the warning is for the prose the user will add next.
|
|
49
|
+
|
|
50
|
+
## Step 3 - Write the file
|
|
51
|
+
|
|
52
|
+
Build the record and render the file with the pure generator, then write it with the Write tool (not shell redirection):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
node -e "
|
|
56
|
+
const s = require('./scripts/lib/manifest/scaffolder.cjs');
|
|
57
|
+
const rec = s.buildSkillRecord({
|
|
58
|
+
name: process.env.SK_NAME,
|
|
59
|
+
description: process.env.SK_DESC,
|
|
60
|
+
argumentHint: process.env.SK_HINT || undefined,
|
|
61
|
+
tools: process.env.SK_TOOLS || undefined,
|
|
62
|
+
userInvocable: process.env.SK_UI === 'true',
|
|
63
|
+
composesWith: (process.env.SK_COMPOSES || '').split(',').map(x => x.trim()).filter(Boolean),
|
|
64
|
+
});
|
|
65
|
+
process.stdout.write(s.renderSkillMd(rec));
|
|
66
|
+
"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`buildSkillRecord` throws on an invalid name, an out-of-budget description, or a malformed tools list. Surface the thrown message to the user and re-prompt the offending field. Capture stdout and write it verbatim to `source/skills/<name>/SKILL.md` via the Write tool.
|
|
70
|
+
|
|
71
|
+
## Step 4 - Tell the user the follow-up
|
|
72
|
+
|
|
73
|
+
The skill stops here by contract. Print the next two commands for the user to run after they add the manifest record:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
1. Add a record for "<name>" to scripts/lib/manifest/skills.json
|
|
77
|
+
(description, argument_hint, tools, user_invocable; put composes_with in extra_frontmatter).
|
|
78
|
+
2. npm run generate:skill-frontmatter && npm run build:skills
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Note that `npm run generate:skill-frontmatter:check` and the skills-coverage test stay red until the manifest record exists; that is expected and is the maintainer's step.
|
|
82
|
+
|
|
83
|
+
## Do Not
|
|
84
|
+
|
|
85
|
+
- Do not edit `scripts/lib/manifest/skills.json`, `package.json`, or any reference doc.
|
|
86
|
+
- Do not run `build:skills` or `generate:skill-frontmatter` for the user; print the commands.
|
|
87
|
+
- Do not write the SKILL.md with shell redirection; use the Write tool so the content is exact.
|
|
88
|
+
- Do not invent a description; require the v3 three-sentence form from the user.
|
|
89
|
+
|
|
90
|
+
## NEW-SKILL COMPLETE
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan
|
|
3
|
-
description: "Stage 3 of 5 orchestrator that reads DESIGN-CONTEXT.md, runs optional research (phase-researcher / pattern-mapper / assumptions-analyzer / synthesizer), spawns design-planner + design-plan-checker, and writes DESIGN-PLAN.md. Use when DESIGN-CONTEXT.md is locked and you need a wave-ordered execution plan."
|
|
3
|
+
description: "Stage 3 of 5 orchestrator that reads DESIGN-CONTEXT.md, runs optional research (phase-researcher / pattern-mapper / assumptions-analyzer / synthesizer), spawns design-planner + design-plan-checker, and writes DESIGN-PLAN.md. Use when DESIGN-CONTEXT.md is locked and you need a wave-ordered execution plan. Activates for requests involving breaking design work into steps, sequencing implementation, or planning a build."
|
|
4
4
|
argument-hint: "[--auto] [--parallel]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
tools: Read, Write, Bash, Glob, Task, AskUserQuestion, ToolSearch, mcp__gdd_state__get, mcp__gdd_state__transition_stage, mcp__gdd_state__add_decision, mcp__gdd_state__add_must_have, mcp__gdd_state__update_progress, mcp__gdd_state__set_status, mcp__gdd_state__add_blocker, mcp__gdd_state__checkpoint, mcp__gdd_state__probe_connections
|
package/skills/progress/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-progress
|
|
3
|
-
description: "Shows current pipeline position and routes to next action. --forensic runs 6-check integrity audit."
|
|
3
|
+
description: "Shows current pipeline position and routes to next action. --forensic runs 6-check integrity audit. Activates for requests involving showing current project state, routing to the next action, or a status check."
|
|
4
4
|
argument-hint: "[--forensic]"
|
|
5
5
|
tools: Read, Bash, Grep, Glob, mcp__gdd_state__get, mcp__gdd_status, mcp__gdd_phase_current
|
|
6
6
|
---
|
|
@@ -78,6 +78,14 @@ Seeds ready: 0
|
|
|
78
78
|
━━━━━━━━━━━━━━━━━━━━━━
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
## Step 3.5 - Composition-graph readiness
|
|
82
|
+
|
|
83
|
+
After the pipeline state (and forensic audit if run), surface a one-line composition-graph hint from `scripts/lib/manifest/skills.json`. Count skill records declaring `composes_with` or `next_skills`, then probe for structural problems (cycles in the directed graph, or edges pointing at a skill name that has no record). Print one line:
|
|
84
|
+
|
|
85
|
+
- `Composition graph: <edges> edges, <skills-with-edges> skills wired | cycles: <n> | dangling: <n>`
|
|
86
|
+
|
|
87
|
+
Run `scripts/validate-composition-graph.cjs` for the authoritative cycle and dangling-edge counts when that validator is present; until then report `0` and note the graph is not yet wired. This is a readiness hint, not a gate.
|
|
88
|
+
|
|
81
89
|
## Step 4 - Update notice (safe-window surface)
|
|
82
90
|
|
|
83
91
|
After printing the pipeline state, emit the plugin-update banner if one is present. This file is written by `hooks/update-check.sh` subject to the state-machine guard (mid-pipeline stages suppress it) and per-version dismissal.
|
package/skills/quick/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-quick
|
|
3
|
-
description: "Run the pipeline with optional agents skipped for speed. Skips: phase-researcher, design-assumptions-analyzer, design-integration-checker. Keeps: planner, executor, verifier, auditor."
|
|
3
|
+
description: "Run the pipeline with optional agents skipped for speed. Skips: phase-researcher, design-assumptions-analyzer, design-integration-checker. Keeps: planner, executor, verifier, auditor. Activates for requests involving a lightweight design pass, a fast iteration, or a quick low-ceremony change."
|
|
4
4
|
argument-hint: "[--skip <agent-name>] [stage]"
|
|
5
5
|
tools: Read, Task
|
|
6
6
|
disable-model-invocation: true
|