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:
@@ -31,7 +31,7 @@ const {
|
||||
resolveConfigHomeFromDescriptor,
|
||||
resolveSkillsBaseFromDescriptor,
|
||||
detectAntigravityDirAmbiguity,
|
||||
} = require(path.join(ROOT, 'gsd-core', 'bin', 'lib', 'runtime-homes.cjs'));
|
||||
} = require(path.join(ROOT, 'msd-core', 'bin', 'lib', 'runtime-homes.cjs'));
|
||||
|
||||
const HOME = os.homedir();
|
||||
|
||||
@@ -272,7 +272,7 @@ describe('#3023: pi PI_CODING_AGENT_DIR — dot-home-nested override semantics',
|
||||
// the developer's REAL home directory back instead, both a correctness bug
|
||||
// and a test-escape hazard.
|
||||
describe('expandTilde honors an injected opts.home (regression)', () => {
|
||||
const INJECTED_HOME = path.join(os.tmpdir(), 'gsd-injected-home-fixture');
|
||||
const INJECTED_HOME = path.join(os.tmpdir(), 'msd-injected-home-fixture');
|
||||
|
||||
test('claude (dot-home): CLAUDE_CONFIG_DIR=~/custom + injected home → resolves under injected home, not os.homedir()', () => {
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -604,7 +604,7 @@ describe('descriptor-driven equivalence: xdg runtimes (opencode, kilo)', () => {
|
||||
|
||||
describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/miss', () => {
|
||||
test('antigravity probe-miss → ~/.gemini/antigravity (first candidate)', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-antigravity-miss-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-antigravity-miss-'));
|
||||
try {
|
||||
// no candidates exist → fallback to first
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -624,7 +624,7 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
});
|
||||
|
||||
test('antigravity probe-hit antigravity → returns ~/.gemini/antigravity', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-antigravity-hit-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-antigravity-hit-'));
|
||||
try {
|
||||
const hitPath = path.join(tmpHome, '.gemini', 'antigravity');
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -644,7 +644,7 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
});
|
||||
|
||||
test('antigravity probe-hit antigravity-ide → returns ~/.gemini/antigravity-ide', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-antigravity-ide-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-antigravity-ide-'));
|
||||
try {
|
||||
const hitPath = path.join(tmpHome, '.gemini', 'antigravity-ide');
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -664,7 +664,7 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
});
|
||||
|
||||
test('antigravity probe-hit antigravity-cli (only cli exists) → returns ~/.gemini/antigravity-cli', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-antigravity-cli-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-antigravity-cli-'));
|
||||
try {
|
||||
const hitPath = path.join(tmpHome, '.gemini', 'antigravity-cli');
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -687,9 +687,9 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
// Before probeExists on dot-home-nested, first-bare-existing-wins meant a CLI
|
||||
// user (antigravity-cli) who also had the IDE's ~/.gemini/antigravity dir
|
||||
// present was shadowed to the legacy dir (probed first). probeExists =
|
||||
// 'gsd-core/VERSION' makes the dir GSD actually owns win, regardless of order.
|
||||
// 'msd-core/VERSION' makes the dir MSD actually owns win, regardless of order.
|
||||
const AG_PROBE = ['antigravity', 'antigravity-ide', 'antigravity-cli'];
|
||||
const AG_MARKER = path.join('gsd-core', 'VERSION');
|
||||
const AG_MARKER = path.join('msd-core', 'VERSION');
|
||||
|
||||
function antigravityDescriptor(withMarker) {
|
||||
const d = {
|
||||
@@ -703,12 +703,12 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
return d;
|
||||
}
|
||||
|
||||
test('coexistence: legacy antigravity + antigravity-cli both exist, only cli is GSD-marked → returns antigravity-cli', () => {
|
||||
test('coexistence: legacy antigravity + antigravity-cli both exist, only cli is MSD-marked → returns antigravity-cli', () => {
|
||||
const home = '/home/u';
|
||||
const cliDir = path.join(home, '.gemini', 'antigravity-cli');
|
||||
const legacyDir = path.join(home, '.gemini', 'antigravity');
|
||||
const markerPath = path.join(cliDir, AG_MARKER);
|
||||
// Both dirs exist on disk; only the cli dir carries gsd-core/VERSION.
|
||||
// Both dirs exist on disk; only the cli dir carries msd-core/VERSION.
|
||||
const existsSync = (p) =>
|
||||
p === markerPath || p === cliDir || p === legacyDir;
|
||||
const result = resolveConfigHomeFromDescriptor(antigravityDescriptor(true), {
|
||||
@@ -716,7 +716,7 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
home,
|
||||
existsSync,
|
||||
});
|
||||
assert.strictEqual(result, cliDir, 'GSD-marked cli dir must win over bare-existing legacy dir');
|
||||
assert.strictEqual(result, cliDir, 'MSD-marked cli dir must win over bare-existing legacy dir');
|
||||
});
|
||||
|
||||
test('coexistence WITHOUT probeExists still shadows to legacy (documents the pre-fix behavior)', () => {
|
||||
@@ -734,7 +734,7 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
assert.strictEqual(result, legacyDir);
|
||||
});
|
||||
|
||||
test('coexistence: legacy + ide both exist, only ide is GSD-marked → returns antigravity-ide', () => {
|
||||
test('coexistence: legacy + ide both exist, only ide is MSD-marked → returns antigravity-ide', () => {
|
||||
const home = '/home/u';
|
||||
const ideDir = path.join(home, '.gemini', 'antigravity-ide');
|
||||
const legacyDir = path.join(home, '.gemini', 'antigravity');
|
||||
@@ -748,12 +748,12 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
assert.strictEqual(result, ideDir);
|
||||
});
|
||||
|
||||
test('marker on legacy dir: GSD lives in legacy antigravity (a real 1.x install) → returns legacy even when cli dir exists bare', () => {
|
||||
test('marker on legacy dir: MSD lives in legacy antigravity (a real 1.x install) → returns legacy even when cli dir exists bare', () => {
|
||||
const home = '/home/u';
|
||||
const legacyDir = path.join(home, '.gemini', 'antigravity');
|
||||
const cliDir = path.join(home, '.gemini', 'antigravity-cli');
|
||||
const markerPath = path.join(legacyDir, AG_MARKER);
|
||||
// Legacy carries the marker; cli dir exists but is not GSD's. Legacy wins.
|
||||
// Legacy carries the marker; cli dir exists but is not MSD's. Legacy wins.
|
||||
const existsSync = (p) => p === markerPath || p === legacyDir || p === cliDir;
|
||||
const result = resolveConfigHomeFromDescriptor(antigravityDescriptor(true), {
|
||||
env: {},
|
||||
@@ -763,10 +763,10 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
assert.strictEqual(result, legacyDir);
|
||||
});
|
||||
|
||||
test('no marker anywhere (dirs exist but no GSD installed yet): falls back to bare-existence first match', () => {
|
||||
test('no marker anywhere (dirs exist but no MSD installed yet): falls back to bare-existence first match', () => {
|
||||
const home = '/home/u';
|
||||
const ideDir = path.join(home, '.gemini', 'antigravity-ide');
|
||||
// Only ide dir exists, no gsd-core/VERSION anywhere → pass 2 returns ide.
|
||||
// Only ide dir exists, no msd-core/VERSION anywhere → pass 2 returns ide.
|
||||
const existsSync = (p) => p === ideDir;
|
||||
const result = resolveConfigHomeFromDescriptor(antigravityDescriptor(true), {
|
||||
env: {},
|
||||
@@ -818,7 +818,7 @@ describe('descriptor-driven equivalence: dot-home-nested antigravity probe hit/m
|
||||
describe('detectAntigravityDirAmbiguity (migration/operator-guidance signal)', () => {
|
||||
const HOMEU = '/home/u';
|
||||
const dir = (name) => path.join(HOMEU, '.gemini', name);
|
||||
const markerOf = (name) => path.join(dir(name), 'gsd-core', 'VERSION');
|
||||
const markerOf = (name) => path.join(dir(name), 'msd-core', 'VERSION');
|
||||
|
||||
test('single dir present → not ambiguous', () => {
|
||||
const cli = dir('antigravity-cli');
|
||||
@@ -830,11 +830,11 @@ describe('detectAntigravityDirAmbiguity (migration/operator-guidance signal)', (
|
||||
assert.strictEqual(r.ambiguous, false);
|
||||
assert.strictEqual(r.resolved, cli);
|
||||
assert.deepStrictEqual(r.presentDirs, [cli]);
|
||||
assert.deepStrictEqual(r.gsdMarkedDirs, [cli]);
|
||||
assert.deepStrictEqual(r.msdMarkedDirs, [cli]);
|
||||
assert.strictEqual(r.envOverridden, false);
|
||||
});
|
||||
|
||||
test('legacy + cli both present, GSD marked in cli → ambiguous, resolves to cli', () => {
|
||||
test('legacy + cli both present, MSD marked in cli → ambiguous, resolves to cli', () => {
|
||||
const legacy = dir('antigravity');
|
||||
const cli = dir('antigravity-cli');
|
||||
const r = detectAntigravityDirAmbiguity({
|
||||
@@ -845,11 +845,11 @@ describe('detectAntigravityDirAmbiguity (migration/operator-guidance signal)', (
|
||||
assert.strictEqual(r.ambiguous, true, 'two probe dirs present must flag ambiguity');
|
||||
assert.strictEqual(r.resolved, cli, 'marker disambiguates resolution to cli');
|
||||
assert.deepStrictEqual(r.presentDirs.sort(), [legacy, cli].sort());
|
||||
assert.deepStrictEqual(r.gsdMarkedDirs, [cli]);
|
||||
assert.deepStrictEqual(r.msdMarkedDirs, [cli]);
|
||||
});
|
||||
|
||||
test('misinstall surface: legacy + cli present but GSD marked ONLY in legacy → ambiguous, resolves to legacy', () => {
|
||||
// This is exactly the #217 victim: GSD was written into the legacy/IDE dir,
|
||||
test('misinstall surface: legacy + cli present but MSD marked ONLY in legacy → ambiguous, resolves to legacy', () => {
|
||||
// This is exactly the #217 victim: MSD was written into the legacy/IDE dir,
|
||||
// so the marker is in legacy and the resolver keeps it there. The detector
|
||||
// flags ambiguity so the installer/update can prompt the operator.
|
||||
const legacy = dir('antigravity');
|
||||
@@ -861,7 +861,7 @@ describe('detectAntigravityDirAmbiguity (migration/operator-guidance signal)', (
|
||||
});
|
||||
assert.strictEqual(r.ambiguous, true);
|
||||
assert.strictEqual(r.resolved, legacy);
|
||||
assert.deepStrictEqual(r.gsdMarkedDirs, [legacy]);
|
||||
assert.deepStrictEqual(r.msdMarkedDirs, [legacy]);
|
||||
});
|
||||
|
||||
test('env override short-circuits: envOverridden flag set when ANTIGRAVITY_CONFIG_DIR present', () => {
|
||||
@@ -879,7 +879,7 @@ describe('detectAntigravityDirAmbiguity (migration/operator-guidance signal)', (
|
||||
|
||||
describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss', () => {
|
||||
test('kimi probe-miss → recommended root ~/.config/agents', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-kimi-miss-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-kimi-miss-'));
|
||||
try {
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
{
|
||||
@@ -898,7 +898,7 @@ describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss
|
||||
});
|
||||
|
||||
test('kimi probe-hit on recommended root ~/.config/agents/skills', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-kimi-recommended-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-kimi-recommended-'));
|
||||
try {
|
||||
const recommended = path.join(tmpHome, '.config', 'agents');
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -922,7 +922,7 @@ describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss
|
||||
});
|
||||
|
||||
test('kimi probe-hit on fallback ~/.agents/skills (recommended does not exist)', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-kimi-fallback-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-kimi-fallback-'));
|
||||
try {
|
||||
const fallback = path.join(tmpHome, '.agents');
|
||||
const result = resolveConfigHomeFromDescriptor(
|
||||
@@ -961,7 +961,7 @@ describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss
|
||||
|
||||
// Verify resolveKimiGlobalDir wrapper delegates correctly
|
||||
test('resolveKimiGlobalDir wrapper: probe-miss → recommended root', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-rkgd-miss-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-rkgd-miss-'));
|
||||
try {
|
||||
assert.strictEqual(
|
||||
resolveKimiGlobalDir({ env: {}, home: tmpHome, existsSync: () => false }),
|
||||
@@ -973,7 +973,7 @@ describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss
|
||||
});
|
||||
|
||||
test('resolveKimiGlobalDir wrapper: fallback probe-hit', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-rkgd-hit-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-rkgd-hit-'));
|
||||
try {
|
||||
const fallback = path.join(tmpHome, '.agents');
|
||||
assert.strictEqual(
|
||||
@@ -991,7 +991,7 @@ describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss
|
||||
|
||||
// Verify resolveAntigravityGlobalDir wrapper delegates correctly
|
||||
test('resolveAntigravityGlobalDir wrapper: probe-miss → ~/.gemini/antigravity', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-ragd-miss-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-ragd-miss-'));
|
||||
try {
|
||||
assert.strictEqual(
|
||||
resolveAntigravityGlobalDir({ env: {}, home: tmpHome, existsSync: () => false }),
|
||||
@@ -1003,7 +1003,7 @@ describe('descriptor-driven equivalence: generic-agents-root kimi probe hit/miss
|
||||
});
|
||||
|
||||
test('resolveAntigravityGlobalDir wrapper: probe-hit antigravity-ide', () => {
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-equiv-ragd-hit-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-equiv-ragd-hit-'));
|
||||
try {
|
||||
const hitPath = path.join(tmpHome, '.gemini', 'antigravity-ide');
|
||||
assert.strictEqual(
|
||||
@@ -1092,7 +1092,7 @@ describe('descriptor-driven global skills base', () => {
|
||||
test('hermes skills base is derived from descriptor artifact layout', () => {
|
||||
const saved = clearAllEnvKeys();
|
||||
try {
|
||||
assert.strictEqual(getGlobalSkillsBase('hermes'), path.join(HOME, '.hermes', 'skills', 'gsd'));
|
||||
assert.strictEqual(getGlobalSkillsBase('hermes'), path.join(HOME, '.hermes', 'skills', 'msd'));
|
||||
} finally {
|
||||
restoreEnvKeys(saved);
|
||||
}
|
||||
@@ -1178,9 +1178,9 @@ describe('descriptor-driven parity: 13 non-probe registry runtimes × no-env-var
|
||||
// to silently fail with:
|
||||
// [agent-skills] WARNING: Global skill not found at "~/.cursor/skills/X/SKILL.md" — skipping
|
||||
//
|
||||
// Fix introduces gsd-core/bin/lib/runtime-homes.cjs with first-class
|
||||
// Fix introduces msd-core/bin/lib/runtime-homes.cjs with first-class
|
||||
// support for every supported runtime, including:
|
||||
// - hermes: nested skills/gsd/<skillName>/ layout (#2841)
|
||||
// - hermes: nested skills/msd/<skillName>/ layout (#2841)
|
||||
// - cline: rules-based, returns null (no skills directory)
|
||||
// - CLAUDE_CONFIG_DIR env var for Claude (was missing)
|
||||
// - All other runtime-specific env vars
|
||||
@@ -1196,7 +1196,7 @@ const {
|
||||
getGlobalConfigDir,
|
||||
getGlobalSkillsBase,
|
||||
getGlobalSkillDir,
|
||||
} = require(path.join(ROOT, 'gsd-core', 'bin', 'lib', 'runtime-homes.cjs'));
|
||||
} = require(path.join(ROOT, 'msd-core', 'bin', 'lib', 'runtime-homes.cjs'));
|
||||
|
||||
// Helper: run fn with an env var temporarily set
|
||||
function withEnv(key, value, fn) {
|
||||
@@ -1231,7 +1231,7 @@ describe('bug #3126: runtime-homes getGlobalConfigDir — defaults', () => {
|
||||
test(`${runtime} default configDir`, () => {
|
||||
// Derive env-var list from the registry so new runtimes are auto-covered.
|
||||
// GROK_AGENTS_HOME is kept explicitly (grok has no registry entry).
|
||||
const { runtimes: _reg3126 } = require(path.join(ROOT, 'gsd-core', 'bin', 'lib', 'capability-registry.cjs'));
|
||||
const { runtimes: _reg3126 } = require(path.join(ROOT, 'msd-core', 'bin', 'lib', 'capability-registry.cjs'));
|
||||
const _regEnvKeys3126 = Object.values(_reg3126).flatMap((r) => {
|
||||
const ch = r.runtime?.configHome;
|
||||
if (!ch) return [];
|
||||
@@ -1296,7 +1296,7 @@ describe('bug #3126: runtime-homes env-var overrides', () => {
|
||||
});
|
||||
|
||||
test('antigravity detects 2.x IDE dir when legacy dir is absent', () => {
|
||||
const home = require('node:fs').mkdtempSync(path.join(os.tmpdir(), 'gsd-antigravity-home-'));
|
||||
const home = require('node:fs').mkdtempSync(path.join(os.tmpdir(), 'msd-antigravity-home-'));
|
||||
try {
|
||||
require('node:fs').mkdirSync(path.join(home, '.gemini', 'antigravity-ide'), { recursive: true });
|
||||
const savedHome = process.env.HOME;
|
||||
@@ -1328,11 +1328,11 @@ describe('bug #3126: runtime-homes getGlobalSkillsBase', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
test('hermes: skills at <configDir>/skills/gsd (nested layout #2841)', () => {
|
||||
test('hermes: skills at <configDir>/skills/msd (nested layout #2841)', () => {
|
||||
withEnv('HERMES_HOME', undefined, () => {
|
||||
assert.strictEqual(
|
||||
getGlobalSkillsBase('hermes'),
|
||||
path.join(os.homedir(), '.hermes', 'skills', 'gsd'),
|
||||
path.join(os.homedir(), '.hermes', 'skills', 'msd'),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1350,24 +1350,24 @@ describe('bug #3126: runtime-homes getGlobalSkillDir', () => {
|
||||
test('cursor: <configDir>/skills/<skillName>', () => {
|
||||
withEnv('CURSOR_CONFIG_DIR', undefined, () => {
|
||||
assert.strictEqual(
|
||||
getGlobalSkillDir('cursor', 'gsd-executor'),
|
||||
path.join(os.homedir(), '.cursor', 'skills', 'gsd-executor'),
|
||||
getGlobalSkillDir('cursor', 'msd-executor'),
|
||||
path.join(os.homedir(), '.cursor', 'skills', 'msd-executor'),
|
||||
);
|
||||
});
|
||||
});
|
||||
test('hermes: <configDir>/skills/gsd/<skillName>', () => {
|
||||
test('hermes: <configDir>/skills/msd/<skillName>', () => {
|
||||
withEnv('HERMES_HOME', undefined, () => {
|
||||
assert.strictEqual(
|
||||
getGlobalSkillDir('hermes', 'gsd-executor'),
|
||||
path.join(os.homedir(), '.hermes', 'skills', 'gsd', 'gsd-executor'),
|
||||
getGlobalSkillDir('hermes', 'msd-executor'),
|
||||
path.join(os.homedir(), '.hermes', 'skills', 'msd', 'msd-executor'),
|
||||
);
|
||||
});
|
||||
});
|
||||
test('cline: returns ~/.cline/skills/gsd-executor (skills-capable since v3.48.0 — #782)', () => {
|
||||
test('cline: returns ~/.cline/skills/msd-executor (skills-capable since v3.48.0 — #782)', () => {
|
||||
withEnv('CLINE_CONFIG_DIR', undefined, () => {
|
||||
assert.strictEqual(
|
||||
getGlobalSkillDir('cline', 'gsd-executor'),
|
||||
path.join(os.homedir(), '.cline', 'skills', 'gsd-executor'),
|
||||
getGlobalSkillDir('cline', 'msd-executor'),
|
||||
path.join(os.homedir(), '.cline', 'skills', 'msd-executor'),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1490,7 +1490,7 @@ describe('bug #3126: buildAgentSkillsBlock resolves the agent-skills path per ru
|
||||
// OWN runtime's skills dir and never falls back to (or leaks into) the
|
||||
// other's.
|
||||
const fs = require('node:fs');
|
||||
const { buildAgentSkillsBlock } = require(path.join(ROOT, 'gsd-core', 'bin', 'lib', 'init.cjs'));
|
||||
const { buildAgentSkillsBlock } = require(path.join(ROOT, 'msd-core', 'bin', 'lib', 'init.cjs'));
|
||||
|
||||
/**
|
||||
* Creates a temp config dir with a real `skills/<skillName>/SKILL.md` fixture,
|
||||
@@ -1498,7 +1498,7 @@ describe('bug #3126: buildAgentSkillsBlock resolves the agent-skills path per ru
|
||||
* (including restoring the env var) afterward.
|
||||
*/
|
||||
function withSkillFixture(configDirEnvKey, skillName, fn) {
|
||||
const tmpConfigDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-3126-skills-'));
|
||||
const tmpConfigDir = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-3126-skills-'));
|
||||
const skillDir = path.join(tmpConfigDir, 'skills', skillName);
|
||||
fs.mkdirSync(skillDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), '# fixture skill\n');
|
||||
@@ -1514,15 +1514,15 @@ describe('bug #3126: buildAgentSkillsBlock resolves the agent-skills path per ru
|
||||
}
|
||||
|
||||
test('cursor: resolves under CURSOR_CONFIG_DIR/skills, never falls back to .claude/skills', () => {
|
||||
withSkillFixture('CURSOR_CONFIG_DIR', 'gsd-executor', (tmpConfigDir) => {
|
||||
withSkillFixture('CURSOR_CONFIG_DIR', 'msd-executor', (tmpConfigDir) => {
|
||||
const diagnostics = { warnings: [] };
|
||||
const block = buildAgentSkillsBlock(
|
||||
{ runtime: 'cursor', agent_skills: { 'gsd-executor': 'global:gsd-executor' } },
|
||||
'gsd-executor',
|
||||
{ runtime: 'cursor', agent_skills: { 'msd-executor': 'global:msd-executor' } },
|
||||
'msd-executor',
|
||||
tmpConfigDir,
|
||||
diagnostics,
|
||||
);
|
||||
const expectedRef = path.join(tmpConfigDir, 'skills', 'gsd-executor', 'SKILL.md').replace(/\\/g, '/');
|
||||
const expectedRef = path.join(tmpConfigDir, 'skills', 'msd-executor', 'SKILL.md').replace(/\\/g, '/');
|
||||
assert.ok(block.includes(expectedRef), `expected block to include ${expectedRef}, got: ${block}`);
|
||||
assert.ok(!block.includes('.claude/skills'), `cursor resolution must not fall back to .claude/skills, got: ${block}`);
|
||||
assert.deepEqual(diagnostics.warnings, [], `expected no warnings, got: ${JSON.stringify(diagnostics.warnings)}`);
|
||||
@@ -1530,15 +1530,15 @@ describe('bug #3126: buildAgentSkillsBlock resolves the agent-skills path per ru
|
||||
});
|
||||
|
||||
test('claude: resolves under CLAUDE_CONFIG_DIR/skills, never leaks into .cursor/skills', () => {
|
||||
withSkillFixture('CLAUDE_CONFIG_DIR', 'gsd-executor', (tmpConfigDir) => {
|
||||
withSkillFixture('CLAUDE_CONFIG_DIR', 'msd-executor', (tmpConfigDir) => {
|
||||
const diagnostics = { warnings: [] };
|
||||
const block = buildAgentSkillsBlock(
|
||||
{ runtime: 'claude', agent_skills: { 'gsd-executor': 'global:gsd-executor' } },
|
||||
'gsd-executor',
|
||||
{ runtime: 'claude', agent_skills: { 'msd-executor': 'global:msd-executor' } },
|
||||
'msd-executor',
|
||||
tmpConfigDir,
|
||||
diagnostics,
|
||||
);
|
||||
const expectedRef = path.join(tmpConfigDir, 'skills', 'gsd-executor', 'SKILL.md').replace(/\\/g, '/');
|
||||
const expectedRef = path.join(tmpConfigDir, 'skills', 'msd-executor', 'SKILL.md').replace(/\\/g, '/');
|
||||
assert.ok(block.includes(expectedRef), `expected block to include ${expectedRef}, got: ${block}`);
|
||||
assert.ok(!block.includes('.cursor/skills'), `claude resolution must not use .cursor/skills, got: ${block}`);
|
||||
assert.deepEqual(diagnostics.warnings, [], `expected no warnings, got: ${JSON.stringify(diagnostics.warnings)}`);
|
||||
@@ -1548,13 +1548,13 @@ describe('bug #3126: buildAgentSkillsBlock resolves the agent-skills path per ru
|
||||
test('per-runtime resolution: two different runtimes in the same process each resolve into THEIR OWN config dir, never the other\'s', () => {
|
||||
// Proves this isn't a single special-cased runtime — cursor and claude,
|
||||
// driven back-to-back, must never cross-resolve into each other's fixture dir.
|
||||
withSkillFixture('CURSOR_CONFIG_DIR', 'gsd-executor', (cursorDir) => {
|
||||
withSkillFixture('CLAUDE_CONFIG_DIR', 'gsd-executor', (claudeDir) => {
|
||||
withSkillFixture('CURSOR_CONFIG_DIR', 'msd-executor', (cursorDir) => {
|
||||
withSkillFixture('CLAUDE_CONFIG_DIR', 'msd-executor', (claudeDir) => {
|
||||
const cursorBlock = buildAgentSkillsBlock(
|
||||
{ runtime: 'cursor', agent_skills: { x: 'global:gsd-executor' } }, 'x', cursorDir, { warnings: [] },
|
||||
{ runtime: 'cursor', agent_skills: { x: 'global:msd-executor' } }, 'x', cursorDir, { warnings: [] },
|
||||
);
|
||||
const claudeBlock = buildAgentSkillsBlock(
|
||||
{ runtime: 'claude', agent_skills: { x: 'global:gsd-executor' } }, 'x', claudeDir, { warnings: [] },
|
||||
{ runtime: 'claude', agent_skills: { x: 'global:msd-executor' } }, 'x', claudeDir, { warnings: [] },
|
||||
);
|
||||
const cursorPosix = cursorDir.replace(/\\/g, '/');
|
||||
const claudePosix = claudeDir.replace(/\\/g, '/');
|
||||
@@ -1573,7 +1573,7 @@ describe('bug #3126: buildAgentSkillsBlock resolves the agent-skills path per ru
|
||||
|
||||
describe('resolveKimiHooksTomlDir — per-runtime hooks root (#2755)', () => {
|
||||
// Pure path computation; the fixture home never needs to exist on disk.
|
||||
const FIXTURE_HOME = path.join(os.tmpdir(), 'gsd-2755-home-fixture');
|
||||
const FIXTURE_HOME = path.join(os.tmpdir(), 'msd-2755-home-fixture');
|
||||
const at = (...seg) => path.join(FIXTURE_HOME, ...seg);
|
||||
|
||||
test('a bare call does not throw', () => {
|
||||
|
||||
Reference in New Issue
Block a user