fix(install): auto-install @gsd-build/sdk so gsd-sdk is on PATH (#2385)

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) <noreply@anthropic.com>
This commit is contained in:
Jeremy McSpadden
2026-04-17 15:56:35 -05:00
parent 794f7e1b0b
commit b2fcacda1b
3 changed files with 47 additions and 2 deletions

View File

@@ -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

View File

@@ -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.
</details>

View File

@@ -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;