fix(#2829): gsd-sdk resolvable in local-mode installs (#2848)

* fix(#2829): gsd-sdk resolvable in local-mode installs

Local-mode installs previously short-circuited installSdkIfNeeded() the
moment opts.isLocal was true, leaving every `gsd-sdk query …` call site
unable to resolve the binary on PATH. The published tarball ships
sdk/dist/cli.js and bin/gsd-sdk.js regardless of mode, and the shim
resolves the CLI relative to its own __dirname — so the same self-link
strategy that powers npx-cache global installs (#2775) also works for
local installs. We now run the shared self-link path whenever the dist
is present, and only fall back to a non-fatal warning + early return
when the dist is genuinely missing (preserving the #2678 contract).

* test(#2829): correct precondition comment about ~/.local/bin

Address CodeRabbit feedback — the test does not create ~/.local/bin,
so reword the inline precondition to "any HOME bin candidate remains
off-PATH" to match what the test actually sets up.

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-04-29 07:59:30 -04:00
committed by GitHub
parent f4412349f0
commit 12b6ba4e34
2 changed files with 178 additions and 7 deletions

View File

@@ -8178,19 +8178,25 @@ function installSdkIfNeeded(opts) {
return;
}
// #2678: local installs do not write to global node_modules, so the SDK
// global-install check is not applicable. Warn and return instead of exiting.
if (opts.isLocal) {
console.warn(`\n ${yellow}⚠${reset} Skipping SDK check for local install — install @gsd-build/sdk globally if you need /gsd-* CLI support.`);
return;
}
const path = require('path');
const fs = require('fs');
const sdkDir = opts.sdkDir || path.resolve(__dirname, '..', 'sdk');
const sdkCliPath = path.join(sdkDir, 'dist', 'cli.js');
// #2678 / #2829: local installs do not write to global node_modules, so we
// cannot fall through to the global-install error path. But the parent
// package (which carries bin/gsd-sdk.js and sdk/dist/cli.js) IS available
// wherever the installer is running from — npx cache, npm-global, or git
// clone. The shim resolves sdk/dist/cli.js relative to its own __dirname,
// so a self-link into a user-writable PATH dir makes `gsd-sdk` callable
// from local-mode installs too. Only when the dist is genuinely missing
// do we bail out with a non-fatal warning.
if (opts.isLocal && !fs.existsSync(sdkCliPath)) {
console.warn(`\n ${yellow}⚠${reset} Skipping SDK check for local install — sdk/dist/cli.js not found at ${sdkCliPath}.`);
return;
}
if (!fs.existsSync(sdkCliPath)) {
const ctx = classifySdkInstall(sdkDir);
const bar = '━'.repeat(72);