* feat(#2790): consolidate 86 gsd-* skills to 59 — zero functional loss
Closes#2790
- `capture.md` — absorbs add-todo (default), note (--note), add-backlog
(--backlog), plant-seed (--seed), check-todos (--list)
- `phase.md` — absorbs add-phase (default), insert-phase (--insert),
remove-phase (--remove), edit-phase (--edit)
- `config.md` — absorbs settings-advanced (--advanced),
settings-integrations (--integrations), set-profile (--profile);
settings.md retained as-is
- `workspace.md` — absorbs new-workspace (--new), list-workspaces
(--list), remove-workspace (--remove)
- `update.md` — adds --sync (absorbs sync-skills) and --reapply
(absorbs reapply-patches)
- `sketch.md` — adds --wrap-up (absorbs sketch-wrap-up)
- `spike.md` — adds --wrap-up (absorbs spike-wrap-up)
- `map-codebase.md` — adds --fast (absorbs scan) and --query (absorbs
intel)
- `code-review.md` — adds --fix (absorbs code-review-fix)
- `progress.md` — adds --next (absorbs next) and --do (absorbs do)
join-discord, research-phase, session-report, from-gsd2,
analyze-dependencies, list-phase-assumptions, plan-milestone-gaps
autonomous.md: updated Skill(skill="gsd:code-review-fix") →
Skill(skill="gsd:code-review", args="--fix --auto") to match
the consolidated skill name
- New: tests/enh-2790-skill-consolidation.test.cjs (48 tests)
- Updated: 14 existing test files redirected from deleted command paths
to their consolidated equivalents
- docs/INVENTORY.md: Commands count 86→59, ghost rows removed, new
consolidated rows added
- docs/INVENTORY-MANIFEST.json: regenerated to match filesystem
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs(#2790): add CHANGELOG entry for skill consolidation
* docs(#2790): update COMMANDS.md for 86→59 skill consolidation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#2790): address CodeRabbit review findings
- CHANGELOG.md: add --next alongside --do in progress flag list
- config.md: remove trailing space from --profile code span (MD038)
- COMMANDS.md: add required descriptions to /gsd-phase examples;
/gsd-phase without args errors, not interactive
- COMMANDS.md: add --next and --do to /gsd-progress flags table + examples
- test: convert content.includes('--reapply') to structural frontmatter
parse; add allow-test-rule comment for workflow content assertions
- test: replace redundant existsSync duplicate with assertion that verifies
the full consolidated flag surface (--sync | --reapply) in argument-hint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#2790): restore reapply-patches workflow and strengthen test assertions
- Create get-shit-done/workflows/reapply-patches.md: the #2790 consolidation
deleted the 14K combined command+workflow file (reapply-patches.md) but
update.md already referenced the workflow via execution_context_extended.
Restoring it fixes a silent behavioral gap where --reapply had no workflow
to load. Includes full three-way merge logic, hunk verification table
(Step 4), and the Hunk Verification Gate (Step 5) that blocks cleanup
until all user-added hunks are confirmed present in the merged output.
- Fix update.md: /gsd-reapply-patches → /gsd-update --reapply (stale ref)
- Fix reapply-verify-hunks.test.cjs: was checking existsSync(update.md) 8×;
now points to the workflow file and asserts real behavioral content
(Post-merge verification, Hunk presence check, Line-count check, backup
reference, per-file tracking, structural ordering)
- Fix reapply-patches.test.cjs: replace content.includes() stubs with
frontmatter-parsed argument-hint assertions; replace 4 existsSync(update.md)
no-ops with real assertions against the workflow content
- Fix edit-phase.test.cjs: /gsd-edit-phase → /gsd-phase (COMMANDS.md now
documents the consolidated command with --edit flag)
- Fix next-safety-gates.test.cjs: split OR predicates into independent
assertions — --next in progress.md and --force in next.md workflow
- Fix workspace.test.cjs: add allow-test-rule comment for routing content
checks (command routing text IS the deployed behavioral contract)
- Fix bug-2439 test: strengthen pre-flight assertion to verify gsd-sdk is
referenced (not just --profile)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address CodeRabbit review findings (CR round 2)
- INVENTORY.md: update sync-skills.md row to reference /gsd-update --sync
instead of stale /gsd-sync-skills (absorbed in #2790)
- enh-2380-sync-skills.test.cjs: align INVENTORY.md assertion with the
corrected reference; was asserting the old /gsd-sync-skills name while the
manifest test correctly asserted /gsd-update, creating conflicting expectations
in the same suite
- reapply-verify-hunks.test.cjs: add explicit notEqual(-1) assertions for all
three anchors before the ordering check so a missing anchor produces a clear
failure instead of a false positive (writeIdx=-1 < verifyIdx=5 is true)
- bug-2439-set-profile-gsd-sdk-preflight.test.cjs: defer fs.readFileSync until
after the existence assertion; eager describe-level read caused the suite to
crash before the existence test could run, making it effectively dead code
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#2790): address CR — INVENTORY routing + reapply test contract wording
Two unresolved CodeRabbit findings (Major):
- docs/INVENTORY.md: workflow-file table still pointed at obsolete
/gsd-do, /gsd-next, /gsd-note, /gsd-add-todo, /gsd-add-backlog,
/gsd-check-todos, /gsd-plant-seed slash commands. Re-route to the
consolidated /gsd-progress (--next, --do) and /gsd-capture (--note,
--backlog, --seed, --list) so the inventory is internally consistent.
- tests/reapply-verify-hunks.test.cjs: 'verification tracks per-file
status' asserted on phrasing that doesn't appear in reapply-patches.md
(the 'per-file' substring only matched accidentally via 'sequential
integer per file'). Switch to the actual contract text — Hunk
Verification Table, one row per hunk per file, verified column.
* test(#2790): update CR-INTEGRATION tests for consolidated --fix invocation
After the merge of main (which carries #2843's hyphen-form fix), the
consolidation in this branch absorbs gsd-code-review-fix into gsd-code-review
as the --fix flag. Update the two CR-INTEGRATION tests that previously
asserted on the standalone gsd-code-review-fix skill name to instead assert
on a gsd-code-review invocation carrying --fix in its arg tokens.
Tests still parse Skill() invocations structurally; only the asserted
skill-name + arg-token shape changed.
* test(#2790): scope success_criteria check to the <success_criteria> block
CodeRabbit nitpick: 'success criteria includes verification' did a
whole-file substring check, which can false-pass if the phrase appears
elsewhere in the document. Extract the <success_criteria>...</success_criteria>
block first via extractTagBlock() and assert against that scope only.
* fix(#2790): post-rebase reconciliation with main
- INVENTORY.md/JSON: add reapply-patches workflow row + bump count to 85
- autonomous.md: switch consolidated --fix invocation to hyphen Skill name
- analyze-dependencies test: assert COMMANDS.md does NOT document the
consolidated-away /gsd-analyze-dependencies entry (was: bare .includes())
* fix(#2790): address remaining CR findings — strengthen contract tests
Doc-fixes:
- INVENTORY.md: route transition.md & edit-phase.md rows to consolidated
/gsd-progress --next and /gsd-phase --edit (was: deleted /gsd-next, /gsd-edit-phase)
- config.md --profile branch: document #2439 pre-flight `command -v gsd-sdk`
guard + install hint BEFORE the gsd-sdk invocation (closes opaque
"command not found: gsd-sdk" regression path)
Test discipline (no-source-grep contract):
- bug-2439: replace bare `content.includes('gsd-sdk')` with structured
parse of <context> block + --profile branch; assert pre-flight token,
install hint, #2439 citation, and ordering vs gsd-sdk invocation
- edit-phase: parse INVENTORY.md edit-phase.md row's "Invoked by" column
and assert `/gsd-phase --edit` (not the deleted /gsd-edit-phase)
- next-safety-gates: tighten `--next` documentation contract — require
--next AND --force AND completeness routing (was OR-based, passed when
only --next present)
- reapply-patches: parse argument-hint flag list structurally; scan ALL
<execution_context*> blocks for the @-include of reapply-patches.md;
parse Hunk Verification Table header columns directly; locate Step 5
via heading parsing then assert (i) table reference, (ii) verified=no
gate, (iii) STOP/halt directive, (iv) explicit absent-table halt path
- workspace: parse frontmatter, tokenize argument-hint across multiple
bracketed segments, parse @-include targets from <execution_context>
rather than substring-matching the file body
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#2784): clear shared ~/.cache/gsd/ cache in update workflow
The SessionStart hook (hooks/gsd-check-update.js) writes update-check
results to $HOME/.cache/gsd/gsd-update-check.json (shared, tool-agnostic).
The update.md run_update step only cleared per-runtime paths like
~/.claude/cache/gsd-update-check.json, so the statusline kept showing the
stale upgrade indicator after a successful update.
Fix: add rm -f "$HOME/.cache/gsd/gsd-update-check.json" to the
cache-clear block in the run_update step.
Regression test: tests/bug-2784-update-cache-clear-path.test.cjs
* fix(#2784): address CodeRabbit review — four edge-cases count, bash fence, structured test assertions
All workflow, command, reference, template, and tool-output files that
surfaced /gsd:<cmd> as a user-typed slash command have been updated to
use /gsd-<cmd>, matching the Claude Code skill directory name.
Closes#2697
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Commands are now installed as commands/gsd/<name>.md and invoked as
/gsd:<name> in Claude Code. The old hyphen form /gsd-<name> was still
hardcoded in hundreds of places across workflows, references, templates,
lib modules, and command files — causing "Unknown command" errors
whenever GSD suggested a command to the user.
Replace all /gsd-<cmd> occurrences where <cmd> is a known command name
(derived at runtime from commands/gsd/*.md) using a targeted Node.js
script. Agent names, tool names (gsd-sdk, gsd-tools), directory names,
and path fragments are not touched.
Adds regression test tests/bug-2543-gsd-slash-namespace.test.cjs that
enforces zero legacy occurrences going forward. Removes inverted
tests/stale-colon-refs.test.cjs (bug #1748) which enforced the now-obsolete
hyphen form; the new bug-2543 test supersedes it. Updates 5 assertion
tests that hardcoded the old hyphen form to accept the new colon form.
Closes#2543
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(install): remove bare ~/.claude reference in update.md (closes#2470)
The installer's copyWithPathReplacement() replaces ~/\.claude\/ (with
trailing slash) but not ~/\.claude (bare, no trailing slash). A comment
on line 398 of update.md used the bare form, which scanForLeakedPaths()
correctly flagged for every non-Claude runtime install.
Replaced the example in the comment with a non-Claude runtime path so
the file passes the scanner for all runtimes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(test): align regex with installer's word-boundary semantics (CodeRabbit #2482)
Replace negative lookahead (?!\/) with \b word boundary to match the
installer's scanForLeakedPaths() pattern. The lookahead would incorrectly
flag ~/.claude_suffix whereas \b correctly excludes it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(test): revert \b regex — (?!\/) was intentionally scoped to bare refs
The installer's scanForLeakedPaths uses \b but the test is specifically
checking for bare ~/.claude without trailing slash that the replacer misses.
~/.claude/ (with slash) at line 359 of update.md is expected and handled.
\b would flag it as a false positive.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(inventory): update workflow count to 81 (graduation.md added in #2490)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: sync ARCHITECTURE.md command count to 74
commands/gsd/ has 74 .md files; the two count references in
ARCHITECTURE.md still said 73. Fixes the command-count-sync
regression test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: normalize Windows paths in update scope detection (#2232)
On Windows with Git Bash, `pwd` returns POSIX-style /c/Users/... paths
while execution_context carries Windows-style C:/Users/... paths. The
string equality check for LOCAL vs GLOBAL install scope never matched,
so every local install on Windows was misdetected as GLOBAL and the
wrong (global) install was updated.
Fix: normalize both paths to POSIX drive-letter form before comparing,
using portable POSIX shell (case+printf+tr, no GNU extensions).
Closes#2232
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(commands): add gsd:inbox command for GitHub issue/PR triage
inbox.md was created but not committed, causing the command count
to read 73 in git while ARCHITECTURE.md correctly stated 74.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
PR #2038 added detect-custom-files to gsd-tools.cjs and the backup_custom_files
step to update.md, but commit 7bfb11b6 is not an ancestor of v1.36.0: main was
rebuilt after the merge, orphaning the change. Users on 1.36.0 running /gsd-update
silently lose any locally-authored files inside GSD-managed directories.
Root cause: git merge-base 7bfb11b6 HEAD returns aa3e9cf (Cline runtime, PR #2032),
117 commits before the release tag. The "merged" GitHub state reflects the PR merge
event, not reachability from the default branch.
Fix: re-apply the three changes from 7bfb11b6 onto current main:
- Add detect-custom-files subcommand to gsd-tools.cjs (walk managed dirs, compare
against gsd-file-manifest.json keys via path.relative(), return JSON list)
- Add 'detect-custom-files' to SKIP_ROOT_RESOLUTION set
- Restore backup_custom_files step in update.md before run_update
- Restore tests/update-custom-backup.test.cjs (7 tests, all passing)
Closes#2229Closes#1997
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When a user manually installs a dev branch where VERSION > npm latest,
gsd-check-update detects hooks as "stale" and the statusline showed
the red "⚠ stale hooks — run /gsd-update" message. Running /gsd-update
would incorrectly downgrade the dev install to the npm release.
Fix: detect dev install (cache.installed > cache.latest) in the
statusline and show an amber "⚠ dev install — re-run installer to sync
hooks" message instead, with /gsd-update reserved for normal upgrades.
Also expand the update.md workflow's installed > latest branch to
explain the situation and give the correct remediation command
(node bin/install.js --global --claude, not /gsd-update).
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
AskUserQuestion is a Claude Code-only tool. When running GSD on OpenAI Codex,
Gemini CLI, or other non-Claude runtimes, the model renders the tool call as a
markdown code block instead of executing it, so the interactive TUI never
appears and the session stalls without collecting user input.
The workflow.text_mode / --text flag mechanism already handles this in 5 of
the 37 affected workflows. This commit adds the same TEXT_MODE fallback
instruction to all remaining 32 workflows so that, when text_mode is enabled,
every AskUserQuestion call is replaced with a plain-text numbered list that
any runtime can handle.
Fixes#2012
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: replace /gsd: command format with /gsd- skill format in all suggestions
All next-step suggestions shown to users were still using the old colon
format (/gsd:xxx) which cannot be copy-pasted as skills. Migrated all
occurrences across agents/, commands/, get-shit-done/, docs/, README files,
bin/install.js (hardcoded defaults for claude runtime), and
get-shit-done/bin/lib/*.cjs (generate-claude-md templates and error messages).
Updated tests to assert new hyphen format instead of old colon format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: migrate remaining /gsd: format to /gsd- in hooks, workflows, and sdk
Addresses remaining user-facing occurrences missed in the initial migration:
- hooks/: fix 4 user-facing messages (pause-work, update, fast, quick)
and 2 comments in gsd-workflow-guard.js
- get-shit-done/workflows/: fix 21 Skill() literal calls that Claude
executes directly (installer does not transform workflow content)
- sdk/prompt-sanitizer.ts: update regex to strip /gsd- format in addition
to legacy /gsd: format; update JSDoc comment
- tests/: update autonomous-ui-steps, prompt-sanitizer to assert new format
Note: commands/gsd/*.md frontmatter (name: gsd:xxx) intentionally unchanged
— installer derives skillName from directory path, not the name field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(plan-phase): preserve --chain flag in auto-advance sync and handle ui-phase gate in chain mode
Bug 1: step 15 sync-flag check only guarded against --auto, causing
_auto_chain_active to be cleared when plan-phase is invoked without
--auto in ARGUMENTS even though a --chain pipeline was active. Added
--chain to the guard condition, matching discuss-phase behaviour.
Bug 2: UI Design Contract gate (step 5.6) always exited the workflow
when UI-SPEC was missing, breaking the discuss --chain pipeline
silently. When _auto_chain_active is true, the gate now auto-invokes
gsd-ui-phase --auto via Skill() and continues to step 6 without
prompting. Manual invocations retain the existing AskUserQuestion flow.
* fix: remove <sub>/clear</sub> pattern and duplicate old-format command in discuss-phase.md
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Honor KILO_CONFIG across installer and workflow resolution, preserve Claude agent tool intent as explicit Kilo permissions, and rewrite relative .claude references during Kilo conversion.
The repository was transferred from the glittercowboy org to gsd-build,
but several files still referenced the old org in URLs. This updates all
repository URL references across READMEs (all languages), package.json,
and the update workflow. Also removes a duplicate language selector in
the main README header.
Files intentionally unchanged:
- CHANGELOG.md (historical entries)
- CODEOWNERS, FUNDING.yml, SECURITY.md (reference @glittercowboy as a
GitHub username/handle, not a repo URL)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The version detection script in update.md used a space-separated string
for RUNTIME_DIRS and iterated with `for entry in $RUNTIME_DIRS`. This
relies on word-splitting which works in bash but fails in zsh (zsh does
not word-split unquoted variables by default), causing the entire string
to be treated as one entry and detection to fall through to UNKNOWN.
Fix: convert RUNTIME_DIRS and ORDERED_RUNTIME_DIRS from space-separated
strings to proper arrays, and iterate with ${array[@]} syntax which
works correctly in both bash and zsh.
Closes#1173
When running /gsd:update from $HOME, the local path ./.claude/ resolves
to the same directory as $HOME/.claude/. The local branch always wins,
triggering --local reinstall that corrupts all paths in a global install.
This is self-reinforcing — once corrupted, every subsequent update
perpetuates the corruption.
Compare canonical paths (via cd + pwd) and only report LOCAL when the
resolved directories differ. When they're the same, fall through to
GLOBAL detection.
Closes#721
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three files had hardcoded `.claude` paths that break OpenCode and
Gemini installations where the config directory is `.config/opencode`,
`.opencode`, or `.gemini` respectively.
Changes:
- hooks/gsd-check-update.js: add detectConfigDir() helper that checks
all runtime directories for get-shit-done/VERSION, falling back to
.claude. Used for cache dir, project VERSION, and global VERSION.
- commands/gsd/reapply-patches.md: detect runtime directory for both
global and local patch directories instead of hardcoding ~/.claude/
and ./.claude/
- workflows/update.md: detect runtime directory for local and global
VERSION/marker files, and clear cache across all runtime directories
Closes#682
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SessionStart hook always writes to ~/.claude/cache/ via os.homedir()
regardless of install type. The update workflow previously only cleared
the install-type-specific path, leaving stale cache at the global path
for local installs.
Clear both ./.claude/cache/ and ~/.claude/cache/ unconditionally.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* Fix /gsd:update to pin installer to latest
* Harden /gsd:update install detection with global fallback
---------
Co-authored-by: Colin <colin@solvely.net>
Hooks had hardcoded `.claude` paths that broke OpenCode users. The
installer now templates `.js` hooks with runtime-specific config dirs,
same as it already does for `.md` files. Also added `./.claude/`
replacement for local install paths in workflows.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When users modify GSD workflow files (e.g., adding bug workarounds),
those changes get wiped on every /gsd:update. This adds automatic
backup and guided restore:
**install.js changes:**
- Writes `gsd-file-manifest.json` after install with SHA256 hashes
of every installed GSD file
- Before wiping on update, compares current files against manifest
to detect user modifications
- Backs up modified files to `gsd-local-patches/` directory
- Reports backed-up patches after install completes
**New command: /gsd:reapply-patches**
- LLM-guided merge of backed-up modifications into new version
- Handles cases where upstream also changed the same file
- Reports merge status per file (merged/skipped/conflict)
**update.md changes:**
- Warning text now mentions automatic backup instead of manual
- New step after install to check for and report backed-up patches
Flow: modify GSD file → /gsd:update → modifications auto-backed up →
new version installed → /gsd:reapply-patches → modifications merged back
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>