Mirror of code, issues, and PRs from the upstream gsd-build/get-shit-done,
which appears compromised or abandoned (maintainer unreachable since
2026-04-01; $GSD token linked to rug-pull).
- Adds rebrand notice block at top of English README
- Removes $GSD token badge and @gsd_foundation X badge (keeps Discord)
- Renames npm packages: get-shit-done-cc -> get-shit-done-redux,
@gsd-build/sdk -> @gsd-redux/sdk
- Updates all repo URLs across docs, workflows, package.json, bin/
- Updates ci@gsd-build -> ci@gsd-redux in workflow git identities
- Leaves CHANGELOG and .changeset/* alone (historical, time-stamped)
* test(#3426): add RED test for Codex Windows hooks .cmd shim requirement
Drive buildCodexHookWindowsShimIR (typed IR) + ensureCodexHooksJsonSessionStart
integration against mocked win32 platform. Counter-tests confirm darwin/linux
paths remain unchanged.
NOTE: Windows wall-clock verification depends on Docker matrix Windows
runners. Local test exercises the generator IR shape only.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#3426): Codex Windows hooks use .cmd shim to avoid bash.exe POSIX-exec failure
Root cause: Codex on Windows runs hook commands from PowerShell/cmd. The previous
hooks.json command format was `"node.exe" "script.js"`. Codex's hook-dispatch shell
(Git Bash / MSYS) tried to POSIX-exec node.exe (a Windows PE binary) via execvp(),
which fails with ENOEXEC — reported as `bash.exe: cannot execute binary file`.
Fix: `ensureCodexHooksJsonSessionStart` now calls `buildCodexHookWindowsShimIR` on
win32 to write a .cmd shim alongside the .js hook file. cmd.exe executes .cmd files
natively via CreateProcess, bypassing the POSIX exec layer entirely. Non-Windows
paths (darwin, linux) are unchanged: they continue to use the node-runner command.
Also adds `gsd-check-update.cmd` to the codex-hooks-json managed-basename set so
reconcileCodexHooksJsonSessionStart correctly replaces stale node-runner entries on
reinstall.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(3426): update changeset to reference PR #3768
* fix(3426): fail-loud on Codex Windows shim-write failure instead of silently restoring broken command
Replace the silent fallback to `projectManagedHookCommand` (the old
`node.exe script.js` form) with an explicit warn-and-skip path.
When `atomicWriteFileSync` fails to write the `.cmd` shim, the previous
code silently called `reconcileCodexHooksJsonSessionStart` with the
legacy node-runner command. That command triggers the exact
`bash.exe: cannot execute binary file` POSIX-exec failure that #3426
exists to fix — so a successful-looking install was secretly restoring
the original bug.
New behaviour:
- Emit `console.warn` with the failure reason and a remediation hint,
matching the `${yellow}⚠${reset} Skipped …` idiom used at line 9098.
- Return `{ changed: false, wrote: false }` to skip registration for
this runtime entirely, so the outer caller can surface "NOT installed"
instead of "installed (but broken)".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(3426): typed-IR assertions on .cmd shim eol/quoting/passthrough + IR extension
Extend `buildCodexHookWindowsShimIR` to expose two new typed fields on
the returned IR object (CONTRIBUTING.md L558-L565 IR-first discipline):
eol: { cmd: '\r\n' } — CRLF is canonical for cmd.exe .cmd files
passthroughArgs: true — shim forwards all args via %*
Add a new describe block (Step 2b) with three IR-level assertions:
1. `eol.cmd === '\r\n'` — prevents silent EOL regression that could
break parsing on Windows versions that require CRLF.
2. `invocation.target` is the raw unquoted path (no shell-metachar
leakage) — quoting happens only at render time.
3. `passthroughArgs === true` — the %* forwarding contract is
explicitly typed so regressions fail before the text is rendered.
All assertions operate on the typed IR returned by the generator, NOT
on the rendered `.cmd` file content — text-matching is the anti-pattern
CONTRIBUTING.md L522-582 prohibits.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(3426): fix Windows CI failures — update hook-command filter patterns
Four test files filtered for managed hooks in hooks.json using the
literal string `gsd-check-update.js`. On Windows the PR-introduced
.cmd shim changes the hooks.json command to
`"path/gsd-check-update.cmd"` (no node prefix, .cmd extension), so
those filters matched 0 entries and 24 Windows subtests failed.
Fixes:
- bug-2760-codex-install-defensive.test.cjs (7 filters): change
`/gsd-check-update\.js/` → `/gsd-check-update/` to match both
.js (POSIX) and .cmd (Windows) commands.
- bug-3357-codex-legacy-hooks-json-migration.test.cjs (3 filters):
same `.js` → no-extension change.
- bug-3427-3433-codex-install-shape.test.cjs (2 filters): same fix;
add explanatory comment to uninstall assertion.
- codex-config.test.cjs (9 filters + 1 exact-command assertion):
bulk-replace all `hooksJsonCommands.filter(cmd => cmd.includes('gsd-check-update.js'))`
with `gsd-check-update`; make the `fresh CODEX_HOME` test platform-
aware — on win32 assert `.cmd` shim path, on POSIX assert the
existing `"runner" "script.js"` form (#3017).
All four suites pass locally (macOS / darwin). Windows subtests
verified against the Windows CI failure log patterns.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(3426): address pr-review-toolkit + codex review findings
- fix(uninstall): add gsd-check-update.cmd to gsdHooks cleanup list so
the .cmd shim is removed from disk on Windows uninstall (was left as
orphan artifact — silent failure post-uninstall)
- test(3426): add uninstall test asserting gsd-check-update.cmd is
deleted from hooks dir after `uninstall(true, 'codex')` (no coverage existed)
- fix(comment): correct JSDoc on buildCodexHookWindowsShimIR — shim
content is three-line @ECHO OFF/@SETLOCAL/@runner snippet, not bare
`@node "script.js" %*` as the old comment claimed
- fix(comment): update stale assertion message in codex-config.test.cjs
L1457 — said "config.toml references it" but the hook is in hooks.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): migrate planning-workspace.cjs tty probe to probeTty seam (#3466)
Replaces direct execFileSync('tty') with probeTty() from the shell-projection
seam. Removes try/catch — probeTty() returns null on error/non-tty/win32.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): migrate commands.cjs to execGit seam (#3466)
- Replaces execSync('git diff --cached --name-only') with execGit array call
- Migrates 14 existing execGit(cwd, args) callers from core.cjs's local
wrapper to the seam's execGit(args, { cwd }) signature
- Drops execGit from the core.cjs destructure to resolve naming collision
Drops try/catch around git diff — execGit returns exitCode without throwing,
so the no-staged-files / not-a-git-repo case is detected by exitCode !== 0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): migrate check-latest-version.cjs to execNpm seam (#3466)
Routes the default-spawn path through execNpm — execNpm owns the win32
shell-flag policy. The injection point remains spawnSync-shaped for test
compatibility; an internal adapter translates { exitCode } → { status }.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): migrate init.cjs git calls to execGit seam (#3466)
Replaces 3 execSync calls with execGit array-args:
- detectChildRepos: git status --porcelain
- cmdInitNewWorkspace: git --version (worktree availability probe)
- cmdRemoveWorkspace: git status --porcelain
Drops 3 try/catch blocks — execGit returns exitCode without throwing, so
best-effort handling becomes a clean exitCode === 0 check.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): migrate core.cjs to execGit seam delegation (#3466)
- Removes direct require('child_process') from core.cjs
- Replaces execFileSync('git check-ignore') with seam's execGit
- Local execGit wrapper now a thin adapter delegating to seam — keeps the
legacy (cwd, args) positional signature and derived timedOut field for
the verify.cjs and worktree-safety.cjs consumers that are out of Phase 2
scope (the wrapper proper would only be removed once those consumers
migrate, tracked separately)
Extends the seam's _spawnResult to expose signal and error fields so callers
can compute timedOut without bypassing the seam. The Phase 1 test suite
asserts on required field presence only, so the extension is
backward-compatible.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): migrate graphify.cjs to execTool seam (#3466)
- execGraphify: spawnSync('graphify', ...) → execTool with env passthrough,
preserving the ENOENT/TIMEOUT/EXIT_NONZERO typed reason mapping using the
seam's signal/error fields
- checkGraphifyInstalled: spawnSync('graphify', ['--help']) → execTool
- checkGraphifyVersion strategy 1: graphify --version via execTool
- checkGraphifyVersion strategy 2: python3 importlib.metadata via execTool
Adds env option to execTool — graphify needs PYTHONUNBUFFERED=1 to drain
buffered stdout on long-running operations.
Changes seam internals to access spawnSync/execFileSync via the non-destructured
childProcess module reference. Destructured imports capture references at load
time and are un-mockable by mock.method(childProcess, 'spawnSync', ...) — which
breaks all the graphify subprocess tests. Non-destructured access restores
mockability without changing public behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(shell-projection): execGit defaults to non-interactive git env (#3466)
Bakes GIT_TERMINAL_PROMPT=0 and GCM_INTERACTIVE=never into execGit's default
env. Without these, a credential prompt or terminal-input probe blocks the
git subprocess indefinitely until our 10s timeout kills it — surfacing as
a generic timeout instead of the actual auth-prompt cause.
These were previously set ad-hoc in worktree-safety.cjs's local execGitDefault
wrapper. Moving them to the seam makes them the consistent default for every
git call across the codebase. Callers can override via opts.env.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(shell-projection): remove core.cjs local execGit wrapper; migrate verify + worktree-safety (#3466)
Completes the Phase 2 "remove local execGit wrapper" criterion. All callers
now use the shell-projection seam's execGit(args, opts) signature directly.
- core.cjs: delete the local execGit wrapper and the execGit export. The
isGitIgnored seam check now calls execGit from the seam. Worktree-safety
function calls drop their execGit DI passthrough — worktree-safety's
internal execGitDefault now delegates to the seam and adds timedOut.
- verify.cjs: 6 callers migrate from execGit(cwd, args) to
execGit(args, { cwd }). Imports execGit from the seam directly. The
inspectWorktreeHealth DI passes the seam's execGit (worktree-safety now
matches that shape).
- worktree-safety.cjs: local execGitDefault becomes a thin adapter over
the seam — no more direct spawnSync. 11 internal callers migrate to the
new shape. DI contract for tests changes from (cwd, args) → (args, opts).
- graphify.cjs: 2 remaining execGit callers migrate from core.cjs (now
removed) to the seam directly.
- test mocks updated in 3 worktree-safety test files to match the new
(args, opts) DI shape — most mocks were shape-agnostic and required no
changes; only those that destructured cwd/args needed updates.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(changeset): add entry for shell-projection Phase 2 migration (#3466)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(pr3476): address CodeRabbit review findings
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: cover Windows hook shell drift for Claude (#3413)
* fix: scope Windows hook syntax to Gemini runtime (#3413)
* docs: add changeset for #3413
* docs: set changeset pr for #3413
* fix: route Windows hook formatting through runtime-aware projection seam
* test: cover runtime projection edge cases for Windows hooks
* fix(docs): add shell-command-projection to inventory parity
* docs: align CLI module shipped count after rebase