Files
msd-core/tests/gsd-tools-path-refs.test.cjs
Tom Boucher c7d25b183a fix(commands): replace undefined $GSD_TOOLS with resolved path (#1766) (#1769)
workstreams.md referenced $GSD_TOOLS (6 occurrences) which is never
defined anywhere in the system. All other 60+ command files use the
standard $HOME/.claude/get-shit-done/bin/gsd-tools.cjs path. The
undefined variable resolves to empty string, causing all workstream
commands to fail with module not found.

Fixes #1766

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 11:30:38 -04:00

58 lines
2.0 KiB
JavaScript

/**
* Regression guard for #1766: $GSD_TOOLS env var undefined
*
* All command files must use the resolved path to gsd-tools.cjs
* ($HOME/.claude/get-shit-done/bin/gsd-tools.cjs), not the undefined
* $GSD_TOOLS variable. This test catches any command file that
* references the undefined variable.
*/
const { describe, test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const COMMANDS_DIR = path.join(__dirname, '..', 'commands', 'gsd');
describe('command files: gsd-tools path references (#1766)', () => {
test('no command file references undefined $GSD_TOOLS variable', () => {
const files = fs.readdirSync(COMMANDS_DIR).filter(f => f.endsWith('.md'));
const violations = [];
for (const file of files) {
const content = fs.readFileSync(path.join(COMMANDS_DIR, file), 'utf-8');
// Match $GSD_TOOLS or "$GSD_TOOLS" or ${GSD_TOOLS} used as a path
// (not as a documentation reference)
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (/\$GSD_TOOLS\b/.test(line) && /node\s/.test(line)) {
violations.push(`${file}:${i + 1}: ${line.trim()}`);
}
}
}
assert.strictEqual(violations.length, 0,
'Command files must not reference undefined $GSD_TOOLS. ' +
'Use $HOME/.claude/get-shit-done/bin/gsd-tools.cjs instead.\n' +
'Violations:\n' + violations.join('\n'));
});
test('workstreams.md uses standard gsd-tools.cjs path', () => {
const content = fs.readFileSync(
path.join(COMMANDS_DIR, 'workstreams.md'), 'utf-8'
);
const nodeLines = content.split('\n').filter(l => /node\s/.test(l));
assert.ok(nodeLines.length > 0,
'workstreams.md should contain node invocations');
for (const line of nodeLines) {
assert.ok(
line.includes('gsd-tools.cjs'),
'Each node invocation must reference gsd-tools.cjs, got: ' + line.trim()
);
}
});
});