refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* GSD Tools Tests - settings.json JSONC (JSON with comments) support
|
||||
* MSD Tools Tests - settings.json JSONC (JSON with comments) support
|
||||
*
|
||||
* Validates that the installer's readSettings() correctly handles
|
||||
* settings.json files containing comments (line and block) without
|
||||
@@ -18,17 +18,17 @@ const { cleanup, mockPartialWriteThenThrow } = require('./helpers.cjs');
|
||||
|
||||
// ─── load real install.js exports once ───────────────────────────────────────
|
||||
//
|
||||
// install.js prints a banner at module-load time (outside its GSD_TEST_MODE
|
||||
// install.js prints a banner at module-load time (outside its MSD_TEST_MODE
|
||||
// guard) — silence stdout for the duration of the require() so test output
|
||||
// stays clean. The main-logic block IS gated on GSD_TEST_MODE, so no
|
||||
// stays clean. The main-logic block IS gated on MSD_TEST_MODE, so no
|
||||
// installer side-effects run.
|
||||
//
|
||||
// Guard line (bin/install.js:12287):
|
||||
// if (require.main === module && !process.env.GSD_TEST_MODE) {
|
||||
// if (require.main === module && !process.env.MSD_TEST_MODE) {
|
||||
//
|
||||
let installExports;
|
||||
{
|
||||
process.env.GSD_TEST_MODE = '1';
|
||||
process.env.MSD_TEST_MODE = '1';
|
||||
const _origWrite = process.stdout.write.bind(process.stdout);
|
||||
process.stdout.write = () => true; // suppress banner
|
||||
try {
|
||||
@@ -123,14 +123,14 @@ describe('stripJsonComments (#1461)', () => {
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node ~/.claude/hooks/gsd-statusline.js"
|
||||
"command": "node ~/.claude/hooks/msd-statusline.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusLine": {
|
||||
"command": "node ~/.claude/hooks/gsd-statusline.js",
|
||||
"command": "node ~/.claude/hooks/msd-statusline.js",
|
||||
"refreshInterval": 10
|
||||
}
|
||||
}`;
|
||||
@@ -143,7 +143,7 @@ describe('stripJsonComments (#1461)', () => {
|
||||
|
||||
describe('readSettings null return on malformed files (#1461)', () => {
|
||||
test('readSettings strips JSONC comments when reading a real file', (t) => {
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-jsonc-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-jsonc-${process.pid}.json`);
|
||||
fs.writeFileSync(tmpFile, `{\n // a comment\n "key": "value"\n}`);
|
||||
t.after(() => fs.unlinkSync(tmpFile));
|
||||
const result = readSettings(tmpFile);
|
||||
@@ -155,7 +155,7 @@ describe('readSettings null return on malformed files (#1461)', () => {
|
||||
});
|
||||
|
||||
test('readSettings returns null on truly malformed files (not empty object)', (t) => {
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-malformed-return-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-malformed-return-${process.pid}.json`);
|
||||
fs.writeFileSync(tmpFile, '{ this is not valid json');
|
||||
t.after(() => fs.unlinkSync(tmpFile));
|
||||
const result = readSettings(tmpFile);
|
||||
@@ -191,7 +191,7 @@ describe('readSettings: JSON null coalesced to empty, malformed warns (#1191)',
|
||||
test('valid JSON null coalesces to {} via the real function (early behavioral anchor)', (t) => {
|
||||
// Behavioral anchor: if someone removes the coalescing, this test catches
|
||||
// it before the more detailed behavioural test below even runs.
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-null-anchor-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-null-anchor-${process.pid}.json`);
|
||||
fs.writeFileSync(tmpFile, 'null');
|
||||
t.after(() => fs.unlinkSync(tmpFile));
|
||||
const result = readSettings(tmpFile);
|
||||
@@ -205,7 +205,7 @@ describe('readSettings: JSON null coalesced to empty, malformed warns (#1191)',
|
||||
test('valid JSON null content returns empty object with no malformed warning (real function)', () => {
|
||||
// A settings file containing literally `null` is valid JSON.
|
||||
// readSettings must treat it as empty settings ({}) — no warning emitted.
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-null-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-null-${process.pid}.json`);
|
||||
fs.writeFileSync(tmpFile, 'null');
|
||||
const warnCalls = [];
|
||||
const origWarn = console.warn;
|
||||
@@ -225,7 +225,7 @@ describe('readSettings: JSON null coalesced to empty, malformed warns (#1191)',
|
||||
test('malformed content returns null and emits malformed warning (real function)', () => {
|
||||
// A file containing `{ broken` is not valid JSON (even after comment-stripping).
|
||||
// readSettings must emit a malformed warning and return null.
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-broken-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-broken-${process.pid}.json`);
|
||||
fs.writeFileSync(tmpFile, '{ broken');
|
||||
const warnCalls = [];
|
||||
const origWarn = console.warn;
|
||||
@@ -243,7 +243,7 @@ describe('readSettings: JSON null coalesced to empty, malformed warns (#1191)',
|
||||
});
|
||||
|
||||
test('valid object content returns parsed object with no warning (real function)', () => {
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-valid-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-valid-${process.pid}.json`);
|
||||
fs.writeFileSync(tmpFile, '{"hooks":{}}');
|
||||
const warnCalls = [];
|
||||
const origWarn = console.warn;
|
||||
@@ -261,7 +261,7 @@ describe('readSettings: JSON null coalesced to empty, malformed warns (#1191)',
|
||||
});
|
||||
|
||||
test('absent file returns empty object with no warning (real function)', () => {
|
||||
const tmpFile = path.join(os.tmpdir(), `gsd-settings-test-absent-${process.pid}.json`);
|
||||
const tmpFile = path.join(os.tmpdir(), `msd-settings-test-absent-${process.pid}.json`);
|
||||
// ensure file does NOT exist
|
||||
try { fs.unlinkSync(tmpFile); } catch { /* already absent */ }
|
||||
const warnCalls = [];
|
||||
@@ -282,12 +282,12 @@ describe('readSettings: JSON null coalesced to empty, malformed warns (#1191)',
|
||||
//
|
||||
// Claude Code discards the ENTIRE settings file on any parse failure, so a
|
||||
// truncated write costs the user every hook, permission, and statusline they
|
||||
// have — not just GSD's entries. writeSettings is the sole writer of this
|
||||
// have — not just MSD's entries. writeSettings is the sole writer of this
|
||||
// surface for six runtimes, so it must never leave a partial file behind.
|
||||
|
||||
describe('writeSettings durability (#1874 F5)', () => {
|
||||
|
||||
// The user's existing settings: entries GSD does not own and must not lose.
|
||||
// The user's existing settings: entries MSD does not own and must not lose.
|
||||
const PRIOR = JSON.stringify({
|
||||
permissions: { allow: ['Bash(npm test)'] },
|
||||
statusLine: { command: '/usr/local/bin/my-statusline' },
|
||||
@@ -295,7 +295,7 @@ describe('writeSettings durability (#1874 F5)', () => {
|
||||
}, null, 2) + '\n';
|
||||
|
||||
function withTmpDir(fn) {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-write-settings-'));
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-write-settings-'));
|
||||
try { return fn(dir); } finally { cleanup(dir); }
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ describe('writeSettings durability (#1874 F5)', () => {
|
||||
'settings.json must be byte-identical to its pre-write contents'
|
||||
);
|
||||
// The real cost of the bug: a truncated file is discarded wholesale by
|
||||
// the host, so assert the user's non-GSD entries actually survive.
|
||||
// the host, so assert the user's non-MSD entries actually survive.
|
||||
const recovered = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
||||
assert.deepStrictEqual(recovered.permissions.allow, ['Bash(npm test)']);
|
||||
assert.strictEqual(recovered.env.MY_TOKEN, 'keep-me');
|
||||
|
||||
Reference in New Issue
Block a user