@opengsd/gsd-core 1.6.0-rc.2 → 1.6.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/plugin.json +2 -1
- package/agents/gsd-advisor-researcher.md +2 -0
- package/agents/gsd-ai-researcher.md +2 -0
- package/agents/gsd-assumptions-analyzer.md +2 -0
- package/agents/gsd-doc-classifier.md +2 -0
- package/agents/gsd-doc-synthesizer.md +2 -0
- package/agents/gsd-domain-researcher.md +2 -0
- package/agents/gsd-eval-auditor.md +6 -9
- package/agents/gsd-phase-researcher.md +2 -0
- package/agents/gsd-planner.md +8 -57
- package/agents/gsd-project-researcher.md +2 -0
- package/agents/gsd-research-synthesizer.md +2 -0
- package/agents/gsd-security-auditor.md +37 -18
- package/agents/gsd-ui-researcher.md +2 -0
- package/bin/install.js +370 -18
- package/gemini-extension.json +1 -1
- package/gsd-core/bin/gsd-tools.cjs +46 -4
- package/gsd-core/bin/lib/audit-command-router.cjs +52 -14
- package/gsd-core/bin/lib/capability-lifecycle.cjs +30 -7
- package/gsd-core/bin/lib/capability-registry.cjs +96 -83
- package/gsd-core/bin/lib/capability-validator.cjs +22 -0
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +40 -2
- package/gsd-core/bin/lib/command-aliases.cjs +10 -1
- package/gsd-core/bin/lib/command-routing-hub.cjs +10 -3
- package/gsd-core/bin/lib/config-schema.cjs +1 -0
- package/gsd-core/bin/lib/config.cjs +67 -24
- package/gsd-core/bin/lib/coverage.cjs +464 -0
- package/gsd-core/bin/lib/decisions.cjs +27 -0
- package/gsd-core/bin/lib/eval-command-router.cjs +21 -0
- package/gsd-core/bin/lib/eval.cjs +60 -0
- package/gsd-core/bin/lib/frontmatter.cjs +132 -13
- package/gsd-core/bin/lib/graphify-command-router.cjs +53 -36
- package/gsd-core/bin/lib/init.cjs +139 -30
- package/gsd-core/bin/lib/install-profiles.cjs +6 -3
- package/gsd-core/bin/lib/intel-command-router.cjs +79 -60
- package/gsd-core/bin/lib/io.cjs +1 -0
- package/gsd-core/bin/lib/phase.cjs +16 -2
- package/gsd-core/bin/lib/plan-scan.cjs +2 -2
- package/gsd-core/bin/lib/planning-workspace.cjs +157 -13
- package/gsd-core/bin/lib/profile-output.cjs +18 -6
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +53 -16
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +21 -3
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +15 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +47 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +10 -0
- package/gsd-core/bin/lib/state.cjs +398 -60
- package/gsd-core/bin/lib/surface.cjs +42 -10
- package/gsd-core/bin/lib/uat-predicate.cjs +13 -6
- package/gsd-core/bin/lib/update-context.cjs +2 -2
- package/gsd-core/bin/lib/verification.cjs +67 -6
- package/gsd-core/bin/lib/verify.cjs +8 -1
- package/gsd-core/bin/shared/config-defaults.manifest.json +3 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +2 -1
- package/gsd-core/references/planner-guidance.md +66 -0
- package/gsd-core/references/planning-config.md +2 -2
- package/gsd-core/references/security-asvs-levels.md +27 -0
- package/gsd-core/references/untrusted-input-boundary.md +13 -0
- package/gsd-core/templates/SECURITY.md +6 -4
- package/gsd-core/templates/summary-complex.md +4 -0
- package/gsd-core/templates/summary-minimal.md +3 -0
- package/gsd-core/templates/summary-standard.md +4 -0
- package/gsd-core/templates/summary.md +41 -0
- package/gsd-core/workflows/autonomous.md +53 -46
- package/gsd-core/workflows/complete-milestone.md +27 -8
- package/gsd-core/workflows/execute-phase.md +1 -1
- package/gsd-core/workflows/execute-plan.md +5 -0
- package/gsd-core/workflows/manager.md +17 -7
- package/gsd-core/workflows/new-project.md +82 -16
- package/gsd-core/workflows/plan-phase.md +15 -0
- package/gsd-core/workflows/profile-user.md +6 -2
- package/gsd-core/workflows/progress.md +37 -4
- package/gsd-core/workflows/quick.md +3 -1
- package/gsd-core/workflows/secure-phase.md +13 -7
- package/gsd-core/workflows/ship.md +3 -1
- package/gsd-core/workflows/spec-phase.md +3 -1
- package/gsd-core/workflows/transition.md +14 -12
- package/gsd-core/workflows/ui-review.md +2 -6
- package/gsd-core/workflows/verify-work.md +74 -1
- package/hooks/dist/gsd-read-injection-scanner.js +49 -25
- package/hooks/gsd-read-injection-scanner.js +49 -25
- package/hooks/hooks.json +1 -1
- package/package.json +4 -2
- package/scripts/check-alias-drift.cjs +5 -0
- package/scripts/gen-plugin-skills.cjs +117 -0
- package/scripts/lint-test-file-count.allowlist.json +2 -1
- package/scripts/prompt-injection-scan.sh +9 -0
- package/scripts/release-notes/conventional-title.cjs +88 -0
- package/scripts/release-notes/format-github-release-notes.cjs +4 -3
- package/skills/gsd-add-tests/SKILL.md +38 -0
- package/skills/gsd-ai-integration-phase/SKILL.md +37 -0
- package/skills/gsd-audit-fix/SKILL.md +33 -0
- package/skills/gsd-audit-milestone/SKILL.md +37 -0
- package/skills/gsd-audit-uat/SKILL.md +25 -0
- package/skills/gsd-autonomous/SKILL.md +51 -0
- package/skills/gsd-capture/SKILL.md +67 -0
- package/skills/gsd-cleanup/SKILL.md +24 -0
- package/skills/gsd-code-review/SKILL.md +59 -0
- package/skills/gsd-complete-milestone/SKILL.md +142 -0
- package/skills/gsd-config/SKILL.md +56 -0
- package/skills/gsd-debug/SKILL.md +53 -0
- package/skills/gsd-discuss-phase/SKILL.md +77 -0
- package/skills/gsd-docs-update/SKILL.md +49 -0
- package/skills/gsd-eval-review/SKILL.md +33 -0
- package/skills/gsd-execute-phase/SKILL.md +65 -0
- package/skills/gsd-explore/SKILL.md +28 -0
- package/skills/gsd-extract-learnings/SKILL.md +22 -0
- package/skills/gsd-fast/SKILL.md +31 -0
- package/skills/gsd-forensics/SKILL.md +56 -0
- package/skills/gsd-graphify/SKILL.md +204 -0
- package/skills/gsd-health/SKILL.md +31 -0
- package/skills/gsd-help/SKILL.md +29 -0
- package/skills/gsd-import/SKILL.md +46 -0
- package/skills/gsd-inbox/SKILL.md +39 -0
- package/skills/gsd-ingest-docs/SKILL.md +43 -0
- package/skills/gsd-manager/SKILL.md +45 -0
- package/skills/gsd-map-codebase/SKILL.md +83 -0
- package/skills/gsd-mempalace-capture/SKILL.md +71 -0
- package/skills/gsd-mempalace-recall/SKILL.md +102 -0
- package/skills/gsd-milestone-summary/SKILL.md +51 -0
- package/skills/gsd-mvp-phase/SKILL.md +45 -0
- package/skills/gsd-new-milestone/SKILL.md +45 -0
- package/skills/gsd-new-project/SKILL.md +47 -0
- package/skills/gsd-ns-context/SKILL.md +24 -0
- package/skills/gsd-ns-ideate/SKILL.md +23 -0
- package/skills/gsd-ns-manage/SKILL.md +35 -0
- package/skills/gsd-ns-project/SKILL.md +26 -0
- package/skills/gsd-ns-review/SKILL.md +28 -0
- package/skills/gsd-ns-workflow/SKILL.md +33 -0
- package/skills/gsd-pause-work/SKILL.md +43 -0
- package/skills/gsd-phase/SKILL.md +57 -0
- package/skills/gsd-plan-phase/SKILL.md +63 -0
- package/skills/gsd-plan-review-convergence/SKILL.md +60 -0
- package/skills/gsd-pr-branch/SKILL.md +26 -0
- package/skills/gsd-profile-user/SKILL.md +47 -0
- package/skills/gsd-progress/SKILL.md +49 -0
- package/skills/gsd-quick/SKILL.md +174 -0
- package/skills/gsd-resume-work/SKILL.md +31 -0
- package/skills/gsd-review/SKILL.md +42 -0
- package/skills/gsd-review-backlog/SKILL.md +63 -0
- package/skills/gsd-secure-phase/SKILL.md +36 -0
- package/skills/gsd-settings/SKILL.md +29 -0
- package/skills/gsd-ship/SKILL.md +24 -0
- package/skills/gsd-sketch/SKILL.md +60 -0
- package/skills/gsd-spec-phase/SKILL.md +63 -0
- package/skills/gsd-spike/SKILL.md +57 -0
- package/skills/gsd-stats/SKILL.md +20 -0
- package/skills/gsd-surface/SKILL.md +162 -0
- package/skills/gsd-thread/SKILL.md +24 -0
- package/skills/gsd-ui-phase/SKILL.md +35 -0
- package/skills/gsd-ui-review/SKILL.md +33 -0
- package/skills/gsd-ultraplan-phase/SKILL.md +34 -0
- package/skills/gsd-undo/SKILL.md +35 -0
- package/skills/gsd-update/SKILL.md +50 -0
- package/skills/gsd-validate-phase/SKILL.md +36 -0
- package/skills/gsd-verify-work/SKILL.md +39 -0
- package/skills/gsd-workspace/SKILL.md +53 -0
- package/skills/gsd-workstreams/SKILL.md +70 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* gen-plugin-skills.cjs — generates skills/gsd-<stem>/SKILL.md from
|
|
6
|
+
* commands/gsd/*.md using convertClaudeCommandToClaudeSkill.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node scripts/gen-plugin-skills.cjs # print summary to stdout
|
|
10
|
+
* node scripts/gen-plugin-skills.cjs --write # write skills/ dir
|
|
11
|
+
* node scripts/gen-plugin-skills.cjs --check # exit 1 if committed skills/ is stale
|
|
12
|
+
*
|
|
13
|
+
* #1596 Phase B-provide. The Claude Code plugin contract discovers skills from
|
|
14
|
+
* a skills/ directory (plugins-reference). GSD's source-of-truth commands live
|
|
15
|
+
* in commands/gsd/*.md (command frontmatter); this script converts each to
|
|
16
|
+
* skill format using the same convertClaudeCommandToClaudeSkill the file-copy
|
|
17
|
+
* installer uses, producing a build-generated skills/ dir that ships in the
|
|
18
|
+
* npm package and serves plugin-only installs.
|
|
19
|
+
*
|
|
20
|
+
* Depends on: gsd-core/bin/lib/runtime-artifact-conversion.cjs (compiled from
|
|
21
|
+
* src/runtime-artifact-conversion.cts by `npm run build:lib`). Must run AFTER
|
|
22
|
+
* build:lib in the build chain.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const fs = require('node:fs');
|
|
26
|
+
const path = require('node:path');
|
|
27
|
+
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
|
28
|
+
|
|
29
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
30
|
+
const COMMANDS_DIR = path.join(ROOT, 'commands', 'gsd');
|
|
31
|
+
const SKILLS_DIR = path.join(ROOT, 'skills');
|
|
32
|
+
const CONVERSION_MODULE = path.join(ROOT, 'gsd-core', 'bin', 'lib', 'runtime-artifact-conversion.cjs');
|
|
33
|
+
const PREFIX = 'gsd-';
|
|
34
|
+
const RUNTIME = 'claude';
|
|
35
|
+
|
|
36
|
+
function generateSkills(conversion) {
|
|
37
|
+
const cmdNames = conversion.readGsdCommandNames();
|
|
38
|
+
const files = fs.readdirSync(COMMANDS_DIR).filter(f => f.endsWith('.md'));
|
|
39
|
+
const results = [];
|
|
40
|
+
for (const file of files) {
|
|
41
|
+
const stem = file.slice(0, -3);
|
|
42
|
+
const skillName = PREFIX + stem;
|
|
43
|
+
const src = fs.readFileSync(path.join(COMMANDS_DIR, file), 'utf8');
|
|
44
|
+
const converted = conversion.convertClaudeCommandToClaudeSkill(src, skillName, RUNTIME, cmdNames, true);
|
|
45
|
+
results.push({ skillName, content: converted });
|
|
46
|
+
}
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function main() {
|
|
51
|
+
const args = new Set(process.argv.slice(2));
|
|
52
|
+
const WRITE = args.has('--write');
|
|
53
|
+
const CHECK = args.has('--check');
|
|
54
|
+
|
|
55
|
+
if (!fs.existsSync(CONVERSION_MODULE)) {
|
|
56
|
+
throw new ExitError(
|
|
57
|
+
1,
|
|
58
|
+
`gen-plugin-skills: ${path.relative(ROOT, CONVERSION_MODULE)} not found.\n` +
|
|
59
|
+
'Run `npm run build:lib` first (this script depends on the compiled converter).'
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const conversion = require(CONVERSION_MODULE);
|
|
63
|
+
const results = generateSkills(conversion);
|
|
64
|
+
|
|
65
|
+
if (WRITE) {
|
|
66
|
+
fs.rmSync(SKILLS_DIR, { recursive: true, force: true });
|
|
67
|
+
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
68
|
+
for (const { skillName, content } of results) {
|
|
69
|
+
const skillDir = path.join(SKILLS_DIR, skillName);
|
|
70
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
71
|
+
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), content);
|
|
72
|
+
}
|
|
73
|
+
process.stdout.write(`gen-plugin-skills: wrote ${results.length} skills to ${path.relative(ROOT, SKILLS_DIR)}/\n`);
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (CHECK) {
|
|
78
|
+
if (!fs.existsSync(SKILLS_DIR)) {
|
|
79
|
+
throw new ExitError(1, 'gen-plugin-skills: skills/ missing. Run: npm run gen:plugin-skills -- --write');
|
|
80
|
+
}
|
|
81
|
+
let stale = 0;
|
|
82
|
+
const expectedNames = new Set(results.map(r => r.skillName));
|
|
83
|
+
for (const { skillName, content } of results) {
|
|
84
|
+
const skillMd = path.join(SKILLS_DIR, skillName, 'SKILL.md');
|
|
85
|
+
if (!fs.existsSync(skillMd)) {
|
|
86
|
+
process.stderr.write(`gen-plugin-skills: missing ${path.relative(ROOT, skillMd)}\n`);
|
|
87
|
+
stale++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (fs.readFileSync(skillMd, 'utf8') !== content) {
|
|
91
|
+
process.stderr.write(`gen-plugin-skills: stale ${path.relative(ROOT, skillMd)}\n`);
|
|
92
|
+
stale++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const existingDirs = fs.readdirSync(SKILLS_DIR, { withFileTypes: true })
|
|
96
|
+
.filter(e => e.isDirectory() && e.name.startsWith(PREFIX));
|
|
97
|
+
for (const dir of existingDirs) {
|
|
98
|
+
if (!expectedNames.has(dir.name)) {
|
|
99
|
+
process.stderr.write(`gen-plugin-skills: stale (no source) ${path.relative(ROOT, path.join(SKILLS_DIR, dir.name))}\n`);
|
|
100
|
+
stale++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (stale > 0) {
|
|
104
|
+
throw new ExitError(1, `gen-plugin-skills: ${stale} stale skill(s). Run: npm run gen:plugin-skills -- --write`);
|
|
105
|
+
}
|
|
106
|
+
process.stdout.write(`gen-plugin-skills: ${results.length} skills up to date\n`);
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
process.stdout.write(
|
|
111
|
+
`gen-plugin-skills: would write ${results.length} skills to ${path.relative(ROOT, SKILLS_DIR)}/\n` +
|
|
112
|
+
' (use --write to generate, --check to verify staleness)\n'
|
|
113
|
+
);
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
runMain(main);
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"config-get-default.test.cjs",
|
|
22
22
|
"config-schema.property.test.cjs",
|
|
23
23
|
"config.test.cjs",
|
|
24
|
-
"enh-1055-config-intent-descriptor-drive.test.cjs"
|
|
24
|
+
"enh-1055-config-intent-descriptor-drive.test.cjs",
|
|
25
|
+
"fix-1628-config-set-validation.test.cjs"
|
|
25
26
|
],
|
|
26
27
|
"issue": "TBD"
|
|
27
28
|
},
|
|
@@ -77,6 +77,7 @@ ALLOWLIST=(
|
|
|
77
77
|
'hooks/gsd-prompt-guard.js'
|
|
78
78
|
'hooks/gsd-read-injection-scanner.js'
|
|
79
79
|
'tests/read-injection-scanner.security.test.cjs'
|
|
80
|
+
'tests/read-injection-scanner.property.test.cjs'
|
|
80
81
|
'tests/security-prompt-injection.security.test.cjs'
|
|
81
82
|
'tests/list-seeds.test.cjs'
|
|
82
83
|
'tests/fixtures/adversarial/security/'
|
|
@@ -85,6 +86,14 @@ ALLOWLIST=(
|
|
|
85
86
|
# and are not attack vectors — they explain/demonstrate injection patterns.
|
|
86
87
|
'TEST-EXAMPLES.md'
|
|
87
88
|
'explanation/security-model.md'
|
|
89
|
+
# The untrusted-input boundary reference quotes injection phrases
|
|
90
|
+
# ("ignore previous instructions", "you are now…") as examples agents must
|
|
91
|
+
# NOT comply with — it is the defense, not an attack vector.
|
|
92
|
+
'references/untrusted-input-boundary.md'
|
|
93
|
+
# Security regression tests for input validators — fixtures must contain
|
|
94
|
+
# real injection payloads to prove the validator rejects them. See
|
|
95
|
+
# DEFECT.PROMPT-INJECTION-SCAN-COLLISION in CONTEXT.md.
|
|
96
|
+
'tests/windsurf-conversion.test.cjs'
|
|
88
97
|
)
|
|
89
98
|
|
|
90
99
|
is_allowlisted() {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Single source of truth for conventional-commit PR-title parsing.
|
|
5
|
+
*
|
|
6
|
+
* Consumed by BOTH:
|
|
7
|
+
* - the release-notes changelog classifier
|
|
8
|
+
* (scripts/release-notes/format-github-release-notes.cjs), and
|
|
9
|
+
* - the PR-title CI gate (.github/workflows/pr-title-validator.yml, via
|
|
10
|
+
* evaluatePrTitle).
|
|
11
|
+
*
|
|
12
|
+
* Keeping one matcher here is the point of #1549: a forked copy of the regex
|
|
13
|
+
* would let the gate accept a title that the changelog then mis-buckets. Both
|
|
14
|
+
* the bucket anchors and the gate must read the title the same way.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Bucket anchors. The leading `^` is load-bearing: the changelog buckets on the
|
|
18
|
+
// type at the START of the title. Anything before it (e.g. a `[security] ` tag)
|
|
19
|
+
// defeats the anchor and silently mis-files the entry — which is exactly the
|
|
20
|
+
// drift the PR-title gate below rejects at open time.
|
|
21
|
+
const FEATURE_RE = /^feat(?:ure)?\s*(?:\(|!|:)/i;
|
|
22
|
+
const FIX_RE = /^fix\s*(?:\(|!|:)/i;
|
|
23
|
+
|
|
24
|
+
// A well-formed conventional header at the START of the title:
|
|
25
|
+
// <type>[(<scope>)][!]:
|
|
26
|
+
// e.g. `fix(#1542):`, `feat(#39)!:`, `fix:`, `enhance(verify-phase):`.
|
|
27
|
+
// Anchored with `^` so a leading tag/prefix fails to match (no `bad-prefix`).
|
|
28
|
+
const HEADER_RE = /^([a-z]+)(\([^)]*\))?(!)?:/i;
|
|
29
|
+
|
|
30
|
+
// An issue reference inside a scope: `(#123)`, `(#123, core)`, etc.
|
|
31
|
+
const ISSUE_REF_IN_SCOPE_RE = /#\d+/;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Classify a clean conventional title into a changelog bucket.
|
|
35
|
+
* Callers that hold a full changelog bullet line (with a `* ` marker and a
|
|
36
|
+
* ` by @author` suffix) must strip those first; this operates on the title.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} title
|
|
39
|
+
* @returns {'Feature'|'Fix'|'Enhancement'}
|
|
40
|
+
*/
|
|
41
|
+
function classifyBucket(title) {
|
|
42
|
+
const t = String(title == null ? '' : title).trim();
|
|
43
|
+
if (FEATURE_RE.test(t)) return 'Feature';
|
|
44
|
+
if (FIX_RE.test(t)) return 'Fix';
|
|
45
|
+
return 'Enhancement';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const REQUIRED_FORMAT_MESSAGE = [
|
|
49
|
+
'PR title must follow `type(#<issue>): summary`.',
|
|
50
|
+
'The type must come first (no leading tags like `[security]`) and the scope',
|
|
51
|
+
'must carry the linked issue ref so the release changelog links to it.',
|
|
52
|
+
'Examples: `fix(#1542): roadmap rollback`, `feat(#39)!: drop legacy flag`,',
|
|
53
|
+
'`enhance(#1549): add PR-title validator`.',
|
|
54
|
+
].join(' ');
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Validate a PR title against the convention the changelog depends on (#1549).
|
|
58
|
+
*
|
|
59
|
+
* @param {{ title?: string }} input
|
|
60
|
+
* @returns {{ valid: true, reason: 'valid' }
|
|
61
|
+
* | { valid: false, reason: 'bad-prefix'|'missing-issue-ref', message: string }}
|
|
62
|
+
*/
|
|
63
|
+
function evaluatePrTitle({ title } = {}) {
|
|
64
|
+
const t = String(title == null ? '' : title).trim();
|
|
65
|
+
|
|
66
|
+
const m = HEADER_RE.exec(t);
|
|
67
|
+
if (!m) {
|
|
68
|
+
// No clean `type[(scope)][!]:` at the start — covers leading tags,
|
|
69
|
+
// `Revert "..."`, empty, and freeform titles.
|
|
70
|
+
return { valid: false, reason: 'bad-prefix', message: REQUIRED_FORMAT_MESSAGE };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const scope = m[2]; // includes the parens, e.g. "(#1542)" — or undefined
|
|
74
|
+
if (!scope || !ISSUE_REF_IN_SCOPE_RE.test(scope)) {
|
|
75
|
+
return { valid: false, reason: 'missing-issue-ref', message: REQUIRED_FORMAT_MESSAGE };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { valid: true, reason: 'valid' };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = {
|
|
82
|
+
FEATURE_RE,
|
|
83
|
+
FIX_RE,
|
|
84
|
+
HEADER_RE,
|
|
85
|
+
classifyBucket,
|
|
86
|
+
evaluatePrTitle,
|
|
87
|
+
REQUIRED_FORMAT_MESSAGE,
|
|
88
|
+
};
|
|
@@ -5,6 +5,7 @@ const os = require('os');
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const { execFileSync } = require('child_process');
|
|
7
7
|
const { runMain, ExitError } = require('../lib/cli-exit.cjs');
|
|
8
|
+
const { classifyBucket } = require('./conventional-title.cjs');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Classify a What's-Changed bullet line into 'Feature', 'Fix', or 'Enhancement'.
|
|
@@ -19,9 +20,9 @@ function classifyTitle(bulletLine) {
|
|
|
19
20
|
const byIdx = withoutMarker.indexOf(' by @');
|
|
20
21
|
const title = (byIdx !== -1 ? withoutMarker.slice(0, byIdx) : withoutMarker).trim();
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return
|
|
23
|
+
// Delegate to the shared matcher so the gate and the changelog can never
|
|
24
|
+
// disagree on bucketing (#1549 — single source of truth).
|
|
25
|
+
return classifyBucket(title);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-add-tests
|
|
3
|
+
description: "Generate tests for a completed phase based on UAT criteria and implementation"
|
|
4
|
+
argument-hint: "<phase> [additional instructions]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Bash
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
- Agent
|
|
13
|
+
- AskUserQuestion
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<objective>
|
|
17
|
+
Generate unit and E2E tests for a completed phase, using its SUMMARY.md, CONTEXT.md, and VERIFICATION.md as specifications.
|
|
18
|
+
|
|
19
|
+
Analyzes implementation files, classifies them into TDD (unit), E2E (browser), or Skip categories, presents a test plan for user approval, then generates tests following RED-GREEN conventions.
|
|
20
|
+
|
|
21
|
+
Output: Test files committed with message `test(phase-{N}): add unit and E2E tests from add-tests command`
|
|
22
|
+
</objective>
|
|
23
|
+
|
|
24
|
+
<execution_context>
|
|
25
|
+
@~/.claude/gsd-core/workflows/add-tests.md
|
|
26
|
+
</execution_context>
|
|
27
|
+
|
|
28
|
+
<context>
|
|
29
|
+
Phase: $ARGUMENTS
|
|
30
|
+
|
|
31
|
+
@.planning/STATE.md
|
|
32
|
+
@.planning/ROADMAP.md
|
|
33
|
+
</context>
|
|
34
|
+
|
|
35
|
+
<process>
|
|
36
|
+
Execute end-to-end.
|
|
37
|
+
Preserve all workflow gates (classification approval, test plan approval, RED-GREEN verification, gap reporting).
|
|
38
|
+
</process>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-ai-integration-phase
|
|
3
|
+
description: "Generate an AI-SPEC.md design contract for phases that involve building AI systems."
|
|
4
|
+
argument-hint: "[phase number]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Bash
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- Agent
|
|
12
|
+
- WebFetch
|
|
13
|
+
- WebSearch
|
|
14
|
+
- AskUserQuestion
|
|
15
|
+
- mcp__context7__*
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<objective>
|
|
19
|
+
Create an AI design contract (AI-SPEC.md) for a phase involving AI system development.
|
|
20
|
+
Orchestrates gsd-framework-selector → gsd-ai-researcher → gsd-domain-researcher → gsd-eval-planner.
|
|
21
|
+
Flow: Select Framework → Research Docs → Research Domain → Design Eval Strategy → Done
|
|
22
|
+
</objective>
|
|
23
|
+
|
|
24
|
+
<execution_context>
|
|
25
|
+
@~/.claude/gsd-core/workflows/ai-integration-phase.md
|
|
26
|
+
@~/.claude/gsd-core/references/ai-frameworks.md
|
|
27
|
+
@~/.claude/gsd-core/references/ai-evals.md
|
|
28
|
+
</execution_context>
|
|
29
|
+
|
|
30
|
+
<context>
|
|
31
|
+
Phase number: $ARGUMENTS — optional, auto-detects next unplanned phase if omitted.
|
|
32
|
+
</context>
|
|
33
|
+
|
|
34
|
+
<process>
|
|
35
|
+
Execute end-to-end.
|
|
36
|
+
Preserve all workflow gates.
|
|
37
|
+
</process>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-audit-fix
|
|
3
|
+
description: "Autonomous audit-to-fix pipeline — find issues, classify, fix, test, commit"
|
|
4
|
+
argument-hint: "--source <audit-uat> [--severity <medium|high|all>] [--max N] [--dry-run]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Bash
|
|
10
|
+
- Grep
|
|
11
|
+
- Glob
|
|
12
|
+
- Agent
|
|
13
|
+
- AskUserQuestion
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<objective>
|
|
17
|
+
Run an audit, classify findings as auto-fixable vs manual-only, then autonomously fix
|
|
18
|
+
auto-fixable issues with test verification and atomic commits.
|
|
19
|
+
|
|
20
|
+
Flags:
|
|
21
|
+
- `--max N` — maximum findings to fix (default: 5)
|
|
22
|
+
- `--severity high|medium|all` — minimum severity to process (default: medium)
|
|
23
|
+
- `--dry-run` — classify findings without fixing (shows classification table)
|
|
24
|
+
- `--source <audit>` — which audit to run (default: audit-uat)
|
|
25
|
+
</objective>
|
|
26
|
+
|
|
27
|
+
<execution_context>
|
|
28
|
+
@~/.claude/gsd-core/workflows/audit-fix.md
|
|
29
|
+
</execution_context>
|
|
30
|
+
|
|
31
|
+
<process>
|
|
32
|
+
Execute end-to-end.
|
|
33
|
+
</process>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-audit-milestone
|
|
3
|
+
description: "Audit milestone completion against original intent before archiving"
|
|
4
|
+
argument-hint: "[version]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Glob
|
|
8
|
+
- Grep
|
|
9
|
+
- Bash
|
|
10
|
+
- Agent
|
|
11
|
+
- Write
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<objective>
|
|
15
|
+
Verify milestone achieved its definition of done. Check requirements coverage, cross-phase integration, and end-to-end flows.
|
|
16
|
+
|
|
17
|
+
**This command IS the orchestrator.** Reads existing VERIFICATION.md files (phases already verified during execute-phase), aggregates tech debt and deferred gaps, then spawns integration checker for cross-phase wiring.
|
|
18
|
+
</objective>
|
|
19
|
+
|
|
20
|
+
<execution_context>
|
|
21
|
+
@~/.claude/gsd-core/workflows/audit-milestone.md
|
|
22
|
+
</execution_context>
|
|
23
|
+
|
|
24
|
+
<context>
|
|
25
|
+
Version: $ARGUMENTS (optional — defaults to current milestone)
|
|
26
|
+
|
|
27
|
+
Core planning files are resolved in-workflow (`init milestone-op`) and loaded only as needed.
|
|
28
|
+
|
|
29
|
+
**Completed Work:**
|
|
30
|
+
Glob: .planning/phases/*/*-SUMMARY.md
|
|
31
|
+
Glob: .planning/phases/*/*-VERIFICATION.md
|
|
32
|
+
</context>
|
|
33
|
+
|
|
34
|
+
<process>
|
|
35
|
+
Execute end-to-end.
|
|
36
|
+
Preserve all workflow gates (scope determination, verification reading, integration check, requirements coverage, routing).
|
|
37
|
+
</process>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-audit-uat
|
|
3
|
+
description: "Cross-phase audit of all outstanding UAT and verification items"
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Glob
|
|
7
|
+
- Grep
|
|
8
|
+
- Bash
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<objective>
|
|
12
|
+
Scan all phases for pending, skipped, blocked, and human_needed UAT items. Cross-reference against codebase to detect stale documentation. Produce prioritized human test plan.
|
|
13
|
+
</objective>
|
|
14
|
+
|
|
15
|
+
<execution_context>
|
|
16
|
+
@~/.claude/gsd-core/workflows/audit-uat.md
|
|
17
|
+
</execution_context>
|
|
18
|
+
|
|
19
|
+
<context>
|
|
20
|
+
Core planning files are loaded in-workflow via CLI.
|
|
21
|
+
|
|
22
|
+
**Scope:**
|
|
23
|
+
Glob: .planning/phases/*/*-UAT.md
|
|
24
|
+
Glob: .planning/phases/*/*-VERIFICATION.md
|
|
25
|
+
</context>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-autonomous
|
|
3
|
+
description: "Run all remaining phases autonomously — discuss→plan→execute per phase"
|
|
4
|
+
argument-hint: "[--from N] [--to N] [--only N] [--interactive] [--converge]"
|
|
5
|
+
effort: max
|
|
6
|
+
allowed-tools:
|
|
7
|
+
- Read
|
|
8
|
+
- Write
|
|
9
|
+
- Bash
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
- AskUserQuestion
|
|
13
|
+
- Agent
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<objective>
|
|
17
|
+
Execute all remaining milestone phases autonomously. For each phase: discuss → plan → execute. Pauses only for user decisions (grey area acceptance, blockers, validation requests).
|
|
18
|
+
|
|
19
|
+
Uses ROADMAP.md phase discovery and Skill() flat invocations for each phase command. After all phases complete: milestone audit → complete → cleanup.
|
|
20
|
+
|
|
21
|
+
**Creates/Updates:**
|
|
22
|
+
- `.planning/STATE.md` — updated after each phase
|
|
23
|
+
- `.planning/ROADMAP.md` — progress updated after each phase
|
|
24
|
+
- Phase artifacts — CONTEXT.md, PLANs, SUMMARYs per phase
|
|
25
|
+
|
|
26
|
+
**After:** Milestone is complete and cleaned up.
|
|
27
|
+
</objective>
|
|
28
|
+
|
|
29
|
+
<execution_context>
|
|
30
|
+
@~/.claude/gsd-core/workflows/autonomous.md
|
|
31
|
+
@~/.claude/gsd-core/references/ui-brand.md
|
|
32
|
+
</execution_context>
|
|
33
|
+
|
|
34
|
+
<context>
|
|
35
|
+
Optional flags:
|
|
36
|
+
- `--from N` — start from phase N instead of the first incomplete phase.
|
|
37
|
+
- `--to N` — stop after phase N completes (halt instead of advancing to next phase).
|
|
38
|
+
- `--only N` — execute only phase N (single-phase mode).
|
|
39
|
+
- `--interactive` — run discuss inline with questions (not auto-answered), then dispatch plan→execute as background agents. Keeps the main context lean while preserving user input on decisions.
|
|
40
|
+
- `--converge` — run each phase's planning step through `gsd-plan-review-convergence` instead of plain `gsd-plan-phase`. Requires `workflow.plan_review_convergence=true`.
|
|
41
|
+
- `--cross-ai` — compatibility alias for `--converge`.
|
|
42
|
+
|
|
43
|
+
When `--converge` or `--cross-ai` is set, reviewer selector flags supported by `gsd-plan-review-convergence` may be passed through: `--codex`, `--gemini`, `--claude`, `--opencode`, `--ollama`, `--lm-studio`, `--llama-cpp`, `--all`, and `--max-cycles N`.
|
|
44
|
+
|
|
45
|
+
Project context, phase list, and state are resolved inside the workflow using init commands (`gsd-tools query init.milestone-op`, `gsd-tools query roadmap.analyze`). No upfront context loading needed.
|
|
46
|
+
</context>
|
|
47
|
+
|
|
48
|
+
<process>
|
|
49
|
+
Execute end-to-end.
|
|
50
|
+
Preserve all workflow gates (phase discovery, per-phase execution, blocker handling, progress display).
|
|
51
|
+
</process>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-capture
|
|
3
|
+
description: "Capture ideas, tasks, notes, and seeds to their destination"
|
|
4
|
+
argument-hint: "[--note | --backlog | --seed | --list | --list-seeds] [text]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Bash
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
- AskUserQuestion
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
<objective>
|
|
17
|
+
Capture ideas, tasks, notes, and seeds to their appropriate destination in the GSD system.
|
|
18
|
+
|
|
19
|
+
Mode routing:
|
|
20
|
+
- **default** (no flag): Capture as a structured todo for later work → add-todo workflow
|
|
21
|
+
- **--note**: Zero-friction idea capture (append/list/promote) → note workflow
|
|
22
|
+
- **--backlog**: Add an idea to the backlog parking lot (999.x numbering) → add-backlog workflow
|
|
23
|
+
- **--seed**: Capture a forward-looking idea with trigger conditions → plant-seed workflow
|
|
24
|
+
- **--list**: List pending todos and select one to work on → check-todos workflow
|
|
25
|
+
- **--list-seeds**: List/audit captured seeds (optional status filter) → list-seeds workflow
|
|
26
|
+
</objective>
|
|
27
|
+
|
|
28
|
+
<routing>
|
|
29
|
+
|
|
30
|
+
| Flag | Destination | Workflow |
|
|
31
|
+
|------|-------------|----------|
|
|
32
|
+
| (none) | Structured todo in .planning/todos/ | add-todo |
|
|
33
|
+
| --note | Timestamped note file, list, or promote | note |
|
|
34
|
+
| --backlog | ROADMAP.md backlog section (999.x) | add-backlog |
|
|
35
|
+
| --seed | .planning/seeds/SEED-NNN-slug.md | plant-seed |
|
|
36
|
+
| --list | Interactive todo browser + action router | check-todos |
|
|
37
|
+
| --list-seeds | Read-only seed list/audit (optional status filter) | list-seeds |
|
|
38
|
+
|
|
39
|
+
</routing>
|
|
40
|
+
|
|
41
|
+
<execution_context>
|
|
42
|
+
@~/.claude/gsd-core/workflows/add-todo.md
|
|
43
|
+
@~/.claude/gsd-core/workflows/note.md
|
|
44
|
+
@~/.claude/gsd-core/workflows/add-backlog.md
|
|
45
|
+
@~/.claude/gsd-core/workflows/plant-seed.md
|
|
46
|
+
@~/.claude/gsd-core/workflows/check-todos.md
|
|
47
|
+
@~/.claude/gsd-core/workflows/list-seeds.md
|
|
48
|
+
@~/.claude/gsd-core/references/ui-brand.md
|
|
49
|
+
</execution_context>
|
|
50
|
+
|
|
51
|
+
<context>
|
|
52
|
+
Arguments: $ARGUMENTS
|
|
53
|
+
|
|
54
|
+
Parse the first token of $ARGUMENTS:
|
|
55
|
+
- If it is `--note`: strip the flag, pass remainder to note workflow
|
|
56
|
+
- If it is `--backlog`: strip the flag, pass remainder to add-backlog workflow
|
|
57
|
+
- If it is `--seed`: strip the flag, pass remainder to plant-seed workflow
|
|
58
|
+
- If it is `--list-seeds`: strip the flag, pass remainder (optional status filter) to list-seeds workflow
|
|
59
|
+
- If it is `--list`: pass remainder (optional area filter) to check-todos workflow
|
|
60
|
+
- Otherwise: pass all of $ARGUMENTS to add-todo workflow
|
|
61
|
+
</context>
|
|
62
|
+
|
|
63
|
+
<process>
|
|
64
|
+
1. Parse the leading flag (if any) from $ARGUMENTS.
|
|
65
|
+
2. Load and execute the appropriate workflow end-to-end based on the routing table above.
|
|
66
|
+
3. Preserve all workflow gates from the target workflow (directory structure, duplicate detection, commits, etc.).
|
|
67
|
+
</process>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-cleanup
|
|
3
|
+
description: "Archive accumulated phase directories from completed milestones"
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Bash
|
|
8
|
+
- AskUserQuestion
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<objective>
|
|
12
|
+
Archive phase directories from completed milestones into `.planning/milestones/v{X.Y}-phases/`.
|
|
13
|
+
|
|
14
|
+
Use when `.planning/phases/` has accumulated directories from past milestones.
|
|
15
|
+
</objective>
|
|
16
|
+
|
|
17
|
+
<execution_context>
|
|
18
|
+
@~/.claude/gsd-core/workflows/cleanup.md
|
|
19
|
+
</execution_context>
|
|
20
|
+
|
|
21
|
+
<process>
|
|
22
|
+
Execute end-to-end.
|
|
23
|
+
Identify completed milestones, show a dry-run summary, and archive on confirmation.
|
|
24
|
+
</process>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-code-review
|
|
3
|
+
description: "Review source files changed during a phase for bugs, security issues, and code quality problems"
|
|
4
|
+
argument-hint: "<phase-number> [--depth=quick|standard|deep] [--files file1,file2,...] [--fix [--all] [--auto]]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
- Write
|
|
11
|
+
- Agent
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<objective>
|
|
15
|
+
Review source files changed during a phase for bugs, security vulnerabilities, and code quality problems.
|
|
16
|
+
|
|
17
|
+
Spawns the gsd-code-reviewer agent to analyze code at the specified depth level. Produces REVIEW.md artifact in the phase directory with severity-classified findings.
|
|
18
|
+
|
|
19
|
+
Arguments:
|
|
20
|
+
- Phase number (required) — which phase's changes to review (e.g., "2" or "02")
|
|
21
|
+
- `--depth=quick|standard|deep` (optional) — review depth level, overrides workflow.code_review_depth config
|
|
22
|
+
- quick: Pattern-matching only (~2 min)
|
|
23
|
+
- standard: Per-file analysis with language-specific checks (~5-15 min, default)
|
|
24
|
+
- deep: Cross-file analysis including import graphs and call chains (~15-30 min)
|
|
25
|
+
- `--files file1,file2,...` (optional) — explicit comma-separated file list, skips SUMMARY/git scoping (highest precedence for scoping)
|
|
26
|
+
- `--fix` (optional) — after review completes (or if REVIEW.md already exists), auto-apply fixes found. Spawns gsd-code-fixer agent. Accepts sub-flags:
|
|
27
|
+
- `--all` — include Info findings in fix scope (default: Critical + Warning only)
|
|
28
|
+
- `--auto` — enable fix + re-review iteration loop, capped at 3 iterations
|
|
29
|
+
|
|
30
|
+
Output: {padded_phase}-REVIEW.md in phase directory + inline summary of findings
|
|
31
|
+
</objective>
|
|
32
|
+
|
|
33
|
+
<execution_context>
|
|
34
|
+
@~/.claude/gsd-core/workflows/code-review.md
|
|
35
|
+
</execution_context>
|
|
36
|
+
|
|
37
|
+
<context>
|
|
38
|
+
Phase: $ARGUMENTS (first positional argument is phase number)
|
|
39
|
+
|
|
40
|
+
Optional flags parsed from $ARGUMENTS:
|
|
41
|
+
- `--depth=VALUE` — Depth override (quick|standard|deep). If provided, overrides workflow.code_review_depth config.
|
|
42
|
+
- `--files=file1,file2,...` — Explicit file list override. Has highest precedence for file scoping per D-08. When provided, workflow skips SUMMARY.md extraction and git diff fallback entirely.
|
|
43
|
+
|
|
44
|
+
Context files (CLAUDE.md, SUMMARY.md, phase state) are resolved inside the workflow via `gsd-tools query init.phase-op` and delegated to agent via `<files_to_read>` blocks.
|
|
45
|
+
</context>
|
|
46
|
+
|
|
47
|
+
<process>
|
|
48
|
+
This command is a thin dispatch layer. It parses arguments and delegates to the workflow.
|
|
49
|
+
|
|
50
|
+
Execute end-to-end.
|
|
51
|
+
|
|
52
|
+
The workflow (not this command) enforces these gates:
|
|
53
|
+
- Phase validation (before config gate)
|
|
54
|
+
- Config gate check (workflow.code_review)
|
|
55
|
+
- File scoping (--files override > SUMMARY.md > git diff fallback)
|
|
56
|
+
- Empty scope check (skip if no files)
|
|
57
|
+
- Agent spawning (gsd-code-reviewer)
|
|
58
|
+
- Result presentation (inline summary + next steps)
|
|
59
|
+
</process>
|