From b2fcacda1b19a987cd27ff8f0e1153239fa82dd8 Mon Sep 17 00:00:00 2001 From: Jeremy McSpadden Date: Fri, 17 Apr 2026 15:56:35 -0500 Subject: [PATCH] fix(install): auto-install @gsd-build/sdk so gsd-sdk is on PATH (#2385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every /gsd-* command shells out to `gsd-sdk query …`, but the SDK was never installed by bin/install.js — the `--sdk` flag documented in README was never implemented. Users upgrading to 1.36+ hit "command not found: gsd-sdk" on every command. - Implement SDK install in finishInstall's finalize path - Default on; --no-sdk to skip; --sdk to force when already present - Idempotent probe via `which gsd-sdk` before reinstalling - Failures are warnings, not fatal — install hint printed Closes #2385 Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 3 +++ README.md | 2 +- bin/install.js | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60db661e..63f7ff7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Fixed +- **Installer now installs `@gsd-build/sdk` automatically** so `gsd-sdk` lands on PATH. Resolves `command not found: gsd-sdk` errors that affected every `/gsd-*` command after a fresh install or `/gsd-update` to 1.36+. Adds `--no-sdk` to opt out and `--sdk` to force reinstall. Implements the `--sdk` flag that was previously documented in README but never wired up (#2385) + ## [1.37.1] - 2026-04-17 ### Fixed diff --git a/README.md b/README.md index 56e2dccc..4d17aa28 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ npx get-shit-done-cc --all --global # Install to all directories Use `--global` (`-g`) or `--local` (`-l`) to skip the location prompt. Use `--claude`, `--opencode`, `--gemini`, `--kilo`, `--codex`, `--copilot`, `--cursor`, `--windsurf`, `--antigravity`, `--augment`, `--trae`, `--qwen`, `--codebuddy`, `--cline`, or `--all` to skip the runtime prompt. -Use `--sdk` to also install the GSD SDK CLI (`gsd-sdk`) for headless autonomous execution. +The GSD SDK CLI (`gsd-sdk`) is installed automatically (required by `/gsd-*` commands). Pass `--no-sdk` to skip the SDK install, or `--sdk` to force a reinstall. diff --git a/bin/install.js b/bin/install.js index 37d79e1d..b3689122 100755 --- a/bin/install.js +++ b/bin/install.js @@ -77,6 +77,8 @@ const hasBoth = args.includes('--both'); // Legacy flag, keeps working const hasAll = args.includes('--all'); const hasUninstall = args.includes('--uninstall') || args.includes('-u'); const hasPortableHooks = args.includes('--portable-hooks') || process.env.GSD_PORTABLE_HOOKS === '1'; +const hasSdk = args.includes('--sdk'); +const hasNoSdk = args.includes('--no-sdk'); // Runtime selection - can be set by flags or interactive prompt let selectedRuntimes = []; @@ -6626,6 +6628,41 @@ function promptLocation(runtimes) { }); } +/** + * Ensure `@gsd-build/sdk` (the `gsd-sdk` binary) is installed globally so + * workflow commands that shell out to `gsd-sdk query …` succeed. + * + * Skip if --no-sdk. Skip if already on PATH (unless --sdk was explicit). + * Failures are warnings, not fatal. + */ +function installSdkIfNeeded() { + if (hasNoSdk) { + console.log(`\n ${dim}Skipping GSD SDK install (--no-sdk)${reset}`); + return; + } + + const { spawnSync } = require('child_process'); + + if (!hasSdk) { + const probe = spawnSync(process.platform === 'win32' ? 'where' : 'which', ['gsd-sdk'], { stdio: 'ignore' }); + if (probe.status === 0) { + console.log(` ${green}✓${reset} GSD SDK already installed (gsd-sdk on PATH)`); + return; + } + } + + console.log(`\n ${cyan}Installing GSD SDK (@gsd-build/sdk)…${reset}`); + const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'; + const result = spawnSync(npmCmd, ['install', '-g', '@gsd-build/sdk'], { stdio: 'inherit' }); + if (result.status === 0) { + console.log(` ${green}✓${reset} Installed @gsd-build/sdk (gsd-sdk now on PATH)`); + } else { + console.warn(` ${yellow}⚠${reset} Failed to install @gsd-build/sdk automatically.`); + console.warn(` Run manually: ${cyan}npm install -g @gsd-build/sdk${reset}`); + console.warn(` Without it, /gsd-* commands will fail with "command not found: gsd-sdk".`); + } +} + /** * Install GSD for all selected runtimes */ @@ -6641,7 +6678,12 @@ function installAllRuntimes(runtimes, isGlobal, isInteractive) { const primaryStatuslineResult = results.find(r => statuslineRuntimes.includes(r.runtime)); const finalize = (shouldInstallStatusline) => { - // Handle SDK installation before printing final summaries + // Install @gsd-build/sdk so `gsd-sdk` lands on PATH. + // Every /gsd-* command shells out to `gsd-sdk query …`; without this, + // commands fail with "command not found: gsd-sdk". + // Runs by default; skip with --no-sdk. Idempotent when already present. + installSdkIfNeeded(); + const printSummaries = () => { for (const result of results) { const useStatusline = statuslineRuntimes.includes(result.runtime) && shouldInstallStatusline;