Commit Graph

33 Commits

Author SHA1 Message Date
Tom Boucher
79002a00cb chore(#518): rename npm package + bin to @opengsd/gsd-core (#519)
* chore: rename npm package + bin to @opengsd/gsd-core (functional)

- package.json: name @opengsd/get-shit-done-redux → @opengsd/gsd-core,
  bin key get-shit-done-redux → gsd-core, repository/homepage/bugs URLs
- package-lock.json: regenerated (npm install --package-lock-only)
- tests/**, scripts/**, bin/**, .github/**, agents/**, commands/**,
  get-shit-done/bin/**, get-shit-done/workflows/**:
  applied the 4-rule replacement (scoped npm ref, GitHub repo path,
  bin/clone invocations) per #505 single-source refactor

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: sweep live references to @opengsd/gsd-core

Update all live documentation (README.md + translations, docs/**,
CONTRIBUTING.md, VERSIONING.md, SECURITY.md, CONTEXT.md,
docs/CANARY.md) to reflect the renamed package and repository.

Rules applied:
- @opengsd/get-shit-done-redux → @opengsd/gsd-core (scoped npm name)
- open-gsd/get-shit-done-redux → open-gsd/gsd-core (GitHub repo)
- GSD-redux/get-shit-done-redux → open-gsd/gsd-core (stale badge org)
- bare bin/clone refs → gsd-core

CHANGELOG.md, docs/adr/**, docs/RELEASE-*.md, docs/research/**,
and .changeset/** are preserved byte-identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: add negative lookbehind to slash-command regex in bug-2954 test

The extractSlashReferences regex matched /gsd-core inside npm package
URLs (@opengsd/gsd-core), producing a false /gsd:core command reference.
Adding a negative lookbehind (?<![a-z]) excludes matches preceded by a
letter, so only standalone /gsd-<cmd> and /gsd:<cmd> tokens are found.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(#518): add changeset for package rename

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(#518): update package-identity expectations to the renamed coordinates

The rebase regenerated the seam to @opengsd/gsd-core (bin gsd-core, repo
open-gsd/gsd-core). The #498 seam tests assert deriveIdentity against the REAL
package.json, so their expected literals must follow the rename. The drift-lint
unit test is left as-is — its SEAM is a self-consistent fixture and its
stale-literal detection cases would shift if altered; the live-repo scan in it
already passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:25:02 -04:00
Tom Boucher
48824f258c fix(#444): resolver preamble checks repo-local .claude install path (#476)
The gsd_run resolver preamble now probes
<repo-root>/.claude/get-shit-done/bin/${_GSD_SHIM_NAME} as the second
check — immediately after the existing get-shit-done/bin/ check and
before command -v / $HOME/.claude fallbacks. This covers the install
layout produced by npx @opengsd/get-shit-done-redux@latest --claude --local.

A _GSD_RUNTIME_ROOT variable is introduced to bind the repo-root
expression once and reuse it for both checks without repeating the
git rev-parse subshell.

76 workflow files regenerated via node scripts/sync-runtime-launcher.cjs.
All parity, size-budget, and new regression tests pass.

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:12:54 -04:00
Tom Boucher
a5eceb1faf fix(#211): add ~/.claude/get-shit-done/bin fallback to gsd_run launcher (closes #394) (#427)
Extends the canonical runtime-launcher snippet with a third resolution arm
that probes $HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME} between the
PATH check and the hard-error exit. Global Claude-Code installs (--claude
without --local) with no PATH wiring and no RUNTIME_DIR no longer hit the
hard-error path.

Resolution order: local/RUNTIME_DIR -> PATH -> ~/.claude/... -> hard error.

Propagated to 76 workflow .md files via sync-runtime-launcher.cjs. Parity
test (G) and bug-211 regression test (4 assertions) added.
2026-05-27 23:17:59 -04:00
Tom Boucher
2b9fa009d3 fix(#373): replace unquoted $GSD_SDK with space-safe gsd_run launcher (#379)
* fix(#373): replace unquoted $GSD_SDK with space-safe gsd_run launcher

Workflow bash blocks resolved the runtime as GSD_SDK="node $GSD_TOOLS" and
invoked it unquoted ($GSD_SDK query ...). On install paths containing spaces
(e.g. /Volumes/Mini Me/...) the unquoted expansion word-split into
`node /Volumes/Mini gsd-tools.cjs ...`, failing with "Cannot find module
'/Volumes/Mini'" and getting masked by `2>/dev/null || echo "{}"` into a
silent empty state.

Replace the string variable with a single-line shell launcher that defines a
gsd_run function, invokes the runtime with a fully-quoted path and "$@", and
preserves the local-cjs / installed-gsd-tools-on-PATH fallback (#3668) plus
the loud not-found error and install hint. The launcher uses _GSD_SHIM_NAME
indirection so no workflow emits the /gsd-tools substring that the do.md
dispatcher-parity scanner would misread, and is single-line to stay within
the per-file progressive-disclosure line budgets (#2551).

The canonical launcher lives in
get-shit-done/workflows/_runtime-launcher.snippet.sh, is propagated once per
file by scripts/sync-runtime-launcher.cjs, and is locked by
tests/runtime-launcher-parity.test.cjs (fails CI on drift, on a reappearing
$GSD_SDK token, or on a /gsd-tools substring). Dependent workflow-assertion
tests are updated from $GSD_SDK to gsd_run, and the runtime launcher is
registered in CONTEXT.md.

Fixes #373

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci(#373): add changeset fragment and allow-test-rule for parity guard

The runtime-launcher parity test is a structural drift guard that reads
workflow markdown to assert the canonical launcher is present and the
retired $GSD_SDK / /gsd-tools tokens are absent; annotate it with
allow-test-rule per the no-source-grep lint escape hatch. Add the required
.changeset fragment for this user-facing fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(#373): make parity PATH-fallback assertion cross-platform (Windows)

Subtest (E) compared GSD_TOOLS against the Node-side absolute temp path,
but the value originates from git-bash which reports the POSIX form, so the
prefix comparison failed on windows-latest while the launcher itself worked
(the installed stub was invoked). Assert the resolved binary by normalized
suffix (/bin/gsd-tools, not .cjs) instead of the absolute prefix; the
behavioral stub-invocation assertion is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 20:21:05 -04:00
Colin Johnson
aaa19b0609 fix: resolve installed gsd-tools in workflows (#354)
* fix: resolve installed gsd-tools in workflows

* chore: add changeset
2026-05-26 18:56:21 -04:00
Tom Boucher
0e6907050e docs(#195): migrate workflow markdown off gsd-sdk query 2026-05-25 12:03:10 -04:00
Tom Boucher
aaba233f83 fix(#170): migrate workflow fallback hints to @opengsd package (#204)
* fix(#170): update workflow fallback install hint package

* chore(#170): add changeset for workflow fallback hint migration

* fix(#170): mark workflow-hint test as structural text contract
2026-05-24 14:16:30 -04:00
Tom Boucher
7ad1a5edf5 fix(3668): isolate --local install from global gsd-sdk (#89)
* fix(3668): isolate --local install from global gsd-sdk

- `buildGsdSdkVersionMismatchReport` now accepts `opts.isLocal`; when
  true it sets `fix_command` to `npx get-shit-done-cc@latest --claude
  --local` instead of `npm install -g …`, removing the misleading global
  upgrade suggestion for local installs.
- Propagate `isLocal` from `installSdkIfNeeded` into the mismatch report
  builder so the right fix_command reaches the renderer.
- Export `buildGsdSdkVersionMismatchReport` and
  `renderGsdSdkVersionMismatchReport` so tests can assert on the IR
  contract directly.
- Add `command -v gsd-sdk … elif node "$GSD_TOOLS"` preflight SDK
  resolution block to all 69 workflow files that called bare `gsd-sdk`
  with no fallback, matching the pattern established in update.md,
  execute-phase.md, and quick.md.
- Add `tests/bug-3668-local-install-sdk-soft-dep.test.cjs` with 5 tests
  covering Defects 1-3, including a CI lint guard that blocks future
  workflow regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* changeset: add Fixed entry for #3668

* fix(3668): add allow-test-rule to suppress false lint-no-source-grep violation

The test reads workflow .md files (product content) to assert structural
invariants — not .cjs source files. The file-presence check is the only
viable IR for markdown guard patterns. Add the // allow-test-rule annotation
so lint-no-source-grep passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(3668): fix do.md false-positive and discuss-phase.md size overflow

Two CI failures introduced by the 69-workflow preflight block:

1. do.md: the path `bin/gsd-tools.cjs` contains `/gsd-tools` which the
   bug-2954 parity test regex `/\/gsd[:-]([a-z][a-z0-9-]*)/g` mistakenly
   extracts as a slash command named `tools`. Fix: store the shim filename
   in _GSD_SHIM_NAME so the path construction no longer contains a static
   `/gsd-tools` literal. Also wire $GSD_SDK into the actual query call.

2. discuss-phase.md: the file was at 499 lines (the 500-line budget from
   #2551). Adding the 11-line preflight block pushed it to 510, failing
   workflow-size-budget.test.cjs. Fix: compress the 11-line preflight +
   2-line invocations into 3 lines (one-liner guard + two $GSD_SDK calls)
   returning the file to 499 lines while retaining the command -v guard
   required by bug-3668-local-install-sdk-soft-dep.test.cjs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(3668): wire \$GSD_SDK through all workflow callsites (#3797)

PR #3797 introduced the resolution preflight block (setting \$GSD_SDK) in
69 workflows but left every downstream gsd-sdk callsite using the bare
command. On local-only installs the preflight exits cleanly, then the
very next line fails with 'command not found'. This is the structural
gap the Codex review flagged.

Changes:
- 687 bare `gsd-sdk` callsites replaced with `\$GSD_SDK` across 75
  workflow files (all bash/sh fenced blocks excluding the resolution
  guard blocks themselves)
- execute-phase.md: was missing the preflight block entirely — added
  the standard 11-line resolution block at the initialize step
- execute-phase.md: inline `if command -v gsd-sdk` availability guard
  (legacy #3384 fallback) replaced with `\$GSD_SDK` + error fallback
  since the new preflight guarantees SDK availability or exits 1
- 6 sub-workflow files (discuss-phase/modes/*, execute-phase/steps/*)
  that have no preflight of their own but use \$GSD_SDK — these are
  loaded by parent workflows that set the variable; callsites updated
  to use \$GSD_SDK so they work when variable is in scope

Transformation script used: /private/tmp/fw2.js (regex-based fence
parser with segment join invariant verification — preserves all blank
lines and prose formatting).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(3668): upgrade CI guard to detect bare callsite routing (#3797)

The previous Defect 3 test checked that 'command -v gsd-sdk' appeared
as a string in the file — a guard-presence check, not a callsite-routing
check. A workflow with the preflight block but 40 bare gsd-sdk calls
below it passed the old test. This is exactly the bug state PR #3797
was supposed to fix.

Upgraded test:
- Parses each workflow file into markdown segments using a regex-based
  fence extractor (preserves all content invariantly)
- Skips bash/sh blocks that contain 'command -v gsd-sdk' (those are
  resolution guards — bare references there are expected)
- Flags any remaining bash/sh block line that invokes gsd-sdk without
  the \$ prefix (isBareGsdSdkInvocation predicate)
- Counter-test proves the predicate correctly flags real callsite lines
  and correctly exempts guard assignments, comments, and \$GSD_SDK refs

Also adds helper functions parseMarkdownSegments, isBareGsdSdkInvocation,
and findMdFiles which are used by both the upgraded Defect 3 test and
the counter-test.

This test would have caught the originally-shipped bug: the preflight
block was present but callsites still used bare gsd-sdk.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): update workflow content tests to accept \$GSD_SDK callsite form (#3797)

Six regression tests assert on the exact textual pattern of gsd-sdk calls
inside workflow .md files. After the #3797 callsite replacement (687 bare
`gsd-sdk` invocations replaced with `\$GSD_SDK`), these tests failed because
they searched for the literal string `gsd-sdk query <cmd>` which no longer
appears at callsites.

Updated each test to accept both the pre-#3797 bare form and the post-#3797
variable form using `(?:\$GSD_SDK|gsd-sdk)` regex alternation (or two-branch
`includes()` checks for non-regex assertions). The structural invariants each
test enforces are unchanged — we're accepting the same behavioral contract
through the new callsite surface.

Tests fixed:
- bug-2334-quick-gsd-sdk-preflight: find init.quick call via \$GSD_SDK or bare
- bug-2661-roadmap-sync-parallel: roadmap.update-plan-progress call pattern
- bug-3360-codex-execute-phase-worktrees: RUNTIME config-get call detection
- bug-3381-verify-work-workstream: init.verify-work / phase.mvp-mode calls
- enh-2433-todo-phase-linking: commit call in new-milestone.md
- enh-2792-namespace-skills: validate.context invocation in context_check step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): update remaining workflow content tests to accept \$GSD_SDK form (#3797)

After #3797 callsite replacement, ultraplan-phase.test.cjs and worktree-cleanup.test.cjs
still assert bare gsd-sdk form. Update to accept either \$GSD_SDK or gsd-sdk. Also trim
the execute-phase.md preflight comment to stay within the XL line-count budget (1810).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(3668): adopt inline-per-fence SDK resolution + restore safety semantics

The brief offered three options:
  (a) inline preflight block per fence
  (b) wrapper script
  (c) shared shell fragment sourced at the top

71 of 72 workflow files already had inline preflight blocks (just broken ones).
Option (b)/(c) would have required changes to install.js + a new shared artifact,
with significant risk of breaking the install pipeline. Option (a) was the path
of least resistance and least new blast radius.

**BLOCKER 1+2+3 (quick.md — GSD_SDK never assigned):**
- quick.md had 12 `$GSD_SDK` references but zero `GSD_SDK=` assignments.
- Added proper local-first preflight block with `git rev-parse --show-toplevel`
  path (not the broken `CLAUDE_FILE_PATHS` which is always empty in Claude Code).
- Each Bash fence in Claude Code runs as a fresh `bash -c`, so env vars don't
  persist. The preflight block must appear in every fence that uses $GSD_SDK.

**BLOCKER 4 (execute-phase.md — || exit 1 dropped):**
- Restored `|| exit 1` after every `worktree.cleanup-wave` call. SDK safety
  refusals (drift detection #3174, deletion block #2384) must surface, not be
  swallowed by the old `|| { fallback }` branch.

**F5 (verify-work.md untyped fence):**
- Changed bare `gsd-sdk` in an untyped fence to `$GSD_SDK`.
- Changed fence tag from untyped to `bash`.

**F6 (non-recursive readdirSync):**
- Defect 2 test now uses `findMdFiles` (recursive) to cover workflow
  subdirectories, not the flat `fs.readdirSync` that missed subdirs.

**F7 (lint misses untyped fences):**
- `parseMarkdownSegments` now treats `lang === ''` fences as bash-fences.

**F8 (missing propagation test):**
- Added two propagation tests in the Defect 3 describe block.

**F9 (priority inverted — global before local):**
- All 72 workflow files now check `[ -f "$GSD_TOOLS" ]` before `command -v gsd-sdk`.
- Path: `$(git rev-parse --show-toplevel 2>/dev/null || pwd)/get-shit-done/bin/gsd-tools.cjs`

**F10/F11 (broken quoting):**
- Changed `GSD_SDK="node "$GSD_TOOLS""` → `GSD_SDK="node $GSD_TOOLS"` across all files.

**SDK-absence fallback removal:**
- The old `|| { STATE_BACKUP=...; while IFS=...WAS_DELETED...; done }` fallback
  code was dead — preflight now exits if neither local nor global SDK exists.
  Removed from quick.md, execute-phase.md. Tests updated to verify SDK delegation
  rather than inline shell mechanics.

**Tests updated:**
- bug-2384, bug-2501, bug-2838, bug-3091, bug-3195, bug-3521, bug-3668,
  worktree-cleanup — all updated to reflect SDK delegation contract.
- Defect 2 test now uses bash-fence scan (not raw content) to skip docs-only
  gsd-sdk prose references (e.g. discuss-phase/modes/text.md).

Closes #3668

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(3668): restore _GSD_SHIM_NAME indirection in do.md to prevent false-positive

The top commit re-introduced a literal /get-shit-done/bin/gsd-tools.cjs path
in do.md, causing bug-2954 test to match /gsd-tools as an unshipped slash
command. Restore the _GSD_SHIM_NAME variable indirection (from ff9939e5) to
break the literal path while preserving local-first preference order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): update worktree.test.cjs to accept SDK delegation contract (#3797)

Mirror the contract update already applied to worktree-cleanup.test.cjs:
- pre-merge deletion check tests: accept worktree.cleanup-wave + deletion
  mention as valid (inline --diff-filter=D was in the removed shell fallback)
- quick.md bug-2431 tests (lock-aware, unlock retry, residual warning): accept
  worktree.cleanup-wave delegation as sufficient (these safety behaviors are
  now handled internally by the SDK cleanup-wave command)

execute-phase.md tests unchanged: it retains inline .git/worktrees/, locked,
git worktree unlock, and Residual worktree in its cleanup-tail snippet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(3668): refactor bug-2384 and bug-2838 from grep to structured assertions

Replace content.includes() on readFileSync-bound variables with parser
functions that split lines and return typed boolean fields, matching the
project's no-source-grep contract (lint-no-source-grep rule F/G).

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:54:20 -04:00
Tom Boucher
e690f1bc90 fix(3718): shell-free Node.js UI safety gate — fixes PowerShell silent-fail (#3718)
* fix(workflows): add word-boundary anchoring to UI safety gate grep

Replace unanchored grep -iE "UI |..." alternation with POSIX ERE
word-boundary-anchored form:

  LC_ALL=C grep -iE "(^|[^[:alnum:]])(UI|...)([^[:alnum:]]|$)"

Unanchored form matched 'ui' inside 'requirements', 'view' inside
'overview' and 'review', 'form' inside 'performance'/'platform'/
'transform' — producing HAS_UI=0 on 100% of standard roadmap phases
(every phase contains a **Requirements**: field).

Fix applied to both plan-phase.md:625 and autonomous.md:284.
LC_ALL=C added for POSIX locale portability on both BSD and GNU grep.

Closes #3706

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(workflows): add regression tests for UI safety gate false-positives (#3706)

- bug-3706-ui-safety-gate-false-positives.test.cjs: 36-test suite covering
  both plan-phase.md and autonomous.md gate behavior; verifies that
  Requirements/overview/performance/platform/transform/review/build/screening
  do NOT trigger the gate, while standalone UI/view/form/screen/dashboard/
  component/lowercase-ui/hyphenated-non-UI DO trigger it.

- autonomous-ui-steps.test.cjs: update stale assertion that checked for the
  old broken grep pattern; now asserts the word-boundary-anchored form.

Test strategy: extract the POSIX ERE pattern from the workflow file and
simulate grep match semantics in JS (no shell exec, no source-grep).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(changeset): add Fixed fragment for PR #3718 (UI safety gate false-positives)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(workflows): document compound-token boundary contract; add comment to gate

Addresses adversarial review finding: word-boundary anchoring intentionally
does not match tokens embedded in compound alphanumeric words (e.g.
"microfrontend", "dashboardWidget", "uiSpec"). This is correct behavior —
gsd-roadmapper generates natural English prose, not camelCase compounds.
Hyphenated forms ("micro-frontend") and spaced forms are caught by the
anchored pattern (hyphen is [^[:alnum:]]).

Add inline comment in both workflow files explaining the pattern intent,
the false-positive prevention, and the compound-word contract.

Add 4 tests (2 per workflow) documenting the compound-word contract:
- "microfrontend" (compound) must NOT trigger gate (documented behavior)
- "micro-frontend" (hyphenated) MUST trigger gate (correct true-positive)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(3718): replace shell grep gate with shell-free Node.js helper

Moves UI safety gate logic from `LC_ALL=C grep -iE` (silently broken on
Windows PowerShell — locale env-var prefix not recognised by pwsh) to
`bin/lib/ui-safety-gate.cjs` (Node.js, reads via stdin to avoid ARG_MAX).

Path is anchored via `git rev-parse --show-toplevel` (GSD_REPO_ROOT) to
avoid CWD-sensitive failure when Claude Code executes from a subdirectory.

Word-boundary regex is identical to the original POSIX ERE pattern:
  (^|[^a-zA-Z0-9])(TOKEN)([^a-zA-Z0-9]|$)
Exit codes mirror grep: 0 = UI found, 1 = not found.

Tests: 51/51 pass — includes spawnSync shell:false + stdin cross-shell
portability tests and ARG_MAX large-input test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(3706): address pr-review-toolkit + codex review findings

- Multi-token-per-line: use matchAll to capture all UI tokens
- Add test for multiple distinct tokens on same line
- Clarify ASCII vs POSIX [:alnum:] in word-boundary comment
- Correct misleading "path anchored" comment in plan-phase/autonomous workflows
- Remove UI_GATE_PATTERN from module.exports (internal implementation detail)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(state): restore ACQUIRE_LOCK_RETRY_ERRNOS in acquireStateLock (#3718)

Commit 473c279c removed ACQUIRE_LOCK_RETRY_ERRNOS and replaced the
correct `throw err` path with `return lockPath`, which silently
"succeeds" on any non-EEXIST error — allowing two concurrent processes
to both hold the lock simultaneously and causing lost updates.

This restores the set of recoverable transient errno codes (Docker
overlay-fs EINVAL/EIO/ENOENT, NFS ESTALE, POSIX EAGAIN/EINTR, Windows
EPERM/EBUSY) that should retry, and restores `throw err` for genuinely
fatal codes.  Equivalent to commit 47983914 on main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 23:08:56 -04:00
Tom Boucher
a60e05c714 fix(claude): restore namespaced /gsd:<command> references (#3452)
* fix(claude): restore namespaced /gsd:<command> references

* test(claude): align slash-command expectations to /gsd: form

* test(claude): align generated command references to /gsd:

* test(claude): finish /gsd: namespace expectation updates
2026-05-12 21:53:24 -04:00
Tom Boucher
87917131f2 refactor(#2790): consolidate 86 gsd-* skills to 59 — fold flags, delete dead skills (#2824)
* 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>
2026-04-30 00:43:47 -04:00
Jeremy McSpadden
4d394a249d fix(commands): normalize gsd slash namespace drift (#2858)
* fix(commands): normalize gsd slash namespace drift

* fix(#2855): address CodeRabbit findings on namespace drift PR

Three CR findings, all valid:

1. autonomous.md line 783 still had `gsd:discuss-phase` (the PR's own
   normalization missed this line). Switched to `gsd-discuss-phase` and
   updated the matching test in autonomous-interactive.test.cjs that was
   asserting the now-retired colon form.

2. tests/bug-2543-gsd-slash-namespace.test.cjs source-grepped the
   fix-slash-commands.cjs script with .includes() rather than driving
   its transform behaviour. Refactored fix-slash-commands.cjs to export
   a pure transformContent(src, cmdNames) function, kept the CLI behaviour
   unchanged via require.main, and replaced the source-grep block with
   five behavioural cases: rewrite, multi-occurrence, idempotence on
   canonical input, no-op on gsd-sdk/gsd-tools, and word-boundary safety.

3. tests/bug-2808-skill-hyphen-name.test.cjs matched `name:` anywhere
   in SKILL.md; a stray name: in the body could satisfy the assertion.
   Scoped the lookup to the YAML frontmatter block via the suggested
   diff (parse the leading --- ... --- region first, then find name:
   inside it).

Full suite: 5854/5854 passing.

* fix(#2855): address remaining CodeRabbit findings on PR #2858

Three structural concerns flagged on the namespace-drift fix PR:

1. scripts/fix-slash-commands.cjs:24 — `buildPattern([])` compiled
   `/gsd:()(?=[^a-zA-Z0-9_-]|$)/g`. The empty capture group still
   matches any `/gsd:` token followed by a non-word boundary
   (whitespace, EOL, punctuation), rewriting it to a stray `/gsd-`.
   Verified live: `transformContent("/gsd:", [])` → `"/gsd-"`. Added
   a guard returning null from `buildPattern` on empty input and
   updated `transformContent` and `processDir` to no-op when the
   pattern is null.

2. tests/autonomous-interactive.test.cjs:44-47 — assertion was
   `content.includes('gsd-discuss-phase') && content.includes('INTERACTIVE')`,
   which would false-pass on any unrelated co-occurrence (e.g.
   `INTERACTIVE=""` initialization plus a stray `gsd-discuss-phase`
   prose mention). Replaced with a structural extraction: locate the
   `**If \`INTERACTIVE\` is set:**` branch, bound it by the next
   `**If` / `<step>` boundary, and assert the
   `Skill(skill="gsd-discuss-phase", ...)` invocation lives inside
   that region. Tolerates whitespace around `(`, `skill`, and `=`.

3. tests/bug-2808-skill-hyphen-name.test.cjs:104 — colon-call regex
   was `Skill\(skill=...` and missed valid formatting like
   `Skill(skill = "gsd:cmd")` or `Skill( skill = ...)`. Loosened to
   `Skill\(\s*skill\s*=\s*...` so reformatting drift can't slip past
   the namespace guard.

Verification: 5854/5854 pass on `npm test` from the rebased branch.

* fix(#2855): drop pre-validation filter that hid namespace drift

CR finding on tests/bug-2808-skill-hyphen-name.test.cjs:128: the test
collected generated skill directories with
`.filter(entry => entry.isDirectory() && entry.name.startsWith('gsd-'))`,
then validated namespace invariants over that filtered list. Anything
that violated the prefix invariant — `gsd:extract-learnings` (colon
form), `extract_learnings` without prefix, `Gsd-foo` mis-cased — would
silently disappear from the iteration and the test would falsely pass.

Drop the `startsWith('gsd-')` filter so every generated directory shows
up. Add explicit assertions before the existing per-skill loop:
  - directory list is non-empty (catches a broken converter that
    produces nothing)
  - every directory begins with `gsd-`
  - every directory contains no `:`
  - every directory contains no `_`

Re-audited the full PR diff for the same anti-pattern: only this one
site filtered before validating the namespace; bug-2643 and
commands-doc-parity also use `readdirSync().filter()` but only by file
extension, which is correct.

5854/5854 on `npm test`.

* fix(#2855): address remaining CR findings (1 active + 2 nitpicks)

Three findings on PR #2858, all the same root cause: input narrowing
before validation lets drift slip past the guards.

1. tests/bug-2808-...:104 (active) — `colonCallRe` captured local names
   with `[a-z0-9-]+`, which excluded the underscore. A drift like
   `Skill(skill="gsd:extract_learnings")` (deprecated colon syntax with
   the old underscore filename) silently slid through. Broadened the
   capture to `[^'"\s)]+` so any malformed local name is surfaced; surrounding pattern (whitespace tolerance, escape support, flags)
   unchanged.

2. tests/bug-2643-...:43 (nitpick) — `extractSkillNamesHyphen` and
   `extractSkillNamesColon` had the same over-strict capture plus
   relied on a single regex over raw bytes, which the project test-
   rigor memory bans (`feedback_no_source_grep_tests.md`). Replaced
   with `extractSkillCalls(content)` — a small structural extractor
   that walks `Skill(` openers, locates each call's matching `)`,
   parses the body's `skill = "..."` keyword argument with permissive
   whitespace + quoting + escape handling, and returns
   `{ name, raw }` records. The two namespace-form helpers become
   thin filters over the structured output. Tightened the body class
   to `[^'"\\]+` so a trailing escape `\` before the closing quote
   (as in `Skill(skill=\"gsd-foo\", …)` written inside another string
   context) doesn't get included in the captured name.

3. tests/bug-2543-...:44 (nitpick) — `DOC_SEARCH_FILES` was a hand-
   curated 7-entry array. Every doc added in the future would silently
   weaken drift detection until someone remembered to extend the list.
   Replaced with `discoverDocSearchFiles(ROOT)`: globs every `.md`
   under `docs/` and adds `README.md` if present. New docs are picked
   up automatically.

Re-audited the diff surface for similar narrowings; no other sites
filter or constrain before validating namespace invariants.

5854/5854 on `npm test`.

* fix(#2855): recurse docs/ tree so localized translations are scanned too

CR finding: discoverDocSearchFiles() stopped at docs/*.md, leaving
localized translation trees (docs/ja-JP/, docs/zh-CN/, docs/ko-KR/,
docs/pt-BR/) and other nested doc collections (docs/skills/,
docs/superpowers/) invisible to the namespace-drift invariant.

Verified the gap: docs/ has 6 nested directories with ~30 .md files
that the previous top-level-only scan was skipping. None contain
/gsd: references today, but a future translation update or new
doc subdir could leak drift.

Switch to an iterative stack walk so every .md under docs/ is scanned
regardless of depth. Stack form (rather than recursion) avoids the
risk of running into the call-stack limit on deep doc trees.

5854/5854 on `npm test`.

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
2026-04-29 22:56:59 -04:00
Tom Boucher
5fe1f00a0d fix(#2808): SKILL.md files use hyphen name form (gsd-cmd not gsd:cmd) (#2819)
* fix(#2808): SKILL.md name uses hyphen form for Claude Code autocomplete

skillFrontmatterName() was converting gsd-<cmd> to gsd:<cmd> (colon) so
installed SKILL.md files had name: gsd:add-phase etc. Claude Code surfaces
this name in autocomplete, showing the deprecated colon form to users even
though the hyphen form is canonical everywhere else.

Root cause: the colon form was needed because workflows called
Skill(skill="gsd:<cmd>"). All 4 remaining colon-form Skill() calls in
autonomous.md and execute-phase.md are updated to hyphen form.

skillFrontmatterName() now returns the hyphen dir name unchanged.
Updated 4 existing tests that asserted colon form.

Regression test: tests/bug-2808-skill-hyphen-name.test.cjs

* fix(#2808): address CodeRabbit — bash/text fences, structured test assertions, fail-loud on errors
2026-04-28 20:22:37 -04:00
Tom Boucher
54e6da3126 fix(#2767): pass paths via --files to gsd-sdk query commit + lint guard (#2781)
* fix(#2767): pass paths via --files to gsd-sdk query commit + lint guard

Workflows, agents, commands, and references passed file paths positionally
to `gsd-sdk query commit`, which silently appended them to the commit
subject and triggered the `.planning/` wholesale-stage fallback in
sdk/src/query/commit.ts:136. Regression of #733/#798.

Inserted `--files` before the path list at every site (81 invocations
across 50 files). Added tests/bug-2767-gsd-sdk-commit-files-flag.test.cjs
as a permanent lint that scans every shipped .md file and asserts each
`gsd-sdk query commit[-to-subrepo]` invocation either uses `--files` or
carries no path arguments.

Closes #2767

* test(#2767): replace source-grep with behavioral SDK test

The original test walked every shipped .md file and regex-tokenized
`gsd-sdk query commit` invocations to assert `--files` was present.
CONTRIBUTING.md prohibits this source-grep pattern.

Rewrite as behavioral SDK tests against `sdk/dist/cli.js` over a real
tmp git project (createTempGitProject helper). Cover both the
well-formed (`--files <paths>`) form — clean subject, exactly-staged
files, .planning/ left untouched — and the buggy positional form,
asserting the documented misbehavior (paths leak into subject + the
`.planning/` wholesale-stage fallback at commit.ts:136). Also asserts
`commit-to-subrepo` rejects when `--files` is omitted (commit.ts:258).

The doc-lint is retained as a supplementary defense-in-depth guard
since agent-prompt markdown invocations cannot be exercised end-to-end
— but it is no longer the primary contract.

* docs(#2767): correct contradictory --files guidance in zh-CN/en docs + fix test docstring
2026-04-27 12:31:43 -04:00
Tom Boucher
b1a670e662 fix(#2697): replace retired /gsd: prefix with /gsd- in all user-facing text (#2699)
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>
2026-04-25 10:59:33 -04:00
Tom Boucher
73c1af5168 fix(#2543): replace legacy /gsd-<cmd> syntax with /gsd:<cmd> across all source files (#2595)
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>
2026-04-22 12:04:25 -04:00
Rezolv
d3a79917fa feat: Phase 2 caller migration — gsd-sdk query in workflows, agents, commands (#2179)
* feat: Phase 2 caller migration — gsd-sdk query in workflows (#2122)

Cherry-picked orchestration rewrites from feat/sdk-foundation (#2008, 4018fee) onto current main, resolving conflicts to keep upstream worktree guards and post-merge test gate. SDK stub registry omitted (out of Phase 2 scope per #2122).

Refs: #2122 #2008
Made-with: Cursor

* docs: add gsd-sdk query migration blurb

Made-with: Cursor

* docs(workflows): extend Phase 2 gsd-sdk query caller migration

- Swap node gsd-tools.cjs for gsd-sdk query in review, plan-phase, execute-plan,
  ship, extract_learnings, ai-integration-phase, eval-review, next, thread
- Document graphify CJS-only in gsd-planner; dual-path in CLI-TOOLS and ARCHITECTURE
- Update tests: workstreams gsd-sdk path, thread frontmatter.get, workspace init.*,
  CRLF-safe autonomous frontmatter parse
- CHANGELOG: Phase 2 caller migration scope

Made-with: Cursor

* docs(phase2): USER-GUIDE + remaining gsd-sdk query call sites

- USER-GUIDE: dual-path CLI section; state validate/sync use full CJS path
- Commands: debug (config-get+tdd), quick (security note), intel Task prompt
- Agent: gsd-debug-session-manager resolve-model via jq
- Workflows: milestone-summary, forensics, next, complete-milestone/verify-work
  (audit-open CJS notes), discuss-phase, progress, verify-phase, add/insert/remove
  phase, transition, manager, quick workflow; remove-phase commit without --files
- Test: quick-session-management accepts frontmatter.get
- CHANGELOG: Phase 2 follow-up bullet

Made-with: Cursor

* docs(phase2): align gsd-sdk query examples in commands and agents

- init.* query names; frontmatter.get uses positional field name
- state.* handlers use positional args; commit uses positional paths
- CJS-only notes for from-gsd2 and graphify; learnings.query wording
- CHANGELOG: Phase 2 orchestration doc pass

Made-with: Cursor

* docs(phase2): normalize gsd-sdk query commit to positional file paths

- Strip --files from commit examples in workflows, references, commands
- Keep commit-to-subrepo ... --files (separate handler)
- git-planning-commit.md: document positional args
- Tests: new-project commit line, state.record-session, gates CRLF, roadmap.analyze
- CHANGELOG [Unreleased]

Made-with: Cursor

* feat(sdk): gsd-sdk query parity with gsd-tools and PR 2179 registry fixes

- Route query via longest-prefix match and dotted single-token expansion; fall back
  to runGsdToolsQuery (same argv as node gsd-tools.cjs) for full CLI coverage.
- Parse gsd-sdk query permissively so gsd-tools flags (--json, --verify, etc.) are
  not rejected by strict parseArgs.
- resolveGsdToolsPath: honor GSD_TOOLS_PATH; prefer bundled get-shit-done copy
  over project .claude installs; export runGsdToolsQuery from the SDK.
- Fix gsd-tools audit-open (core.output; pass object for --json JSON).
- Register summary-extract as alias of summary.extract; fix audit-fix workflow to
  call audit-uat instead of invalid init.audit-uat (PR review).

Updates QUERY-HANDLERS.md and CHANGELOG [Unreleased].

Made-with: Cursor

* fix(sdk): Phase 2 scope — Trek-e review (#2179, #2122)

- Remove gsd-sdk query passthrough to gsd-tools.cjs; drop GSD_TOOLS_PATH
- Consolidate argv routing in resolveQueryArgv(); update USAGE and QUERY-HANDLERS
- Surface @file: read failures in GSDTools.parseOutput
- execute-plan: defer Task Commit Protocol to gsd-executor
- stale-colon-refs: skip .planning/ and root CLAUDE.md (gitignored overlays)
- CHANGELOG [Unreleased]: maintainer review and routing notes

Made-with: Cursor
2026-04-15 22:46:31 -04:00
Tom Boucher
8f1dd94495 fix: extract smart_discuss step to reference to reduce autonomous.md token count (#2227)
autonomous.md reported 11,748 tokens (over the Claude Code Read tool's 10K
limit), causing it to be read in 150-line chunks and generating a warning
on every /gsd-autonomous invocation.

Extract the 280-line smart_discuss step into a new reference file
(get-shit-done/references/autonomous-smart-discuss.md) and replace the
step body with a lean stub that directs the agent to read the reference.
This follows the established planner decomposition pattern.

autonomous.md: 38,750 → 29,411 chars (~7,350 tokens, well under 10K limit)

Fixes #2196

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 14:59:18 -04:00
Tom Boucher
47badff2ee fix(workflow): add plain-text fallback for AskUserQuestion on non-Claude runtimes (#2042)
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>
2026-04-10 12:30:46 -04:00
Bill Huang
99c089bfbf feat: add /gsd:code-review and /gsd:code-review-fix commands (#1630)
* feat: add /gsd:code-review and /gsd:code-review-fix commands

Closes #1636

Add two new slash commands that close the gap between phase execution
and verification. After /gsd:execute-phase completes, /gsd:code-review
reviews produced code for bugs, security issues, and quality problems.
/gsd:code-review-fix then auto-fixes issues found by the review.

## New Files

- agents/gsd-code-reviewer.md — Review agent with 3 depth levels
  (quick/standard/deep) and structured REVIEW.md output
- agents/gsd-code-fixer.md — Fix agent with atomic git rollback,
  3-tier verification, per-finding atomic commits, logic-bug flagging
- commands/gsd/code-review.md — Slash command definition
- commands/gsd/code-review-fix.md — Slash command definition
- get-shit-done/workflows/code-review.md — Review orchestration:
  3-tier file scoping, repo-boundary path validation, config gate
- get-shit-done/workflows/code-review-fix.md — Fix orchestration:
  --all/--auto flags, 3-iteration cap, artifact backup across iterations
- tests/code-review.test.cjs — 35 tests covering agents, commands,
  workflows, config, integration, rollback strategy, and logic-bug flagging

## Modified Files

- get-shit-done/bin/lib/config.cjs — Register workflow.code_review and
  workflow.code_review_depth with defaults and typo suggestions
- get-shit-done/workflows/execute-phase.md — Add code_review_gate step
  (PIPE-01): runs after aggregate_results, advisory only, non-blocking
- get-shit-done/workflows/quick.md — Add Step 6.25 code review (PIPE-03):
  scopes via git diff, uses gsd-code-reviewer, advisory only
- get-shit-done/workflows/autonomous.md — Add Step 3c.5 review+fix chain
  (PIPE-02): auto-chains code-review-fix --auto when issues found

## Design Decisions

- Rollback uses git checkout -- {file} (atomic) not Write tool (partial write risk)
- Logic-bug fixes flagged "requires human verification" (syntax check cannot verify semantics)
- Path traversal guard rejects --files paths outside repo root
- Fail-closed scoping: no HEAD~N heuristics when scope is ambiguous

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add /gsd:code-review and /gsd:code-review-fix commands

Closes #1636

Add two new slash commands that close the gap between phase execution
and verification. After /gsd:execute-phase completes, /gsd:code-review
reviews produced code for bugs, security issues, and quality problems.
/gsd:code-review-fix then auto-fixes issues found by the review.

## New Files

- agents/gsd-code-reviewer.md — Review agent: 3 depth levels, REVIEW.md
- agents/gsd-code-fixer.md — Fix agent: git rollback, 3-tier verification,
  logic-bug flagging, per-finding atomic commits
- commands/gsd/code-review.md, code-review-fix.md — Slash command definitions
- get-shit-done/workflows/code-review.md — Review orchestration: 3-tier
  file scoping, path traversal guard, config gate
- get-shit-done/workflows/code-review-fix.md — Fix orchestration:
  --all/--auto flags, 3-iteration cap, artifact backup
- tests/code-review.test.cjs — 35 tests: agents, commands, workflows,
  config, integration, rollback, logic-bug flagging

## Modified Files

- get-shit-done/bin/lib/config.cjs — Register workflow.code_review and
  workflow.code_review_depth config keys
- get-shit-done/workflows/execute-phase.md — Add code_review_gate step
  (PIPE-01): after aggregate_results, advisory, non-blocking
- get-shit-done/workflows/quick.md — Add Step 6.25 code review (PIPE-03):
  git diff scoping, gsd-code-reviewer, advisory
- get-shit-done/workflows/autonomous.md — Add Step 3c.5 review+fix chain
  (PIPE-02): auto-chains code-review-fix --auto when issues found

## Design decisions

- Rollback uses git checkout -- {file} (atomic) not Write tool
- Logic-bug fixes flagged requires human verification (syntax != semantics)
- --files paths validated within repo root (path traversal guard)
- Fail-closed: no HEAD~N heuristics when scope ambiguous

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve contradictory rollback instructions in gsd-code-fixer

rollback_strategy said git checkout, critical_rules said Write tool.
Align all three sections (rollback_strategy, execution_flow step b,
critical_rules) to use git checkout -- {file} consistently.

Also remove in-memory PRE_FIX_CONTENT capture — no longer needed
since git checkout is the rollback mechanism.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address all review feedback from rounds 3-4

Blocking (bash compatibility):
- Replace mapfile -t with portable while IFS= read -r loops in both
  workflows (mapfile is bash 4+; macOS ships bash 3.2 by default)
- Add macOS bash version note to platform_notes

Blocking (quick.md scope heuristic):
- Replace fragile HEAD~$(wc -l SUMMARY.md) with git log --grep based
  diff, matching the more robust approach in code-review.md

Security (path traversal):
- Document realpath -m macOS behavior in platform_notes; guard remains
  fail-closed on macOS without coreutils

Logic / correctness:
- Fix REVIEW_PATH / FIX_REPORT_PATH interpolation in node -e strings;
  use process.env.REVIEW_PATH via env var prefix to avoid single-quote
  path injection risk
- Add iteration semantics comment clarifying off-by-one behavior
- Remove duplicate "3. Determine changed files" heading in gsd-code-reviewer.md

Agent:
- Add logic-bug limitation section to gsd-code-fixer verification_strategy

Tests (39 total, up from 32):
- Add rollback uses git checkout test
- Add success_criteria consistency test (must not say Write tool)
- Add logic-bug flagging test
- Add files_reviewed_list spec test
- Add path traversal guard structural test
- Add mapfile-in-bash-blocks tests (bash 3.2 compatibility)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add gsd-code-reviewer to quick.md available_agent_types and copilot install test

- quick.md Step 6.25 spawns gsd-code-reviewer but the workflow's
  <available_agent_types> block did not list it, failing the spawn
  consistency CI check (#1357)
- copilot-install.test.cjs hardcoded agent list was missing
  gsd-code-fixer.agent.md and gsd-code-reviewer.agent.md, failing
  the Copilot full install verification test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace /gsd: colon refs with /gsd- hyphen format in new files

Fixes stale-colon-refs CI test (#1748). All 19 violations replaced:
- agents/gsd-code-fixer.md (2): description + role spawned-by text
- agents/gsd-code-reviewer.md (4): description + role + fallback note + error msg
- get-shit-done/workflows/code-review-fix.md (7): error msgs + retry suggestions
- get-shit-done/workflows/code-review.md (5): error msgs + retry suggestions
- get-shit-done/workflows/execute-phase.md (1): code_review_gate suggestion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 19:43:45 -04:00
Tom Boucher
6bd786bf88 test: add stale /gsd: colon reference regression guard (#1753)
* test: add stale /gsd: colon reference regression guard

Fixes #1748

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: replace 39 stale /gsd: colon references with /gsd- hyphen format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 10:23:41 -04:00
Tom Boucher
1e43accd95 feat(autonomous): add --to N flag to stop after specific phase (#1646)
Allows users to run autonomous mode up to a specific phase number.
After the target phase completes, execution halts instead of advancing.

Closes #1644

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 07:58:27 -04:00
Quang Do
d4767ac2e0 fix: replace /gsd: slash command format with /gsd- skill format in all user-facing content (#1579)
* 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>
2026-04-04 07:24:31 -04:00
Tibsfox
2aca125308 feat(autonomous): add --interactive flag for lean context with user input
The autonomous workflow previously had two extremes: full auto-answer
mode (--auto discuss, lean context but no user input) or manager mode
(interactive but bloated context from accumulating everything inline).

The --interactive flag bridges this gap:
- Discuss runs inline via gsd:discuss-phase (asks questions, waits for
  user answers — preserving all design decisions)
- Plan and execute dispatch as background agents (fresh context per
  phase — no accumulation in the main session)
- Pipeline parallelism: discuss Phase N+1 while Phase N builds in the
  background

This keeps the main context lean (only discuss conversations accumulate)
while preserving user input on all decisions. Particularly helpful for
users hitting context limits with /gsd:manager on multi-phase milestones.

Usage:
  /gsd:autonomous --interactive
  /gsd:autonomous --interactive --from 3
  /gsd:autonomous --interactive --only 5

Also adds --only N flag parsing to the upstream workflow (previously only
in PR #1444's branch).

Closes #1413

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 14:58:52 -07:00
Tom Boucher
fd2e844e9c Merge pull request #1544 from Tibsfox/fix/autonomous-phase-count-display-1516
fix(autonomous): clarify phase count display to prevent misleading N/T banner
2026-04-01 17:43:53 -04:00
Tibsfox
66e3cf87fe fix(autonomous): clarify phase count display to prevent misleading N/T (#1516)
When phase numbers are globally sequential across milestones (e.g.,
phases 61-67), the banner showed "Phase 63/5" where 5 was the count of
remaining phases — easily mistaken for "63 out of 5 total." Clarify
that T must be total milestone phases and add fallback display format
for when phase numbers exceed the total count.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:35:57 -07:00
Tom Boucher
35b835b861 Merge pull request #1508 from Ecko95/fix/infinite-self-discuss-loop
fix: prevent infinite self-discuss loop in auto/headless mode
2026-04-01 17:34:15 -04:00
Joshua Duffill
0782b5bdf0 fix: prevent infinite self-discuss loop in auto/headless mode (#1426)
When running in --auto or headless mode, the discuss step could loop
indefinitely — each pass reads its own CONTEXT.md, finds "gaps" in
referenced types/interfaces, creates new decisions to fill them, and
repeats. Observed: 34 passes, 167 decisions, 7 hours, zero code written.

Fixes:
- Add max_discuss_passes config (default: 3) to WorkflowConfig
- Add single-pass guard instruction to SDK self-discuss prompt
- Add pass cap documentation to CLI discuss-phase workflow
- Add pass guard step to SDK headless discuss-phase prompt
- Add stall detection note to autonomous workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 09:25:03 +02:00
Tibsfox
3e8c8f6f39 feat(autonomous): add --only N flag for single-phase execution
Adds --only N flag to /gsd:autonomous that restricts execution to a
single phase, enabling safe parallel execution across terminals:

  Terminal 1: /gsd:autonomous --only 16
  Terminal 2: /gsd:autonomous --only 17
  Terminal 3: /gsd:autonomous --only 18

Changes:
- Step 1: Parse --only N alongside --from N (also sets FROM_PHASE)
- Step 2: Filter phase list to exact match when --only active
- Step 4: Skip iteration — single phase does not loop
- Step 5: Skip lifecycle — audit/complete/cleanup only for full runs
- Step 6: Resume message uses --only when active
- Success criteria updated with --only N requirements

Parallel safety: each phase operates in its own .planning/phases/NN-*
directory. ROADMAP.md and STATE.md are read-only during phase execution.

Closes #1383

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 01:21:04 -07:00
Tom Boucher
7a35c7319d fix: add ui-phase and ui-review steps to autonomous workflow
The autonomous workflow ran discuss -> plan -> execute per phase but
skipped ui-phase (design contract) and ui-review (visual audit) for
frontend phases. This adds two conditional steps that match the UI
detection logic already in plan-phase step 5.6:

- Step 3a.5: generates UI-SPEC before planning if frontend indicators
  are detected and no UI-SPEC exists
- Step 3d.5: runs advisory UI review after successful execution if a
  UI-SPEC is present

Both steps respect workflow.ui_phase and workflow.ui_review config
toggles and skip silently for non-frontend phases.

Fixes #1375

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:02:06 -04:00
Tom Boucher
58c2b1f502 fix: Windows shell robustness, project_root detection, and hook stdin safety (#1343)
Address 4 root causes of Windows + Claude Code reliability issues:

1. Workflow shell robustness: add || true guards to informational commands
   (ls, grep, find, cat) that return non-zero on "no results", preventing
   workflow step failures under strict execution models. Guard glob loops
   with [ -e "$var" ] || continue to handle empty glob expansion.

2. Hook stdin handling: replace readFileSync('/dev/stdin') with async
   process.stdin + timeout in agent templates (gsd-verifier.md). Existing
   JS hooks already have timeout guards.

3. project_root detection: fix isInsideGitRepo() to check .git at the
   candidate parent level (not just below it), enabling correct detection
   when .git and .planning/ are siblings at the same directory level —
   the common single-repo case from a subdirectory.

4. @file: handoff: add missing @file: handlers to autonomous.md and
   manager.md workflows that call gsd-tools init but lacked the handler
   for large output payloads.

Fixes #1343

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:20:15 -04:00
Tom Boucher
2b31a8d3e1 feat: add workflow.skip_discuss setting to bypass discuss-phase in autonomous mode
When enabled, /gsd:autonomous chains directly from plan-phase to execute-phase,
skipping smart discuss. A minimal CONTEXT.md is auto-generated from the ROADMAP
phase goal so downstream agents have valid input. Manual /gsd:discuss-phase still
works regardless of the setting.

Changes:
- config.cjs: add workflow.skip_discuss to VALID_CONFIG_KEYS and hardcoded defaults (false)
- autonomous.md: check workflow.skip_discuss before smart_discuss, write minimal CONTEXT.md when skipping
- settings.md: add Skip Discuss toggle to interactive settings UI and global defaults
- config.test.cjs: 6 regression tests for the new config key

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:13:31 -04:00
erre
c71c15c76e feat: add Copilot CLI runtime support and gsd-autonomous skill (#911)
* gsd: Installed

* docs: complete project research

Research for adding GitHub Copilot CLI as 5th runtime to installer.

Files:
- STACK.md: Zero new deps, Copilot reads from .github/, tool name mapping
- FEATURES.md: 18 table stakes, 4 differentiators, 6 anti-features
- ARCHITECTURE.md: Codex-parallel pattern, 5 new functions, 12 existing changes
- PITFALLS.md: 10 pitfalls with prevention strategies and phase mapping
- SUMMARY.md: Synthesized findings, 4-phase roadmap suggestion

* docs(01): create phase plan for core installer plumbing

* feat(01-01): add Copilot as 5th runtime across all install.js locations

- Add --copilot flag parsing and selectedRuntimes integration
- Add 'copilot' to --all array (5 runtimes)
- getDirName('copilot') returns '.github' (local path)
- getGlobalDir('copilot') returns ~/.copilot with COPILOT_CONFIG_DIR override
- getConfigDirFromHome handles copilot for both local/global
- Banner and help text updated to include Copilot
- promptRuntime: Copilot as option 5, All renumbered to option 6
- install(): isCopilot variable, runtimeLabel, skip hooks (Codex pattern)
- install(): Copilot early return before hooks/settings configuration
- finishInstall(): Copilot program name and /gsd-new-project command
- uninstall(): Copilot runtime label and isCopilot variable
- GSD_TEST_MODE exports: getDirName, getGlobalDir, getConfigDirFromHome

* test(01-01): add Copilot plumbing unit tests

- 19 tests covering getDirName, getGlobalDir, getConfigDirFromHome
- getGlobalDir: default path, explicit dir, COPILOT_CONFIG_DIR env var, priority
- Source code integration checks for CLI-01 through CLI-06
- Verifies --both flag unchanged, hooks skipped, prompt options correct
- All 481 tests pass (19 new + 462 existing, no regressions)

* docs(01-01): complete core installer plumbing plan

- Mark Phase 1 and Plan 01-01 as complete in ROADMAP.md
- All 6 requirements (CLI-01 through CLI-06) fulfilled

* gsd: planning

* docs(02): create phase 2 content conversion engine plans

* feat(02-01): add Copilot tool mapping constant and conversion functions

- Add claudeToCopilotTools constant (13 Claude→Copilot tool mappings)
- Add convertCopilotToolName() with mcp__context7__ wildcard handling
- Add convertClaudeToCopilotContent() for CONV-06 (4 path patterns) + CONV-07 (gsd:→gsd-)
- Add convertClaudeCommandToCopilotSkill() for skill frontmatter transformation
- Add convertClaudeAgentToCopilotAgent() with tool dedup and JSON array format
- Export all new functions + constant via GSD_TEST_MODE

* feat(02-01): wire Copilot conversion into install() flow

- Add copyCommandsAsCopilotSkills() for folder-per-skill structure
- Add isCopilot branch in install() skill copy section
- Add isCopilot branch in agent loop with .agent.md rename
- Skip generic path replacement for Copilot (converter handles it)
- Add isCopilot branch in copyWithPathReplacement for .md files
- Add .cjs/.js content transformation for CONV-06/CONV-07
- Export copyCommandsAsCopilotSkills via GSD_TEST_MODE
- CONV-09 not generated (discarded), CONV-10 confirmed working

* docs(02-01): complete content conversion engine plan

- Create 02-01-SUMMARY.md with execution results
- Update STATE.md with Phase 2 position and decisions
- Mark CONV-01 through CONV-10 requirements complete

* test(02-02): add unit tests for Copilot conversion functions

- 16 tests for convertCopilotToolName (all 12 direct mappings, mcp prefix, wildcard, unknown fallback, constant size)
- 8 tests for convertClaudeToCopilotContent (4 path patterns, gsd: conversion, mixed content, no double-replace, passthrough)
- 7 tests for convertClaudeCommandToCopilotSkill (all fields, missing optional fields, CONV-06/07, no frontmatter, agent field)
- 7 tests for convertClaudeAgentToCopilotAgent (dedup, JSON array, field preservation, mcp tools, no tools, CONV-06/07, no frontmatter)

* test(02-02): add integration tests for Copilot skill copy and agent conversion

- copyCommandsAsCopilotSkills produces 31 skill folders with SKILL.md files
- Skill content verified: comma-separated allowed-tools, no YAML multiline, CONV-06/07 applied
- Old skill directories cleaned up on re-run
- gsd-executor agent: 6 tools → 4 after dedup (Write+Edit→edit, Grep+Glob→search)
- gsd-phase-researcher: mcp__context7__* wildcard → io.github.upstash/context7/*
- All 11 agents convert without error, all have frontmatter and tools
- Engine .md and .cjs files: no ~/.claude/ or gsd: references after conversion
- Full suite: 527 tests pass, zero regressions

* docs(02-02): complete Copilot conversion test suite plan

- SUMMARY: 46 new tests covering all conversion functions
- STATE: Phase 02 complete, 3/3 plans done
- ROADMAP: Phase 02 marked complete

* docs(03): research phase domain

* docs(03-instructions-lifecycle): create phase plan

* feat(03-01): add copilot-instructions template and merge/strip functions

- Create get-shit-done/templates/copilot-instructions.md with 5 GSD instructions
- Add GSD_COPILOT_INSTRUCTIONS_MARKER and GSD_COPILOT_INSTRUCTIONS_CLOSE_MARKER constants
- Add mergeCopilotInstructions() with 3-case merge (create, replace, append)
- Add stripGsdFromCopilotInstructions() with null-return for GSD-only content

* feat(03-01): wire install, fix uninstall/manifest/patches for Copilot

- Wire mergeCopilotInstructions() into install() before Copilot early return
- Add else-if isCopilot uninstall branch: remove skills/gsd-*/ + clean instructions
- Fix writeManifest() to hash Copilot skills: (isCodex || isCopilot)
- Fix reportLocalPatches() to show /gsd-reapply-patches for Copilot
- Export new functions and constants in GSD_TEST_MODE
- All 527 existing tests pass with zero regressions

* docs(03-01): complete instructions lifecycle plan

- Create 03-01-SUMMARY.md with execution results
- Update STATE.md: Phase 3 Plan 1 position, decisions, session
- Update ROADMAP.md: Phase 03 progress (1/2 plans)
- Mark INST-01, INST-02, LIFE-01, LIFE-02, LIFE-03 complete

* test(03-02): add unit tests for mergeCopilotInstructions and stripGsdFromCopilotInstructions

- 10 new tests: 5 merge cases + 5 strip cases
- Tests cover create/replace/append merge scenarios
- Tests cover null-return, content preservation, no-markers passthrough
- Added beforeEach/afterEach imports for temp dir lifecycle
- Exported writeManifest and reportLocalPatches via GSD_TEST_MODE for Task 2

* test(03-02): add integration tests for uninstall, manifest, and patches Copilot fixes

- 3 uninstall tests: gsd-* skill identification, instructions cleanup, GSD-only deletion
- writeManifest hashes Copilot skills in manifest JSON (proves isCopilot fix)
- reportLocalPatches uses /gsd-reapply-patches for Copilot (dash format)
- reportLocalPatches uses /gsd:reapply-patches for Claude (no regression)
- Full suite: 543 tests pass, 0 failures

* docs(03-02): complete instructions lifecycle tests plan

- SUMMARY.md with 16 new tests documented
- STATE.md updated: Phase 3 complete, 5/5 plans done
- ROADMAP.md updated: Phase 03 marked complete

* docs(04): capture phase context

* docs(04): research phase domain

* docs(04): create phase plan — E2E integration tests for Copilot install/uninstall

* test(04-01): add E2E Copilot full install verification tests

- 9 tests: skills count/structure, agents count/names, instructions markers
- Manifest structure, categories, SHA256 integrity verification
- Engine directory completeness (bin, references, templates, workflows, CHANGELOG, VERSION)
- Uses execFileSync in isolated /tmp dirs with GSD_TEST_MODE stripped from env

* test(04-01): add E2E Copilot uninstall verification tests

- 6 tests: engine removal, instructions removal, GSD skills/agents cleanup
- Preserves non-GSD custom skills and agents after uninstall
- Standalone lifecycle tests for preservation (install → add custom → uninstall → verify)
- Full suite: 558 tests passing, 0 failures

* docs(04-01): complete E2E Copilot install/uninstall integration tests plan

- SUMMARY.md: 15 E2E tests, SHA256 integrity, 558 total tests passing
- STATE.md: Phase 4 complete, 6/6 plans done
- ROADMAP.md: Phase 4 marked complete
- REQUIREMENTS.md: QUAL-01 complete, QUAL-02 out of scope

* fix: use .github paths for Copilot --local instead of ~/.copilot

convertClaudeToCopilotContent() was hardcoded to always map ~/.claude/
and $HOME/.claude/ to ~/.copilot/ and $HOME/.copilot/ regardless of
install mode. For --local installs these should map to .github/ (repo-
relative, no ./ prefix) since Copilot resolves @file references from
the repo root.

Local mode:  ~/.claude/ → .github/  |  $HOME/.claude/ → .github/
Global mode: ~/.claude/ → ~/.copilot/  |  $HOME/.claude/ → $HOME/.copilot/

Added isGlobal parameter to convertClaudeToCopilotContent,
convertClaudeCommandToCopilotSkill, convertClaudeAgentToCopilotAgent,
copyCommandsAsCopilotSkills, and copyWithPathReplacement. All call
sites in install() now pass isGlobal through.

Tests updated to cover both local (default) and global modes.
565 tests passing, 0 failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: use double quotes for argument-hint in Copilot skills

The converter was hardcoding single quotes around argument-hint values
in skill frontmatter. This breaks YAML parsing when the value itself
contains single quotes (e.g., "e.g., 'v1.1 Notifications'").

Now uses yamlQuote() (JSON.stringify) which produces double-quoted
strings with proper escaping.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: complete v1.23 milestone — Copilot CLI Support

Archive milestone artifacts, retrospective, and update project docs.

- Archive: v1.23-ROADMAP.md, v1.23-REQUIREMENTS.md, v1.23-MILESTONE-AUDIT.md
- Create: MILESTONES.md, RETROSPECTIVE.md
- Evolve: PROJECT.md (validated reqs, key decisions, shipped context)
- Reorganize: ROADMAP.md (collapsed v1.23, progress table)
- Update: STATE.md (status: completed)
- Delete: REQUIREMENTS.md (archived, fresh for next milestone)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: archive phase directories from v1.23 milestone

* chore: Clean gsd tracking

* fix: update test counts for new upstream commands and agents

Upstream added validate-phase command (32 skills) and nyquist-auditor agent (12 agents).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: Remove copilot instructions

* chore: Improve loop

* gsd: installation

* docs: start milestone v1.24 Autonomous Skill

* docs: internal research for autonomous skill

* docs: define milestone v1.24 requirements

* docs: create milestone v1.24 roadmap (4 phases)

* docs: phase 5 context — skill scaffolding decisions

* docs(5): research phase domain

* docs(05): create phase plan — 2 plans in 2 waves

* docs(phase-5): add validation strategy

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(05-01): add failing tests for colon-outside-bold regex format

- Test get-phase with **Goal**: format (colon outside bold)
- Test analyze with **Goal**: and **Depends on**: formats
- Test mixed colon-inside and colon-outside bold formats
- All 3 new tests fail confirming the regex bug

* fix(05-01): fix regex for goal/depends_on extraction in roadmap.cjs

- Fix 3 regex patterns to support both **Goal:** and **Goal**: formats
- Pattern: /\*\*Goal(?::\*\*|\*\*:)/ handles colon inside or outside bold
- Fix in both source (get-shit-done/) and runtime (.github/) copies
- All 28 tests pass including 4 new colon-outside-bold tests
- Live verification: all 4 phases return non-null goals from real ROADMAP.md

* feat(05-01): create gsd:autonomous command file

- name: gsd:autonomous with argument-hint: [--from N]
- Sections: objective, execution_context, context, process
- References workflows/autonomous.md and references/ui-brand.md
- Follows exact pattern of new-milestone.md (42 lines)

* docs(05-01): complete roadmap regex fix + autonomous command plan

* feat(05-02): create autonomous workflow with phase discovery and Skill() execution

- Initialize step with milestone-op bootstrap and --from N flag parsing
- Phase discovery via roadmap analyze with incomplete filtering and sort
- Execute step uses Skill() flat calls for discuss/plan/execute (not Task())
- Progress banner: GSD ► AUTONOMOUS ▸ Phase N/T format with bar
- Iterate step re-reads ROADMAP.md after each phase for dynamic phase detection
- Handle blocker step with retry/skip/stop user options

* test(05-02): add autonomous skill generation tests and fix skill count

- Test autonomous.md converts to gsd-autonomous Copilot skill with correct frontmatter
- Test CONV-07 converts gsd: to gsd- in autonomous command body content
- Update skill count from 32 to 33 (autonomous.md added in plan 01)
- All 645 tests pass across full suite

* docs(05-02): complete autonomous workflow plan

* docs: phase 5 complete — update roadmap and state

* docs: phase 6 context — smart discuss decisions

* docs(06): research smart discuss phase domain

* docs(06): create phase plan

* feat(06-01): replace Skill(discuss-phase) with inline smart discuss

- Add <step name="smart_discuss"> with 5 sub-steps: load prior context, scout codebase, analyze phase with infrastructure detection, present proposals per area in tables, write CONTEXT.md
- Rewire execute_phase step 3a: check has_context before/after, reference smart_discuss inline
- Remove Skill(gsd:discuss-phase) call entirely
- Preserve Skill(gsd:plan-phase) and Skill(gsd:execute-phase) calls unchanged
- Update success criteria to mention smart discuss
- Grey area proposals use table format with recommended/alternative columns
- AskUserQuestion offers Accept all, Change QN, Discuss deeper per area
- Infrastructure phases auto-detected and skip to minimal CONTEXT.md
- CONTEXT.md output uses identical XML-wrapped sections as discuss-phase.md

* docs(06-01): complete smart discuss inline logic plan

* docs(07): phase execution chain context — flag strategy, validation routing, error recovery

* docs(07): research phase execution chain domain

* docs(07): create phase plan

* feat(07-01): wire phase execution chain with verification routing

- Add --no-transition flag to execute-phase Skill() call in step 3c
- Replace step 3d transition with VERIFICATION.md-based routing
- Route on passed/human_needed/gaps_found with appropriate user prompts
- Add gap closure cycle with 1-retry limit to prevent infinite loops
- Route execute-phase failures (no VERIFICATION.md) to handle_blocker
- Update success_criteria with all new verification behaviors

* docs(07-01): complete phase execution chain plan

* docs(08): multi-phase orchestration & lifecycle context

* docs(08): research phase domain

* docs(08): create phase plan

* feat(08-01): add lifecycle step, fix progress bar, document smart_discuss

- Add lifecycle step (audit→complete→cleanup) after all phases complete
- Fix progress bar N/T to use phase number/total milestone phases
- Add smart_discuss CTRL-03 compliance documentation note
- Rewire iterate step to route to lifecycle instead of manual banner
- Renumber handle_blocker from step 5 to step 6
- Add 10 lifecycle-related items to success criteria
- File grows from 630 to 743 lines, 6 to 7 named steps

* docs(08-01): complete multi-phase orchestration & lifecycle plan

* docs: v1.24 milestone audit — passed (18/18 requirements)

* chore: complete v1.24 milestone — Autonomous Skill

* chore: archive phase directories from v1.24 milestone

* gsd: clean

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-14 17:41:19 -06:00