Commit Graph

148 Commits

Author SHA1 Message Date
Tom Boucher
8d6577d101 fix: update Discord invite link from vanity URL to permanent link (#1648)
The discord.gg/gsd vanity link was lost due to a drop in server boosts.
Updated all references to the permanent invite link discord.gg/mYgfVNfA2r
across READMEs, issue templates, install script, and join-discord command.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:04:13 -04:00
Elwin
66368a42d9 feat: add Trae runtime install support (#1566)
* feat: add Trae runtime install support

- Add Trae as a supported runtime in bin/install.js
- Update README and ARCHITECTURE documentation for Trae support
- Add trae-install.test.cjs test file
- Update multi-runtime-select tests for Trae compatibility

* feat(trae): add TRAE_CONFIG_DIR environment variable support

Add support for TRAE_CONFIG_DIR environment variable as an additional way to specify the config directory for Trae runtime, following the same precedence pattern as other runtimes.

* fix(trae): improve slash command conversion and subagent type mapping

Update the slash command regex pattern to properly match and convert command names. Change subagent type mapping from "general-purpose" to "general_purpose_task" to match Trae's conventions. Also add comprehensive tests for Trae uninstall cleanup behavior.

* docs: add Trae and Windsurf to supported runtimes in translations

Update Korean, Japanese, and Portuguese README files to include Trae and Windsurf as supported runtimes in the documentation. Add installation and uninstallation instructions for Trae.

* fix: update runtime selection logic and path replacements

- Change 'All' shortcut from option 11 to 12 to accommodate new runtime
- Update path replacement regex to handle gsd- prefix more precisely
- Adjust test cases to reflect new runtime selection numbering
- Add configDir to trae install options for proper path resolution

* test(trae-install): add tests for getGlobalDir function

Add test cases to verify behavior of getGlobalDir function with different configurations:
- Default directory when no env var or explicit dir is provided
- Explicit directory takes priority
- Respects TRAE_CONFIG_DIR env var
- Priority of explicit dir over env var
- Compatibility with other runtimes
2026-04-04 08:13:15 -04:00
Tom Boucher
9d626de5fa fix(hooks): add read-before-edit guard for non-Claude runtimes (#1645)
* fix(hooks): add read-before-edit guidance for non-Claude runtimes

When models that don't natively enforce read-before-edit hit the guard,
the error message now includes explicit instruction to Read first.
This prevents infinite retry loops that burn through usage.

Closes #1628

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

* fix(build): register gsd-read-guard.js in HOOKS_TO_COPY and harden tests

The hook was missing from scripts/build-hooks.js, so global installs
would never receive the hook file in hooks/dist/. Also adds tests for
build registration, install uninstall list, and non-string file_path.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 07:35:18 -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
Alex Alecu
5451e13abb fix: clean up remaining Kilo review follow-ups
Remove the unused JSONC helper and duplicate test export so the installer only keeps the shipped fixes. This closes the remaining code-level review feedback after the Kilo support sync.
2026-04-03 14:34:21 +03:00
Alex Alecu
0866290c1b merge: sync Kilo runtime branch with latest main 2026-04-03 12:47:24 +03:00
Alex Alecu
b8b01fca64 fix: normalize Kilo skill paths and guard OpenCode permissions
Keep Kilo skill path rewrites consistent and avoid rewriting valid string-valued OpenCode permission configs while preserving resolved config-dir handling.
2026-04-03 10:55:34 +03:00
Tom Boucher
647ddcecf9 Merge pull request #1524 from Tavernari/feat/augment-support
feat: Add Augment Code runtime support
2026-04-02 18:02:32 -04:00
Tom Boucher
56ec1f0360 Merge pull request #1428 from Tibsfox/fix/preserve-profile-on-update-1423
fix(install): preserve USER-PROFILE.md and dev-preferences.md on update
2026-04-02 18:01:30 -04:00
Tom Boucher
8af7ad96fc Merge pull request #1564 from Tibsfox/feat/hooks-opt-in-1473d
feat(hooks): opt-in session-state, commit-validation, phase-boundary hooks
2026-04-02 17:49:08 -04:00
Alex Alecu
fc1a4ccba1 merge: sync Kilo runtime branch with main
Bring the latest main branch updates into feat/kilo-runtime-support while preserving KILO_CONFIG resolution, Kilo agent permission conversion, and relative .claude path rewrites.
2026-04-02 16:00:09 +03:00
Tibsfox
6c5f89a4fd fix(install): preserve dev-preferences.md in Claude Code legacy cleanup path
After #1540 migrated Claude Code to skills/ format, the uninstall
added a legacy commands/gsd/ cleanup that wiped the directory without
checking for user files. Add preserve logic to the legacy cleanup path
matching what Gemini's commands/gsd/ path already has.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 05:55:42 -07:00
Tibsfox
bdd41f961e fix(install): add error handling on restore and scalability note
Address review feedback: wrap writeFileSync in try/catch so restore
failures surface a clear error instead of silently losing user files.
Add comment noting the naming convention approach for future scaling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 05:54:19 -07:00
Tibsfox
6f3a9d88c7 fix(install): preserve USER-PROFILE.md and dev-preferences.md on update
The uninstall step wipes get-shit-done/ and commands/gsd/ directories
entirely, destroying user-generated files like USER-PROFILE.md (from
/gsd:profile-user) and dev-preferences.md. These files are now read
before rmSync and restored immediately after.

Closes #1423

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 05:54:19 -07:00
Alex Alecu
f8edfe7f15 fix: align Kilo config and agent conversion
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.
2026-04-02 15:44:46 +03:00
Tibsfox
4157c7f20a feat(hooks): add opt-in community hooks for GSD projects
Port 3 community hooks from gsd-skill-creator, gated behind hooks.community config flag. All hooks are registered on install but are no-ops unless the project config has hooks: { community: true }.

gsd-session-state.sh (SessionStart): outputs STATE.md head for orientation. gsd-validate-commit.sh (PreToolUse/Bash): blocks non-Conventional-Commits messages. gsd-phase-boundary.sh (PostToolUse/Write|Edit): warns when .planning/ files are modified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 04:23:44 -07:00
Alex Alecu
52585de4ab fix: move Kilo above OpenCode in installer 2026-04-02 11:34:31 +03:00
Nic Barrett
b12d684940 fix(opencode): guard string-valued permission config (#781) 2026-04-01 17:02:33 -05:00
Tom Boucher
a96b9e209c Merge pull request #1474 from Tibsfox/fix/reapply-patches-misclassification-1469
fix(reapply-patches): three-way merge and never-skip invariant for backed-up files
2026-04-01 17:25:55 -04:00
Victor Carvalho Tavernari
7e71fac76f fix: verify and correct Augment tool mappings based on auggie CLI 2026-04-01 22:24:33 +01:00
Victor Carvalho Tavernari
5a43437bc0 feat: add Augment Code runtime support
- Add --augment flag to install for Augment only
- Add Augment to --all and interactive menu (now 9 runtimes + All)
- Create conversion functions for Augment skills and agents:
  - convertClaudeToAugmentMarkdown: path and brand replacement
  - convertClaudeCommandToAugmentSkill: skill format with adapter header
  - convertClaudeAgentToAugmentAgent: agent format conversion
  - copyCommandsAsAugmentSkills: copy commands as skills
- Map tool names: Bash → launch-process, Edit → str-replace-editor, etc.
- Add runtime label and uninstall support for Augment
- Add tests: augment-conversion.test.cjs with 15 test cases
- Update multi-runtime-select.test.cjs to include Augment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 22:24:33 +01:00
Tom Boucher
77953ec1d9 Merge pull request #1436 from Tibsfox/fix/codex-path-replacement-1430
fix(install): add .claude path replacement for Codex runtime
2026-04-01 17:11:54 -04:00
Tom Boucher
8cd6dd33c5 Merge pull request #1540 from gsd-build/fix/1504-claude-skills-migration
fix: migrate Claude Code commands/ to skills/ format for 2.1.88+
2026-04-01 17:07:43 -04:00
Tom Boucher
01fda70a19 fix: migrate Claude Code commands/ to skills/ format for 2.1.88+ compatibility
Claude Code 2.1.88+ deprecated commands/ subdirectory discovery in favor of
skills/*/SKILL.md format. This migrates the Claude Code installer to use the
same skills pattern already used by Codex, Copilot, Cursor, Windsurf, and
Antigravity.

Key changes:
- New convertClaudeCommandToClaudeSkill() preserving allowed-tools and argument-hint
- New copyCommandsAsClaudeSkills() mirroring Copilot pattern
- Install now writes skills/gsd-*/SKILL.md instead of commands/gsd/*.md
- Legacy commands/gsd/ cleaned up during install
- Manifest tracks skills/ for Claude Code
- Uninstall handles both skills/ and legacy commands/

Fixes #1504
Supersedes #1538

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:04:53 -04:00
Tom Boucher
2f03830f4c Merge pull request #1500 from Tibsfox/fix/settings-jsonc-comments-1461
fix(install): handle JSONC (comments) in settings.json without data loss
2026-04-01 17:00:55 -04:00
Tom Boucher
1dc0d90c6e Merge pull request #1394 from Tibsfox/fix/issue-triage-batch-1392-1391-1389
fix: trailing slash, slug newlines, and duplicate command registration
2026-04-01 12:12:37 -04:00
Nick Gagne
eecb06cabe Fix path replacement for ~/.claude to ~/.github (#1529)
* Fix path replacement for ~/.claude to ~/.github

The current rules miss replacing this path because the current rules look for the .claude directory with a trailing slash, which this does not have.

* Fix regex to replace trailing .claude with .github
2026-04-01 08:48:24 -06:00
Alex Alecu
ac4836d270 feat: add Kilo CLI runtime support 2026-03-31 15:59:31 +03:00
Tibsfox
ffe5319fe5 fix(install): handle JSONC (comments) in settings.json without data loss
When settings.json contains comments (// or /* */), which many CLI tools
allow, JSON.parse() fails and readSettings() silently returned {}.
This empty object was then written back by writeSettings(), destroying
the user's entire configuration.

Changes:
- Add stripJsonComments() that handles line comments, block comments,
  trailing commas, and preserves comments inside string values
- readSettings() tries standard JSON first (fast path), falls back to
  JSONC stripping on parse failure
- On truly malformed files (even JSONC stripping fails), return null
  with a warning instead of silently returning {} — prevents data loss
- All callers of readSettings() now guard against null return to skip
  settings modification rather than overwriting with empty object

Closes #1461

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:52:51 -07:00
Tibsfox
88af6fdcda fix(reapply-patches): three-way merge and never-skip invariant for backed-up files
The reapply-patches workflow used a two-way comparison (user's backup vs
new version) which couldn't distinguish user customizations from version
drift. This caused 10/10 files to be misclassified as "no custom content"
in real-world usage, silently discarding user modifications.

Changes:
- Rewrite workflow with three-way merge strategy (pristine baseline vs
  user-modified backup vs newly installed version)
- Add critical invariant: files in gsd-local-patches/ must NEVER be
  classified as "no custom content" — they were backed up because the
  installer's hash check detected modifications
- Add git-aware detection path using commit history when config dir is
  a git repo
- Add pristine_hashes to backup-meta.json so the reapply workflow can
  verify reconstructed baseline files
- Add from_manifest_timestamp to backup-meta.json for version tracking
- Conservative default: flag as CONFLICT when uncertain, not SKIP

Closes #1469

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 10:04:22 -07:00
Tibsfox
2b8c95a05c fix(install): add .claude path replacement for Codex runtime
convertClaudeToCodexMarkdown() was missing path replacement — unlike
Copilot/Gemini/Antigravity converters which all replace $HOME/.claude/
paths. This left hardcoded .claude references in Codex agent files,
causing ENOENT when gsd-tools.cjs tried to load from ~/.claude/ on
Codex installations.

Closes #1430

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:41:03 -07:00
TÂCHES
89f95c43ba feat: auto --init flag, headless prompts, and prompt sanitizer (#1417)
* fix: Created 10 headless prompt files (5 workflows + 5 agents) in sdk/p…

- "sdk/prompts/workflows/execute-plan.md"
- "sdk/prompts/workflows/research-phase.md"
- "sdk/prompts/workflows/plan-phase.md"
- "sdk/prompts/workflows/verify-phase.md"
- "sdk/prompts/workflows/discuss-phase.md"
- "sdk/prompts/agents/gsd-executor.md"
- "sdk/prompts/agents/gsd-phase-researcher.md"
- "sdk/prompts/agents/gsd-planner.md"

GSD-Task: S01/T02

* feat: Created prompt-sanitizer.ts, wired headless prompt loading into P…

- "sdk/src/prompt-sanitizer.ts"
- "sdk/src/phase-prompt.ts"
- "sdk/src/gsd-tools.ts"
- "sdk/src/gsd-tools.test.ts"
- "sdk/src/phase-runner-types.test.ts"

GSD-Task: S01/T01

* test: Added 111 unit tests covering sanitizePrompt(), headless prompt l…

- "sdk/src/prompt-sanitizer.test.ts"
- "sdk/src/headless-prompts.test.ts"
- "sdk/src/phase-prompt.test.ts"

GSD-Task: S01/T03

* feat: Wired sdkPromptsDir preference and sanitizePrompt into InitRunner…

- "sdk/src/init-runner.ts"
- "sdk/package.json"

GSD-Task: S02/T01

* feat: add --init flag to auto command for single-command PRD-to-execution

gsd-sdk auto --init @path/to/prd.md now bootstraps the project (init)
then immediately runs the autonomous phase execution loop.

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

* chore: add remaining headless prompt files and templates

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

* test: Extended init-runner.test.ts with 7 sdkPromptsDir preference and…

- "sdk/src/init-runner.test.ts"

GSD-Task: S02/T03

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:40:34 -06:00
TÂCHES
a858c6ddff feat: add --sdk flag and interactive SDK prompt to installer (#1415)
Add installSdk() and promptSdk() to the installer so users can
optionally install @gsd-build/sdk during GSD setup. The --sdk flag
installs without prompting; interactive installs get a Y/N prompt
after runtime installation completes. SDK installs use @latest with
suppressed npm noise (--force --no-fund --loglevel=error, stdio: pipe).

Cherry-picked from fix/sdk-cli-runtime-bugs (de9f18f) which was
left out of #1407.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:02:23 -06:00
Tibsfox
69e104dffc fix(windsurf): remove trailing slash from .windsurf/rules path
Node v25 preserves trailing slashes in path.join, causing
writeFileSync to fail with ENOENT when the converted path
ends in '/'. Affects all Windsurf users on Node v25+.

Fixes gsd-build/get-shit-done#1392

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 01:13:46 -07:00
Tom Boucher
f4d8858188 fix: repair trapped non-boolean keys under [features] on Codex re-install
Pre-#1346 GSD installs prepended [features] before bare top-level keys
in ~/.codex/config.toml, trapping keys like model="gpt-5.3-codex" under
[features] where Codex expects only booleans. The #1346 fix prevented
NEW corruption but did not repair EXISTING corrupted configs. Re-installing
GSD left the trapped keys in place, causing "invalid type: string, expected
a boolean" on every Codex launch.

repairTrappedFeaturesKeys() now detects non-boolean key-value lines inside
[features] and relocates them before the [features] header during
ensureCodexHooksFeature(), so re-installs heal previously corrupted configs.

Fixes #1379

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 14:50:02 -04:00
Tom Boucher
60fda20885 Merge pull request #1346 from ChaptersOfFloatingLife/fix/codex-config-toplevel-keys
fix: preserve top-level config keys and use absolute agent paths for Codex ≥0.116
2026-03-23 22:26:56 -04:00
Tom Boucher
7f1479d370 Merge pull request #1347 from gsd-build/fix/hook-field-validation
fix: validate hook field requirements to prevent silent settings.json rejection
2026-03-23 22:18:29 -04:00
Tom Boucher
c2292598c7 fix: validate hook field requirements to prevent silent settings.json rejection
Add validateHookFields() that strips invalid hook entries before they
cause Claude Code's Zod schema to silently discard the entire
settings.json file. Agent hooks require "prompt", command hooks require
"command", and entries without a valid hooks sub-array are removed.

Uses a clean two-pass approach: first validate and build new arrays
(no mutation inside filter predicates), then collect-and-delete empty
event keys (no delete during Object.keys iteration). Result entries
are shallow copies so the original input objects are never mutated.

Includes 24 tests covering passthrough, removal, structural invalidity,
empty cleanup, mutation safety, unknown types, and iteration safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 22:11:54 -04:00
CI
9f8d11d603 fix: preserve top-level config keys and use absolute agent paths for Codex ≥0.116
Two fixes for Codex config.toml compatibility:

1. ensureCodexHooksFeature: insert [features] before the first table header
   instead of prepending it before all content. Prepending traps bare
   top-level keys (model, model_reasoning_effort) under [features], where
   Codex rejects them with "invalid type: string, expected a boolean".

2. generateCodexConfigBlock: use absolute config_file paths when targetDir
   is provided. Codex ≥0.116 requires AbsolutePathBuf and cannot resolve
   relative "agents/..." paths, failing with "AbsolutePathBuf deserialized
   without a base path".

Fixes #1202

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:11:31 +08:00
Tom Boucher
8579a30065 feat: add Windsurf runtime support
Adds full Windsurf (by Codeium) runtime integration, following the same
pattern as the existing Cursor support. Windsurf uses .windsurf/ for
local config and ~/.windsurf/ for global config, with skills in
.windsurf/skills/ using the SKILL.md structure.

What:
- CLI flag --windsurf and interactive prompt option (8)
- Directory mapping (.windsurf local, ~/.windsurf global)
- Content converter functions (tool names, path replacements, brand refs)
- Skill copy function (copyCommandsAsWindsurfSkills)
- Agent conversion (convertClaudeAgentToWindsurfAgent)
- Install/uninstall branches
- Banner, help text, and issue template updates
- Windsurf conversion test suite (windsurf-conversion.test.cjs)
- Updated multi-runtime selection tests for 8 runtimes

Closes #1336

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:50:23 -04:00
Tom Boucher
156c008c33 Merge pull request #1296 from gsd-build/fix/gemini-before-tool-hook-1295
fix: use BeforeTool hook event for Gemini CLI prompt guard
2026-03-21 14:10:55 -04:00
Tom Boucher
4395b2ecf9 fix: use BeforeTool hook event for Gemini CLI instead of PreToolUse
Gemini CLI uses BeforeTool (not PreToolUse) for pre-tool hooks, matching
the existing pattern where AfterTool is used instead of PostToolUse. The
prompt injection guard hook was hardcoded to PreToolUse, causing Gemini
CLI to log "Invalid hook event name: PreToolUse" on startup.

Apply the same runtime-conditional mapping used for post-tool hooks, and
update the uninstall cleanup to iterate both event names.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:08:32 -04:00
Tom Boucher
87e3b41d67 Merge pull request #1291 from gsd-build/feat/multi-runtime-select-1281
feat: multi-runtime selection in interactive installer
2026-03-21 10:05:56 -04:00
Tom Boucher
f3ce0957cd feat: multi-runtime selection in interactive installer (#1281)
The interactive prompt now accepts comma-separated or space-separated
choices (e.g., "1,4,6" or "1 4 6") to install multiple runtimes in
one go, without needing --all or running the installer multiple times.

- Replaced if/else-if chain with runtimeMap lookup + split parser
- Added hint text: "Select multiple: 1,4,6 or 1 4 6"
- Invalid choices silently filtered, duplicates deduplicated
- Empty input still defaults to Claude Code
- Choice "8" still selects all runtimes

Tests: 10 new tests covering comma/space/mixed separators,
deduplication, invalid input filtering, order preservation,
and source-level assertions.

Closes #1281

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 09:52:52 -04:00
Tom Boucher
f9cb02e005 fix: use $HOME instead of ~ in installed shell command paths (#1284)
The installer pathPrefix for global installs replaced os.homedir()
with ~, which does NOT expand inside double-quoted shell commands
in POSIX shells. This caused MODULE_NOT_FOUND errors when executing
commands like: node "~/.claude/get-shit-done/bin/gsd-tools.cjs"

Changed pathPrefix to use $HOME instead of ~, which correctly expands
inside double quotes. Also fixed a quoted-tilde instance in do.md.

- bin/install.js: $HOME prefix instead of ~ for global installs
- get-shit-done/workflows/do.md: node "$HOME/..." instead of "~/"
- tests/path-replacement.test.cjs: updated + 3 new regression tests

Closes #1284

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 09:24:31 -04:00
Tom Boucher
02254db611 fix: resolve ProviderModelNotFoundError on non-Claude runtimes (#1156)
Extend resolve_model_ids to accept "omit" value: returns empty string
so non-Claude runtimes (OpenCode, Codex, Gemini, etc.) use their
configured default model instead of unresolvable Claude aliases.

- resolve_model_ids: "omit" short-circuits before alias resolution
- model_overrides still respected (checked first) for explicit IDs
- Installer sets resolve_model_ids: "omit" in ~/.gsd/defaults.json
  for non-Claude runtimes during install
- 4 new tests covering omit behavior and override passthrough
- Fix websearch test mocks for fs.writeSync output change (#1276)

Closes #1156

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:57:20 -04:00
Tom Boucher
c4b313c60f fix: stale hook detection checks wrong directory path
gsd-check-update.js looked for hooks in configDir/hooks/ (e.g.,
~/.claude/hooks/) but the installer writes hooks to
configDir/get-shit-done/hooks/. This mismatch caused false stale
hook warnings that persisted even after updating.

Also clears the update cache during install so the next session
re-evaluates hook versions with the correct path.

Closes #1249

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:24:06 -04:00
Tom Boucher
62db008570 security: add prompt injection guards, path traversal prevention, and input validation
Defense-in-depth security hardening for a codebase where markdown files become
LLM system prompts. Adds centralized security module, PreToolUse hook for
injection detection, and CI-ready codebase scan.

New files:
- security.cjs: path traversal prevention, prompt injection scanner/sanitizer,
  safe JSON parsing, field name validation, shell arg validation
- gsd-prompt-guard.js: PreToolUse hook scans .planning/ writes for injection
- security.test.cjs: 62 unit tests for all security functions
- prompt-injection-scan.test.cjs: CI scan of all agent/workflow/command files

Hardened code paths:
- readTextArgOrFile: path traversal guard (--prd, --text-file)
- cmdStateUpdate/Patch: field name validation prevents regex injection
- cmdCommit: sanitizeForPrompt strips invisible chars from commit messages
- gsd-tools --fields: safeJsonParse wraps unprotected JSON.parse
- cmdFrontmatterGet/Set: null byte rejection
- cmdVerifyPathExists: null byte rejection
- install.js: registers prompt guard hook, updates uninstaller

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:38:26 -04:00
Tom Boucher
9bf85fb97d fix(install): add matcher and timeout to context-monitor hook (#1246)
The gsd-context-monitor PostToolUse hook was configured without a
matcher or timeout, causing it to fire on every tool use including
Read, Glob, and Grep. When multiple Read calls happen in parallel,
some hook processes failed with errors.

Added matcher: 'Bash|Edit|Write|MultiEdit|Agent|Task' to limit the
hook to tools that actually modify context significantly. Added
timeout: 10 to prevent hangs.

Includes migration logic: existing installations without matcher/timeout
get them added on next /gsd:update.
2026-03-20 10:45:56 -04:00
Disaster-Terminator
b6a49163ea fix(codex-config): preserve EOL when enabling codex hooks 2026-03-20 13:24:19 +08:00