* 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>
3.5 KiB
<required_reading> Read all files referenced by the invoking prompt's execution_context before starting. </required_reading>
<available_agent_types> Valid GSD subagent types (use exact names — do not fall back to 'general-purpose'):
- gsd-codebase-mapper — Maps project structure and dependencies </available_agent_types>
Focus-to-Document Mapping
| Focus | Documents Produced |
|---|---|
tech |
STACK.md, INTEGRATIONS.md |
arch |
ARCHITECTURE.md, STRUCTURE.md |
quality |
CONVENTIONS.md, TESTING.md |
concerns |
CONCERNS.md |
tech+arch |
STACK.md, INTEGRATIONS.md, ARCHITECTURE.md, STRUCTURE.md |
Step 1: Parse arguments and resolve focus
Parse the user's input for --focus <area>. Default to tech+arch if not specified.
Validate that the focus is one of: tech, arch, quality, concerns, tech+arch.
If invalid:
Unknown focus area: "{input}". Valid options: tech, arch, quality, concerns, tech+arch
Exit.
Step 2: Check for existing documents
_GSD_SHIM_NAME="gsd-tools.cjs"; GSD_TOOLS="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/get-shit-done-redux@latest --claude --local" >&2; exit 1; fi
INIT=$(gsd_run query init.map-codebase 2>/dev/null || echo "{}")
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
Look up which documents would be produced for the selected focus (from the mapping table above).
For each target document, check if it already exists in .planning/codebase/:
ls -la .planning/codebase/{DOCUMENT}.md 2>/dev/null
If any exist, show their modification dates and ask:
Existing documents found:
- STACK.md (modified 2026-04-03)
- INTEGRATIONS.md (modified 2026-04-01)
Overwrite with fresh scan? [y/N]
If user says no, exit.
Step 3: Create output directory
mkdir -p .planning/codebase
Step 4: Spawn mapper agent
Spawn a single gsd-codebase-mapper agent with the selected focus area:
Agent(
prompt="Scan this codebase with focus: {focus}. Write results to .planning/codebase/. Produce only: {document_list}",
subagent_type="gsd-codebase-mapper",
model="{resolved_model}"
)
ORCHESTRATOR RULE — CODEX RUNTIME: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
Step 5: Report
## Scan Complete
**Focus:** {focus}
**Documents produced:**
{list of documents written with line counts}
Use `/gsd:map-codebase` for a comprehensive 4-area parallel scan.
<success_criteria>
- Focus area correctly parsed (default: tech+arch)
- Existing documents detected with modification dates shown
- User prompted before overwriting
- Single mapper agent spawned with correct focus
- Output documents written to .planning/codebase/ </success_criteria>