* fix(#1223): install scripts/fix-slash-commands.cjs so gsd-tools loads Before this fix, bin/install.js copied scripts/changeset/ and scripts/lib/ into the runtime config dir but omitted scripts/fix-slash-commands.cjs. gsd-core/bin/lib/command-roster.cjs requires this file at module load via require('../../../scripts/fix-slash-commands.cjs'), so every gsd-tools command crashed with MODULE_NOT_FOUND on every installed runtime. Four changes: - bin/install.js copy step: copy fix-slash-commands.cjs into <configDir>/scripts/ with source-missing hard-fail and verifyFileInstalled smoke check - bin/install.js writeManifest: track scripts/fix-slash-commands.cjs (not covered by the changeset/lib subdir loops) - bin/install.js uninstall: best-effort unlinkSync before scripts/ rmdir - scripts/fix-slash-commands.cjs readCmdNames(): wrap readdirSync in try/catch returning [] so skill-based/global installs without a local commands/gsd/ directory do not throw ENOENT Tests added to tests/install.test.cjs (6 new tests): - smoke: install() copies fix-slash-commands.cjs - e2e: spawned gsd-tools.cjs does not crash with MODULE_NOT_FOUND - manifest: writeManifest() tracks the file - uninstall: uninstall() removes the file - readCmdNames unit: export returns an array - readCmdNames spawn: absent COMMANDS_DIR returns exit 0 (no throw) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1223): backfill changeset PR number (#1240) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -92,9 +92,21 @@ function transformContentToHyphen(src, cmdNames) {
|
||||
}
|
||||
|
||||
function readCmdNames() {
|
||||
return fs.readdirSync(COMMANDS_DIR)
|
||||
.filter(f => f.endsWith('.md'))
|
||||
.map(f => f.replace(/\.md$/, ''));
|
||||
try {
|
||||
return fs.readdirSync(COMMANDS_DIR)
|
||||
.filter(f => f.endsWith('.md'))
|
||||
.map(f => f.replace(/\.md$/, ''));
|
||||
} catch (err) {
|
||||
// Only swallow the missing-directory case. Any other error (EACCES, ENOTDIR,
|
||||
// etc.) indicates a real misconfiguration and must propagate so callers are
|
||||
// not silently handed an empty registry while the real problem goes undetected.
|
||||
if (err.code !== 'ENOENT') throw err;
|
||||
// COMMANDS_DIR may not exist on installs that use skill-based runtimes or
|
||||
// global Claude installs (no local commands/gsd/ directory). Return [] so
|
||||
// callers that handle an empty array gracefully (buildPattern returns null,
|
||||
// transformContent is a no-op) are not broken by a missing directory.
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function processFile(file, cmdNames) {
|
||||
|
||||
Reference in New Issue
Block a user