mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-25 17:25:23 +02:00
Compare commits
19 Commits
fix/2646-i
...
b1a670e662
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1a670e662 | ||
|
|
7c6f8005f3 | ||
|
|
cd05725576 | ||
|
|
c811792967 | ||
|
|
34b39f0a37 | ||
|
|
b1278f6fc3 | ||
|
|
303fd26b45 | ||
|
|
7b470f2625 | ||
|
|
c8ae6b3b4f | ||
|
|
7ed05c8811 | ||
|
|
0f8f7537da | ||
|
|
709f0382bf | ||
|
|
a6e692f789 | ||
|
|
b67ab38098 | ||
|
|
06463860e4 | ||
|
|
259c1d07d3 | ||
|
|
387c8a1f9c | ||
|
|
e973ff4cb6 | ||
|
|
8caa7d4c3a |
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -192,6 +192,9 @@ jobs:
|
||||
- name: Build SDK dist for tarball
|
||||
run: npm run build:sdk
|
||||
|
||||
- name: Verify tarball ships sdk/dist/cli.js (bug #2647)
|
||||
run: bash scripts/verify-tarball-sdk-dist.sh
|
||||
|
||||
- name: Dry-run publish validation
|
||||
run: |
|
||||
npm publish --dry-run --tag next
|
||||
@@ -333,6 +336,9 @@ jobs:
|
||||
- name: Build SDK dist for tarball
|
||||
run: npm run build:sdk
|
||||
|
||||
- name: Verify tarball ships sdk/dist/cli.js (bug #2647)
|
||||
run: bash scripts/verify-tarball-sdk-dist.sh
|
||||
|
||||
- name: Dry-run publish validation
|
||||
run: |
|
||||
npm publish --dry-run
|
||||
|
||||
@@ -28,6 +28,8 @@ If you use GSD **as a workflow**—milestones, phases, `.planning/` artifacts, b
|
||||
|
||||
### Fixed
|
||||
|
||||
- **End-of-phase routing suggestions now use `/gsd-<cmd>` (not the retired `/gsd:<cmd>`)** — All user-visible command suggestions in workflows (`execute-phase.md`, `transition.md`), tool output (`profile-output.cjs`, `init.cjs`), references, and templates have been updated from `/gsd:<cmd>` to `/gsd-<cmd>`, matching the Claude Code skill directory name and the user-typed slash-command format. Internal `Skill(skill="gsd:<cmd>")` calls (no leading slash) are preserved unchanged — those resolve by frontmatter `name:` not directory name. The namespace test (`bug-2543-gsd-slash-namespace.test.cjs`) has been updated to enforce the current invariant. Closes #2697.
|
||||
|
||||
- **`gsd-sdk query` now resolves parent `.planning/` root in multi-repo (`sub_repos`) workspaces** — when invoked from inside a `sub_repos`-listed child repo (e.g. `workspace/app/`), the SDK now walks up to the parent workspace that owns `.planning/`, matching the legacy `gsd-tools.cjs` `findProjectRoot` behavior. Previously `gsd-sdk query init.new-milestone` reported `project_exists: false` from the sub-repo, while `gsd-tools.cjs` resolved the parent root correctly. Resolution happens once in `cli.ts` before dispatch; if `projectDir` already owns `.planning/` (including explicit `--project-dir`), the walk is a no-op. Ported as `findProjectRoot` in `sdk/src/query/helpers.ts` with the same detection order (own `.planning/` wins, then parent `sub_repos` match, then legacy `multiRepo: true`, then `.git` heuristic), capped at 10 parent levels and never crossing `$HOME`. Closes #2623.
|
||||
- **Shell hooks falsely flagged as stale on every session** — `gsd-phase-boundary.sh`, `gsd-session-state.sh`, and `gsd-validate-commit.sh` now ship with a `# gsd-hook-version: {{GSD_VERSION}}` header; the installer substitutes `{{GSD_VERSION}}` in `.sh` hooks the same way it does for `.js` hooks; and the stale-hook detector in `gsd-check-update.js` now matches bash `#` comment syntax in addition to JS `//` syntax. All three changes are required together — neither the regex fix alone nor the install fix alone is sufficient to resolve the false positive (#2136, #2206, #2209, #2210, #2212)
|
||||
|
||||
|
||||
217
bin/install.js
217
bin/install.js
@@ -1113,11 +1113,31 @@ function convertClaudeCommandToCopilotSkill(content, skillName, isGlobal = false
|
||||
return `${fm}\n${body}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a skill directory name (gsd-<cmd>) to the frontmatter `name:` used
|
||||
* by Claude Code as the skill identity. Workflows emit `Skill(skill="gsd:<cmd>")`
|
||||
* (colon form) and Claude Code resolves skills by frontmatter `name:`, not
|
||||
* directory name — so emit colon form here. Directory stays hyphenated for
|
||||
* Windows path safety. See #2643.
|
||||
*
|
||||
* Codex must NOT use this helper: its adapter invokes skills as `$gsd-<cmd>`
|
||||
* (shell-var syntax) and a colon would terminate the variable name. Codex
|
||||
* keeps the hyphen form via `yamlQuote(skillName)` directly.
|
||||
*/
|
||||
function skillFrontmatterName(skillDirName) {
|
||||
if (typeof skillDirName !== 'string') return skillDirName;
|
||||
// Idempotent on already-colon form.
|
||||
if (skillDirName.includes(':')) return skillDirName;
|
||||
// Only rewrite the first hyphen after the `gsd` prefix.
|
||||
return skillDirName.replace(/^gsd-/, 'gsd:');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Claude command (.md) to a Claude skill (SKILL.md).
|
||||
* Claude Code is the native format, so minimal conversion needed —
|
||||
* preserve allowed-tools as YAML multiline list, preserve argument-hint,
|
||||
* convert name from gsd:xxx to gsd-xxx format.
|
||||
* preserve allowed-tools as YAML multiline list, preserve argument-hint.
|
||||
* Emits `name: gsd:<cmd>` (colon) so Skill(skill="gsd:<cmd>") calls in
|
||||
* workflows resolve on flat-skills installs — see #2643.
|
||||
*/
|
||||
function convertClaudeCommandToClaudeSkill(content, skillName) {
|
||||
const { frontmatter, body } = extractFrontmatterAndBody(content);
|
||||
@@ -1137,7 +1157,8 @@ function convertClaudeCommandToClaudeSkill(content, skillName) {
|
||||
}
|
||||
|
||||
// Reconstruct frontmatter in Claude skill format
|
||||
let fm = `---\nname: ${skillName}\ndescription: ${yamlQuote(description)}\n`;
|
||||
const frontmatterName = skillFrontmatterName(skillName);
|
||||
let fm = `---\nname: ${frontmatterName}\ndescription: ${yamlQuote(description)}\n`;
|
||||
if (argumentHint) fm += `argument-hint: ${yamlQuote(argumentHint)}\n`;
|
||||
if (agent) fm += `agent: ${agent}\n`;
|
||||
if (toolsBlock) fm += toolsBlock;
|
||||
@@ -1873,6 +1894,14 @@ function convertClaudeToCodexMarkdown(content) {
|
||||
converted = converted.replace(/\$HOME\/\.claude\//g, '$HOME/.codex/');
|
||||
converted = converted.replace(/~\/\.claude\//g, '~/.codex/');
|
||||
converted = converted.replace(/\.\/\.claude\//g, './.codex/');
|
||||
// Bare/project-relative .claude/... references (#2639). Covers strings like
|
||||
// "check `.claude/skills/`" where there is no ~/, $HOME/, or ./ anchor.
|
||||
// Negative lookbehind prevents double-replacing already-anchored forms and
|
||||
// avoids matching inside URLs or other slash-prefixed paths.
|
||||
converted = converted.replace(/(?<![A-Za-z0-9_\-./~$])\.claude\//g, '.codex/');
|
||||
// `.claudeignore` → `.codexignore` (#2639). Codex honors its own ignore
|
||||
// file; leaving the Claude-specific name is misleading in agent prompts.
|
||||
converted = converted.replace(/\.claudeignore\b/g, '.codexignore');
|
||||
// Runtime-neutral agent name replacement (#766)
|
||||
converted = neutralizeAgentReferences(converted, 'AGENTS.md');
|
||||
return converted;
|
||||
@@ -2037,7 +2066,10 @@ function generateCodexConfigBlock(agents, targetDir) {
|
||||
];
|
||||
|
||||
for (const { name, description } of agents) {
|
||||
lines.push(`[agents.${name}]`);
|
||||
// #2645 — Codex schema requires [[agents]] array-of-tables, not [agents.<name>] maps.
|
||||
// Emitting [agents.<name>] produces `invalid type: map, expected a sequence` on load.
|
||||
lines.push(`[[agents]]`);
|
||||
lines.push(`name = ${JSON.stringify(name)}`);
|
||||
lines.push(`description = ${JSON.stringify(description)}`);
|
||||
lines.push(`config_file = "${agentsPrefix}/${name}.toml"`);
|
||||
lines.push('');
|
||||
@@ -2046,8 +2078,39 @@ function generateCodexConfigBlock(agents, targetDir) {
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip any managed GSD agent sections from a TOML string.
|
||||
*
|
||||
* Handles BOTH shapes so reinstall self-heals broken legacy configs:
|
||||
* - Legacy: `[agents.gsd-*]` single-keyed map tables (pre-#2645).
|
||||
* - Current: `[[agents]]` array-of-tables whose `name = "gsd-*"`.
|
||||
*
|
||||
* A section runs from its header to the next `[` header or EOF.
|
||||
*/
|
||||
function stripCodexGsdAgentSections(content) {
|
||||
return content.replace(/^\[agents\.gsd-[^\]]+\]\n(?:(?!\[)[^\n]*\n?)*/gm, '');
|
||||
// Use the TOML-aware section parser so we never absorb adjacent user-authored
|
||||
// tables — even if their headers are indented or otherwise oddly placed.
|
||||
const sections = getTomlTableSections(content).filter((section) => {
|
||||
// Legacy `[agents.gsd-<name>]` map tables (pre-#2645).
|
||||
if (!section.array && /^agents\.gsd-/.test(section.path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Current `[[agents]]` array-of-tables — only strip blocks whose
|
||||
// `name = "gsd-..."`, preserving user-authored [[agents]] entries.
|
||||
if (section.array && section.path === 'agents') {
|
||||
const body = content.slice(section.headerEnd, section.end);
|
||||
const nameMatch = body.match(/^[ \t]*name[ \t]*=[ \t]*["']([^"']+)["']/m);
|
||||
return Boolean(nameMatch && /^gsd-/.test(nameMatch[1]));
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return removeContentRanges(
|
||||
content,
|
||||
sections.map(({ start, end }) => ({ start, end })),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2745,13 +2808,27 @@ function isLegacyGsdAgentsSection(body) {
|
||||
|
||||
function stripLeakedGsdCodexSections(content) {
|
||||
const leakedSections = getTomlTableSections(content)
|
||||
.filter((section) =>
|
||||
section.path.startsWith('agents.gsd-') ||
|
||||
(
|
||||
.filter((section) => {
|
||||
// Legacy [agents.gsd-<name>] map tables (pre-#2645).
|
||||
if (!section.array && section.path.startsWith('agents.gsd-')) return true;
|
||||
|
||||
// Legacy bare [agents] table with only the old max_threads/max_depth keys.
|
||||
if (
|
||||
!section.array &&
|
||||
section.path === 'agents' &&
|
||||
isLegacyGsdAgentsSection(content.slice(section.headerEnd, section.end))
|
||||
)
|
||||
);
|
||||
) return true;
|
||||
|
||||
// Current [[agents]] array-of-tables whose name is gsd-*. Preserve
|
||||
// user-authored [[agents]] entries (other names) untouched.
|
||||
if (section.array && section.path === 'agents') {
|
||||
const body = content.slice(section.headerEnd, section.end);
|
||||
const nameMatch = body.match(/^[ \t]*name[ \t]*=[ \t]*["']([^"']+)["']/m);
|
||||
if (nameMatch && /^gsd-/.test(nameMatch[1])) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (leakedSections.length === 0) {
|
||||
return content;
|
||||
@@ -3232,15 +3309,16 @@ function installCodexConfig(targetDir, agentsSrc) {
|
||||
|
||||
for (const file of agentEntries) {
|
||||
let content = fs.readFileSync(path.join(agentsSrc, file), 'utf8');
|
||||
// Replace full .claude/get-shit-done prefix so path resolves to codex GSD install
|
||||
// Replace full .claude/get-shit-done prefix so path resolves to the Codex
|
||||
// GSD install before generic .claude → .codex conversion rewrites it.
|
||||
content = content.replace(/~\/\.claude\/get-shit-done\//g, codexGsdPath);
|
||||
content = content.replace(/\$HOME\/\.claude\/get-shit-done\//g, codexGsdPath);
|
||||
// Replace remaining .claude paths with .codex equivalents (#2320).
|
||||
// Capture group handles both trailing-slash form (~/.claude/) and
|
||||
// bare end-of-string form (~/.claude) in a single pass.
|
||||
content = content.replace(/\$HOME\/\.claude(\/|$)/g, '$HOME/.codex$1');
|
||||
content = content.replace(/~\/\.claude(\/|$)/g, '~/.codex$1');
|
||||
content = content.replace(/\.\/\.claude(\/|$)/g, './.codex$1');
|
||||
// Route TOML emit through the same full Claude→Codex conversion pipeline
|
||||
// used on the `.md` emit path (#2639). Covers: slash-command rewrites,
|
||||
// $ARGUMENTS → {{GSD_ARGS}}, /clear removal, anchored and bare .claude/
|
||||
// paths, .claudeignore → .codexignore, and standalone "Claude" /
|
||||
// CLAUDE.md neutralization via neutralizeAgentReferences(..., 'AGENTS.md').
|
||||
content = convertClaudeToCodexMarkdown(content);
|
||||
const { frontmatter } = extractFrontmatterAndBody(content);
|
||||
const name = extractFrontmatterField(frontmatter, 'name') || file.replace('.md', '');
|
||||
const description = extractFrontmatterField(frontmatter, 'description') || '';
|
||||
@@ -7023,8 +7101,72 @@ function maybeSuggestPathExport(globalBin, homeDir) {
|
||||
* --no-sdk skips the check entirely (back-compat).
|
||||
* --sdk forces the check even if it would otherwise be skipped.
|
||||
*/
|
||||
function installSdkIfNeeded() {
|
||||
if (hasNoSdk) {
|
||||
/**
|
||||
* Classify the install context for the SDK directory.
|
||||
*
|
||||
* Distinguishes three shapes the installer must handle differently when
|
||||
* `sdk/dist/` is missing:
|
||||
*
|
||||
* - `tarball` + `npxCache: true`
|
||||
* User ran `npx get-shit-done-cc@latest`. sdk/ lives under
|
||||
* `<npm-cache>/_npx/<hash>/node_modules/get-shit-done-cc/sdk` which
|
||||
* is treated as read-only by npm/npx on Windows (#2649). We MUST
|
||||
* NOT attempt a nested `npm install` there — it will fail with
|
||||
* EACCES/EPERM and produce the misleading "Failed to npm install
|
||||
* in sdk/" error the user reported. Point at the global upgrade.
|
||||
*
|
||||
* - `tarball` + `npxCache: false`
|
||||
* User ran a global install (`npm i -g get-shit-done-cc`). sdk/dist
|
||||
* ships in the published tarball; if it's missing, the published
|
||||
* artifact itself is broken (see #2647). Same user-facing fix:
|
||||
* upgrade to latest.
|
||||
*
|
||||
* - `dev-clone`
|
||||
* Developer running from a git clone. Keep the existing "cd sdk &&
|
||||
* npm install && npm run build" hint — the user is expected to run
|
||||
* that themselves. The installer itself never shells out to npm.
|
||||
*
|
||||
* Detection heuristics are path-based and side-effect-free: we look for
|
||||
* `_npx` and `node_modules` segments that indicate a packaged install,
|
||||
* and for a `.git` directory nearby that indicates a clone. A best-effort
|
||||
* write probe detects read-only filesystems (tmpfile create + unlink);
|
||||
* probe failures are treated as read-only.
|
||||
*/
|
||||
function classifySdkInstall(sdkDir) {
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const segments = sdkDir.split(/[\\/]+/);
|
||||
const npxCache = segments.includes('_npx');
|
||||
const inNodeModules = segments.includes('node_modules');
|
||||
const parent = path.dirname(sdkDir);
|
||||
const hasGitNearby = fs.existsSync(path.join(parent, '.git'));
|
||||
|
||||
let mode;
|
||||
if (hasGitNearby && !npxCache && !inNodeModules) {
|
||||
mode = 'dev-clone';
|
||||
} else if (npxCache || inNodeModules) {
|
||||
mode = 'tarball';
|
||||
} else {
|
||||
mode = 'dev-clone';
|
||||
}
|
||||
|
||||
let readOnly = npxCache; // assume true for npx cache
|
||||
if (!readOnly) {
|
||||
try {
|
||||
const probe = path.join(sdkDir, `.gsd-write-probe-${process.pid}`);
|
||||
fs.writeFileSync(probe, '');
|
||||
fs.unlinkSync(probe);
|
||||
} catch {
|
||||
readOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
return { mode, npxCache, readOnly };
|
||||
}
|
||||
|
||||
function installSdkIfNeeded(opts) {
|
||||
opts = opts || {};
|
||||
if (hasNoSdk && !opts.sdkDir) {
|
||||
console.log(`\n ${dim}Skipping GSD SDK check (--no-sdk)${reset}`);
|
||||
return;
|
||||
}
|
||||
@@ -7032,9 +7174,11 @@ function installSdkIfNeeded() {
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const sdkCliPath = path.resolve(__dirname, '..', 'sdk', 'dist', 'cli.js');
|
||||
const sdkDir = opts.sdkDir || path.resolve(__dirname, '..', 'sdk');
|
||||
const sdkCliPath = path.join(sdkDir, 'dist', 'cli.js');
|
||||
|
||||
if (!fs.existsSync(sdkCliPath)) {
|
||||
const ctx = classifySdkInstall(sdkDir);
|
||||
const bar = '━'.repeat(72);
|
||||
const redBold = `${red}${bold}`;
|
||||
console.error('');
|
||||
@@ -7043,9 +7187,33 @@ function installSdkIfNeeded() {
|
||||
console.error(`${redBold}${bar}${reset}`);
|
||||
console.error(` ${red}Reason:${reset} sdk/dist/cli.js not found at ${sdkCliPath}`);
|
||||
console.error('');
|
||||
console.error(` This should not happen with a published tarball install.`);
|
||||
console.error(` If you are running from a git clone, build the SDK first:`);
|
||||
console.error(` ${cyan}cd sdk && npm install && npm run build${reset}`);
|
||||
|
||||
if (ctx.mode === 'tarball') {
|
||||
// User install (including `npx get-shit-done-cc@latest`, which stages
|
||||
// a read-only tarball under the npx cache). The sdk/dist/ artifact
|
||||
// should ship in the published tarball. If it's missing, the only
|
||||
// sane fix from the user's side is a fresh global install of a
|
||||
// version that includes dist/. Do NOT attempt a nested `npm install`
|
||||
// inside the (read-only) npx cache — that's the #2649 failure mode.
|
||||
if (ctx.npxCache) {
|
||||
console.error(` Detected read-only npx cache install (${dim}${sdkDir}${reset}).`);
|
||||
console.error(` The installer will ${bold}not${reset} attempt \`npm install\` inside the npx cache.`);
|
||||
console.error('');
|
||||
} else {
|
||||
console.error(` The published tarball appears to be missing sdk/dist/ (see #2647).`);
|
||||
console.error('');
|
||||
}
|
||||
console.error(` Fix: install a version that ships sdk/dist/ globally:`);
|
||||
console.error(` ${cyan}npm install -g get-shit-done-cc@latest${reset}`);
|
||||
console.error(` Or, if you prefer a one-shot run, clear the npx cache first:`);
|
||||
console.error(` ${cyan}npx --yes get-shit-done-cc@latest${reset}`);
|
||||
console.error(` Or build from source (git clone):`);
|
||||
console.error(` ${cyan}git clone https://github.com/gsd-build/get-shit-done && cd get-shit-done/sdk && npm install && npm run build${reset}`);
|
||||
} else {
|
||||
// Dev clone: keep the existing build-from-source hint.
|
||||
console.error(` Running from a git clone — build the SDK first:`);
|
||||
console.error(` ${cyan}cd sdk && npm install && npm run build${reset}`);
|
||||
}
|
||||
console.error(`${redBold}${bar}${reset}`);
|
||||
console.error('');
|
||||
process.exit(1);
|
||||
@@ -7146,6 +7314,8 @@ if (process.env.GSD_TEST_MODE) {
|
||||
readGsdEffectiveModelOverrides,
|
||||
install,
|
||||
uninstall,
|
||||
installSdkIfNeeded,
|
||||
classifySdkInstall,
|
||||
convertClaudeCommandToCodexSkill,
|
||||
convertClaudeToOpencodeFrontmatter,
|
||||
convertClaudeToKiloFrontmatter,
|
||||
@@ -7173,6 +7343,7 @@ if (process.env.GSD_TEST_MODE) {
|
||||
convertClaudeAgentToAntigravityAgent,
|
||||
copyCommandsAsAntigravitySkills,
|
||||
convertClaudeCommandToClaudeSkill,
|
||||
skillFrontmatterName,
|
||||
copyCommandsAsClaudeSkills,
|
||||
convertClaudeToWindsurfMarkdown,
|
||||
convertClaudeCommandToWindsurfSkill,
|
||||
|
||||
@@ -42,7 +42,7 @@ the normal phase sequence and accumulate context over time.
|
||||
**Plans:** 0 plans
|
||||
|
||||
Plans:
|
||||
- [ ] TBD (promote with /gsd:review-backlog when ready)
|
||||
- [ ] TBD (promote with /gsd-review-backlog when ready)
|
||||
```
|
||||
|
||||
4. **Create the phase directory:**
|
||||
@@ -65,15 +65,15 @@ the normal phase sequence and accumulate context over time.
|
||||
Directory: .planning/phases/{NEXT}-{slug}/
|
||||
|
||||
This item lives in the backlog parking lot.
|
||||
Use /gsd:discuss-phase {NEXT} to explore it further.
|
||||
Use /gsd:review-backlog to promote items to active milestone.
|
||||
Use /gsd-discuss-phase {NEXT} to explore it further.
|
||||
Use /gsd-review-backlog to promote items to active milestone.
|
||||
```
|
||||
|
||||
</process>
|
||||
|
||||
<notes>
|
||||
- 999.x numbering keeps backlog items out of the active phase sequence
|
||||
- Phase directories are created immediately, so /gsd:discuss-phase and /gsd:plan-phase work on them
|
||||
- Phase directories are created immediately, so /gsd-discuss-phase and /gsd-plan-phase work on them
|
||||
- No `Depends on:` field — backlog items are unsequenced by definition
|
||||
- Sparse numbering is fine (999.1, 999.3) — always uses next-decimal
|
||||
</notes>
|
||||
|
||||
@@ -13,8 +13,8 @@ allowed-tools:
|
||||
- AskUserQuestion
|
||||
argument-instructions: |
|
||||
Parse the argument as a phase number (integer, decimal, or letter-suffix), plus optional free-text instructions.
|
||||
Example: /gsd:add-tests 12
|
||||
Example: /gsd:add-tests 12 focus on edge cases in the pricing module
|
||||
Example: /gsd-add-tests 12
|
||||
Example: /gsd-add-tests 12 focus on edge cases in the pricing module
|
||||
---
|
||||
<objective>
|
||||
Generate unit and E2E tests for a completed phase, using its SUMMARY.md, CONTEXT.md, and VERIFICATION.md as specifications.
|
||||
|
||||
@@ -25,7 +25,7 @@ Then suggest `Depends on` updates to ROADMAP.md.
|
||||
<context>
|
||||
No arguments required. Requires an active milestone with ROADMAP.md.
|
||||
|
||||
Run this command BEFORE `/gsd:manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution.
|
||||
Run this command BEFORE `/gsd-manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution.
|
||||
</context>
|
||||
|
||||
<process>
|
||||
|
||||
@@ -42,19 +42,19 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
|
||||
0. **Check for audit:**
|
||||
|
||||
- Look for `.planning/v{{version}}-MILESTONE-AUDIT.md`
|
||||
- If missing or stale: recommend `/gsd:audit-milestone` first
|
||||
- If audit status is `gaps_found`: recommend `/gsd:plan-milestone-gaps` first
|
||||
- If missing or stale: recommend `/gsd-audit-milestone` first
|
||||
- If audit status is `gaps_found`: recommend `/gsd-plan-milestone-gaps` first
|
||||
- If audit status is `passed`: proceed to step 1
|
||||
|
||||
```markdown
|
||||
## Pre-flight Check
|
||||
|
||||
{If no v{{version}}-MILESTONE-AUDIT.md:}
|
||||
⚠ No milestone audit found. Run `/gsd:audit-milestone` first to verify
|
||||
⚠ No milestone audit found. Run `/gsd-audit-milestone` first to verify
|
||||
requirements coverage, cross-phase integration, and E2E flows.
|
||||
|
||||
{If audit has gaps:}
|
||||
⚠ Milestone audit found gaps. Run `/gsd:plan-milestone-gaps` to create
|
||||
⚠ Milestone audit found gaps. Run `/gsd-plan-milestone-gaps` to create
|
||||
phases that close the gaps, or proceed anyway to accept as tech debt.
|
||||
|
||||
{If audit passed:}
|
||||
@@ -108,7 +108,7 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
|
||||
- Ask about pushing tag
|
||||
|
||||
8. **Offer next steps:**
|
||||
- `/gsd:new-milestone` — start next milestone (questioning → research → requirements → roadmap)
|
||||
- `/gsd-new-milestone` — start next milestone (questioning → research → requirements → roadmap)
|
||||
|
||||
</process>
|
||||
|
||||
@@ -132,5 +132,5 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
|
||||
- **Archive before deleting:** Always create archive files before updating/deleting originals
|
||||
- **One-line summary:** Collapsed milestone in ROADMAP.md should be single line with link
|
||||
- **Context efficiency:** Archive keeps ROADMAP.md and REQUIREMENTS.md constant size per milestone
|
||||
- **Fresh requirements:** Next milestone starts with `/gsd:new-milestone` which includes requirements definition
|
||||
- **Fresh requirements:** Next milestone starts with `/gsd-new-milestone` which includes requirements definition
|
||||
</critical_rules>
|
||||
|
||||
@@ -88,11 +88,11 @@ Active Debug Sessions
|
||||
hypothesis: Missing null check on req.body.user
|
||||
next: Verify fix passes regression test
|
||||
─────────────────────────────────────────────
|
||||
Run `/gsd:debug continue <slug>` to resume a session.
|
||||
No sessions? `/gsd:debug <description>` to start.
|
||||
Run `/gsd-debug continue <slug>` to resume a session.
|
||||
No sessions? `/gsd-debug <description>` to start.
|
||||
```
|
||||
|
||||
If no files exist or the glob returns nothing: print "No active debug sessions. Run `/gsd:debug <issue description>` to start one."
|
||||
If no files exist or the glob returns nothing: print "No active debug sessions. Run `/gsd-debug <issue description>` to start one."
|
||||
|
||||
STOP after displaying list. Do NOT proceed to further steps.
|
||||
|
||||
@@ -117,7 +117,7 @@ No agent spawn. Just information display. STOP after printing.
|
||||
|
||||
When SUBCMD=continue and SLUG is set:
|
||||
|
||||
Check `.planning/debug/{SLUG}.md` exists. If not, print "No active debug session found with slug: {SLUG}. Check `/gsd:debug list` for active sessions." and stop.
|
||||
Check `.planning/debug/{SLUG}.md` exists. If not, print "No active debug session found with slug: {SLUG}. Check `/gsd-debug list` for active sessions." and stop.
|
||||
|
||||
Read file and print Current Focus block to console:
|
||||
|
||||
@@ -247,7 +247,7 @@ specialist_dispatch_enabled: true
|
||||
Display the compact summary returned by the session manager.
|
||||
|
||||
If summary shows `DEBUG SESSION COMPLETE`: done.
|
||||
If summary shows `ABANDONED`: note session saved at `.planning/debug/{slug}.md` for later `/gsd:debug continue {slug}`.
|
||||
If summary shows `ABANDONED`: note session saved at `.planning/debug/{slug}.md` for later `/gsd-debug continue {slug}`.
|
||||
|
||||
</process>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Open-ended Socratic ideation session. Guides the developer through exploring an
|
||||
probing questions, optionally spawns research, then routes outputs to the appropriate GSD
|
||||
artifacts (notes, todos, seeds, research questions, requirements, or new phases).
|
||||
|
||||
Accepts an optional topic argument: `/gsd:explore authentication strategy`
|
||||
Accepts an optional topic argument: `/gsd-explore authentication strategy`
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -16,8 +16,8 @@ Execute a trivial task directly in the current context without spawning subagent
|
||||
or generating PLAN.md files. For tasks too small to justify planning overhead:
|
||||
typo fixes, config changes, small refactors, forgotten commits, simple additions.
|
||||
|
||||
This is NOT a replacement for /gsd:quick — use /gsd:quick for anything that
|
||||
needs research, multi-step planning, or verification. /gsd:fast is for tasks
|
||||
This is NOT a replacement for /gsd-quick — use /gsd-quick for anything that
|
||||
needs research, multi-step planning, or verification. /gsd-fast is for tasks
|
||||
you could describe in one sentence and execute in under 2 minutes.
|
||||
</objective>
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ Knowledge graph is disabled. To activate:
|
||||
|
||||
node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs config-set graphify.enabled true
|
||||
|
||||
Then run /gsd:graphify build to create the initial graph.
|
||||
Then run /gsd-graphify build to create the initial graph.
|
||||
```
|
||||
|
||||
---
|
||||
@@ -65,7 +65,7 @@ Parse `$ARGUMENTS` to determine the operation mode:
|
||||
```
|
||||
GSD > GRAPHIFY
|
||||
|
||||
Usage: /gsd:graphify <mode>
|
||||
Usage: /gsd-graphify <mode>
|
||||
|
||||
Modes:
|
||||
build Build or rebuild the knowledge graph
|
||||
@@ -85,7 +85,7 @@ node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs graphify query <term>
|
||||
Parse the JSON output and display results:
|
||||
- If the output contains `"disabled": true`, display the disabled message from Step 1 and **STOP**
|
||||
- If the output contains `"error"` field, display the error message and **STOP**
|
||||
- If no nodes found, display: `No graph matches for '<term>'. Try /gsd:graphify build to create or rebuild the graph.`
|
||||
- If no nodes found, display: `No graph matches for '<term>'. Try /gsd-graphify build to create or rebuild the graph.`
|
||||
- Otherwise, display matched nodes grouped by type, with edge relationships and confidence tiers (EXTRACTED/INFERRED/AMBIGUOUS)
|
||||
|
||||
**STOP** after displaying results. Do not spawn an agent.
|
||||
|
||||
@@ -4,7 +4,6 @@ description: Insert urgent work as decimal phase (e.g., 72.1) between existing p
|
||||
argument-hint: <after> <description>
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Write
|
||||
- Bash
|
||||
---
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Intel system is disabled. To activate:
|
||||
|
||||
gsd-sdk query config-set intel.enabled true
|
||||
|
||||
Then run /gsd:intel refresh to build the initial index.
|
||||
Then run /gsd-intel refresh to build the initial index.
|
||||
```
|
||||
|
||||
---
|
||||
@@ -63,7 +63,7 @@ Parse `$ARGUMENTS` to determine the operation mode:
|
||||
```
|
||||
GSD > INTEL
|
||||
|
||||
Usage: /gsd:intel <mode>
|
||||
Usage: /gsd-intel <mode>
|
||||
|
||||
Modes:
|
||||
query <term> Search intel files for a term
|
||||
@@ -82,7 +82,7 @@ gsd-sdk query intel.query <term>
|
||||
|
||||
Parse the JSON output and display results:
|
||||
- If the output contains `"disabled": true`, display the disabled message from Step 1 and **STOP**
|
||||
- If no matches found, display: `No intel matches for '<term>'. Try /gsd:intel refresh to build the index.`
|
||||
- If no matches found, display: `No intel matches for '<term>'. Try /gsd-intel refresh to build the index.`
|
||||
- Otherwise, display matching entries grouped by intel file
|
||||
|
||||
**STOP** after displaying results. Do not spawn an agent.
|
||||
|
||||
@@ -30,8 +30,8 @@ Focus area: $ARGUMENTS (optional - if provided, tells agents to focus on specifi
|
||||
Check for .planning/STATE.md - loads context if project already initialized
|
||||
|
||||
**This command can run:**
|
||||
- Before /gsd:new-project (brownfield codebases) - creates codebase map first
|
||||
- After /gsd:new-project (greenfield codebases) - updates codebase map as code evolves
|
||||
- Before /gsd-new-project (brownfield codebases) - creates codebase map first
|
||||
- After /gsd-new-project (greenfield codebases) - updates codebase map as code evolves
|
||||
- Anytime to refresh codebase understanding
|
||||
</context>
|
||||
|
||||
@@ -59,7 +59,7 @@ Check for .planning/STATE.md - loads context if project already initialized
|
||||
4. Wait for agents to complete, collect confirmations (NOT document contents)
|
||||
5. Verify all 7 documents exist with line counts
|
||||
6. Commit codebase map
|
||||
7. Offer next steps (typically: /gsd:new-project or /gsd:plan-phase)
|
||||
7. Offer next steps (typically: /gsd-new-project or /gsd-plan-phase)
|
||||
</process>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
@@ -21,7 +21,7 @@ Brownfield equivalent of new-project. Project exists, PROJECT.md has history. Ga
|
||||
- `.planning/ROADMAP.md` — phase structure (continues numbering)
|
||||
- `.planning/STATE.md` — reset for new milestone
|
||||
|
||||
**After:** `/gsd:plan-phase [N]` to start execution.
|
||||
**After:** `/gsd-plan-phase [N]` to start execution.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -29,7 +29,7 @@ Initialize a new project through unified flow: questioning → research (optiona
|
||||
- `.planning/ROADMAP.md` — phase structure
|
||||
- `.planning/STATE.md` — project memory
|
||||
|
||||
**After this command:** Run `/gsd:plan-phase 1` to start execution.
|
||||
**After this command:** Run `/gsd-plan-phase 1` to start execution.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -30,7 +30,7 @@ Create a physical workspace directory containing copies of specified git repos (
|
||||
- `<path>/.planning/` — independent planning directory
|
||||
- `<path>/<repo>/` — git worktree or clone for each specified repo
|
||||
|
||||
**After this command:** `cd` into the workspace and run `/gsd:new-project` to initialize GSD.
|
||||
**After this command:** `cd` into the workspace and run `/gsd-new-project` to initialize GSD.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -10,11 +10,11 @@ allowed-tools:
|
||||
- AskUserQuestion
|
||||
---
|
||||
<objective>
|
||||
Create all phases necessary to close gaps identified by `/gsd:audit-milestone`.
|
||||
Create all phases necessary to close gaps identified by `/gsd-audit-milestone`.
|
||||
|
||||
Reads MILESTONE-AUDIT.md, groups gaps into logical phases, creates phase entries in ROADMAP.md, and offers to plan each phase.
|
||||
|
||||
One command creates all fix phases — no manual `/gsd:add-phase` per gap.
|
||||
One command creates all fix phases — no manual `/gsd-add-phase` per gap.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -40,7 +40,7 @@ Phase number: $ARGUMENTS (optional — auto-detects next unplanned phase if omit
|
||||
- `--gaps` — Gap closure mode (reads VERIFICATION.md, skips research)
|
||||
- `--skip-verify` — Skip verification loop
|
||||
- `--prd <file>` — Use a PRD/acceptance criteria file instead of discuss-phase. Parses requirements into CONTEXT.md automatically. Skips discuss-phase entirely.
|
||||
- `--reviews` — Replan incorporating cross-AI review feedback from REVIEWS.md (produced by `/gsd:review`)
|
||||
- `--reviews` — Replan incorporating cross-AI review feedback from REVIEWS.md (produced by `/gsd-review`)
|
||||
- `--text` — Use plain-text numbered lists instead of TUI menus (required for `/rc` remote sessions)
|
||||
|
||||
Normalize phase input in step 2 before any directory lookups.
|
||||
|
||||
@@ -16,7 +16,7 @@ milestone arrives. Seeds solve context rot: instead of a one-liner in Deferred t
|
||||
reads, a seed preserves the full WHY, WHEN to surface, and breadcrumbs to details.
|
||||
|
||||
Creates: .planning/seeds/SEED-NNN-slug.md
|
||||
Consumed by: /gsd:new-milestone (scans seeds and presents matches)
|
||||
Consumed by: /gsd-new-milestone (scans seeds and presents matches)
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -71,7 +71,7 @@ For each directory found:
|
||||
- Check if PLAN.md exists
|
||||
- Check if SUMMARY.md exists; if so, read `status` from its frontmatter via:
|
||||
```bash
|
||||
gsd-sdk query frontmatter.get .planning/quick/{dir}/SUMMARY.md status 2>/dev/null
|
||||
gsd-sdk query frontmatter.get .planning/quick/{dir}/SUMMARY.md status
|
||||
```
|
||||
- Determine directory creation date: `stat -f "%SB" -t "%Y-%m-%d"` (macOS) or `stat -c "%w"` (Linux); fall back to the date prefix in the directory name (format: `YYYYMMDD-` prefix)
|
||||
- Derive display status:
|
||||
@@ -118,7 +118,7 @@ Status: {status from SUMMARY.md frontmatter, or "no summary yet"}
|
||||
Description: {first non-empty line from PLAN.md after frontmatter}
|
||||
Last action: {last meaningful line of SUMMARY.md, or "none"}
|
||||
─────────────────────────────────────
|
||||
Resume with: /gsd:quick resume {slug}
|
||||
Resume with: /gsd-quick resume {slug}
|
||||
```
|
||||
|
||||
No agent spawn. STOP after printing.
|
||||
|
||||
@@ -115,7 +115,7 @@ Read `backup-meta.json` from the patches directory.
|
||||
```
|
||||
No local patches found. Nothing to reapply.
|
||||
|
||||
Local patches are automatically saved when you run /gsd:update
|
||||
Local patches are automatically saved when you run /gsd-update
|
||||
after modifying any GSD workflow, command, or agent files.
|
||||
```
|
||||
Exit.
|
||||
@@ -278,7 +278,7 @@ Before proceeding to cleanup, evaluate the Hunk Verification Table produced in S
|
||||
**If the Hunk Verification Table is absent** (Step 4 did not produce it), STOP immediately and report to the user:
|
||||
```
|
||||
ERROR: Hunk Verification Table is missing. Post-merge verification was not completed.
|
||||
Rerun /gsd:reapply-patches to retry with full verification.
|
||||
Rerun /gsd-reapply-patches to retry with full verification.
|
||||
```
|
||||
|
||||
**If any row in the Hunk Verification Table shows `verified: no`**, STOP and report to the user:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: gsd:research-phase
|
||||
description: Research how to implement a phase (standalone - usually use /gsd:plan-phase instead)
|
||||
description: Research how to implement a phase (standalone - usually use /gsd-plan-phase instead)
|
||||
argument-hint: "[phase]"
|
||||
allowed-tools:
|
||||
- Read
|
||||
@@ -11,7 +11,7 @@ allowed-tools:
|
||||
<objective>
|
||||
Research how to implement a phase. Spawns gsd-phase-researcher agent with phase context.
|
||||
|
||||
**Note:** This is a standalone research command. For most workflows, use `/gsd:plan-phase` which integrates research automatically.
|
||||
**Note:** This is a standalone research command. For most workflows, use `/gsd-plan-phase` which integrates research automatically.
|
||||
|
||||
**Use this command when:**
|
||||
- You want to research without planning yet
|
||||
@@ -115,7 +115,7 @@ Mode: ecosystem
|
||||
</additional_context>
|
||||
|
||||
<downstream_consumer>
|
||||
Your RESEARCH.md will be loaded by `/gsd:plan-phase` which uses specific sections:
|
||||
Your RESEARCH.md will be loaded by `/gsd-plan-phase` which uses specific sections:
|
||||
- `## Standard Stack` → Plans use these libraries
|
||||
- `## Architecture Patterns` → Task structure follows these
|
||||
- `## Don't Hand-Roll` → Tasks NEVER build custom solutions for listed problems
|
||||
|
||||
@@ -13,7 +13,7 @@ allowed-tools:
|
||||
<objective>
|
||||
Invoke external AI CLIs (Gemini, Claude, Codex, OpenCode, Qwen Code, Cursor) to independently review phase plans.
|
||||
Produces a structured REVIEWS.md with per-reviewer feedback that can be fed back into
|
||||
planning via /gsd:plan-phase --reviews.
|
||||
planning via /gsd-plan-phase --reviews.
|
||||
|
||||
**Flow:** Detect CLIs → Build review prompt → Invoke each CLI → Collect responses → Write REVIEWS.md
|
||||
</objective>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: gsd:scan
|
||||
description: Rapid codebase assessment — lightweight alternative to /gsd:map-codebase
|
||||
description: Rapid codebase assessment — lightweight alternative to /gsd-map-codebase
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Write
|
||||
@@ -14,7 +14,7 @@ allowed-tools:
|
||||
Run a focused codebase scan for a single area, producing targeted documents in `.planning/codebase/`.
|
||||
Accepts an optional `--focus` flag: `tech`, `arch`, `quality`, `concerns`, or `tech+arch` (default).
|
||||
|
||||
Lightweight alternative to `/gsd:map-codebase` — spawns one mapper agent instead of four parallel ones.
|
||||
Lightweight alternative to `/gsd-map-codebase` — spawns one mapper agent instead of four parallel ones.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -9,4 +9,4 @@ allowed-tools:
|
||||
|
||||
Show the following output to the user verbatim, with no extra commentary:
|
||||
|
||||
!`if ! command -v gsd-sdk >/dev/null 2>&1; then printf '⚠ gsd-sdk not found in PATH — /gsd:set-profile requires it.\n\nInstall the GSD SDK:\n npm install -g @gsd-build/sdk\n\nOr update GSD to get the latest packages:\n /gsd:update\n'; exit 1; fi; gsd-sdk query config-set-model-profile $ARGUMENTS --raw`
|
||||
!`if ! command -v gsd-sdk >/dev/null 2>&1; then printf '⚠ gsd-sdk not found in PATH — /gsd-set-profile requires it.\n\nInstall the GSD SDK:\n npm install -g @gsd-build/sdk\n\nOr update GSD to get the latest packages:\n /gsd-update\n'; exit 1; fi; gsd-sdk query config-set-model-profile $ARGUMENTS --raw`
|
||||
|
||||
@@ -9,7 +9,7 @@ allowed-tools:
|
||||
---
|
||||
|
||||
<objective>
|
||||
Interactive configuration of GSD power-user knobs that don't belong in the common-case `/gsd:settings` prompt.
|
||||
Interactive configuration of GSD power-user knobs that don't belong in the common-case `/gsd-settings` prompt.
|
||||
|
||||
Routes to the settings-advanced workflow which handles:
|
||||
- Config existence ensuring (workstream-aware path resolution)
|
||||
@@ -18,7 +18,7 @@ Routes to the settings-advanced workflow which handles:
|
||||
- Config merging that preserves every unrelated key
|
||||
- Confirmation table display
|
||||
|
||||
Use `/gsd:settings` for the common-case toggles (model profile, research/plan_check/verifier, branching strategy, context warnings). Use `/gsd:settings-advanced` once those are set and you want to tune the internals.
|
||||
Use `/gsd-settings` for the common-case toggles (model profile, research/plan_check/verifier, branching strategy, context warnings). Use `/gsd-settings-advanced` once those are set and you want to tune the internals.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -19,8 +19,8 @@ API keys are stored plaintext in `.planning/config.json` but are masked
|
||||
(`****<last-4>`) in every piece of interactive output. The workflow never
|
||||
echoes plaintext to stdout, stderr, or any log.
|
||||
|
||||
This command is deliberately distinct from `/gsd:settings` (workflow toggles)
|
||||
and any `/gsd:settings-advanced` tuning surface. It handles *connectivity*,
|
||||
This command is deliberately distinct from `/gsd-settings` (workflow toggles)
|
||||
and any `/gsd-settings-advanced` tuning surface. It handles *connectivity*,
|
||||
not pipeline shape.
|
||||
</objective>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ allowed-tools:
|
||||
- AskUserQuestion
|
||||
---
|
||||
<objective>
|
||||
Bridge local completion → merged PR. After /gsd:verify-work passes, ship the work: push branch, create PR with auto-generated body, optionally trigger review, and track the merge.
|
||||
Bridge local completion → merged PR. After /gsd-verify-work passes, ship the work: push branch, create PR with auto-generated body, optionally trigger review, and track the merge.
|
||||
|
||||
Closes the plan → execute → verify → ship loop.
|
||||
</objective>
|
||||
|
||||
@@ -25,7 +25,7 @@ Two modes:
|
||||
- **Idea mode** (default) — describe a design idea to sketch
|
||||
- **Frontier mode** (no argument or "frontier") — analyzes existing sketch landscape and proposes consistency and frontier sketches
|
||||
|
||||
Does not require `/gsd:new-project` — auto-creates `.planning/sketches/` if needed.
|
||||
Does not require `/gsd-new-project` — auto-creates `.planning/sketches/` if needed.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -58,5 +58,5 @@ Execute the spec-phase workflow from @~/.claude/get-shit-done/workflows/spec-pha
|
||||
- Gate passed: ambiguity ≤ 0.20 AND all dimension minimums met
|
||||
- SPEC.md written with falsifiable requirements, explicit boundaries, and acceptance criteria
|
||||
- SPEC.md committed atomically
|
||||
- User knows they can now run /gsd:discuss-phase which will load SPEC.md automatically
|
||||
- User knows they can now run /gsd-discuss-phase which will load SPEC.md automatically
|
||||
</success_criteria>
|
||||
|
||||
@@ -25,7 +25,7 @@ Two modes:
|
||||
- **Idea mode** (default) — describe an idea to spike
|
||||
- **Frontier mode** (no argument or "frontier") — analyzes existing spike landscape and proposes integration and frontier spikes
|
||||
|
||||
Does not require `/gsd:new-project` — auto-creates `.planning/spikes/` if needed.
|
||||
Does not require `/gsd-new-project` — auto-creates `.planning/spikes/` if needed.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -38,7 +38,7 @@ ls .planning/threads/*.md 2>/dev/null
|
||||
For each thread file found:
|
||||
- Read frontmatter `status` field via:
|
||||
```bash
|
||||
gsd-sdk query frontmatter.get .planning/threads/{file} status 2>/dev/null
|
||||
gsd-sdk query frontmatter.get .planning/threads/{file} status
|
||||
```
|
||||
- If frontmatter `status` field is missing, fall back to reading markdown heading `## Status: OPEN` (or IN PROGRESS / RESOLVED) from the file body
|
||||
- Read frontmatter `updated` field for the last-updated date
|
||||
@@ -62,7 +62,7 @@ frontend-build-tools resolved 2026-04-01 Vite vs webpack
|
||||
|
||||
If no threads exist (or none match the filter):
|
||||
```
|
||||
No threads found. Create one with: /gsd:thread <description>
|
||||
No threads found. Create one with: /gsd-thread <description>
|
||||
```
|
||||
|
||||
STOP after displaying. Do NOT proceed to further steps.
|
||||
@@ -117,8 +117,8 @@ When SUBCMD=status and SLUG is set (already sanitized):
|
||||
Next Steps:
|
||||
{content of ## Next Steps section}
|
||||
─────────────────────────────────────
|
||||
Resume with: /gsd:thread {SLUG}
|
||||
Close with: /gsd:thread close {SLUG}
|
||||
Resume with: /gsd-thread {SLUG}
|
||||
Close with: /gsd-thread close {SLUG}
|
||||
```
|
||||
|
||||
No agent spawn. STOP after printing.
|
||||
@@ -201,8 +201,8 @@ updated: {today ISO date}
|
||||
Thread: {slug}
|
||||
File: .planning/threads/{slug}.md
|
||||
|
||||
Resume anytime with: /gsd:thread {slug}
|
||||
Close when done with: /gsd:thread close {slug}
|
||||
Resume anytime with: /gsd-thread {slug}
|
||||
Close when done with: /gsd-thread close {slug}
|
||||
```
|
||||
</mode_create>
|
||||
|
||||
@@ -210,10 +210,10 @@ updated: {today ISO date}
|
||||
|
||||
<notes>
|
||||
- Threads are NOT phase-scoped — they exist independently of the roadmap
|
||||
- Lighter weight than /gsd:pause-work — no phase state, no plan context
|
||||
- Lighter weight than /gsd-pause-work — no phase state, no plan context
|
||||
- The value is in Context and Next Steps — a cold-start session can pick up immediately
|
||||
- Threads can be promoted to phases or backlog items when they mature:
|
||||
/gsd:add-phase or /gsd:add-backlog with context from the thread
|
||||
/gsd-add-phase or /gsd-add-backlog with context from the thread
|
||||
- Thread files live in .planning/threads/ — no collision with phases or other GSD structures
|
||||
- Thread status values: `open`, `in_progress`, `resolved`
|
||||
</notes>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: gsd:ultraplan-phase
|
||||
description: "[BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely while terminal stays free, review in browser with inline comments, import back via /gsd:import. Claude Code only."
|
||||
description: "[BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely while terminal stays free, review in browser with inline comments, import back via /gsd-import. Claude Code only."
|
||||
argument-hint: "[phase-number]"
|
||||
allowed-tools:
|
||||
- Read
|
||||
@@ -13,9 +13,9 @@ allowed-tools:
|
||||
Offload GSD's plan phase to Claude Code's ultraplan cloud infrastructure.
|
||||
|
||||
Ultraplan drafts the plan in a remote cloud session while your terminal stays free.
|
||||
Review and comment on the plan in your browser, then import it back via /gsd:import --from.
|
||||
Review and comment on the plan in your browser, then import it back via /gsd-import --from.
|
||||
|
||||
⚠ BETA: ultraplan is in research preview. Use /gsd:plan-phase for stable local planning.
|
||||
⚠ BETA: ultraplan is in research preview. Use /gsd-plan-phase for stable local planning.
|
||||
Requirements: Claude Code v2.1.91+, claude.ai account, GitHub repository.
|
||||
</objective>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Validate built features through conversational testing with persistent state.
|
||||
|
||||
Purpose: Confirm what Claude built actually works from user's perspective. One test at a time, plain text responses, no interrogation. When issues are found, automatically diagnose, plan fixes, and prepare for execution.
|
||||
|
||||
Output: {phase_num}-UAT.md tracking all test results. If issues found: diagnosed gaps, verified fix plans ready for /gsd:execute-phase
|
||||
Output: {phase_num}-UAT.md tracking all test results. If issues found: diagnosed gaps, verified fix plans ready for /gsd-execute-phase
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
|
||||
@@ -6,13 +6,13 @@ allowed-tools:
|
||||
- Bash
|
||||
---
|
||||
|
||||
# /gsd:workstreams
|
||||
# /gsd-workstreams
|
||||
|
||||
Manage parallel workstreams for concurrent milestone work.
|
||||
|
||||
## Usage
|
||||
|
||||
`/gsd:workstreams [subcommand] [args]`
|
||||
`/gsd-workstreams [subcommand] [args]`
|
||||
|
||||
### Subcommands
|
||||
|
||||
@@ -40,7 +40,7 @@ Display the workstreams in a table format showing name, status, current phase, a
|
||||
### create
|
||||
Run: `gsd-sdk query workstream.create <name> --raw --cwd "$CWD"`
|
||||
After creation, display the new workstream path and suggest next steps:
|
||||
- `/gsd:new-milestone --ws <name>` to set up the milestone
|
||||
- `/gsd-new-milestone --ws <name>` to set up the milestone
|
||||
|
||||
### status
|
||||
Run: `gsd-sdk query workstream.status <name> --raw --cwd "$CWD"`
|
||||
@@ -61,7 +61,7 @@ Run: `gsd-sdk query workstream.complete <name> --raw --cwd "$CWD"`
|
||||
Archive the workstream to milestones/.
|
||||
|
||||
### resume
|
||||
Set the workstream as active and suggest `/gsd:resume-work --ws <name>`.
|
||||
Set the workstream as active and suggest `/gsd-resume-work --ws <name>`.
|
||||
|
||||
## Step 3: Display Results
|
||||
|
||||
|
||||
@@ -483,6 +483,12 @@ async function runCommand(command, args, cwd, raw, defaultValue) {
|
||||
} else if (subcommand === 'prune') {
|
||||
const { 'keep-recent': keepRecent, 'dry-run': dryRun } = parseNamedArgs(args, ['keep-recent'], ['dry-run']);
|
||||
state.cmdStatePrune(cwd, { keepRecent: keepRecent || '3', dryRun: !!dryRun }, raw);
|
||||
} else if (subcommand === 'milestone-switch') {
|
||||
// Bug #2630: reset STATE.md frontmatter + Current Position for new milestone.
|
||||
// NB: the flag is `--milestone`, not `--version` — gsd-tools reserves
|
||||
// `--version` as a globally-invalid help flag (see NEVER_VALID_FLAGS above).
|
||||
const { milestone, name } = parseNamedArgs(args, ['milestone', 'name']);
|
||||
state.cmdStateMilestoneSwitch(cwd, milestone, name, raw);
|
||||
} else {
|
||||
state.cmdStateLoad(cwd, raw);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Scans all .planning/ artifact categories for items with open/unresolved state.
|
||||
* Returns structured JSON for workflow consumption.
|
||||
* Called by: gsd-tools.cjs audit-open
|
||||
* Used by: /gsd:complete-milestone pre-close gate
|
||||
* Used by: /gsd-complete-milestone pre-close gate
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -773,7 +773,7 @@ function cmdScaffold(cwd, type, options, raw) {
|
||||
switch (type) {
|
||||
case 'context': {
|
||||
filePath = path.join(phaseDir, `${padded}-CONTEXT.md`);
|
||||
content = `---\nphase: "${padded}"\nname: "${name || phaseInfo?.phase_name || 'Unnamed'}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${name || phaseInfo?.phase_name || 'Unnamed'} — Context\n\n## Decisions\n\n_Decisions will be captured during /gsd:discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
|
||||
content = `---\nphase: "${padded}"\nname: "${name || phaseInfo?.phase_name || 'Unnamed'}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${name || phaseInfo?.phase_name || 'Unnamed'} — Context\n\n## Decisions\n\n_Decisions will be captured during /gsd-discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
|
||||
break;
|
||||
}
|
||||
case 'uat': {
|
||||
|
||||
@@ -47,6 +47,7 @@ const VALID_CONFIG_KEYS = new Set([
|
||||
'workflow.inline_plan_threshold',
|
||||
'hooks.context_warnings',
|
||||
'hooks.workflow_guard',
|
||||
'workflow.context_coverage_gate',
|
||||
'statusline.show_last_command',
|
||||
'workflow.ui_review',
|
||||
'workflow.max_discuss_passes',
|
||||
|
||||
@@ -42,7 +42,7 @@ function validateKnownConfigKeyPath(keyPath) {
|
||||
* Merges (increasing priority):
|
||||
* 1. Hardcoded defaults — every key that loadConfig() resolves, plus mode/granularity
|
||||
* 2. User-level defaults from ~/.gsd/defaults.json (if present)
|
||||
* 3. userChoices — the settings the user explicitly selected during /gsd:new-project
|
||||
* 3. userChoices — the settings the user explicitly selected during /gsd-new-project
|
||||
*
|
||||
* Uses the canonical `git` namespace for branching keys (consistent with VALID_CONFIG_KEYS
|
||||
* and the settings workflow). loadConfig() handles both flat and nested formats, so this
|
||||
@@ -166,7 +166,7 @@ function buildNewProjectConfig(userChoices) {
|
||||
* Command: create a fully-materialized .planning/config.json for a new project.
|
||||
*
|
||||
* Accepts user-chosen settings as a JSON string (the keys the user explicitly
|
||||
* configured during /gsd:new-project). All remaining keys are filled from
|
||||
* configured during /gsd-new-project). All remaining keys are filled from
|
||||
* hardcoded defaults and optional ~/.gsd/defaults.json.
|
||||
*
|
||||
* Idempotent: if config.json already exists, returns { created: false }.
|
||||
|
||||
@@ -263,7 +263,7 @@ const CONFIG_DEFAULTS = {
|
||||
phase_naming: 'sequential', // 'sequential' (default, auto-increment) or 'custom' (arbitrary string IDs)
|
||||
project_code: null, // optional short prefix for phase dirs (e.g., 'CK' → 'CK-01-foundation')
|
||||
subagent_timeout: 300000, // 5 min default; increase for large codebases or slower models (ms)
|
||||
security_enforcement: true, // workflow.security_enforcement — threat-model-anchored security verification via /gsd:secure-phase
|
||||
security_enforcement: true, // workflow.security_enforcement — threat-model-anchored security verification via /gsd-secure-phase
|
||||
security_asvs_level: 1, // workflow.security_asvs_level — OWASP ASVS verification level (1=opportunistic, 2=standard, 3=comprehensive)
|
||||
security_block_on: 'high', // workflow.security_block_on — minimum severity that blocks phase advancement ('high' | 'medium' | 'low')
|
||||
post_planning_gaps: true, // workflow.post_planning_gaps — unified post-planning gap report (#2493): scan REQUIREMENTS.md + CONTEXT.md decisions vs all PLAN.md files
|
||||
@@ -288,26 +288,40 @@ function loadConfig(cwd) {
|
||||
// Auto-detect and sync sub_repos: scan for child directories with .git
|
||||
let configDirty = false;
|
||||
|
||||
// Migrate legacy "multiRepo: true" boolean → sub_repos array
|
||||
// Migrate legacy "multiRepo: true" boolean → planning.sub_repos array.
|
||||
// Canonical location is planning.sub_repos (#2561); writing to top-level
|
||||
// would be flagged as unknown by the validator below (#2638).
|
||||
if (parsed.multiRepo === true && !parsed.sub_repos && !parsed.planning?.sub_repos) {
|
||||
const detected = detectSubRepos(cwd);
|
||||
if (detected.length > 0) {
|
||||
parsed.sub_repos = detected;
|
||||
if (!parsed.planning) parsed.planning = {};
|
||||
parsed.planning.sub_repos = detected;
|
||||
parsed.planning.commit_docs = false;
|
||||
delete parsed.multiRepo;
|
||||
configDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep sub_repos in sync with actual filesystem
|
||||
const currentSubRepos = parsed.sub_repos || parsed.planning?.sub_repos || [];
|
||||
// Self-heal legacy/buggy installs: strip any stale top-level sub_repos,
|
||||
// preserving its value as the planning.sub_repos seed if that slot is empty.
|
||||
if (Object.prototype.hasOwnProperty.call(parsed, 'sub_repos')) {
|
||||
if (!parsed.planning) parsed.planning = {};
|
||||
if (!parsed.planning.sub_repos) {
|
||||
parsed.planning.sub_repos = parsed.sub_repos;
|
||||
}
|
||||
delete parsed.sub_repos;
|
||||
configDirty = true;
|
||||
}
|
||||
|
||||
// Keep planning.sub_repos in sync with actual filesystem
|
||||
const currentSubRepos = parsed.planning?.sub_repos || [];
|
||||
if (Array.isArray(currentSubRepos) && currentSubRepos.length > 0) {
|
||||
const detected = detectSubRepos(cwd);
|
||||
if (detected.length > 0) {
|
||||
const sorted = [...currentSubRepos].sort();
|
||||
if (JSON.stringify(sorted) !== JSON.stringify(detected)) {
|
||||
parsed.sub_repos = detected;
|
||||
if (!parsed.planning) parsed.planning = {};
|
||||
parsed.planning.sub_repos = detected;
|
||||
configDirty = true;
|
||||
}
|
||||
}
|
||||
@@ -1742,11 +1756,28 @@ function resolveReasoningEffortInternal(cwd, agentType) {
|
||||
*/
|
||||
function extractOneLinerFromBody(content) {
|
||||
if (!content) return null;
|
||||
// Normalize EOLs so matching works for LF and CRLF files.
|
||||
const normalized = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
||||
// Strip frontmatter first
|
||||
const body = content.replace(/^---\n[\s\S]*?\n---\n*/, '');
|
||||
// Find the first **...** line after a # heading
|
||||
const match = body.match(/^#[^\n]*\n+\*\*([^*]+)\*\*/m);
|
||||
return match ? match[1].trim() : null;
|
||||
const body = normalized.replace(/^---\n[\s\S]*?\n---\n*/, '');
|
||||
// Find the first **...** span on a line after a # heading.
|
||||
// Two supported template forms:
|
||||
// 1) Labeled: **One-liner:** Real prose here. (bug #2660 — new template)
|
||||
// 2) Bare: **Real prose here.** (legacy template)
|
||||
// For (1), the first bold span ends in a colon and the prose that follows
|
||||
// on the same line is the one-liner. For (2), the bold span itself is the
|
||||
// one-liner.
|
||||
const match = body.match(/^#[^\n]*\n+\*\*([^*\n]+)\*\*([^\n]*)/m);
|
||||
if (!match) return null;
|
||||
const boldInner = match[1].trim();
|
||||
const afterBold = match[2];
|
||||
// Labeled form: bold span is a "Label:" prefix — capture prose after it.
|
||||
if (/:\s*$/.test(boldInner)) {
|
||||
const prose = afterBold.trim();
|
||||
return prose.length > 0 ? prose : null;
|
||||
}
|
||||
// Bare form: the bold content itself is the one-liner.
|
||||
return boldInner.length > 0 ? boldInner : null;
|
||||
}
|
||||
|
||||
// ─── Misc utilities ───────────────────────────────────────────────────────────
|
||||
|
||||
@@ -253,7 +253,7 @@ function buildMessage(elements, affectedPaths, action) {
|
||||
lines.push(`Auto-remap scheduled for paths: ${affectedPaths.join(', ')}`);
|
||||
} else {
|
||||
lines.push(
|
||||
`Run /gsd:map-codebase --paths ${affectedPaths.join(',')} to refresh planning context.`,
|
||||
`Run /gsd-map-codebase --paths ${affectedPaths.join(',')} to refresh planning context.`,
|
||||
);
|
||||
}
|
||||
return lines.join('\n');
|
||||
|
||||
@@ -420,7 +420,7 @@ function buildPreview(gsd2Data, artifacts) {
|
||||
lines.push('');
|
||||
lines.push('Cannot migrate automatically:');
|
||||
lines.push(' - GSD-2 cost/token ledger (no v1 equivalent)');
|
||||
lines.push(' - GSD-2 database state (rebuilt from files on first /gsd:health)');
|
||||
lines.push(' - GSD-2 database state (rebuilt from files on first /gsd-health)');
|
||||
lines.push(' - VS Code extension state');
|
||||
|
||||
return lines.join('\n');
|
||||
|
||||
@@ -827,20 +827,70 @@ function cmdInitMilestoneOp(cwd, raw) {
|
||||
let phaseCount = 0;
|
||||
let completedPhases = 0;
|
||||
const phasesDir = path.join(planningDir(cwd), 'phases');
|
||||
|
||||
// Bug #2633 — ROADMAP.md (current milestone section) is the authority for
|
||||
// phase counts, NOT the on-disk `.planning/phases/` directory. After
|
||||
// `phases clear` between milestones, on-disk dirs will be a subset of the
|
||||
// roadmap until each phase is materialized; reading from disk causes
|
||||
// `all_phases_complete: true` to fire prematurely.
|
||||
let roadmapPhaseNumbers = [];
|
||||
try {
|
||||
const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
|
||||
const roadmapRaw = fs.readFileSync(roadmapPath, 'utf-8');
|
||||
const currentSection = extractCurrentMilestone(roadmapRaw, cwd);
|
||||
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
|
||||
let m;
|
||||
while ((m = phasePattern.exec(currentSection)) !== null) {
|
||||
roadmapPhaseNumbers.push(m[1]);
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
|
||||
// Canonicalize a phase token by stripping leading zeros from the integer
|
||||
// head while preserving any [A-Z]? suffix and dotted segments. So "03" →
|
||||
// "3", "03A" → "3A", "03.1" → "3.1", "3A" → "3A". Disk dirs that pad
|
||||
// ("03-alpha") then match roadmap tokens ("Phase 3") without ever
|
||||
// collapsing distinct tokens like "3" / "3A" / "3.1" into the same bucket.
|
||||
const canonicalizePhase = (tok) => {
|
||||
const m = tok.match(/^(\d+)([A-Z]?(?:\.\d+)*)$/);
|
||||
return m ? String(parseInt(m[1], 10)) + m[2] : tok;
|
||||
};
|
||||
const diskPhaseDirs = new Map();
|
||||
try {
|
||||
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
||||
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
||||
phaseCount = dirs.length;
|
||||
for (const e of entries) {
|
||||
if (!e.isDirectory()) continue;
|
||||
const m = e.name.match(/^(\d+[A-Z]?(?:\.\d+)*)/);
|
||||
if (!m) continue;
|
||||
diskPhaseDirs.set(canonicalizePhase(m[1]), e.name);
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
|
||||
// Count phases with summaries (completed)
|
||||
for (const dir of dirs) {
|
||||
if (roadmapPhaseNumbers.length > 0) {
|
||||
phaseCount = roadmapPhaseNumbers.length;
|
||||
for (const num of roadmapPhaseNumbers) {
|
||||
const dirName = diskPhaseDirs.get(canonicalizePhase(num));
|
||||
if (!dirName) continue;
|
||||
try {
|
||||
const phaseFiles = fs.readdirSync(path.join(phasesDir, dir));
|
||||
const phaseFiles = fs.readdirSync(path.join(phasesDir, dirName));
|
||||
const hasSummary = phaseFiles.some(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
||||
if (hasSummary) completedPhases++;
|
||||
} catch { /* intentionally empty */ }
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
} else {
|
||||
// Fallback: no parseable ROADMAP — preserve legacy on-disk behavior.
|
||||
try {
|
||||
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
||||
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
||||
phaseCount = dirs.length;
|
||||
for (const dir of dirs) {
|
||||
try {
|
||||
const phaseFiles = fs.readdirSync(path.join(phasesDir, dir));
|
||||
const hasSummary = phaseFiles.some(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
||||
if (hasSummary) completedPhases++;
|
||||
} catch { /* intentionally empty */ }
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
}
|
||||
|
||||
// Check archive
|
||||
const archiveDir = path.join(planningRoot(cwd), 'archive');
|
||||
@@ -929,10 +979,10 @@ function cmdInitManager(cwd, raw) {
|
||||
|
||||
// Validate prerequisites
|
||||
if (!fs.existsSync(paths.roadmap)) {
|
||||
error('No ROADMAP.md found. Run /gsd:new-milestone first.');
|
||||
error('No ROADMAP.md found. Run /gsd-new-milestone first.');
|
||||
}
|
||||
if (!fs.existsSync(paths.state)) {
|
||||
error('No STATE.md found. Run /gsd:new-milestone first.');
|
||||
error('No STATE.md found. Run /gsd-new-milestone first.');
|
||||
}
|
||||
const rawContent = fs.readFileSync(paths.roadmap, 'utf-8');
|
||||
const content = extractCurrentMilestone(rawContent, cwd);
|
||||
@@ -1111,7 +1161,7 @@ function cmdInitManager(cwd, raw) {
|
||||
phase_name: phase.name,
|
||||
action: 'execute',
|
||||
reason: `${phase.plan_count} plans ready, dependencies met`,
|
||||
command: `/gsd:execute-phase ${phase.number}`,
|
||||
command: `/gsd-execute-phase ${phase.number}`,
|
||||
});
|
||||
} else if (phase.disk_status === 'discussed' || phase.disk_status === 'researched') {
|
||||
recommendedActions.push({
|
||||
@@ -1119,7 +1169,7 @@ function cmdInitManager(cwd, raw) {
|
||||
phase_name: phase.name,
|
||||
action: 'plan',
|
||||
reason: 'Context gathered, ready for planning',
|
||||
command: `/gsd:plan-phase ${phase.number}`,
|
||||
command: `/gsd-plan-phase ${phase.number}`,
|
||||
});
|
||||
} else if ((phase.disk_status === 'empty' || phase.disk_status === 'no_directory') && phase.is_next_to_discuss) {
|
||||
recommendedActions.push({
|
||||
@@ -1127,7 +1177,7 @@ function cmdInitManager(cwd, raw) {
|
||||
phase_name: phase.name,
|
||||
action: 'discuss',
|
||||
reason: 'Unblocked, ready to gather context',
|
||||
command: `/gsd:discuss-phase ${phase.number}`,
|
||||
command: `/gsd-discuss-phase ${phase.number}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1230,6 +1280,7 @@ function cmdInitProgress(cwd, raw) {
|
||||
// Build set of phases defined in ROADMAP for the current milestone
|
||||
const roadmapPhaseNums = new Set();
|
||||
const roadmapPhaseNames = new Map();
|
||||
const roadmapCheckboxStates = new Map();
|
||||
try {
|
||||
const roadmapContent = extractCurrentMilestone(
|
||||
fs.readFileSync(path.join(planningDir(cwd), 'ROADMAP.md'), 'utf-8'), cwd
|
||||
@@ -1240,6 +1291,13 @@ function cmdInitProgress(cwd, raw) {
|
||||
roadmapPhaseNums.add(hm[1]);
|
||||
roadmapPhaseNames.set(hm[1], hm[2].replace(/\(INSERTED\)/i, '').trim());
|
||||
}
|
||||
// #2646: parse `- [x] Phase N` checkbox states so ROADMAP-only phases
|
||||
// inherit completion from the ROADMAP when no phase directory exists.
|
||||
const cbPattern = /-\s*\[(x| )\]\s*.*Phase\s+(\d+[A-Z]?(?:\.\d+)*)[:\s]/gi;
|
||||
let cbm;
|
||||
while ((cbm = cbPattern.exec(roadmapContent)) !== null) {
|
||||
roadmapCheckboxStates.set(cbm[2], cbm[1].toLowerCase() === 'x');
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
|
||||
const isDirInMilestone = getMilestonePhaseFilter(cwd);
|
||||
@@ -1295,21 +1353,27 @@ function cmdInitProgress(cwd, raw) {
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
|
||||
// Add phases defined in ROADMAP but not yet scaffolded to disk
|
||||
// Add phases defined in ROADMAP but not yet scaffolded to disk. When the
|
||||
// ROADMAP has a `- [x] Phase N` checkbox, honor it as 'complete' so
|
||||
// completed_count and status reflect the ROADMAP source of truth (#2646).
|
||||
for (const [num, name] of roadmapPhaseNames) {
|
||||
const stripped = num.replace(/^0+/, '') || '0';
|
||||
if (!seenPhaseNums.has(stripped)) {
|
||||
const checkboxComplete =
|
||||
roadmapCheckboxStates.get(num) === true ||
|
||||
roadmapCheckboxStates.get(stripped) === true;
|
||||
const status = checkboxComplete ? 'complete' : 'not_started';
|
||||
const phaseInfo = {
|
||||
number: num,
|
||||
name: name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, ''),
|
||||
directory: null,
|
||||
status: 'not_started',
|
||||
status,
|
||||
plan_count: 0,
|
||||
summary_count: 0,
|
||||
has_research: false,
|
||||
};
|
||||
phases.push(phaseInfo);
|
||||
if (!nextPhase && !currentPhase) {
|
||||
if (!nextPhase && !currentPhase && status !== 'complete') {
|
||||
nextPhase = phaseInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ function cmdPhaseAdd(cwd, description, raw, customId) {
|
||||
|
||||
// Build phase entry
|
||||
const dependsOn = config.phase_naming === 'custom' ? '' : `\n**Depends on:** Phase ${typeof _newPhaseId === 'number' ? _newPhaseId - 1 : 'TBD'}`;
|
||||
const phaseEntry = `\n### Phase ${_newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${_newPhaseId} to break down)\n`;
|
||||
const phaseEntry = `\n### Phase ${_newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd-plan-phase ${_newPhaseId} to break down)\n`;
|
||||
|
||||
// Find insertion point: before last "---" or at end
|
||||
let updatedContent;
|
||||
@@ -458,7 +458,7 @@ function cmdPhaseAddBatch(cwd, descriptions, raw) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
fs.writeFileSync(path.join(dirPath, '.gitkeep'), '');
|
||||
const dependsOn = config.phase_naming === 'custom' ? '' : `\n**Depends on:** Phase ${typeof newPhaseId === 'number' ? newPhaseId - 1 : 'TBD'}`;
|
||||
const phaseEntry = `\n### Phase ${newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${newPhaseId} to break down)\n`;
|
||||
const phaseEntry = `\n### Phase ${newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd-plan-phase ${newPhaseId} to break down)\n`;
|
||||
const lastSeparator = rawContent.lastIndexOf('\n---');
|
||||
rawContent = lastSeparator > 0
|
||||
? rawContent.slice(0, lastSeparator) + phaseEntry + rawContent.slice(lastSeparator)
|
||||
@@ -542,7 +542,7 @@ function cmdPhaseInsert(cwd, afterPhase, description, raw) {
|
||||
fs.writeFileSync(path.join(dirPath, '.gitkeep'), '');
|
||||
|
||||
// Build phase entry
|
||||
const phaseEntry = `\n### Phase ${_decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${_decimalPhase} to break down)\n`;
|
||||
const phaseEntry = `\n### Phase ${_decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd-plan-phase ${_decimalPhase} to break down)\n`;
|
||||
|
||||
// Insert after the target phase section
|
||||
const headerPattern = new RegExp(`(#{2,4}\\s*Phase\\s+0*${afterPhaseEscaped}:[^\\n]*\\n)`, 'i');
|
||||
@@ -828,7 +828,7 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
|
||||
// Update plan count in phase section.
|
||||
// Use direct .replace() rather than replaceInCurrentMilestone() so this
|
||||
// works when the current milestone section is itself inside a <details>
|
||||
// block (the standard /gsd:new-project layout). replaceInCurrentMilestone
|
||||
// block (the standard /gsd-new-project layout). replaceInCurrentMilestone
|
||||
// scopes to content after the last </details>, which misses content inside
|
||||
// the current milestone's own <details> wrapper (#2005).
|
||||
// The phase-scoped heading pattern is specific enough to avoid matching
|
||||
|
||||
@@ -173,7 +173,7 @@ const CLAUDE_INSTRUCTIONS = {
|
||||
};
|
||||
|
||||
const CLAUDE_MD_FALLBACKS = {
|
||||
project: 'Project not yet initialized. Run /gsd:new-project to set up.',
|
||||
project: 'Project not yet initialized. Run /gsd-new-project to set up.',
|
||||
stack: 'Technology stack not yet documented. Will populate after codebase mapping or first phase.',
|
||||
conventions: 'Conventions not yet established. Will populate as patterns emerge during development.',
|
||||
architecture: 'Architecture not yet mapped. Follow existing patterns found in the codebase.',
|
||||
@@ -187,9 +187,9 @@ const CLAUDE_MD_WORKFLOW_ENFORCEMENT = [
|
||||
'Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.',
|
||||
'',
|
||||
'Use these entry points:',
|
||||
'- `/gsd:quick` for small fixes, doc updates, and ad-hoc tasks',
|
||||
'- `/gsd:debug` for investigation and bug fixing',
|
||||
'- `/gsd:execute-phase` for planned phase work',
|
||||
'- `/gsd-quick` for small fixes, doc updates, and ad-hoc tasks',
|
||||
'- `/gsd-debug` for investigation and bug fixing',
|
||||
'- `/gsd-execute-phase` for planned phase work',
|
||||
'',
|
||||
'Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.',
|
||||
].join('\n');
|
||||
@@ -198,7 +198,7 @@ const CLAUDE_MD_PROFILE_PLACEHOLDER = [
|
||||
'<!-- GSD:profile-start -->',
|
||||
'## Developer Profile',
|
||||
'',
|
||||
'> Profile not yet configured. Run `/gsd:profile-user` to generate your developer profile.',
|
||||
'> Profile not yet configured. Run `/gsd-profile-user` to generate your developer profile.',
|
||||
'> This section is managed by `generate-claude-profile` -- do not edit manually.',
|
||||
'<!-- GSD:profile-end -->',
|
||||
].join('\n');
|
||||
@@ -768,7 +768,7 @@ function cmdGenerateDevPreferences(cwd, options, raw) {
|
||||
|
||||
let stackBlock;
|
||||
if (analysis.data_source === 'questionnaire') {
|
||||
stackBlock = 'Stack preferences not available (questionnaire-only profile). Run `/gsd:profile-user --refresh` with session data to populate.';
|
||||
stackBlock = 'Stack preferences not available (questionnaire-only profile). Run `/gsd-profile-user --refresh` with session data to populate.';
|
||||
} else if (options.stack) {
|
||||
stackBlock = options.stack;
|
||||
} else {
|
||||
@@ -854,7 +854,7 @@ function cmdGenerateClaudeProfile(cwd, options, raw) {
|
||||
'<!-- GSD:profile-start -->',
|
||||
'## Developer Profile',
|
||||
'',
|
||||
`> Generated by GSD from ${dataSource}. Run \`/gsd:profile-user --refresh\` to update.`,
|
||||
`> Generated by GSD from ${dataSource}. Run \`/gsd-profile-user --refresh\` to update.`,
|
||||
'',
|
||||
'| Dimension | Rating | Confidence |',
|
||||
'|-----------|--------|------------|',
|
||||
@@ -1053,7 +1053,7 @@ function cmdGenerateClaudeMd(cwd, options, raw) {
|
||||
let message = `Generated ${genCount}/${totalManaged} sections.`;
|
||||
if (sectionsFallback.length > 0) message += ` Fallback: ${sectionsFallback.join(', ')}.`;
|
||||
if (sectionsSkipped.length > 0) message += ` Skipped (manually edited): ${sectionsSkipped.join(', ')}.`;
|
||||
if (profileStatus === 'placeholder_added') message += ' Run /gsd:profile-user to unlock Developer Profile.';
|
||||
if (profileStatus === 'placeholder_added') message += ' Run /gsd-profile-user to unlock Developer Profile.';
|
||||
|
||||
const result = {
|
||||
claude_md_path: outputPath,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* Secrets handling — masking convention for API keys and other
|
||||
* credentials managed via /gsd:settings-integrations.
|
||||
* credentials managed via /gsd-settings-integrations.
|
||||
*
|
||||
* Convention: strings 8+ chars long render as `****<last-4>`; shorter
|
||||
* strings render as `****` with no tail (to avoid leaking a meaningful
|
||||
|
||||
@@ -1253,6 +1253,70 @@ function cmdStatePlannedPhase(cwd, phaseNumber, planCount, raw) {
|
||||
output({ updated, phase: phaseNumber, plan_count: planCount }, raw, updated.length > 0 ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug #2630: reset STATE.md for a new milestone cycle.
|
||||
* Stomps frontmatter milestone/milestone_name/status/progress AND rewrites
|
||||
* the Current Position body. Preserves Accumulated Context.
|
||||
* Symmetric with the SDK `stateMilestoneSwitch` handler.
|
||||
*/
|
||||
function cmdStateMilestoneSwitch(cwd, version, name, raw) {
|
||||
if (!version || !String(version).trim()) {
|
||||
output({ error: 'milestone required (--milestone <vX.Y>)' }, raw);
|
||||
return;
|
||||
}
|
||||
const resolvedName = (name && String(name).trim()) || 'milestone';
|
||||
const statePath = planningPaths(cwd).state;
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
|
||||
const lockPath = acquireStateLock(statePath);
|
||||
try {
|
||||
const content = fs.existsSync(statePath) ? fs.readFileSync(statePath, 'utf-8') : '';
|
||||
const existingFm = extractFrontmatter(content);
|
||||
const body = stripFrontmatter(content);
|
||||
|
||||
const positionPattern = /(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i;
|
||||
const resetPositionBody =
|
||||
`\nPhase: Not started (defining requirements)\n` +
|
||||
`Plan: —\n` +
|
||||
`Status: Defining requirements\n` +
|
||||
`Last activity: ${today} — Milestone ${version} started\n\n`;
|
||||
let newBody;
|
||||
if (positionPattern.test(body)) {
|
||||
newBody = body.replace(positionPattern, (_m, header) => `${header}${resetPositionBody}`);
|
||||
} else {
|
||||
const preface = body.trim().length > 0 ? body : '# Project State\n';
|
||||
newBody = `${preface.trimEnd()}\n\n## Current Position\n${resetPositionBody}`;
|
||||
}
|
||||
|
||||
const fm = {
|
||||
gsd_state_version: existingFm.gsd_state_version || '1.0',
|
||||
milestone: version,
|
||||
milestone_name: resolvedName,
|
||||
status: 'planning',
|
||||
last_updated: new Date().toISOString(),
|
||||
last_activity: today,
|
||||
progress: {
|
||||
total_phases: 0,
|
||||
completed_phases: 0,
|
||||
total_plans: 0,
|
||||
completed_plans: 0,
|
||||
percent: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const yamlStr = reconstructFrontmatter(fm);
|
||||
const assembled = `---\n${yamlStr}\n---\n\n${newBody.replace(/^\n+/, '')}`;
|
||||
atomicWriteFileSync(statePath, normalizeMd(assembled), 'utf-8');
|
||||
output(
|
||||
{ switched: true, version, name: resolvedName, status: 'planning' },
|
||||
raw,
|
||||
'true',
|
||||
);
|
||||
} finally {
|
||||
releaseStateLock(lockPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gate 1: Validate STATE.md against filesystem.
|
||||
* Returns { valid, warnings, drift } JSON.
|
||||
@@ -1644,6 +1708,7 @@ module.exports = {
|
||||
cmdStateValidate,
|
||||
cmdStateSync,
|
||||
cmdStatePrune,
|
||||
cmdStateMilestoneSwitch,
|
||||
cmdSignalWaiting,
|
||||
cmdSignalResume,
|
||||
};
|
||||
|
||||
@@ -555,7 +555,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
|
||||
// ─── Check 1: .planning/ exists ───────────────────────────────────────────
|
||||
if (!fs.existsSync(planBase)) {
|
||||
addIssue('error', 'E001', '.planning/ directory not found', 'Run /gsd:new-project to initialize');
|
||||
addIssue('error', 'E001', '.planning/ directory not found', 'Run /gsd-new-project to initialize');
|
||||
output({
|
||||
status: 'broken',
|
||||
errors,
|
||||
@@ -568,7 +568,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
|
||||
// ─── Check 2: PROJECT.md exists and has required sections ─────────────────
|
||||
if (!fs.existsSync(projectPath)) {
|
||||
addIssue('error', 'E002', 'PROJECT.md not found', 'Run /gsd:new-project to create');
|
||||
addIssue('error', 'E002', 'PROJECT.md not found', 'Run /gsd-new-project to create');
|
||||
} else {
|
||||
const content = fs.readFileSync(projectPath, 'utf-8');
|
||||
const requiredSections = ['## What This Is', '## Core Value', '## Requirements'];
|
||||
@@ -581,39 +581,68 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
|
||||
// ─── Check 3: ROADMAP.md exists ───────────────────────────────────────────
|
||||
if (!fs.existsSync(roadmapPath)) {
|
||||
addIssue('error', 'E003', 'ROADMAP.md not found', 'Run /gsd:new-milestone to create roadmap');
|
||||
addIssue('error', 'E003', 'ROADMAP.md not found', 'Run /gsd-new-milestone to create roadmap');
|
||||
}
|
||||
|
||||
// ─── Check 4: STATE.md exists and references valid phases ─────────────────
|
||||
if (!fs.existsSync(statePath)) {
|
||||
addIssue('error', 'E004', 'STATE.md not found', 'Run /gsd:health --repair to regenerate', true);
|
||||
addIssue('error', 'E004', 'STATE.md not found', 'Run /gsd-health --repair to regenerate', true);
|
||||
repairs.push('regenerateState');
|
||||
} else {
|
||||
const stateContent = fs.readFileSync(statePath, 'utf-8');
|
||||
// Extract phase references from STATE.md
|
||||
const phaseRefs = [...stateContent.matchAll(/[Pp]hase\s+(\d+(?:\.\d+)*)/g)].map(m => m[1]);
|
||||
// Get disk phases
|
||||
const diskPhases = new Set();
|
||||
const phaseRefs = [...stateContent.matchAll(/[Pp]hase\s+(\d+[A-Z]?(?:\.\d+)*)/g)].map(m => m[1]);
|
||||
// Bug #2633 — ROADMAP.md is the authority for which phases are valid.
|
||||
// STATE.md may legitimately reference current-milestone future phases
|
||||
// (not yet materialized on disk) and shipped-milestone history phases
|
||||
// (archived / cleared off disk). Matching only against on-disk dirs
|
||||
// produces false W002 warnings in both cases.
|
||||
const validPhases = new Set();
|
||||
try {
|
||||
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
if (e.isDirectory()) {
|
||||
const m = e.name.match(/^(\d+(?:\.\d+)*)/);
|
||||
if (m) diskPhases.add(m[1]);
|
||||
const m = e.name.match(/^(\d+[A-Z]?(?:\.\d+)*)/);
|
||||
if (m) validPhases.add(m[1]);
|
||||
}
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
// Union in every phase declared anywhere in ROADMAP.md (current + shipped + backlog).
|
||||
try {
|
||||
if (fs.existsSync(roadmapPath)) {
|
||||
const roadmapRaw = fs.readFileSync(roadmapPath, 'utf-8');
|
||||
const all = [...roadmapRaw.matchAll(/#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)/gi)];
|
||||
for (const m of all) validPhases.add(m[1]);
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
// Compare canonical full phase tokens. Also accept a leading-zero variant
|
||||
// on the integer prefix only (e.g. "03" matching "3", "03.1" matching
|
||||
// "3.1") so historic STATE.md formatting still validates. Suffix tokens
|
||||
// like "3A" must match exactly — never collapsed to "3".
|
||||
const normalizedValid = new Set();
|
||||
for (const p of validPhases) {
|
||||
normalizedValid.add(p);
|
||||
const dotIdx = p.indexOf('.');
|
||||
const head = dotIdx === -1 ? p : p.slice(0, dotIdx);
|
||||
const tail = dotIdx === -1 ? '' : p.slice(dotIdx);
|
||||
if (/^\d+$/.test(head)) {
|
||||
normalizedValid.add(head.padStart(2, '0') + tail);
|
||||
}
|
||||
}
|
||||
// Check for invalid references
|
||||
for (const ref of phaseRefs) {
|
||||
const normalizedRef = String(parseInt(ref, 10)).padStart(2, '0');
|
||||
if (!diskPhases.has(ref) && !diskPhases.has(normalizedRef) && !diskPhases.has(String(parseInt(ref, 10)))) {
|
||||
// Only warn if phases dir has any content (not just an empty project)
|
||||
if (diskPhases.size > 0) {
|
||||
const dotIdx = ref.indexOf('.');
|
||||
const head = dotIdx === -1 ? ref : ref.slice(0, dotIdx);
|
||||
const tail = dotIdx === -1 ? '' : ref.slice(dotIdx);
|
||||
const padded = /^\d+$/.test(head) ? head.padStart(2, '0') + tail : ref;
|
||||
if (!normalizedValid.has(ref) && !normalizedValid.has(padded)) {
|
||||
// Only warn if we know any valid phases (not just an empty project)
|
||||
if (normalizedValid.size > 0) {
|
||||
addIssue(
|
||||
'warning',
|
||||
'W002',
|
||||
`STATE.md references phase ${ref}, but only phases ${[...diskPhases].sort().join(', ')} exist`,
|
||||
'Review STATE.md manually before changing it; /gsd:health --repair will not overwrite an existing STATE.md for phase mismatches'
|
||||
`STATE.md references phase ${ref}, but only phases ${[...validPhases].sort().join(', ')} are declared`,
|
||||
'Review STATE.md manually before changing it; /gsd-health --repair will not overwrite an existing STATE.md for phase mismatches'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -622,7 +651,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
|
||||
// ─── Check 5: config.json valid JSON + valid schema ───────────────────────
|
||||
if (!fs.existsSync(configPath)) {
|
||||
addIssue('warning', 'W003', 'config.json not found', 'Run /gsd:health --repair to create with defaults', true);
|
||||
addIssue('warning', 'W003', 'config.json not found', 'Run /gsd-health --repair to create with defaults', true);
|
||||
repairs.push('createConfig');
|
||||
} else {
|
||||
try {
|
||||
@@ -634,7 +663,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
addIssue('warning', 'W004', `config.json: invalid model_profile "${parsed.model_profile}"`, `Valid values: ${validProfiles.join(', ')}`);
|
||||
}
|
||||
} catch (err) {
|
||||
addIssue('error', 'E005', `config.json: JSON parse error - ${err.message}`, 'Run /gsd:health --repair to reset to defaults', true);
|
||||
addIssue('error', 'E005', `config.json: JSON parse error - ${err.message}`, 'Run /gsd-health --repair to reset to defaults', true);
|
||||
repairs.push('resetConfig');
|
||||
}
|
||||
}
|
||||
@@ -645,11 +674,11 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
const configRaw = fs.readFileSync(configPath, 'utf-8');
|
||||
const configParsed = JSON.parse(configRaw);
|
||||
if (configParsed.workflow && configParsed.workflow.nyquist_validation === undefined) {
|
||||
addIssue('warning', 'W008', 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)', 'Run /gsd:health --repair to add key', true);
|
||||
addIssue('warning', 'W008', 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)', 'Run /gsd-health --repair to add key', true);
|
||||
if (!repairs.includes('addNyquistKey')) repairs.push('addNyquistKey');
|
||||
}
|
||||
if (configParsed.workflow && configParsed.workflow.ai_integration_phase === undefined) {
|
||||
addIssue('warning', 'W016', 'config.json: workflow.ai_integration_phase absent (defaults to enabled — run /gsd:ai-integration-phase before planning AI system phases)', 'Run /gsd:health --repair to add key', true);
|
||||
addIssue('warning', 'W016', 'config.json: workflow.ai_integration_phase absent (defaults to enabled — run /gsd-ai-integration-phase before planning AI system phases)', 'Run /gsd-health --repair to add key', true);
|
||||
if (!repairs.includes('addAiIntegrationPhaseKey')) repairs.push('addAiIntegrationPhaseKey');
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
@@ -699,7 +728,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
try {
|
||||
const researchContent = fs.readFileSync(path.join(phasesDir, e.name, researchFile), 'utf-8');
|
||||
if (researchContent.includes('## Validation Architecture')) {
|
||||
addIssue('warning', 'W009', `Phase ${e.name}: has Validation Architecture in RESEARCH.md but no VALIDATION.md`, 'Re-run /gsd:plan-phase with --research to regenerate');
|
||||
addIssue('warning', 'W009', `Phase ${e.name}: has Validation Architecture in RESEARCH.md but no VALIDATION.md`, 'Re-run /gsd-plan-phase with --research to regenerate');
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
}
|
||||
@@ -792,7 +821,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
if (statusVal !== 'complete' && statusVal !== 'done') {
|
||||
addIssue('warning', 'W011',
|
||||
`STATE.md says current phase is ${statePhase} (status: ${statusVal || 'unknown'}) but ROADMAP.md shows it as [x] complete — state files may be out of sync`,
|
||||
'Run /gsd:progress to re-derive current position, or manually update STATE.md');
|
||||
'Run /gsd-progress to re-derive current position, or manually update STATE.md');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -895,7 +924,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
if (missingFromRegistry.length > 0) {
|
||||
addIssue('warning', 'W018',
|
||||
`MILESTONES.md missing ${missingFromRegistry.length} archived milestone(s): ${missingFromRegistry.join(', ')}`,
|
||||
'Run /gsd:health --backfill to synthesize missing entries from archive snapshots',
|
||||
'Run /gsd-health --backfill to synthesize missing entries from archive snapshots',
|
||||
true);
|
||||
repairs.push('backfillMilestones');
|
||||
}
|
||||
@@ -969,7 +998,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
stateContent += `**Current phase:** (determining...)\n`;
|
||||
stateContent += `**Status:** Resuming\n\n`;
|
||||
stateContent += `## Session Log\n\n`;
|
||||
stateContent += `- ${new Date().toISOString().split('T')[0]}: STATE.md regenerated by /gsd:health --repair\n`;
|
||||
stateContent += `- ${new Date().toISOString().split('T')[0]}: STATE.md regenerated by /gsd-health --repair\n`;
|
||||
writeStateMd(statePath, stateContent, cwd);
|
||||
repairActions.push({ action: repair, success: true, path: 'STATE.md' });
|
||||
break;
|
||||
@@ -1019,7 +1048,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
||||
// Build minimal entry from snapshot title or version
|
||||
const titleMatch = snapshot && snapshot.match(/^#\s+(.+)$/m);
|
||||
const milestoneName = titleMatch ? titleMatch[1].replace(/^Milestone\s+/i, '').replace(/^v[\d.]+\s*/, '').trim() : ver;
|
||||
const entry = `## ${ver}${milestoneName && milestoneName !== ver ? ` ${milestoneName}` : ''} (Backfilled: ${today})\n\n**Note:** Synthesized from archive snapshot by \`/gsd:health --backfill\`. Original completion date unknown.\n\n---\n\n`;
|
||||
const entry = `## ${ver}${milestoneName && milestoneName !== ver ? ` ${milestoneName}` : ''} (Backfilled: ${today})\n\n**Note:** Synthesized from archive snapshot by \`/gsd-health --backfill\`. Original completion date unknown.\n\n---\n\n`;
|
||||
const milestonesContent = fs.existsSync(milestonesPath)
|
||||
? fs.readFileSync(milestonesPath, 'utf-8')
|
||||
: '';
|
||||
|
||||
@@ -78,7 +78,7 @@ function cmdWorkstreamCreate(cwd, name, options, raw) {
|
||||
|
||||
const baseDir = planningRoot(cwd);
|
||||
if (!fs.existsSync(baseDir)) {
|
||||
error('.planning/ directory not found — run /gsd:new-project first');
|
||||
error('.planning/ directory not found — run /gsd-new-project first');
|
||||
}
|
||||
|
||||
const wsRoot = path.join(baseDir, 'workstreams');
|
||||
|
||||
@@ -72,21 +72,21 @@ reads is inert — the consumption mechanism is what gives an artifact meaning.
|
||||
- **Location**: `.planning/spikes/SPIKE-NNN/`
|
||||
- **Consumed by**: Planner when spike is referenced; `pause-work` for spike context handoff
|
||||
|
||||
### Spike README.md / MANIFEST.md (per-spike, via /gsd:spike)
|
||||
### Spike README.md / MANIFEST.md (per-spike, via /gsd-spike)
|
||||
- **Shape**: YAML frontmatter (spike, name, validates, verdict, related, tags) + run instructions + results
|
||||
- **Lifecycle**: Created by `/gsd:spike` → Verified → Wrapped up by `/gsd:spike-wrap-up`
|
||||
- **Lifecycle**: Created by `/gsd-spike` → Verified → Wrapped up by `/gsd-spike-wrap-up`
|
||||
- **Location**: `.planning/spikes/NNN-name/README.md`, `.planning/spikes/MANIFEST.md`
|
||||
- **Consumed by**: `/gsd:spike-wrap-up` for curation; `pause-work` for spike context handoff
|
||||
- **Consumed by**: `/gsd-spike-wrap-up` for curation; `pause-work` for spike context handoff
|
||||
|
||||
### Sketch README.md / MANIFEST.md / index.html (per-sketch)
|
||||
- **Shape**: YAML frontmatter (sketch, name, question, winner, tags) + variants as tabbed HTML
|
||||
- **Lifecycle**: Created by `/gsd:sketch` → Evaluated → Wrapped up by `/gsd:sketch-wrap-up`
|
||||
- **Lifecycle**: Created by `/gsd-sketch` → Evaluated → Wrapped up by `/gsd-sketch-wrap-up`
|
||||
- **Location**: `.planning/sketches/NNN-name/README.md`, `.planning/sketches/NNN-name/index.html`, `.planning/sketches/MANIFEST.md`
|
||||
- **Consumed by**: `/gsd:sketch-wrap-up` for curation; `pause-work` for sketch context handoff
|
||||
- **Consumed by**: `/gsd-sketch-wrap-up` for curation; `pause-work` for sketch context handoff
|
||||
|
||||
### WRAP-UP-SUMMARY.md (per wrap-up session)
|
||||
- **Shape**: Curation results, included/excluded items, feature/design area groupings
|
||||
- **Lifecycle**: Created by `/gsd:spike-wrap-up` or `/gsd:sketch-wrap-up`
|
||||
- **Lifecycle**: Created by `/gsd-spike-wrap-up` or `/gsd-sketch-wrap-up`
|
||||
- **Location**: `.planning/spikes/WRAP-UP-SUMMARY.md` or `.planning/sketches/WRAP-UP-SUMMARY.md`
|
||||
- **Consumed by**: Project history; not read by automated workflows
|
||||
|
||||
|
||||
@@ -50,13 +50,13 @@ Standard format for presenting next steps after completing a command or workflow
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:execute-phase 2`
|
||||
`/gsd-execute-phase 2`
|
||||
|
||||
---
|
||||
|
||||
**Also available:**
|
||||
- Review plan before executing
|
||||
- `/gsd:list-phase-assumptions 2` — check assumptions
|
||||
- `/gsd-list-phase-assumptions 2` — check assumptions
|
||||
|
||||
---
|
||||
```
|
||||
@@ -75,7 +75,7 @@ Add note that this is the last plan and what comes after:
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:execute-phase 2`
|
||||
`/gsd-execute-phase 2`
|
||||
|
||||
---
|
||||
|
||||
@@ -97,13 +97,13 @@ Add note that this is the last plan and what comes after:
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:plan-phase 2`
|
||||
`/gsd-plan-phase 2`
|
||||
|
||||
---
|
||||
|
||||
**Also available:**
|
||||
- `/gsd:discuss-phase 2` — gather context first
|
||||
- `/gsd:research-phase 2` — investigate unknowns
|
||||
- `/gsd-discuss-phase 2` — gather context first
|
||||
- `/gsd-research-phase 2` — investigate unknowns
|
||||
- Review roadmap
|
||||
|
||||
---
|
||||
@@ -126,13 +126,13 @@ Show completion status before next action:
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:plan-phase 3`
|
||||
`/gsd-plan-phase 3`
|
||||
|
||||
---
|
||||
|
||||
**Also available:**
|
||||
- `/gsd:discuss-phase 3` — gather context first
|
||||
- `/gsd:research-phase 3` — investigate unknowns
|
||||
- `/gsd-discuss-phase 3` — gather context first
|
||||
- `/gsd-research-phase 3` — investigate unknowns
|
||||
- Review what Phase 2 built
|
||||
|
||||
---
|
||||
@@ -151,11 +151,11 @@ When there's no clear primary action:
|
||||
|
||||
`/clear` then one of:
|
||||
|
||||
**To plan directly:** `/gsd:plan-phase 3`
|
||||
**To plan directly:** `/gsd-plan-phase 3`
|
||||
|
||||
**To discuss context first:** `/gsd:discuss-phase 3`
|
||||
**To discuss context first:** `/gsd-discuss-phase 3`
|
||||
|
||||
**To research unknowns:** `/gsd:research-phase 3`
|
||||
**To research unknowns:** `/gsd-research-phase 3`
|
||||
|
||||
---
|
||||
```
|
||||
@@ -175,7 +175,7 @@ All 4 phases shipped
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:new-milestone`
|
||||
`/gsd-new-milestone`
|
||||
|
||||
---
|
||||
```
|
||||
@@ -218,7 +218,7 @@ Extract: `**02-03: Refresh Token Rotation** — Add /api/auth/refresh with slidi
|
||||
## To Continue
|
||||
|
||||
Run `/clear`, then paste:
|
||||
/gsd:execute-phase 2
|
||||
/gsd-execute-phase 2
|
||||
```
|
||||
|
||||
User has no idea what 02-03 is about.
|
||||
@@ -226,7 +226,7 @@ User has no idea what 02-03 is about.
|
||||
### Don't: Missing /clear explanation
|
||||
|
||||
```
|
||||
`/gsd:plan-phase 3`
|
||||
`/gsd-plan-phase 3`
|
||||
|
||||
Run /clear first.
|
||||
```
|
||||
@@ -246,7 +246,7 @@ Sounds like an afterthought. Use "Also available:" instead.
|
||||
|
||||
```
|
||||
```
|
||||
/gsd:plan-phase 3
|
||||
/gsd-plan-phase 3
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Doc Conflict Engine
|
||||
|
||||
Shared conflict-detection contract for workflows that ingest external content into `.planning/` (e.g., `/gsd:import`, `/gsd:ingest-docs`). Defines the report format, severity semantics, and safety-gate behavior. The specific checks that populate each severity bucket are workflow-specific and defined by the calling workflow.
|
||||
Shared conflict-detection contract for workflows that ingest external content into `.planning/` (e.g., `/gsd-import`, `/gsd-ingest-docs`). Defines the report format, severity semantics, and safety-gate behavior. The specific checks that populate each severity bucket are workflow-specific and defined by the calling workflow.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Domain-Aware Probing Patterns
|
||||
|
||||
Shared reference for `/gsd-begin`, `/gsd:discuss-phase`, and domain exploration workflows.
|
||||
Shared reference for `/gsd-begin`, `/gsd-discuss-phase`, and domain exploration workflows.
|
||||
|
||||
When the user mentions a technology area, use these probes to ask insightful follow-up questions. Don't run through them as a checklist -- pick the 2-3 most relevant based on context. The goal is to surface hidden assumptions and trade-offs the user may not have considered yet.
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ Simple 2-option confirmation for re-planning, rebuild, replace plans, commit.
|
||||
4-option escalation for review escalation (max retries exceeded).
|
||||
- question: "Phase {N} has failed verification {attempt} times. How should we proceed?"
|
||||
- header: "Escalate"
|
||||
- options: Accept gaps | Re-plan (via /gsd:plan-phase) | Debug (via /gsd:debug) | Retry
|
||||
- options: Accept gaps | Re-plan (via /gsd-plan-phase) | Debug (via /gsd-debug) | Retry
|
||||
|
||||
## Pattern: multi-option-gaps
|
||||
4-option gap handler for review gaps-found.
|
||||
@@ -78,7 +78,7 @@ Up to 4 suggested next actions with selection (status, resume workflows).
|
||||
3-option confirmation for quick task scope validation.
|
||||
- question: "This task looks complex. Proceed as quick task or use full planning?"
|
||||
- header: "Scope"
|
||||
- options: Quick task | Full plan (via /gsd:plan-phase) | Revise
|
||||
- options: Quick task | Full plan (via /gsd-plan-phase) | Revise
|
||||
|
||||
## Pattern: depth-select
|
||||
3-option depth selection for planning workflow preferences.
|
||||
|
||||
@@ -38,7 +38,7 @@ Canonical gate types used across GSD workflows. Every validation checkpoint maps
|
||||
**Recovery:** Developer investigates root cause, fixes, restarts from checkpoint.
|
||||
**Examples:**
|
||||
- Context window critically low during execution
|
||||
- STATE.md in error state blocking /gsd:next
|
||||
- STATE.md in error state blocking /gsd-next
|
||||
- Verification finds critical missing deliverables
|
||||
|
||||
---
|
||||
|
||||
@@ -274,7 +274,7 @@ Set `commit_docs: false` so planning docs stay local and are not committed to an
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Auto-detection:** During `/gsd:new-project`, directories with their own `.git` folder are detected and offered for selection as sub-repos. On subsequent runs, `loadConfig` auto-syncs the `sub_repos` list with the filesystem — adding newly created repos and removing deleted ones. This means `config.json` may be rewritten automatically when repos change on disk.
|
||||
1. **Auto-detection:** During `/gsd-new-project`, directories with their own `.git` folder are detected and offered for selection as sub-repos. On subsequent runs, `loadConfig` auto-syncs the `sub_repos` list with the filesystem — adding newly created repos and removing deleted ones. This means `config.json` may be rewritten automatically when repos change on disk.
|
||||
2. **File grouping:** Code files are grouped by their sub-repo prefix (e.g., `backend/src/api/users.ts` belongs to the `backend/` repo).
|
||||
3. **Independent commits:** Each sub-repo receives its own atomic commit via `gsd-tools.cjs commit-to-subrepo`. File paths are made relative to the sub-repo root before staging.
|
||||
4. **Planning stays local:** The `.planning/` directory is not committed; it acts as cross-repo coordination.
|
||||
|
||||
@@ -75,7 +75,7 @@ If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic
|
||||
|
||||
```bash
|
||||
# Via settings command
|
||||
/gsd:settings
|
||||
/gsd-settings
|
||||
# → Select "Inherit" for model profile
|
||||
|
||||
# Or manually in .planning/config.json
|
||||
@@ -115,7 +115,7 @@ Overrides take precedence over the profile. Valid values: `opus`, `sonnet`, `hai
|
||||
|
||||
## Switching Profiles
|
||||
|
||||
Runtime: `/gsd:set-profile <profile>`
|
||||
Runtime: `/gsd-set-profile <profile>`
|
||||
|
||||
Per-project default: Set in `.planning/config.json`:
|
||||
```json
|
||||
|
||||
@@ -36,7 +36,7 @@ Configuration options for `.planning/` directory behavior.
|
||||
| `workflow.use_worktrees` | `true` | Whether executor agents run in isolated git worktrees. Set to `false` to disable worktrees — agents execute sequentially on the main working tree instead. Recommended for solo developers or when worktree merges cause issues. |
|
||||
| `workflow.subagent_timeout` | `300000` | Timeout in milliseconds for parallel subagent tasks (e.g. codebase mapping). Increase for large codebases or slower models. Default: 300000 (5 minutes). |
|
||||
| `workflow.inline_plan_threshold` | `2` | Plans with this many tasks or fewer execute inline (Pattern C) instead of spawning a subagent. Avoids ~14K token spawn overhead for small plans. Set to `0` to always spawn subagents. |
|
||||
| `manager.flags.discuss` | `""` | Flags passed to `/gsd:discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) |
|
||||
| `manager.flags.discuss` | `""` | Flags passed to `/gsd-discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) |
|
||||
| `manager.flags.plan` | `""` | Flags passed to plan workflow when dispatched from manager |
|
||||
| `manager.flags.execute` | `""` | Flags passed to execute workflow when dispatched from manager |
|
||||
| `response_language` | `null` | Language for user-facing questions and prompts across all phases/subagents (e.g. `"Portuguese"`, `"Japanese"`, `"Spanish"`). When set, all spawned agents include a directive to respond in this language. |
|
||||
@@ -236,7 +236,7 @@ Generated from `CONFIG_DEFAULTS` (core.cjs) and `VALID_CONFIG_KEYS` (config.cjs)
|
||||
| `context_window` | number | `200000` | `200000`, `1000000` | Context window size; set `1000000` for 1M-context models |
|
||||
| `resolve_model_ids` | boolean\|string | `false` | `false`, `true`, `"omit"` | Map model aliases to full Claude IDs; `"omit"` returns empty string |
|
||||
| `context` | string\|null | `null` | `"dev"`, `"research"`, `"review"` | Execution context profile that adjusts agent behavior: `"dev"` for development tasks, `"research"` for investigation/exploration, `"review"` for code review workflows |
|
||||
| `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /gsd:review (e.g., `review.models.gemini`). Falls back to CLI default when null. |
|
||||
| `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /gsd-review (e.g., `review.models.gemini`). Falls back to CLI default when null. |
|
||||
|
||||
### Workflow Fields
|
||||
|
||||
@@ -252,7 +252,7 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
|
||||
| `workflow.auto_advance` | boolean | `false` | `true`, `false` | Auto-advance to next phase after completion |
|
||||
| `workflow.node_repair` | boolean | `true` | `true`, `false` | Attempt automatic repair of failed plan nodes |
|
||||
| `workflow.node_repair_budget` | number | `2` | Any positive integer | Max repair retries per failed node |
|
||||
| `workflow.ai_integration_phase` | boolean | `true` | `true`, `false` | Run /gsd:ai-integration-phase before planning AI system phases |
|
||||
| `workflow.ai_integration_phase` | boolean | `true` | `true`, `false` | Run /gsd-ai-integration-phase before planning AI system phases |
|
||||
| `workflow.ui_phase` | boolean | `true` | `true`, `false` | Generate UI-SPEC.md for frontend phases |
|
||||
| `workflow.ui_safety_gate` | boolean | `true` | `true`, `false` | Require safety gate approval for UI changes |
|
||||
| `workflow.text_mode` | boolean | `false` | `true`, `false` | Use plain-text numbered lists instead of AskUserQuestion menus |
|
||||
@@ -265,7 +265,7 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
|
||||
| `workflow.code_review` | boolean | `true` | `true`, `false` | Enable built-in code review step in the ship workflow |
|
||||
| `workflow.code_review_depth` | string | `"standard"` | `"light"`, `"standard"`, `"deep"` | Depth level for code review analysis in the ship workflow |
|
||||
| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
|
||||
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/gsd:secure-phase`. When `false`, security checks are skipped entirely |
|
||||
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/gsd-secure-phase`. When `false`, security checks are skipped entirely |
|
||||
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive |
|
||||
| `workflow.security_block_on` | string | `"high"` | `"high"`, `"medium"`, `"low"` | Minimum severity that blocks phase advancement |
|
||||
| `workflow.post_planning_gaps` | boolean | `true` | `true`, `false` | Post-planning gap report (#2493). After plans are generated, scans REQUIREMENTS.md and CONTEXT.md `<decisions>` against all PLAN.md files and emits a unified `Source \| Item \| Status` table. Non-blocking. Set to `false` to skip Step 13e of plan-phase. _Alias:_ `post_planning_gaps` is the flat-key form used in `CONFIG_DEFAULTS`; `workflow.post_planning_gaps` is the canonical namespaced form. |
|
||||
@@ -319,11 +319,11 @@ Set via `learnings.*` namespace (e.g., `"learnings": { "max_inject": 5 }`). Used
|
||||
|
||||
### Intel Fields
|
||||
|
||||
Set via `intel.*` namespace (e.g., `"intel": { "enabled": true }`). Controls the queryable codebase intelligence system consumed by `/gsd:intel`.
|
||||
Set via `intel.*` namespace (e.g., `"intel": { "enabled": true }`). Controls the queryable codebase intelligence system consumed by `/gsd-intel`.
|
||||
|
||||
| Key | Type | Default | Allowed Values | Description |
|
||||
|-----|------|---------|----------------|-------------|
|
||||
| `intel.enabled` | boolean | `false` | `true`, `false` | Enable queryable codebase intelligence system. When `true`, `/gsd:intel` commands build and query a JSON index in `.planning/intel/`. |
|
||||
| `intel.enabled` | boolean | `false` | `true`, `false` | Enable queryable codebase intelligence system. When `true`, `/gsd-intel` commands build and query a JSON index in `.planning/intel/`. |
|
||||
|
||||
### Manager Fields
|
||||
|
||||
@@ -331,7 +331,7 @@ Set via `manager.*` namespace (e.g., `"manager": { "flags": { "discuss": "--auto
|
||||
|
||||
| Key | Type | Default | Allowed Values | Description |
|
||||
|-----|------|---------|----------------|-------------|
|
||||
| `manager.flags.discuss` | string | `""` | Any CLI flags string | Flags passed to `/gsd:discuss-phase` from manager (e.g., `"--auto --analyze"`) |
|
||||
| `manager.flags.discuss` | string | `""` | Any CLI flags string | Flags passed to `/gsd-discuss-phase` from manager (e.g., `"--auto --analyze"`) |
|
||||
| `manager.flags.plan` | string | `""` | Any CLI flags string | Flags passed to plan workflow from manager |
|
||||
| `manager.flags.execute` | string | `""` | Any CLI flags string | Flags passed to execute workflow from manager |
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ Apply this recommendation to the revision? [Yes] / [No, let me decide]
|
||||
### 3. Explore — Approach Comparison (requires #1729)
|
||||
|
||||
**When:** During Socratic conversation, when multiple viable approaches emerge.
|
||||
**Note:** This integration point will be added when /gsd:explore (#1729) lands.
|
||||
**Note:** This integration point will be added when /gsd-explore (#1729) lands.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -163,10 +163,10 @@ Then re-run verification to apply.
|
||||
|
||||
Overrides can also be managed through the verification workflow:
|
||||
|
||||
1. Run `/gsd:verify-work` — verification finds gaps
|
||||
1. Run `/gsd-verify-work` — verification finds gaps
|
||||
2. Review gaps — determine which are intentional deviations
|
||||
3. Add override entries to VERIFICATION.md frontmatter
|
||||
4. Re-run `/gsd:verify-work` — overrides are applied, remaining gaps shown
|
||||
4. Re-run `/gsd-verify-work` — overrides are applied, remaining gaps shown
|
||||
|
||||
</creating_overrides>
|
||||
|
||||
@@ -183,7 +183,7 @@ When a phase is re-verified (e.g., after gap closure):
|
||||
|
||||
### At Milestone Completion
|
||||
|
||||
During `/gsd:audit-milestone`, overrides are surfaced in the audit report:
|
||||
During `/gsd-audit-milestone`, overrides are surfaced in the audit report:
|
||||
|
||||
```
|
||||
### Verification Overrides ({count} across {phase_count} phases)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI-SPEC — Phase {N}: {phase_name}
|
||||
|
||||
> AI design contract generated by `/gsd:ai-integration-phase`. Consumed by `gsd-planner` and `gsd-eval-auditor`.
|
||||
> AI design contract generated by `/gsd-ai-integration-phase`. Consumed by `gsd-planner` and `gsd-eval-auditor`.
|
||||
> Locks framework selection, implementation guidance, and evaluation strategy before planning begins.
|
||||
|
||||
---
|
||||
|
||||
@@ -104,7 +104,7 @@ files_changed: []
|
||||
|
||||
<lifecycle>
|
||||
|
||||
**Creation:** Immediately when /gsd:debug is called
|
||||
**Creation:** Immediately when /gsd-debug is called
|
||||
- Create file with trigger from user input
|
||||
- Set status to "gathering"
|
||||
- Current Focus: next_action = "gather symptoms"
|
||||
|
||||
@@ -12,24 +12,24 @@ These files live directly at `.planning/` — not inside phase subdirectories.
|
||||
|
||||
| File | Template | Produced by | Purpose |
|
||||
|------|----------|-------------|---------|
|
||||
| `PROJECT.md` | `project.md` | `/gsd:new-project` | Project identity, goals, requirements summary |
|
||||
| `ROADMAP.md` | `roadmap.md` | `/gsd:new-milestone`, `/gsd:new-project` | Phase plan with milestones and progress tracking |
|
||||
| `STATE.md` | `state.md` | `/gsd:new-project`, `/gsd:health --repair` | Current session state, active phase, last activity |
|
||||
| `REQUIREMENTS.md` | `requirements.md` | `/gsd:new-milestone` | Functional requirements with traceability |
|
||||
| `MILESTONES.md` | `milestone.md` | `/gsd:complete-milestone` | Log of completed milestones with accomplishments |
|
||||
| `BACKLOG.md` | *(inline)* | `/gsd:add-backlog` | Pending ideas and deferred work |
|
||||
| `LEARNINGS.md` | *(inline)* | `/gsd-extract-learnings`, `/gsd:execute-phase` | Phase retrospective learnings for future plans |
|
||||
| `THREADS.md` | *(inline)* | `/gsd:thread` | Persistent discussion threads |
|
||||
| `config.json` | `config.json` | `/gsd:new-project`, `/gsd:health --repair` | Project-specific GSD configuration |
|
||||
| `PROJECT.md` | `project.md` | `/gsd-new-project` | Project identity, goals, requirements summary |
|
||||
| `ROADMAP.md` | `roadmap.md` | `/gsd-new-milestone`, `/gsd-new-project` | Phase plan with milestones and progress tracking |
|
||||
| `STATE.md` | `state.md` | `/gsd-new-project`, `/gsd-health --repair` | Current session state, active phase, last activity |
|
||||
| `REQUIREMENTS.md` | `requirements.md` | `/gsd-new-milestone` | Functional requirements with traceability |
|
||||
| `MILESTONES.md` | `milestone.md` | `/gsd-complete-milestone` | Log of completed milestones with accomplishments |
|
||||
| `BACKLOG.md` | *(inline)* | `/gsd-add-backlog` | Pending ideas and deferred work |
|
||||
| `LEARNINGS.md` | *(inline)* | `/gsd-extract-learnings`, `/gsd-execute-phase` | Phase retrospective learnings for future plans |
|
||||
| `THREADS.md` | *(inline)* | `/gsd-thread` | Persistent discussion threads |
|
||||
| `config.json` | `config.json` | `/gsd-new-project`, `/gsd-health --repair` | Project-specific GSD configuration |
|
||||
| `CLAUDE.md` | `claude-md.md` | `/gsd-profile` | Auto-assembled Claude Code context file |
|
||||
|
||||
### Version-stamped artifacts (pattern: `vX.Y-*.md`)
|
||||
|
||||
| Pattern | Produced by | Purpose |
|
||||
|---------|-------------|---------|
|
||||
| `vX.Y-MILESTONE-AUDIT.md` | `/gsd:audit-milestone` | Milestone audit report before archiving |
|
||||
| `vX.Y-MILESTONE-AUDIT.md` | `/gsd-audit-milestone` | Milestone audit report before archiving |
|
||||
|
||||
These files are archived to `.planning/milestones/` by `/gsd:complete-milestone`. Finding them at the `.planning/` root after completion indicates the archive step was skipped.
|
||||
These files are archived to `.planning/milestones/` by `/gsd-complete-milestone`. Finding them at the `.planning/` root after completion indicates the archive step was skipped.
|
||||
|
||||
---
|
||||
|
||||
@@ -39,24 +39,24 @@ These files live inside a phase directory. They are NOT checked by W019 (which o
|
||||
|
||||
| File Pattern | Template | Produced by | Purpose |
|
||||
|-------------|----------|-------------|---------|
|
||||
| `NN-MM-PLAN.md` | `phase-prompt.md` | `/gsd:plan-phase` | Executable implementation plan |
|
||||
| `NN-MM-SUMMARY.md` | `summary.md` | `/gsd:execute-phase` | Post-execution summary with learnings |
|
||||
| `NN-CONTEXT.md` | `context.md` | `/gsd:discuss-phase` | Scoped discussion decisions for the phase |
|
||||
| `NN-RESEARCH.md` | `research.md` | `/gsd:research-phase`, `/gsd:plan-phase` | Technical research for the phase |
|
||||
| `NN-VALIDATION.md` | `VALIDATION.md` | `/gsd:research-phase` (Nyquist) | Validation architecture (Nyquist method) |
|
||||
| `NN-UAT.md` | `UAT.md` | `/gsd:validate-phase` | User acceptance test results |
|
||||
| `NN-PATTERNS.md` | *(inline)* | `/gsd:plan-phase` (pattern mapper) | Analog file mapping for the phase |
|
||||
| `NN-UI-SPEC.md` | `UI-SPEC.md` | `/gsd:ui-phase` | UI design contract |
|
||||
| `NN-SECURITY.md` | `SECURITY.md` | `/gsd:secure-phase` | Security threat model |
|
||||
| `NN-AI-SPEC.md` | `AI-SPEC.md` | `/gsd:ai-integration-phase` | AI integration spec with eval strategy |
|
||||
| `NN-DEBUG.md` | `DEBUG.md` | `/gsd:debug` | Debug session log |
|
||||
| `NN-REVIEWS.md` | *(inline)* | `/gsd:review` | Cross-AI review feedback |
|
||||
| `NN-MM-PLAN.md` | `phase-prompt.md` | `/gsd-plan-phase` | Executable implementation plan |
|
||||
| `NN-MM-SUMMARY.md` | `summary.md` | `/gsd-execute-phase` | Post-execution summary with learnings |
|
||||
| `NN-CONTEXT.md` | `context.md` | `/gsd-discuss-phase` | Scoped discussion decisions for the phase |
|
||||
| `NN-RESEARCH.md` | `research.md` | `/gsd-research-phase`, `/gsd-plan-phase` | Technical research for the phase |
|
||||
| `NN-VALIDATION.md` | `VALIDATION.md` | `/gsd-research-phase` (Nyquist) | Validation architecture (Nyquist method) |
|
||||
| `NN-UAT.md` | `UAT.md` | `/gsd-validate-phase` | User acceptance test results |
|
||||
| `NN-PATTERNS.md` | *(inline)* | `/gsd-plan-phase` (pattern mapper) | Analog file mapping for the phase |
|
||||
| `NN-UI-SPEC.md` | `UI-SPEC.md` | `/gsd-ui-phase` | UI design contract |
|
||||
| `NN-SECURITY.md` | `SECURITY.md` | `/gsd-secure-phase` | Security threat model |
|
||||
| `NN-AI-SPEC.md` | `AI-SPEC.md` | `/gsd-ai-integration-phase` | AI integration spec with eval strategy |
|
||||
| `NN-DEBUG.md` | `DEBUG.md` | `/gsd-debug` | Debug session log |
|
||||
| `NN-REVIEWS.md` | *(inline)* | `/gsd-review` | Cross-AI review feedback |
|
||||
|
||||
---
|
||||
|
||||
## Milestone Archive (`.planning/milestones/`)
|
||||
|
||||
Files archived by `/gsd:complete-milestone`. These are never checked by W019.
|
||||
Files archived by `/gsd-complete-milestone`. These are never checked by W019.
|
||||
|
||||
| File Pattern | Source |
|
||||
|-------------|--------|
|
||||
|
||||
@@ -106,7 +106,7 @@ blocked: [N]
|
||||
**Gaps:**
|
||||
- APPEND only when issue found (YAML format)
|
||||
- After diagnosis: fill `root_cause`, `artifacts`, `missing`, `debug_session`
|
||||
- This section feeds directly into /gsd:plan-phase --gaps
|
||||
- This section feeds directly into /gsd-plan-phase --gaps
|
||||
|
||||
</section_rules>
|
||||
|
||||
@@ -120,7 +120,7 @@ blocked: [N]
|
||||
4. UAT.md Gaps section updated with diagnosis:
|
||||
- Each gap gets `root_cause`, `artifacts`, `missing`, `debug_session` filled
|
||||
5. status → "diagnosed"
|
||||
6. Ready for /gsd:plan-phase --gaps with root causes
|
||||
6. Ready for /gsd-plan-phase --gaps with root causes
|
||||
|
||||
**After diagnosis:**
|
||||
```yaml
|
||||
@@ -144,7 +144,7 @@ blocked: [N]
|
||||
|
||||
<lifecycle>
|
||||
|
||||
**Creation:** When /gsd:verify-work starts new session
|
||||
**Creation:** When /gsd-verify-work starts new session
|
||||
- Extract tests from SUMMARY.md files
|
||||
- Set status to "testing"
|
||||
- Current Test points to test 1
|
||||
@@ -171,7 +171,7 @@ blocked: [N]
|
||||
- Present summary with outstanding items highlighted
|
||||
|
||||
**Resuming partial session:**
|
||||
- `/gsd:verify-work {phase}` picks up from first pending/blocked test
|
||||
- `/gsd-verify-work {phase}` picks up from first pending/blocked test
|
||||
- When all items resolved, status advances to "complete"
|
||||
|
||||
**Resume after /clear:**
|
||||
|
||||
@@ -29,7 +29,7 @@ created: {date}
|
||||
|
||||
- **After every task commit:** Run `{quick run command}`
|
||||
- **After every plan wave:** Run `{full suite command}`
|
||||
- **Before `/gsd:verify-work`:** Full suite must be green
|
||||
- **Before `/gsd-verify-work`:** Full suite must be green
|
||||
- **Max feedback latency:** {N} seconds
|
||||
|
||||
---
|
||||
|
||||
@@ -21,7 +21,7 @@ The profile section is managed exclusively by `generate-claude-profile`.
|
||||
|
||||
**Fallback text:**
|
||||
```
|
||||
Project not yet initialized. Run /gsd:new-project to set up.
|
||||
Project not yet initialized. Run /gsd-new-project to set up.
|
||||
```
|
||||
|
||||
### Stack Section
|
||||
@@ -96,9 +96,9 @@ No project skills found. Add skills to any of: `.claude/skills/`, `.agents/skill
|
||||
Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.
|
||||
|
||||
Use these entry points:
|
||||
- `/gsd:quick` for small fixes, doc updates, and ad-hoc tasks
|
||||
- `/gsd:debug` for investigation and bug fixing
|
||||
- `/gsd:execute-phase` for planned phase work
|
||||
- `/gsd-quick` for small fixes, doc updates, and ad-hoc tasks
|
||||
- `/gsd-debug` for investigation and bug fixing
|
||||
- `/gsd-execute-phase` for planned phase work
|
||||
|
||||
Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.
|
||||
<!-- GSD:workflow-end -->
|
||||
@@ -109,7 +109,7 @@ Do not make direct repo edits outside a GSD workflow unless the user explicitly
|
||||
<!-- GSD:profile-start -->
|
||||
## Developer Profile
|
||||
|
||||
> Profile not yet configured. Run `/gsd:profile-user` to generate your developer profile.
|
||||
> Profile not yet configured. Run `/gsd-profile-user` to generate your developer profile.
|
||||
> This section is managed by `generate-claude-profile` — do not edit manually.
|
||||
<!-- GSD:profile-end -->
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Create: .planning/debug/{slug}.md
|
||||
|
||||
## Usage
|
||||
|
||||
**From /gsd:debug:**
|
||||
**From /gsd-debug:**
|
||||
```python
|
||||
Task(
|
||||
prompt=filled_template,
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Load developer preferences into this session
|
||||
# Developer Preferences
|
||||
|
||||
> Generated by GSD on {{generated_at}} from {{data_source}}.
|
||||
> Run `/gsd:profile-user --refresh` to regenerate.
|
||||
> Run `/gsd-profile-user --refresh` to regenerate.
|
||||
|
||||
## Behavioral Directives
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Template for `.planning/phases/XX-name/DISCOVERY.md` - shallow research for libr
|
||||
|
||||
**Purpose:** Answer "which library/option should we use" questions during mandatory discovery in plan-phase.
|
||||
|
||||
For deep ecosystem research ("how do experts build this"), use `/gsd:research-phase` which produces RESEARCH.md.
|
||||
For deep ecosystem research ("how do experts build this"), use `/gsd-research-phase` which produces RESEARCH.md.
|
||||
|
||||
---
|
||||
|
||||
@@ -142,5 +142,5 @@ Create `.planning/phases/XX-name/DISCOVERY.md`:
|
||||
- Niche/complex domains (3D, games, audio, shaders)
|
||||
- Need ecosystem knowledge, not just library choice
|
||||
- "How do experts build this" questions
|
||||
- Use `/gsd:research-phase` for these
|
||||
- Use `/gsd-research-phase` for these
|
||||
</guidelines>
|
||||
|
||||
@@ -142,7 +142,7 @@ After completion, create `.planning/phases/XX-name/{phase}-{plan}-SUMMARY.md`
|
||||
| `user_setup` | No | Array of human-required setup items (external services) |
|
||||
| `must_haves` | Yes | Goal-backward verification criteria (see below) |
|
||||
|
||||
**Wave is pre-computed:** Wave numbers are assigned during `/gsd:plan-phase`. Execute-phase reads `wave` directly from frontmatter and groups plans by wave number. No runtime dependency analysis needed.
|
||||
**Wave is pre-computed:** Wave numbers are assigned during `/gsd-plan-phase`. Execute-phase reads `wave` directly from frontmatter and groups plans by wave number. No runtime dependency analysis needed.
|
||||
|
||||
**Must-haves enable verification:** The `must_haves` field carries goal-backward requirements from planning to execution. After all plans complete, execute-phase spawns a verification subagent that checks these criteria against the actual codebase.
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ Template for spawning gsd-planner agent. The agent contains all planning experti
|
||||
</planning_context>
|
||||
|
||||
<downstream_consumer>
|
||||
Output consumed by /gsd:execute-phase
|
||||
Output consumed by /gsd-execute-phase
|
||||
Plans must be executable prompts with:
|
||||
- Frontmatter (wave, depends_on, files_modified, autonomous)
|
||||
- Tasks in XML format
|
||||
@@ -68,7 +68,7 @@ Before returning PLANNING COMPLETE:
|
||||
|
||||
## Usage
|
||||
|
||||
**From /gsd:plan-phase (standard mode):**
|
||||
**From /gsd-plan-phase (standard mode):**
|
||||
```python
|
||||
Task(
|
||||
prompt=filled_template,
|
||||
@@ -77,7 +77,7 @@ Task(
|
||||
)
|
||||
```
|
||||
|
||||
**From /gsd:plan-phase --gaps (gap closure mode):**
|
||||
**From /gsd-plan-phase --gaps (gap closure mode):**
|
||||
```python
|
||||
Task(
|
||||
prompt=filled_template, # with mode: gap_closure
|
||||
|
||||
@@ -149,7 +149,7 @@ and implemented by workflows/transition.md and workflows/complete-milestone.md.
|
||||
|
||||
For existing codebases:
|
||||
|
||||
1. **Map codebase first** via `/gsd:map-codebase`
|
||||
1. **Map codebase first** via `/gsd-map-codebase`
|
||||
|
||||
2. **Infer Validated requirements** from existing code:
|
||||
- What does the codebase actually do?
|
||||
|
||||
@@ -18,7 +18,7 @@ Template for `.planning/phases/XX-name/{phase_num}-RESEARCH.md` - comprehensive
|
||||
<user_constraints>
|
||||
## User Constraints (from CONTEXT.md)
|
||||
|
||||
**CRITICAL:** If CONTEXT.md exists from /gsd:discuss-phase, copy locked decisions here verbatim. These MUST be honored by the planner.
|
||||
**CRITICAL:** If CONTEXT.md exists from /gsd-discuss-phase, copy locked decisions here verbatim. These MUST be honored by the planner.
|
||||
|
||||
### Locked Decisions
|
||||
[Copy from CONTEXT.md `## Decisions` section - these are NON-NEGOTIABLE]
|
||||
|
||||
@@ -96,7 +96,7 @@ Status: ✓ = met minimum, ⚠ = below minimum (planner treats as assumption)
|
||||
|
||||
*Phase: [XX-name]*
|
||||
*Spec created: [date]*
|
||||
*Next step: /gsd:discuss-phase [X] — implementation decisions (how to build what's specified above)*
|
||||
*Next step: /gsd-discuss-phase [X] — implementation decisions (how to build what's specified above)*
|
||||
```
|
||||
|
||||
<good_examples>
|
||||
@@ -192,7 +192,7 @@ The database has a `posts` table and `follows` table. No feed query or feed UI e
|
||||
|
||||
*Phase: 03-post-feed*
|
||||
*Spec created: 2025-01-20*
|
||||
*Next step: /gsd:discuss-phase 3 — implementation decisions (card layout, loading skeleton, etc.)*
|
||||
*Next step: /gsd-discuss-phase 3 — implementation decisions (card layout, loading skeleton, etc.)*
|
||||
```
|
||||
|
||||
**Example 2: CLI tool (Database backup)**
|
||||
@@ -280,7 +280,7 @@ No backup tooling exists. The project uses PostgreSQL. Developers currently use
|
||||
|
||||
*Phase: 02-backup-command*
|
||||
*Spec created: 2025-01-20*
|
||||
*Next step: /gsd:discuss-phase 2 — implementation decisions (progress reporting, flag design, etc.)*
|
||||
*Next step: /gsd-discuss-phase 2 — implementation decisions (progress reporting, flag design, etc.)*
|
||||
```
|
||||
|
||||
</good_examples>
|
||||
|
||||
@@ -153,10 +153,10 @@ Updated after each plan completion.
|
||||
|
||||
**Decisions:** Reference to PROJECT.md Key Decisions table, plus recent decisions summary for quick access. Full decision log lives in PROJECT.md.
|
||||
|
||||
**Pending Todos:** Ideas captured via /gsd:add-todo
|
||||
**Pending Todos:** Ideas captured via /gsd-add-todo
|
||||
- Count of pending todos
|
||||
- Reference to .planning/todos/pending/
|
||||
- Brief list if few, count if many (e.g., "5 pending todos — see /gsd:check-todos")
|
||||
- Brief list if few, count if many (e.g., "5 pending todos — see /gsd-check-todos")
|
||||
|
||||
**Blockers/Concerns:** From "Next Phase Readiness" sections
|
||||
- Issues that affect future work
|
||||
|
||||
@@ -11,15 +11,15 @@ Read all files referenced by the invoking prompt's execution_context before star
|
||||
<step name="parse_arguments">
|
||||
Parse the command arguments:
|
||||
- All arguments become the phase description
|
||||
- Example: `/gsd:add-phase Add authentication` → description = "Add authentication"
|
||||
- Example: `/gsd:add-phase Fix critical performance issues` → description = "Fix critical performance issues"
|
||||
- Example: `/gsd-add-phase Add authentication` → description = "Add authentication"
|
||||
- Example: `/gsd-add-phase Fix critical performance issues` → description = "Fix critical performance issues"
|
||||
|
||||
If no arguments provided:
|
||||
|
||||
```
|
||||
ERROR: Phase description required
|
||||
Usage: /gsd:add-phase <description>
|
||||
Example: /gsd:add-phase Add authentication system
|
||||
Usage: /gsd-add-phase <description>
|
||||
Example: /gsd-add-phase Add authentication system
|
||||
```
|
||||
|
||||
Exit.
|
||||
@@ -36,7 +36,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
Check `roadmap_exists` from init JSON. If false:
|
||||
```
|
||||
ERROR: No roadmap found (.planning/ROADMAP.md)
|
||||
Run /gsd:new-project to initialize.
|
||||
Run /gsd-new-project to initialize.
|
||||
```
|
||||
Exit.
|
||||
</step>
|
||||
@@ -89,12 +89,12 @@ Roadmap updated: .planning/ROADMAP.md
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:plan-phase {N}`
|
||||
`/gsd-plan-phase {N}`
|
||||
|
||||
---
|
||||
|
||||
**Also available:**
|
||||
- `/gsd:add-phase <description>` — add another phase
|
||||
- `/gsd-add-phase <description>` — add another phase
|
||||
- Review roadmap
|
||||
|
||||
---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<purpose>
|
||||
Generate unit and E2E tests for a completed phase based on its SUMMARY.md, CONTEXT.md, and implementation. Classifies each changed file into TDD (unit), E2E (browser), or Skip categories, presents a test plan for user approval, then generates tests following RED-GREEN conventions.
|
||||
|
||||
Users currently hand-craft `/gsd:quick` prompts for test generation after each phase. This workflow standardizes the process with proper classification, quality gates, and gap reporting.
|
||||
Users currently hand-craft `/gsd-quick` prompts for test generation after each phase. This workflow standardizes the process with proper classification, quality gates, and gap reporting.
|
||||
</purpose>
|
||||
|
||||
<required_reading>
|
||||
@@ -15,15 +15,15 @@ Parse `$ARGUMENTS` for:
|
||||
- Phase number (integer, decimal, or letter-suffix) → store as `$PHASE_ARG`
|
||||
- Remaining text after phase number → store as `$EXTRA_INSTRUCTIONS` (optional)
|
||||
|
||||
Example: `/gsd:add-tests 12 focus on edge cases` → `$PHASE_ARG=12`, `$EXTRA_INSTRUCTIONS="focus on edge cases"`
|
||||
Example: `/gsd-add-tests 12 focus on edge cases` → `$PHASE_ARG=12`, `$EXTRA_INSTRUCTIONS="focus on edge cases"`
|
||||
|
||||
If no phase argument provided:
|
||||
|
||||
```
|
||||
ERROR: Phase number required
|
||||
Usage: /gsd:add-tests <phase> [additional instructions]
|
||||
Example: /gsd:add-tests 12
|
||||
Example: /gsd:add-tests 12 focus on edge cases in the pricing module
|
||||
Usage: /gsd-add-tests <phase> [additional instructions]
|
||||
Example: /gsd-add-tests 12
|
||||
Example: /gsd-add-tests 12 focus on edge cases in the pricing module
|
||||
```
|
||||
|
||||
Exit.
|
||||
@@ -54,7 +54,7 @@ Read the phase artifacts (in order of priority):
|
||||
If no SUMMARY.md exists:
|
||||
```
|
||||
ERROR: No SUMMARY.md found for phase ${PHASE_ARG}
|
||||
This command works on completed phases. Run /gsd:execute-phase first.
|
||||
This command works on completed phases. Run /gsd-execute-phase first.
|
||||
```
|
||||
Exit.
|
||||
|
||||
@@ -318,7 +318,7 @@ Present next steps:
|
||||
## ▶ Next Up — [${PROJECT_CODE}] ${PROJECT_TITLE}
|
||||
|
||||
{if bugs discovered:}
|
||||
**Fix discovered bugs:** `/gsd:quick fix the {N} test failures discovered in phase ${phase_number}`
|
||||
**Fix discovered bugs:** `/gsd-quick fix the {N} test failures discovered in phase ${phase_number}`
|
||||
|
||||
{if blocked tests:}
|
||||
**Resolve test blockers:** {description of what's needed}
|
||||
@@ -329,8 +329,8 @@ Present next steps:
|
||||
---
|
||||
|
||||
**Also available:**
|
||||
- `/gsd:add-tests {next_phase}` — test another phase
|
||||
- `/gsd:verify-work {phase_number}` — run UAT verification
|
||||
- `/gsd-add-tests {next_phase}` — test another phase
|
||||
- `/gsd-verify-work {phase_number}` — run UAT verification
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
@@ -28,7 +28,7 @@ Note existing areas from the todos array for consistency in infer_area step.
|
||||
|
||||
<step name="extract_content">
|
||||
**With arguments:** Use as the title/focus.
|
||||
- `/gsd:add-todo Add auth token refresh` → title = "Add auth token refresh"
|
||||
- `/gsd-add-todo Add auth token refresh` → title = "Add auth token refresh"
|
||||
|
||||
**Without arguments:** Analyze recent conversation to extract:
|
||||
- The specific problem, idea, or task discussed
|
||||
@@ -143,7 +143,7 @@ Would you like to:
|
||||
|
||||
1. Continue with current work
|
||||
2. Add another todo
|
||||
3. View all todos (/gsd:check-todos)
|
||||
3. View all todos (/gsd-check-todos)
|
||||
```
|
||||
</step>
|
||||
|
||||
|
||||
@@ -43,11 +43,11 @@ AI_PHASE_ENABLED=$(gsd-sdk query config-get workflow.ai_integration_phase 2>/dev
|
||||
|
||||
**If `AI_PHASE_ENABLED` is `false`:**
|
||||
```
|
||||
AI phase is disabled in config. Enable via /gsd:settings.
|
||||
AI phase is disabled in config. Enable via /gsd-settings.
|
||||
```
|
||||
Exit workflow.
|
||||
|
||||
**If `planning_exists` is false:** Error — run `/gsd:new-project` first.
|
||||
**If `planning_exists` is false:** Error — run `/gsd-new-project` first.
|
||||
|
||||
## 2. Parse and Validate Phase
|
||||
|
||||
@@ -64,7 +64,7 @@ PHASE_INFO=$(gsd-sdk query roadmap.get-phase "${PHASE}")
|
||||
**If `has_context` is false:**
|
||||
```
|
||||
No CONTEXT.md found for Phase {N}.
|
||||
Recommended: run /gsd:discuss-phase {N} first to capture framework preferences.
|
||||
Recommended: run /gsd-discuss-phase {N} first to capture framework preferences.
|
||||
Continuing without user decisions — framework selector will ask all questions.
|
||||
```
|
||||
Continue (non-blocking).
|
||||
@@ -122,7 +122,7 @@ Goal: {phase_goal}
|
||||
|
||||
Parse selector output for: `primary_framework`, `system_type`, `model_provider`, `eval_concerns`, `alternative_framework`.
|
||||
|
||||
**If selector fails or returns empty:** Exit with error — "Framework selection failed. Re-run /gsd:ai-integration-phase {N} or answer the framework question in /gsd:discuss-phase {N} first."
|
||||
**If selector fails or returns empty:** Exit with error — "Framework selection failed. Re-run /gsd-ai-integration-phase {N} or answer the framework question in /gsd-discuss-phase {N} first."
|
||||
|
||||
## 6. Initialize AI-SPEC.md
|
||||
|
||||
@@ -266,7 +266,7 @@ git commit -m "docs({phase_slug}): generate AI-SPEC.md — {primary_framework} +
|
||||
◆ Output: {ai_spec_path}
|
||||
|
||||
Next step:
|
||||
/gsd:plan-phase {N} — planner will consume AI-SPEC.md
|
||||
/gsd-plan-phase {N} — planner will consume AI-SPEC.md
|
||||
```
|
||||
|
||||
</process>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<purpose>
|
||||
Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution by `/gsd:manager`.
|
||||
Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution by `/gsd-manager`.
|
||||
</purpose>
|
||||
|
||||
<process>
|
||||
|
||||
## 1. Load ROADMAP.md
|
||||
|
||||
Read `.planning/ROADMAP.md`. If it does not exist, error: "No ROADMAP.md found — run `/gsd:new-project` first."
|
||||
Read `.planning/ROADMAP.md`. If it does not exist, error: "No ROADMAP.md found — run `/gsd-new-project` first."
|
||||
|
||||
Extract all phases. For each phase capture:
|
||||
- Phase number and name
|
||||
@@ -91,6 +91,6 @@ When writing to ROADMAP.md:
|
||||
- Preserve all other phase content unchanged
|
||||
- Do not reorder phases
|
||||
|
||||
After applying: "ROADMAP.md updated. Run `/gsd:manager` to execute phases in the correct order."
|
||||
After applying: "ROADMAP.md updated. Run `/gsd-manager` to execute phases in the correct order."
|
||||
|
||||
</process>
|
||||
|
||||
@@ -18,7 +18,7 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
|
||||
```bash
|
||||
INIT=$(gsd-sdk query init.milestone-op)
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS_CHECKER=$(gsd-sdk query agent-skills gsd-integration-checker 2>/dev/null)
|
||||
AGENT_SKILLS_CHECKER=$(gsd-sdk query agent-skills gsd-integration-checker)
|
||||
```
|
||||
|
||||
Extract from init JSON: `milestone_version`, `milestone_name`, `phase_count`, `completed_phases`, `commit_docs`.
|
||||
@@ -158,7 +158,7 @@ Classify per phase:
|
||||
|
||||
Add to audit YAML: `nyquist: { compliant_phases, partial_phases, missing_phases, overall }`
|
||||
|
||||
Discovery only — never auto-calls `/gsd:validate-phase`.
|
||||
Discovery only — never auto-calls `/gsd-validate-phase`.
|
||||
|
||||
## 6. Aggregate into v{version}-MILESTONE-AUDIT.md
|
||||
|
||||
@@ -231,7 +231,7 @@ All requirements covered. Cross-phase integration verified. E2E flows complete.
|
||||
|
||||
/clear then:
|
||||
|
||||
/gsd:complete-milestone {version}
|
||||
/gsd-complete-milestone {version}
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -264,9 +264,9 @@ All requirements covered. Cross-phase integration verified. E2E flows complete.
|
||||
|
||||
| Phase | VALIDATION.md | Compliant | Action |
|
||||
|-------|---------------|-----------|--------|
|
||||
| {phase} | exists/missing | true/false/partial | `/gsd:validate-phase {N}` |
|
||||
| {phase} | exists/missing | true/false/partial | `/gsd-validate-phase {N}` |
|
||||
|
||||
Phases needing validation: run `/gsd:validate-phase {N}` for each flagged phase.
|
||||
Phases needing validation: run `/gsd-validate-phase {N}` for each flagged phase.
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -276,13 +276,13 @@ Phases needing validation: run `/gsd:validate-phase {N}` for each flagged phase.
|
||||
|
||||
/clear then:
|
||||
|
||||
/gsd:plan-milestone-gaps
|
||||
/gsd-plan-milestone-gaps
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
**Also available:**
|
||||
- cat .planning/v{version}-MILESTONE-AUDIT.md — see full report
|
||||
- /gsd:complete-milestone {version} — proceed anyway (accept tech debt)
|
||||
- /gsd-complete-milestone {version} — proceed anyway (accept tech debt)
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -312,13 +312,13 @@ All requirements met. No critical blockers. Accumulated tech debt needs review.
|
||||
|
||||
**A. Complete milestone** — accept debt, track in backlog
|
||||
|
||||
/gsd:complete-milestone {version}
|
||||
/gsd-complete-milestone {version}
|
||||
|
||||
**B. Plan cleanup phase** — address debt before completing
|
||||
|
||||
/clear then:
|
||||
|
||||
/gsd:plan-milestone-gaps
|
||||
/gsd-plan-milestone-gaps
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
</offer_next>
|
||||
|
||||
@@ -76,9 +76,9 @@ Present the audit report:
|
||||
|
||||
## Recommended Actions
|
||||
|
||||
1. **Close stale items:** `/gsd:verify-work {phase}` — mark stale tests as resolved
|
||||
1. **Close stale items:** `/gsd-verify-work {phase}` — mark stale tests as resolved
|
||||
2. **Run active tests:** Human UAT test plan below
|
||||
3. **When prerequisites met:** Retest blocked items with `/gsd:verify-work {phase}`
|
||||
3. **When prerequisites met:** Retest blocked items with `/gsd-verify-work {phase}`
|
||||
```
|
||||
</step>
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
|
||||
Parse JSON for: `milestone_version`, `milestone_name`, `phase_count`, `completed_phases`, `roadmap_exists`, `state_exists`, `commit_docs`.
|
||||
|
||||
**If `roadmap_exists` is false:** Error — "No ROADMAP.md found. Run `/gsd:new-milestone` first."
|
||||
**If `state_exists` is false:** Error — "No STATE.md found. Run `/gsd:new-milestone` first."
|
||||
**If `roadmap_exists` is false:** Error — "No ROADMAP.md found. Run `/gsd-new-milestone` first."
|
||||
**If `state_exists` is false:** Error — "No STATE.md found. Run `/gsd-new-milestone` first."
|
||||
|
||||
Display startup banner:
|
||||
|
||||
@@ -537,7 +537,7 @@ Read and execute: `$HOME/.claude/get-shit-done/references/autonomous-smart-discu
|
||||
Completed through phase ${TO_PHASE} as requested.
|
||||
Remaining phases were not executed.
|
||||
|
||||
Resume with: /gsd:autonomous --from ${next_incomplete_phase}
|
||||
Resume with: /gsd-autonomous --from ${next_incomplete_phase}
|
||||
```
|
||||
|
||||
Proceed directly to lifecycle step (which handles partial completion — skips audit/complete/cleanup since not all phases are done). Exit cleanly.
|
||||
@@ -589,7 +589,7 @@ If all phases complete, proceed to lifecycle step.
|
||||
Phase ${ONLY_PHASE}: ${PHASE_NAME} — Done
|
||||
Mode: Single phase (--only)
|
||||
|
||||
Lifecycle skipped — run /gsd:autonomous without --only
|
||||
Lifecycle skipped — run /gsd-autonomous without --only
|
||||
after all phases complete to trigger audit/complete/cleanup.
|
||||
```
|
||||
|
||||
@@ -647,7 +647,7 @@ Ask user via AskUserQuestion:
|
||||
|
||||
On **"Continue anyway"**: Display `Audit ⏭ Gaps accepted — proceeding to complete milestone` and proceed to 5b.
|
||||
|
||||
On **"Stop"**: Go to handle_blocker with "User stopped — audit gaps remain. Run /gsd:audit-milestone to review, then /gsd:complete-milestone when ready."
|
||||
On **"Stop"**: Go to handle_blocker with "User stopped — audit gaps remain. Run /gsd-audit-milestone to review, then /gsd-complete-milestone when ready."
|
||||
|
||||
**If `tech_debt`:**
|
||||
|
||||
@@ -662,7 +662,7 @@ Show the summary, then ask user via AskUserQuestion:
|
||||
|
||||
On **"Continue with tech debt"**: Display `Audit ⏭ Tech debt acknowledged — proceeding to complete milestone` and proceed to 5b.
|
||||
|
||||
On **"Stop"**: Go to handle_blocker with "User stopped — tech debt to address. Run /gsd:audit-milestone to review details."
|
||||
On **"Stop"**: Go to handle_blocker with "User stopped — tech debt to address. Run /gsd-audit-milestone to review details."
|
||||
|
||||
**5b. Complete Milestone**
|
||||
|
||||
@@ -732,7 +732,7 @@ When any phase operation fails or a blocker is detected, present 3 options via A
|
||||
Skipped: {list of skipped phases}
|
||||
Remaining: {list of remaining phases}
|
||||
|
||||
Resume with: /gsd:autonomous ${ONLY_PHASE ? "--only " + ONLY_PHASE : "--from " + next_phase}${TO_PHASE ? " --to " + TO_PHASE : ""}
|
||||
Resume with: /gsd-autonomous ${ONLY_PHASE ? "--only " + ONLY_PHASE : "--from " + next_phase}${TO_PHASE ? " --to " + TO_PHASE : ""}
|
||||
```
|
||||
|
||||
</step>
|
||||
|
||||
@@ -22,14 +22,14 @@ If `todo_count` is 0:
|
||||
```
|
||||
No pending todos.
|
||||
|
||||
Todos are captured during work sessions with /gsd:add-todo.
|
||||
Todos are captured during work sessions with /gsd-add-todo.
|
||||
|
||||
---
|
||||
|
||||
Would you like to:
|
||||
|
||||
1. Continue with current phase (/gsd:progress)
|
||||
2. Add a todo now (/gsd:add-todo)
|
||||
1. Continue with current phase (/gsd-progress)
|
||||
2. Add a todo now (/gsd-add-todo)
|
||||
```
|
||||
|
||||
Exit.
|
||||
@@ -37,8 +37,8 @@ Exit.
|
||||
|
||||
<step name="parse_filter">
|
||||
Check for area filter in arguments:
|
||||
- `/gsd:check-todos` → show all
|
||||
- `/gsd:check-todos api` → filter to area:api only
|
||||
- `/gsd-check-todos` → show all
|
||||
- `/gsd-check-todos api` → filter to area:api only
|
||||
</step>
|
||||
|
||||
<step name="list_todos">
|
||||
@@ -56,7 +56,7 @@ Pending Todos:
|
||||
---
|
||||
|
||||
Reply with a number to view details, or:
|
||||
- `/gsd:check-todos [area]` to filter by area
|
||||
- `/gsd-check-todos [area]` to filter by area
|
||||
- `q` to exit
|
||||
```
|
||||
|
||||
@@ -120,7 +120,7 @@ Use AskUserQuestion:
|
||||
- question: "What would you like to do with this todo?"
|
||||
- options:
|
||||
- "Work on it now" — move to done, start working
|
||||
- "Create a phase" — /gsd:add-phase with this scope
|
||||
- "Create a phase" — /gsd-add-phase with this scope
|
||||
- "Brainstorm approach" — think through before deciding
|
||||
- "Put it back" — return to list
|
||||
</step>
|
||||
@@ -136,7 +136,7 @@ Update STATE.md todo count. Present problem/solution context. Begin work or ask
|
||||
Note todo reference in phase planning notes. Keep in pending. Return to list or exit.
|
||||
|
||||
**Create a phase:**
|
||||
Display: `/gsd:add-phase [description from todo]`
|
||||
Display: `/gsd-add-phase [description from todo]`
|
||||
Keep in pending. User runs command in fresh context.
|
||||
|
||||
**Brainstorm approach:**
|
||||
|
||||
@@ -93,7 +93,7 @@ Verify that REVIEW.md exists:
|
||||
|
||||
```bash
|
||||
if [ ! -f "${REVIEW_PATH}" ]; then
|
||||
echo "Error: No REVIEW.md found for Phase ${PHASE_ARG}. Run /gsd:code-review ${PHASE_ARG} first."
|
||||
echo "Error: No REVIEW.md found for Phase ${PHASE_ARG}. Run /gsd-code-review ${PHASE_ARG} first."
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
@@ -221,7 +221,7 @@ Check if FIX_REPORT_PATH exists:
|
||||
Either way:
|
||||
```
|
||||
Some fix commits may already exist in git history — check git log for fix(${PADDED_PHASE}) commits.
|
||||
You can retry with /gsd:code-review-fix ${PHASE_ARG}.
|
||||
You can retry with /gsd-code-review-fix ${PHASE_ARG}.
|
||||
```
|
||||
|
||||
Exit workflow (skip auto loop).
|
||||
@@ -394,7 +394,7 @@ if [ ! -f "${FIX_REPORT_PATH}" ]; then
|
||||
echo "The fixer agent may have failed before completing."
|
||||
echo "Check git log for any fix(${PADDED_PHASE}) commits."
|
||||
echo ""
|
||||
echo "Retry: /gsd:code-review-fix ${PHASE_ARG}"
|
||||
echo "Retry: /gsd-code-review-fix ${PHASE_ARG}"
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
exit 1
|
||||
@@ -451,7 +451,7 @@ if [ "$FIX_STATUS" = "all_fixed" ]; then
|
||||
echo "Full report: ${FIX_REPORT_PATH}"
|
||||
echo ""
|
||||
echo "Next step:"
|
||||
echo " /gsd:verify-work — Verify phase completion"
|
||||
echo " /gsd-verify-work — Verify phase completion"
|
||||
echo ""
|
||||
fi
|
||||
```
|
||||
@@ -465,8 +465,8 @@ if [ "$FIX_STATUS" = "partial" ] || [ "$FIX_STATUS" = "none_fixed" ]; then
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " cat ${FIX_REPORT_PATH} — View fix report"
|
||||
echo " /gsd:code-review ${PHASE_NUMBER} — Re-review code"
|
||||
echo " /gsd:verify-work — Verify phase completion"
|
||||
echo " /gsd-code-review ${PHASE_NUMBER} — Re-review code"
|
||||
echo " /gsd-verify-work — Verify phase completion"
|
||||
echo ""
|
||||
fi
|
||||
```
|
||||
|
||||
@@ -227,7 +227,7 @@ if [ ${#REVIEW_FILES[@]} -eq 0 ]; then
|
||||
else
|
||||
# Fail closed — no reliable diff base found. Do not use arbitrary HEAD~N.
|
||||
echo "Warning: No phase commits found for '${PADDED_PHASE}'. Cannot determine reliable diff scope."
|
||||
echo "Use --files flag to specify files explicitly: /gsd:code-review ${PHASE_ARG} --files=file1,file2,..."
|
||||
echo "Use --files flag to specify files explicitly: /gsd-code-review ${PHASE_ARG} --files=file1,file2,..."
|
||||
fi
|
||||
fi
|
||||
```
|
||||
@@ -372,7 +372,7 @@ If the Task() call fails (agent error, timeout, or exception):
|
||||
```
|
||||
Error: Code review agent failed: ${error_message}
|
||||
|
||||
No REVIEW.md created. You can retry with /gsd:code-review ${PHASE_ARG} or check agent logs.
|
||||
No REVIEW.md created. You can retry with /gsd-code-review ${PHASE_ARG} or check agent logs.
|
||||
```
|
||||
|
||||
Do NOT proceed to commit_review step. Do NOT create a partial or empty REVIEW.md. Exit workflow.
|
||||
@@ -405,7 +405,7 @@ if [ -f "${REVIEW_PATH}" ]; then
|
||||
fi
|
||||
else
|
||||
echo "Warning: Agent completed but REVIEW.md not found at ${REVIEW_PATH}. This may indicate an agent issue."
|
||||
echo "No REVIEW.md to commit. Please retry with /gsd:code-review ${PHASE_ARG}"
|
||||
echo "No REVIEW.md to commit. Please retry with /gsd-code-review ${PHASE_ARG}"
|
||||
fi
|
||||
```
|
||||
</step>
|
||||
@@ -469,7 +469,7 @@ If total findings > 0:
|
||||
Full report: ${REVIEW_PATH}
|
||||
|
||||
Next steps:
|
||||
/gsd:code-review-fix ${PHASE_NUMBER} — Auto-fix issues
|
||||
/gsd-code-review-fix ${PHASE_NUMBER} — Auto-fix issues
|
||||
cat ${REVIEW_PATH} — View full report
|
||||
```
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ When a milestone completes:
|
||||
Before proceeding with milestone close, run the comprehensive open artifact audit.
|
||||
|
||||
```bash
|
||||
gsd-sdk query audit-open 2>/dev/null
|
||||
gsd-sdk query audit-open
|
||||
```
|
||||
|
||||
If the output contains open items (any section with count > 0):
|
||||
@@ -51,7 +51,7 @@ Display the full audit report to the user.
|
||||
Then ask:
|
||||
```
|
||||
These items are open. Choose an action:
|
||||
[R] Resolve — stop and fix items, then re-run /gsd:complete-milestone
|
||||
[R] Resolve — stop and fix items, then re-run /gsd-complete-milestone
|
||||
[A] Acknowledge all — document as deferred and proceed with close
|
||||
[C] Cancel — exit without closing
|
||||
```
|
||||
@@ -124,7 +124,7 @@ Requirements: {N}/{M} v1 requirements checked off
|
||||
|
||||
MUST present 3 options:
|
||||
1. **Proceed anyway** — mark milestone complete with known gaps
|
||||
2. **Run audit first** — `/gsd:audit-milestone` to assess gap severity
|
||||
2. **Run audit first** — `/gsd-audit-milestone` to assess gap severity
|
||||
3. **Abort** — return to development
|
||||
|
||||
If user selects "Proceed anyway": note incomplete requirements in MILESTONES.md under `### Known Gaps` with REQ-IDs and descriptions.
|
||||
@@ -441,7 +441,7 @@ mv .planning/phases/{phase-dir} .planning/milestones/v[X.Y]-phases/
|
||||
```
|
||||
Verify: `✅ Phase directories archived to .planning/milestones/v[X.Y]-phases/`
|
||||
|
||||
If "Skip": Phase directories remain in `.planning/phases/` as raw execution history. Use `/gsd:cleanup` later to archive retroactively.
|
||||
If "Skip": Phase directories remain in `.planning/phases/` as raw execution history. Use `/gsd-cleanup` later to archive retroactively.
|
||||
|
||||
After archival, the AI still handles:
|
||||
- Reorganizing ROADMAP.md with milestone grouping (requires judgment) — overwrite in place after extracting Backlog section
|
||||
@@ -786,7 +786,7 @@ Tag: v[X.Y]
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:new-milestone`
|
||||
`/gsd-new-milestone`
|
||||
|
||||
---
|
||||
```
|
||||
@@ -842,6 +842,6 @@ Milestone completion is successful when:
|
||||
- [ ] Known gaps recorded in MILESTONES.md if user proceeded with incomplete requirements
|
||||
- [ ] RETROSPECTIVE.md updated with milestone section
|
||||
- [ ] Cross-milestone trends updated
|
||||
- [ ] User knows next step (/gsd:new-milestone)
|
||||
- [ ] User knows next step (/gsd-new-milestone)
|
||||
|
||||
</success_criteria>
|
||||
|
||||
@@ -87,7 +87,7 @@ This runs in parallel - all gaps investigated simultaneously.
|
||||
**Load agent skills:**
|
||||
|
||||
```bash
|
||||
AGENT_SKILLS_DEBUGGER=$(gsd-sdk query agent-skills gsd-debugger 2>/dev/null)
|
||||
AGENT_SKILLS_DEBUGGER=$(gsd-sdk query agent-skills gsd-debugger)
|
||||
EXPECTED_BASE=$(git rev-parse HEAD)
|
||||
```
|
||||
|
||||
@@ -220,7 +220,7 @@ Agents only diagnose—plan-phase --gaps handles fixes (no fix application).
|
||||
|
||||
**Agent times out:**
|
||||
- Check DEBUG-{slug}.md for partial progress
|
||||
- Can resume with /gsd:debug
|
||||
- Can resume with /gsd-debug
|
||||
|
||||
**All agents fail:**
|
||||
- Something systemic (permissions, git, etc.)
|
||||
|
||||
@@ -4,7 +4,7 @@ Produces DISCOVERY.md (for Level 2-3) that informs PLAN.md creation.
|
||||
|
||||
Called from plan-phase.md's mandatory_discovery step with a depth parameter.
|
||||
|
||||
NOTE: For comprehensive ecosystem research ("how do experts build this"), use /gsd:research-phase instead, which produces RESEARCH.md.
|
||||
NOTE: For comprehensive ecosystem research ("how do experts build this"), use /gsd-research-phase instead, which produces RESEARCH.md.
|
||||
</purpose>
|
||||
|
||||
<depth_levels>
|
||||
@@ -254,8 +254,8 @@ Confidence: [level]
|
||||
|
||||
What's next?
|
||||
|
||||
1. Discuss phase context (/gsd:discuss-phase [current-phase])
|
||||
2. Create phase plan (/gsd:plan-phase [current-phase])
|
||||
1. Discuss phase context (/gsd-discuss-phase [current-phase])
|
||||
2. Create phase plan (/gsd-plan-phase [current-phase])
|
||||
3. Refine discovery (dig deeper)
|
||||
4. Review discovery
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ Phase number from argument (required).
|
||||
```bash
|
||||
INIT=$(gsd-sdk query init.phase-op "${PHASE}")
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS_ANALYZER=$(gsd-sdk query agent-skills gsd-assumptions-analyzer 2>/dev/null)
|
||||
AGENT_SKILLS_ANALYZER=$(gsd-sdk query agent-skills gsd-assumptions-analyzer)
|
||||
```
|
||||
|
||||
Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`,
|
||||
@@ -77,7 +77,7 @@ Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phas
|
||||
```
|
||||
Phase [X] not found in roadmap.
|
||||
|
||||
Use /gsd:progress to see available phases.
|
||||
Use /gsd-progress to see available phases.
|
||||
```
|
||||
Exit workflow.
|
||||
|
||||
@@ -599,13 +599,13 @@ Created: .planning/phases/${PADDED_PHASE}-${SLUG}/${PADDED_PHASE}-CONTEXT.md
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:plan-phase ${PHASE}`
|
||||
`/gsd-plan-phase ${PHASE}`
|
||||
|
||||
---
|
||||
|
||||
**Also available:**
|
||||
- `/gsd:plan-phase ${PHASE} --skip-research` — plan without research
|
||||
- `/gsd:ui-phase ${PHASE}` — generate UI design contract (if frontend work)
|
||||
- `/gsd-plan-phase ${PHASE} --skip-research` — plan without research
|
||||
- `/gsd-ui-phase ${PHASE}` — generate UI design contract (if frontend work)
|
||||
- Review/edit CONTEXT.md before continuing
|
||||
|
||||
---
|
||||
@@ -619,7 +619,7 @@ Check for auto-advance trigger:
|
||||
2. Sync chain flag:
|
||||
```bash
|
||||
if [[ ! "$ARGUMENTS" =~ --auto ]]; then
|
||||
gsd-sdk query config-set workflow._auto_chain_active false 2>/dev/null
|
||||
gsd-sdk query config-set workflow._auto_chain_active false || true
|
||||
fi
|
||||
```
|
||||
3. Read consolidated auto-mode (`active` = chain flag OR user preference):
|
||||
|
||||
@@ -5,7 +5,7 @@ Power user mode for discuss-phase. Generates ALL questions upfront into a JSON s
|
||||
</purpose>
|
||||
|
||||
<trigger>
|
||||
This workflow executes when `--power` flag is present in ARGUMENTS to `/gsd:discuss-phase`.
|
||||
This workflow executes when `--power` flag is present in ARGUMENTS to `/gsd-discuss-phase`.
|
||||
|
||||
The caller (discuss-phase.md) has already:
|
||||
- Validated the phase exists
|
||||
@@ -265,7 +265,7 @@ Process all answered questions from the JSON file and generate CONTEXT.md.
|
||||
```
|
||||
Warning: Only {answered}/{total} questions answered ({pct}%).
|
||||
CONTEXT.md generated with available decisions. Unanswered questions listed as deferred.
|
||||
Consider running /gsd:discuss-phase {N} again to refine before planning.
|
||||
Consider running /gsd-discuss-phase {N} again to refine before planning.
|
||||
```
|
||||
|
||||
7. Print completion message:
|
||||
@@ -275,7 +275,7 @@ CONTEXT.md written: {phase_dir}/{padded_phase}-CONTEXT.md
|
||||
Decisions captured: {answered}
|
||||
Deferred: {remaining}
|
||||
|
||||
Next step: /gsd:plan-phase {N}
|
||||
Next step: /gsd-plan-phase {N}
|
||||
```
|
||||
</step>
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ Phase: "API documentation" → Structure/navigation, Code examples depth,
|
||||
|
||||
<process>
|
||||
|
||||
**Express path available:** If you already have a PRD or acceptance criteria document, use `/gsd:plan-phase {phase} --prd path/to/prd.md` to skip this discussion and go straight to planning.
|
||||
**Express path available:** If you already have a PRD or acceptance criteria document, use `/gsd-plan-phase {phase} --prd path/to/prd.md` to skip this discussion and go straight to planning.
|
||||
|
||||
<step name="initialize" priority="first">
|
||||
Phase number from argument (required).
|
||||
@@ -111,7 +111,7 @@ Phase number from argument (required).
|
||||
```bash
|
||||
INIT=$(gsd-sdk query init.phase-op "${PHASE}")
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS_ADVISOR=$(gsd-sdk query agent-skills gsd-advisor-researcher 2>/dev/null)
|
||||
AGENT_SKILLS_ADVISOR=$(gsd-sdk query agent-skills gsd-advisor-researcher)
|
||||
```
|
||||
|
||||
Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `has_verification`, `plan_count`, `roadmap_exists`, `planning_exists`, `response_language`.
|
||||
@@ -121,7 +121,7 @@ Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phas
|
||||
**If `phase_found` is false:**
|
||||
```
|
||||
Phase [X] not found in roadmap.
|
||||
Use /gsd:progress ${GSD_WS} to see available phases.
|
||||
Use /gsd-progress ${GSD_WS} to see available phases.
|
||||
```
|
||||
Exit workflow.
|
||||
|
||||
@@ -172,7 +172,7 @@ Write these answers inline before continuing. If a blocking anti-pattern cannot
|
||||
</step>
|
||||
|
||||
<step name="check_spec">
|
||||
Check if a SPEC.md (from `/gsd:spec-phase`) exists for this phase. SPEC.md locks requirements before implementation decisions.
|
||||
Check if a SPEC.md (from `/gsd-spec-phase`) exists for this phase. SPEC.md locks requirements before implementation decisions.
|
||||
|
||||
```bash
|
||||
ls ${phase_dir}/*-SPEC.md 2>/dev/null | grep -v AI-SPEC | head -1 || true
|
||||
@@ -187,7 +187,7 @@ ls ${phase_dir}/*-SPEC.md 2>/dev/null | grep -v AI-SPEC | head -1 || true
|
||||
|
||||
**If no SPEC.md is found:** Continue with `spec_loaded = false`.
|
||||
|
||||
**Note:** SPEC.md files named `AI-SPEC.md` (from `/gsd:ai-integration-phase`) are excluded — different purpose.
|
||||
**Note:** SPEC.md files named `AI-SPEC.md` (from `/gsd-ai-integration-phase`) are excluded — different purpose.
|
||||
</step>
|
||||
|
||||
<step name="check_existing">
|
||||
@@ -252,7 +252,7 @@ RAW_SKETCHES=$(ls .planning/sketches/MANIFEST.md 2>/dev/null)
|
||||
|
||||
If findings skills exist, read SKILL.md and reference files; extract validated patterns, landmines, constraints, design decisions. Add them to `<prior_decisions>`.
|
||||
|
||||
If raw spikes/sketches exist but no findings skill, note: `⚠ Unpackaged spikes/sketches detected — run /gsd:spike-wrap-up or /gsd:sketch-wrap-up to make findings available.`
|
||||
If raw spikes/sketches exist but no findings skill, note: `⚠ Unpackaged spikes/sketches detected — run /gsd-spike-wrap-up or /gsd-sketch-wrap-up to make findings available.`
|
||||
|
||||
Build internal `<prior_decisions>` with sections for Project-Level (from PROJECT.md / REQUIREMENTS.md), From Prior Phases (per-phase decisions), and From Spike/Sketch Findings (validated patterns, landmines, design decisions).
|
||||
|
||||
@@ -418,11 +418,11 @@ Created: .planning/phases/${PADDED_PHASE}-${SLUG}/${PADDED_PHASE}-CONTEXT.md
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:plan-phase ${PHASE} ${GSD_WS}`
|
||||
`/gsd-plan-phase ${PHASE} ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
**Also available:** `--chain` for auto plan+execute after; `/gsd:plan-phase ${PHASE} --skip-research ${GSD_WS}` to plan without research; `/gsd:ui-phase ${PHASE} ${GSD_WS}` for UI design contracts; review/edit CONTEXT.md before continuing.
|
||||
**Also available:** `--chain` for auto plan+execute after; `/gsd-plan-phase ${PHASE} --skip-research ${GSD_WS}` to plan without research; `/gsd-ui-phase ${PHASE} ${GSD_WS}` for UI design contracts; review/edit CONTEXT.md before continuing.
|
||||
```
|
||||
</step>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
(the user's persistent settings preference):
|
||||
```bash
|
||||
if [[ ! "$ARGUMENTS" =~ --auto ]] && [[ ! "$ARGUMENTS" =~ --chain ]]; then
|
||||
gsd-sdk query config-set workflow._auto_chain_active false 2>/dev/null
|
||||
gsd-sdk query config-set workflow._auto_chain_active false || true
|
||||
fi
|
||||
```
|
||||
|
||||
@@ -75,22 +75,22 @@
|
||||
|
||||
/clear then:
|
||||
|
||||
Next: /gsd:discuss-phase ${NEXT_PHASE} ${WAS_CHAIN ? "--chain" : "--auto"} ${GSD_WS}
|
||||
Next: /gsd-discuss-phase ${NEXT_PHASE} ${WAS_CHAIN ? "--chain" : "--auto"} ${GSD_WS}
|
||||
```
|
||||
- **PLANNING COMPLETE** → Planning done, execution didn't complete:
|
||||
```
|
||||
Auto-advance partial: Planning complete, execution did not finish.
|
||||
Continue: /gsd:execute-phase ${PHASE} ${GSD_WS}
|
||||
Continue: /gsd-execute-phase ${PHASE} ${GSD_WS}
|
||||
```
|
||||
- **PLANNING INCONCLUSIVE / CHECKPOINT** → Stop chain:
|
||||
```
|
||||
Auto-advance stopped: Planning needs input.
|
||||
Continue: /gsd:plan-phase ${PHASE} ${GSD_WS}
|
||||
Continue: /gsd-plan-phase ${PHASE} ${GSD_WS}
|
||||
```
|
||||
- **GAPS FOUND** → Stop chain:
|
||||
```
|
||||
Auto-advance stopped: Gaps found during execution.
|
||||
Continue: /gsd:plan-phase ${PHASE} --gaps ${GSD_WS}
|
||||
Continue: /gsd-plan-phase ${PHASE} --gaps ${GSD_WS}
|
||||
```
|
||||
|
||||
7. **If none of `--auto`, `--chain`, nor config enabled:** route to
|
||||
|
||||
@@ -17,7 +17,7 @@ Claude App cannot forward TUI menu selections back to the host.
|
||||
## Activation
|
||||
|
||||
- Per-session: pass `--text` flag to any command (e.g.,
|
||||
`/gsd:discuss-phase --text`)
|
||||
`/gsd-discuss-phase --text`)
|
||||
- Per-project: `gsd-sdk query config-set workflow.text_mode true`
|
||||
|
||||
Text mode applies to ALL workflows in the session, not just discuss-phase.
|
||||
|
||||
@@ -39,35 +39,35 @@ Evaluate `$ARGUMENTS` against these routing rules. Apply the **first matching**
|
||||
|
||||
| If the text describes... | Route to | Why |
|
||||
|--------------------------|----------|-----|
|
||||
| Starting a new project, "set up", "initialize" | `/gsd:new-project` | Needs full project initialization |
|
||||
| Mapping or analyzing an existing codebase | `/gsd:map-codebase` | Codebase discovery |
|
||||
| A bug, error, crash, failure, or something broken | `/gsd:debug` | Needs systematic investigation |
|
||||
| Spiking, "test if", "will this work", "experiment", "prove this out", validate feasibility | `/gsd:spike` | Throwaway experiment to validate feasibility |
|
||||
| Sketching, "mockup", "what would this look like", "prototype the UI", "design this", explore visual direction | `/gsd:sketch` | Throwaway HTML mockups to explore design |
|
||||
| Wrapping up spikes, "package the spikes", "consolidate spike findings" | `/gsd:spike-wrap-up` | Package spike findings into reusable skill |
|
||||
| Wrapping up sketches, "package the designs", "consolidate sketch findings" | `/gsd:sketch-wrap-up` | Package sketch findings into reusable skill |
|
||||
| Exploring, researching, comparing, or "how does X work" | `/gsd:research-phase` | Domain research before planning |
|
||||
| Discussing vision, "how should X look", brainstorming | `/gsd:discuss-phase` | Needs context gathering |
|
||||
| A complex task: refactoring, migration, multi-file architecture, system redesign | `/gsd:add-phase` | Needs a full phase with plan/build cycle |
|
||||
| Planning a specific phase or "plan phase N" | `/gsd:plan-phase` | Direct planning request |
|
||||
| Executing a phase or "build phase N", "run phase N" | `/gsd:execute-phase` | Direct execution request |
|
||||
| Running all remaining phases automatically | `/gsd:autonomous` | Full autonomous execution |
|
||||
| A review or quality concern about existing work | `/gsd:verify-work` | Needs verification |
|
||||
| Checking progress, status, "where am I" | `/gsd:progress` | Status check |
|
||||
| Resuming work, "pick up where I left off" | `/gsd:resume-work` | Session restoration |
|
||||
| A note, idea, or "remember to..." | `/gsd:add-todo` | Capture for later |
|
||||
| Adding tests, "write tests", "test coverage" | `/gsd:add-tests` | Test generation |
|
||||
| Completing a milestone, shipping, releasing | `/gsd:complete-milestone` | Milestone lifecycle |
|
||||
| A specific, actionable, small task (add feature, fix typo, update config) | `/gsd:quick` | Self-contained, single executor |
|
||||
| Starting a new project, "set up", "initialize" | `/gsd-new-project` | Needs full project initialization |
|
||||
| Mapping or analyzing an existing codebase | `/gsd-map-codebase` | Codebase discovery |
|
||||
| A bug, error, crash, failure, or something broken | `/gsd-debug` | Needs systematic investigation |
|
||||
| Spiking, "test if", "will this work", "experiment", "prove this out", validate feasibility | `/gsd-spike` | Throwaway experiment to validate feasibility |
|
||||
| Sketching, "mockup", "what would this look like", "prototype the UI", "design this", explore visual direction | `/gsd-sketch` | Throwaway HTML mockups to explore design |
|
||||
| Wrapping up spikes, "package the spikes", "consolidate spike findings" | `/gsd-spike-wrap-up` | Package spike findings into reusable skill |
|
||||
| Wrapping up sketches, "package the designs", "consolidate sketch findings" | `/gsd-sketch-wrap-up` | Package sketch findings into reusable skill |
|
||||
| Exploring, researching, comparing, or "how does X work" | `/gsd-research-phase` | Domain research before planning |
|
||||
| Discussing vision, "how should X look", brainstorming | `/gsd-discuss-phase` | Needs context gathering |
|
||||
| A complex task: refactoring, migration, multi-file architecture, system redesign | `/gsd-add-phase` | Needs a full phase with plan/build cycle |
|
||||
| Planning a specific phase or "plan phase N" | `/gsd-plan-phase` | Direct planning request |
|
||||
| Executing a phase or "build phase N", "run phase N" | `/gsd-execute-phase` | Direct execution request |
|
||||
| Running all remaining phases automatically | `/gsd-autonomous` | Full autonomous execution |
|
||||
| A review or quality concern about existing work | `/gsd-verify-work` | Needs verification |
|
||||
| Checking progress, status, "where am I" | `/gsd-progress` | Status check |
|
||||
| Resuming work, "pick up where I left off" | `/gsd-resume-work` | Session restoration |
|
||||
| A note, idea, or "remember to..." | `/gsd-add-todo` | Capture for later |
|
||||
| Adding tests, "write tests", "test coverage" | `/gsd-add-tests` | Test generation |
|
||||
| Completing a milestone, shipping, releasing | `/gsd-complete-milestone` | Milestone lifecycle |
|
||||
| A specific, actionable, small task (add feature, fix typo, update config) | `/gsd-quick` | Self-contained, single executor |
|
||||
|
||||
**Requires `.planning/` directory:** All routes except `/gsd:new-project`, `/gsd:map-codebase`, `/gsd:spike`, `/gsd:sketch`, `/gsd:help`, and `/gsd:join-discord`. If the project doesn't exist and the route requires it, suggest `/gsd:new-project` first.
|
||||
**Requires `.planning/` directory:** All routes except `/gsd-new-project`, `/gsd-map-codebase`, `/gsd-spike`, `/gsd-sketch`, `/gsd-help`, and `/gsd-join-discord`. If the project doesn't exist and the route requires it, suggest `/gsd-new-project` first.
|
||||
|
||||
**Ambiguity handling:** If the text could reasonably match multiple routes, ask the user via AskUserQuestion with the top 2-3 options. For example:
|
||||
|
||||
```
|
||||
"Refactor the authentication system" could be:
|
||||
1. /gsd:add-phase — Full planning cycle (recommended for multi-file refactors)
|
||||
2. /gsd:quick — Quick execution (if scope is small and clear)
|
||||
1. /gsd-add-phase — Full planning cycle (recommended for multi-file refactors)
|
||||
2. /gsd-quick — Quick execution (if scope is small and clear)
|
||||
|
||||
Which approach fits better?
|
||||
```
|
||||
|
||||
@@ -16,7 +16,7 @@ Load docs-update context:
|
||||
```bash
|
||||
INIT=$(gsd-sdk query docs-init)
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS=$(gsd-sdk query agent-skills gsd-doc-writer 2>/dev/null)
|
||||
AGENT_SKILLS=$(gsd-sdk query agent-skills gsd-doc-writer)
|
||||
```
|
||||
|
||||
Extract from init JSON:
|
||||
@@ -988,8 +988,8 @@ Failed claims:
|
||||
|
||||
Display note:
|
||||
```
|
||||
To fix failures automatically: /gsd:docs-update (runs generation + fix loop)
|
||||
To regenerate all docs from scratch: /gsd:docs-update --force
|
||||
To fix failures automatically: /gsd-docs-update (runs generation + fix loop)
|
||||
To regenerate all docs from scratch: /gsd-docs-update --force
|
||||
```
|
||||
|
||||
Clean up temp files: remove `.planning/tmp/verify-*.json` files.
|
||||
@@ -1024,7 +1024,7 @@ This would expose credentials if committed.
|
||||
Action required:
|
||||
1. Review the flagged lines above
|
||||
2. Remove any real secrets from the doc files
|
||||
3. Re-run /gsd:docs-update to regenerate clean docs
|
||||
3. Re-run /gsd-docs-update to regenerate clean docs
|
||||
```
|
||||
|
||||
Then confirm with AskUserQuestion:
|
||||
@@ -1126,7 +1126,7 @@ All generated files committed.
|
||||
Remind the user they can fact-check generated docs:
|
||||
|
||||
```
|
||||
Run `/gsd:docs-update --verify-only` to fact-check generated docs against the codebase.
|
||||
Run `/gsd-docs-update --verify-only` to fact-check generated docs against the codebase.
|
||||
```
|
||||
|
||||
End workflow.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<purpose>
|
||||
Retroactive audit of an implemented AI phase's evaluation coverage. Standalone command that works on any GSD-managed AI phase. Produces a scored EVAL-REVIEW.md with gap analysis and remediation plan.
|
||||
|
||||
Use after /gsd:execute-phase to verify that the evaluation strategy from AI-SPEC.md was actually implemented. Mirrors the pattern of /gsd:ui-review and /gsd:validate-phase.
|
||||
Use after /gsd-execute-phase to verify that the evaluation strategy from AI-SPEC.md was actually implemented. Mirrors the pattern of /gsd-ui-review and /gsd-validate-phase.
|
||||
</purpose>
|
||||
|
||||
<required_reading>
|
||||
@@ -40,7 +40,7 @@ EVAL_REVIEW_FILE=$(ls "${PHASE_DIR}"/*-EVAL-REVIEW.md 2>/dev/null | head -1)
|
||||
|
||||
**State A** — AI-SPEC.md + SUMMARY.md exist: Full audit against spec
|
||||
**State B** — SUMMARY.md exists, no AI-SPEC.md: Audit against general best practices
|
||||
**State C** — No SUMMARY.md: Exit — "Phase {N} not executed. Run /gsd:execute-phase {N} first."
|
||||
**State C** — No SUMMARY.md: Exit — "Phase {N} not executed. Run /gsd-execute-phase {N} first."
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
@@ -58,7 +58,7 @@ If "Re-audit": continue.
|
||||
```
|
||||
No AI-SPEC.md found for Phase {N}.
|
||||
Audit will evaluate against general AI eval best practices rather than a phase-specific plan.
|
||||
Consider running /gsd:ai-integration-phase {N} before implementation next time.
|
||||
Consider running /gsd-ai-integration-phase {N} before implementation next time.
|
||||
```
|
||||
Continue (non-blocking).
|
||||
|
||||
@@ -124,10 +124,10 @@ Read the written EVAL-REVIEW.md. Extract:
|
||||
◆ Output: {eval_review_path}
|
||||
|
||||
{If PRODUCTION READY:}
|
||||
Next step: /gsd:plan-phase (next phase) or deploy
|
||||
Next step: /gsd-plan-phase (next phase) or deploy
|
||||
|
||||
{If NEEDS WORK:}
|
||||
Address critical gaps in EVAL-REVIEW.md, then re-run /gsd:eval-review {N}
|
||||
Address critical gaps in EVAL-REVIEW.md, then re-run /gsd-eval-review {N}
|
||||
|
||||
{If SIGNIFICANT GAPS or NOT IMPLEMENTED:}
|
||||
Review AI-SPEC.md evaluation plan. Critical eval dimensions are not implemented.
|
||||
|
||||
@@ -69,7 +69,7 @@ Load all context in one call:
|
||||
```bash
|
||||
INIT=$(gsd-sdk query init.execute-phase "${PHASE_ARG}")
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS=$(gsd-sdk query agent-skills gsd-executor 2>/dev/null)
|
||||
AGENT_SKILLS=$(gsd-sdk query agent-skills gsd-executor)
|
||||
```
|
||||
|
||||
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`, `response_language`.
|
||||
@@ -130,7 +130,7 @@ inline path for each plan.
|
||||
```bash
|
||||
# REQUIRED: prevents stale auto-chain from previous --auto runs
|
||||
if [[ ! "$ARGUMENTS" =~ --auto ]]; then
|
||||
gsd-sdk query config-set workflow._auto_chain_active false 2>/dev/null
|
||||
gsd-sdk query config-set workflow._auto_chain_active false || true
|
||||
fi
|
||||
```
|
||||
</step>
|
||||
@@ -344,7 +344,7 @@ between a large tool_result and the next assistant turn (seen on Claude Code
|
||||
+ Opus 4.7 at ~200K+ cache_read). To keep the stream warm, emit short
|
||||
assistant-text heartbeats — **no tool call, just a literal line** — at every
|
||||
wave and plan boundary. Each heartbeat MUST start with `[checkpoint]` so
|
||||
tooling and `/gsd:manager`'s background-completion handler can grep partial
|
||||
tooling and `/gsd-manager`'s background-completion handler can grep partial
|
||||
transcripts. `{P}/{Q}` is the phase-wide completed/total plans counter and
|
||||
increases monotonically across waves. `{status}` is `complete` (success),
|
||||
`failed` (executor error), or `checkpoint` (human-gate returned).
|
||||
@@ -1017,13 +1017,13 @@ If `SECURITY_CFG` is `true` AND `SECURITY_FILE` is empty (no SECURITY.md yet):
|
||||
Include in the next-steps routing output:
|
||||
```
|
||||
⚠ Security enforcement enabled — run before advancing:
|
||||
/gsd:secure-phase {PHASE} ${GSD_WS}
|
||||
/gsd-secure-phase {PHASE} ${GSD_WS}
|
||||
```
|
||||
|
||||
If `SECURITY_CFG` is `true` AND SECURITY.md exists: check frontmatter `threats_open`. If > 0:
|
||||
```
|
||||
⚠ Security gate: {threats_open} threats open
|
||||
/gsd:secure-phase {PHASE} — resolve before advancing
|
||||
/gsd-secure-phase {PHASE} — resolve before advancing
|
||||
```
|
||||
</step>
|
||||
|
||||
@@ -1093,8 +1093,8 @@ Apply the same "incomplete" filtering rules as earlier:
|
||||
|
||||
Selected wave finished successfully. This phase still has incomplete plans, so phase-level verification and completion were intentionally skipped.
|
||||
|
||||
/gsd:execute-phase {phase} ${GSD_WS} # Continue remaining waves
|
||||
/gsd:execute-phase {phase} --wave {next} ${GSD_WS} # Run the next wave explicitly
|
||||
/gsd-execute-phase {phase} ${GSD_WS} # Continue remaining waves
|
||||
/gsd-execute-phase {phase} --wave {next} ${GSD_WS} # Run the next wave explicitly
|
||||
```
|
||||
|
||||
**If no incomplete plans remain after the selected wave finishes:**
|
||||
@@ -1127,7 +1127,7 @@ REVIEW_STATUS=$(sed -n '/^---$/,/^---$/p' "$REVIEW_FILE" | grep "^status:" | hea
|
||||
If REVIEW_STATUS is not "clean" and not "skipped" and not empty, display:
|
||||
```
|
||||
Code review found issues. Consider running:
|
||||
/gsd:code-review-fix ${PHASE_NUMBER}
|
||||
/gsd-code-review-fix ${PHASE_NUMBER}
|
||||
```
|
||||
|
||||
**Error handling:** If the Skill invocation fails or throws, catch the error, display "Code review encountered an error (non-blocking): {error}" and proceed to next step. Review failures must never block execution.
|
||||
@@ -1339,7 +1339,7 @@ spawn template, and the two `workflow.drift_*` config keys.
|
||||
Verify phase achieved its GOAL, not just completed tasks.
|
||||
|
||||
```bash
|
||||
VERIFIER_SKILLS=$(gsd-sdk query agent-skills gsd-verifier 2>/dev/null)
|
||||
VERIFIER_SKILLS=$(gsd-sdk query agent-skills gsd-verifier)
|
||||
```
|
||||
|
||||
```
|
||||
@@ -1379,7 +1379,7 @@ grep "^status:" "$PHASE_DIR"/*-VERIFICATION.md | cut -d: -f2 | tr -d ' '
|
||||
|--------|--------|
|
||||
| `passed` | → update_roadmap |
|
||||
| `human_needed` | Present items for human testing, get approval or feedback |
|
||||
| `gaps_found` | Present gap summary, offer `/gsd:plan-phase {phase} --gaps ${GSD_WS}` |
|
||||
| `gaps_found` | Present gap summary, offer `/gsd-plan-phase {phase} --gaps ${GSD_WS}` |
|
||||
|
||||
**If human_needed:**
|
||||
|
||||
@@ -1434,12 +1434,12 @@ All automated checks passed. {N} items need human testing:
|
||||
|
||||
{From VERIFICATION.md human_verification section}
|
||||
|
||||
Items saved to `{phase_num}-HUMAN-UAT.md` — they will appear in `/gsd:progress` and `/gsd:audit-uat`.
|
||||
Items saved to `{phase_num}-HUMAN-UAT.md` — they will appear in `/gsd-progress` and `/gsd-audit-uat`.
|
||||
|
||||
"approved" → continue | Report issues → gap closure
|
||||
```
|
||||
|
||||
**If user says "approved":** Proceed to `update_roadmap`. The HUMAN-UAT.md file persists with `status: partial` and will surface in future progress checks until the user runs `/gsd:verify-work` on it.
|
||||
**If user says "approved":** Proceed to `update_roadmap`. The HUMAN-UAT.md file persists with `status: partial` and will surface in future progress checks until the user runs `/gsd-verify-work` on it.
|
||||
|
||||
**If user reports issues:** Proceed to gap closure as currently implemented.
|
||||
|
||||
@@ -1458,13 +1458,13 @@ Items saved to `{phase_num}-HUMAN-UAT.md` — they will appear in `/gsd:progress
|
||||
|
||||
`/clear` then:
|
||||
|
||||
`/gsd:plan-phase {X} --gaps ${GSD_WS}`
|
||||
`/gsd-plan-phase {X} --gaps ${GSD_WS}`
|
||||
|
||||
Also: `cat {phase_dir}/{phase_num}-VERIFICATION.md` — full report
|
||||
Also: `/gsd:verify-work {X} ${GSD_WS}` — manual testing first
|
||||
Also: `/gsd-verify-work {X} ${GSD_WS}` — manual testing first
|
||||
```
|
||||
|
||||
Gap closure cycle: `/gsd:plan-phase {X} --gaps ${GSD_WS}` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/gsd:execute-phase {X} --gaps-only ${GSD_WS}` → verifier re-runs.
|
||||
Gap closure cycle: `/gsd-plan-phase {X} --gaps ${GSD_WS}` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/gsd-execute-phase {X} --gaps-only ${GSD_WS}` → verifier re-runs.
|
||||
</step>
|
||||
|
||||
<step name="update_roadmap">
|
||||
@@ -1490,7 +1490,7 @@ Extract from result: `next_phase`, `next_phase_name`, `is_last_phase`, `warnings
|
||||
|
||||
{list each warning}
|
||||
|
||||
These items are tracked and will appear in `/gsd:progress` and `/gsd:audit-uat`.
|
||||
These items are tracked and will appear in `/gsd-progress` and `/gsd-audit-uat`.
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -1577,7 +1577,7 @@ gsd-sdk query commit "docs(phase-{X}): evolve PROJECT.md after phase completion"
|
||||
|
||||
<step name="offer_next">
|
||||
|
||||
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
|
||||
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd-plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
|
||||
|
||||
**No-transition check (spawned by auto-advance chain):**
|
||||
|
||||
@@ -1640,10 +1640,10 @@ If CONTEXT.md does **not** exist for the next phase, present:
|
||||
```
|
||||
## ✓ Phase {X}: {Name} Complete
|
||||
|
||||
/gsd:progress ${GSD_WS} — see updated roadmap
|
||||
/gsd:discuss-phase {next} ${GSD_WS} — start here: discuss next phase before planning ← recommended
|
||||
/gsd:plan-phase {next} ${GSD_WS} — plan next phase (skip discuss)
|
||||
/gsd:execute-phase {next} ${GSD_WS} — execute next phase (skip discuss and plan)
|
||||
/gsd-progress ${GSD_WS} — see updated roadmap
|
||||
/gsd-discuss-phase {next} ${GSD_WS} — start here: discuss next phase before planning ← recommended
|
||||
/gsd-plan-phase {next} ${GSD_WS} — plan next phase (skip discuss)
|
||||
/gsd-execute-phase {next} ${GSD_WS} — execute next phase (skip discuss and plan)
|
||||
```
|
||||
|
||||
If CONTEXT.md **exists** for the next phase, present:
|
||||
@@ -1651,10 +1651,10 @@ If CONTEXT.md **exists** for the next phase, present:
|
||||
```
|
||||
## ✓ Phase {X}: {Name} Complete
|
||||
|
||||
/gsd:progress ${GSD_WS} — see updated roadmap
|
||||
/gsd:plan-phase {next} ${GSD_WS} — start here: plan next phase (CONTEXT.md already present) ← recommended
|
||||
/gsd:discuss-phase {next} ${GSD_WS} — re-discuss next phase
|
||||
/gsd:execute-phase {next} ${GSD_WS} — execute next phase (skip planning)
|
||||
/gsd-progress ${GSD_WS} — see updated roadmap
|
||||
/gsd-plan-phase {next} ${GSD_WS} — start here: plan next phase (CONTEXT.md already present) ← recommended
|
||||
/gsd-discuss-phase {next} ${GSD_WS} — re-discuss next phase
|
||||
/gsd-execute-phase {next} ${GSD_WS} — execute next phase (skip planning)
|
||||
```
|
||||
|
||||
Only suggest the commands listed above. Do not invent or hallucinate command names.
|
||||
@@ -1681,7 +1681,7 @@ For 1M+ context models, consider:
|
||||
</failure_handling>
|
||||
|
||||
<resumption>
|
||||
Re-run `/gsd:execute-phase {phase}` → discover_plans finds completed SUMMARYs → skips them → resumes from first incomplete plan → continues wave execution.
|
||||
Re-run `/gsd-execute-phase {phase}` → discover_plans finds completed SUMMARYs → skips them → resumes from first incomplete plan → continues wave execution.
|
||||
|
||||
STATE.md tracks: last completed plan, current wave, pending checkpoints.
|
||||
</resumption>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user