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 Test Helpers
|
||||
* MSD Tools Test Helpers
|
||||
*/
|
||||
|
||||
const { execFileSync } = require('child_process');
|
||||
@@ -10,12 +10,12 @@ const { createFixture } = require('./fixtures/index.cjs');
|
||||
const processSeam = require('./helpers/process-seam.cjs');
|
||||
const { SEAM_DEFAULT_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
const TOOLS_PATH = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
const TOOLS_PATH = path.join(__dirname, '..', 'msd-core', 'bin', 'msd-tools.cjs');
|
||||
|
||||
// Session-IDENTITY vars. Blanked so a child cannot inherit the developer's
|
||||
// terminal/agent session and key shared state off it.
|
||||
const SESSION_IDENTITY_ENV_KEYS = [
|
||||
'GSD_SESSION_KEY',
|
||||
'MSD_SESSION_KEY',
|
||||
'CODEX_THREAD_ID',
|
||||
'CLAUDE_SESSION_ID',
|
||||
'CLAUDE_CODE_SESSION_ID',
|
||||
@@ -45,16 +45,16 @@ let _builtLib = null;
|
||||
function builtLib() {
|
||||
if (_builtLib) return _builtLib;
|
||||
try {
|
||||
const { runtimes } = require('../gsd-core/bin/lib/capability-registry.cjs');
|
||||
const { runtimes } = require('../msd-core/bin/lib/capability-registry.cjs');
|
||||
const {
|
||||
NON_REGISTRY_CONFIG_HOME_DESCRIPTORS,
|
||||
GSD_LOCATION_ENV_KEYS,
|
||||
} = require('../gsd-core/bin/lib/runtime-homes.cjs');
|
||||
_builtLib = { runtimes, NON_REGISTRY_CONFIG_HOME_DESCRIPTORS, GSD_LOCATION_ENV_KEYS };
|
||||
MSD_LOCATION_ENV_KEYS,
|
||||
} = require('../msd-core/bin/lib/runtime-homes.cjs');
|
||||
_builtLib = { runtimes, NON_REGISTRY_CONFIG_HOME_DESCRIPTORS, MSD_LOCATION_ENV_KEYS };
|
||||
} catch (cause) {
|
||||
throw new Error(
|
||||
'tests/helpers.cjs derives the config-location scrub set from the built runtime '
|
||||
+ 'lib (gsd-core/bin/lib), which is not present. Run `npm run build:lib` first — '
|
||||
+ 'lib (msd-core/bin/lib), which is not present. Run `npm run build:lib` first — '
|
||||
+ '`npm test` does this for you via its pretest script.',
|
||||
{ cause },
|
||||
);
|
||||
@@ -65,9 +65,9 @@ function builtLib() {
|
||||
// Config-location vars that are neither in the registry nor descriptor-shaped,
|
||||
// each with its reader:
|
||||
// GROK_AGENTS_HOME — hardcoded `grok` branch in getGlobalConfigDir (src/runtime-homes.cts)
|
||||
// GSD_RUNTIME — selects WHICH runtime home resolves (src/model-resolver.cts)
|
||||
// GSD_PROJECT — planningDir() project segment (src/planning-workspace.cts)
|
||||
// GSD_WORKSTREAM — planningDir() workstream segment (src/planning-workspace.cts)
|
||||
// MSD_RUNTIME — selects WHICH runtime home resolves (src/model-resolver.cts)
|
||||
// MSD_PROJECT — planningDir() project segment (src/planning-workspace.cts)
|
||||
// MSD_WORKSTREAM — planningDir() workstream segment (src/planning-workspace.cts)
|
||||
//
|
||||
// #2665 round 3: this list shrinks as sources become enumerable, and that direction
|
||||
// is the point. KIMI_SHARE_DIR was NOT added here — it now derives from
|
||||
@@ -75,12 +75,12 @@ function builtLib() {
|
||||
// names is precisely what reopened this bug three times.
|
||||
const NON_REGISTRY_CONFIG_LOCATION_ENV_KEYS = [
|
||||
'GROK_AGENTS_HOME',
|
||||
'GSD_RUNTIME',
|
||||
'GSD_PROJECT',
|
||||
'GSD_WORKSTREAM',
|
||||
// #3245: host-session signals GSD now reads (host-runtime-detection.cts's
|
||||
'MSD_RUNTIME',
|
||||
'MSD_PROJECT',
|
||||
'MSD_WORKSTREAM',
|
||||
// #3245: host-session signals MSD now reads (host-runtime-detection.cts's
|
||||
// detectHostRuntime / resolveReportedRuntime). Scrubbed for the same reason
|
||||
// GSD_RUNTIME is — an ambiently-set CODEX_SANDBOX / (this repo's test suite
|
||||
// MSD_RUNTIME is — an ambiently-set CODEX_SANDBOX / (this repo's test suite
|
||||
// running from inside a Codex session, or any host that happens to export
|
||||
// these) would non-deterministically flip the detected runtime for every
|
||||
// test that does not explicitly pass them. Tests that WANT them set still
|
||||
@@ -93,7 +93,7 @@ const NON_REGISTRY_CONFIG_LOCATION_ENV_KEYS = [
|
||||
// Write-escape PERMISSIONS — deliberately its own family, and deliberately NOT
|
||||
// folded into any of the four rungs below.
|
||||
//
|
||||
// #2665 round 5: GSD_ALLOW_SYMLINKED_DEST is boolean and names no path, so it is
|
||||
// #2665 round 5: MSD_ALLOW_SYMLINKED_DEST is boolean and names no path, so it is
|
||||
// not a config-location var by any honest reading. But install-engine.cts reads it
|
||||
// env-first (`:214`) and threads it as `allowOptInFollow` into the symlink-escape
|
||||
// guard at four call sites, each gating a write (`:361/:367`, `:416/:424`,
|
||||
@@ -104,7 +104,7 @@ const NON_REGISTRY_CONFIG_LOCATION_ENV_KEYS = [
|
||||
// Blanking is fail-safe in the only direction that matters: '' is neither '1' nor
|
||||
// 'true', so a blanked value makes the guard STRICTER, never looser. That asymmetry
|
||||
// is why this can be scrubbed wholesale without reasoning about each call site.
|
||||
const WRITE_ESCAPE_PERMISSION_ENV_KEYS = ['GSD_ALLOW_SYMLINKED_DEST'];
|
||||
const WRITE_ESCAPE_PERMISSION_ENV_KEYS = ['MSD_ALLOW_SYMLINKED_DEST'];
|
||||
|
||||
// Config-LOCATION vars — distinct in kind from the session-identity vars above:
|
||||
// these decide WHERE a child writes, so leaving one ambient lets a test that
|
||||
@@ -120,7 +120,7 @@ const WRITE_ESCAPE_PERMISSION_ENV_KEYS = ['GSD_ALLOW_SYMLINKED_DEST'];
|
||||
let _configLocationEnvKeys = null;
|
||||
function configLocationEnvKeys() {
|
||||
if (_configLocationEnvKeys) return _configLocationEnvKeys;
|
||||
const { runtimes, NON_REGISTRY_CONFIG_HOME_DESCRIPTORS, GSD_LOCATION_ENV_KEYS } = builtLib();
|
||||
const { runtimes, NON_REGISTRY_CONFIG_HOME_DESCRIPTORS, MSD_LOCATION_ENV_KEYS } = builtLib();
|
||||
_configLocationEnvKeys = [
|
||||
...new Set([
|
||||
// 1. Every runtime descriptor the capability registry carries — including
|
||||
@@ -140,9 +140,9 @@ function configLocationEnvKeys() {
|
||||
...(d?.env ?? []),
|
||||
...(d?.skillsHome?.env ?? []),
|
||||
]),
|
||||
// 3. GSD's OWN location vars — a different family: they decide where GSD keeps
|
||||
// user-owned state ($GSD_HOME/.gsd/), not where a runtime keeps its config.
|
||||
...GSD_LOCATION_ENV_KEYS,
|
||||
// 3. MSD's OWN location vars — a different family: they decide where MSD keeps
|
||||
// user-owned state ($MSD_HOME/.msd/), not where a runtime keeps its config.
|
||||
...MSD_LOCATION_ENV_KEYS,
|
||||
// 4. The residue that is neither registry-carried nor descriptor-shaped.
|
||||
...NON_REGISTRY_CONFIG_LOCATION_ENV_KEYS,
|
||||
// 5. Write-escape permissions — NOT locations. Same mechanism because the
|
||||
@@ -170,7 +170,7 @@ function testEnvBase() {
|
||||
* installer IN-PROCESS — `install(true, 'claude')` — resolves through the same
|
||||
* env-first `getGlobalConfigDir`, so an ambient CLAUDE_CONFIG_DIR beats a
|
||||
* sandboxed `process.env.HOME` and a complete global install (agents/, commands/,
|
||||
* skills/, gsd-core/, manifest, settings) lands in the developer's live config
|
||||
* skills/, msd-core/, manifest, settings) lands in the developer's live config
|
||||
* dir. No child-env scrub can reach that call; only clearing the parent's env can.
|
||||
*
|
||||
* Pair with a HOME sandbox, not instead of one: HOME covers the home-derived
|
||||
@@ -195,16 +195,16 @@ function scrubConfigLocationEnv() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Run gsd-tools command.
|
||||
* Run msd-tools command.
|
||||
*
|
||||
* @param {string|string[]} args - Command string (shell-interpreted) or array
|
||||
* of arguments (shell-bypassed via execFileSync, safe for JSON and dollar signs).
|
||||
* @param {string} cwd - Working directory.
|
||||
* @param {object} [env] - Optional env overrides merged on top of process.env.
|
||||
* Pass { HOME: cwd } to sandbox ~/.gsd/ lookups in tests that assert concrete
|
||||
* Pass { HOME: cwd } to sandbox ~/.msd/ lookups in tests that assert concrete
|
||||
* config values that could be overridden by a developer's defaults.json.
|
||||
*/
|
||||
function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
function runMsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
// Resolve argv once so both the first attempt and the retry use the same vector.
|
||||
const childEnv = { ...process.env, ...testEnvBase(), ...env };
|
||||
const argv = Array.isArray(args)
|
||||
@@ -216,7 +216,7 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
// typed { outcome, exitCode, stdout, stderr, timedOut, signal, killed, code }
|
||||
// result — never throws for a kill/timeout/buffer-overflow/spawn-failure.
|
||||
// This adapter is the ONLY place that retries and the ONLY place that
|
||||
// reconstructs runGsdTools's legacy { success, output, error, exitCode }
|
||||
// reconstructs runMsdTools's legacy { success, output, error, exitCode }
|
||||
// shape, so all 136 callers keep their existing contract byte-identically.
|
||||
//
|
||||
// `processSeam.runNode` is looked up on the module object (not destructured
|
||||
@@ -233,8 +233,8 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
|
||||
function throwResourceStarvation(result) {
|
||||
throw new Error(
|
||||
`[runGsdTools: resource-starvation / subprocess-kill after retry] ` +
|
||||
`gsd-tools was killed before completion ` +
|
||||
`[runMsdTools: resource-starvation / subprocess-kill after retry] ` +
|
||||
`msd-tools was killed before completion ` +
|
||||
`(signal=${result.signal}, code=${result.code}, killed=${result.killed}). ` +
|
||||
`This indicates host OOM or scheduler contention, not a product bug. ` +
|
||||
`stdout=${(result.stdout || '').trim()} ` +
|
||||
@@ -260,7 +260,7 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
// note so CI logs show "stderr: (empty)" rather than silently losing
|
||||
// the fact that the child process produced no error output — empty
|
||||
// stderr with a non-zero exit code is a signal of OS-level crash (OOM
|
||||
// kill, worker thread fatal error) rather than a gsd-tools application
|
||||
// kill, worker thread fatal error) rather than a msd-tools application
|
||||
// error.
|
||||
const commandLine = [process.execPath, TOOLS_PATH, ...argv].join(' ');
|
||||
const error = stderrRaw
|
||||
@@ -296,7 +296,7 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
return {
|
||||
success: false,
|
||||
output: (result.stdout || '').trim(),
|
||||
error: `gsd-tools output exceeded the subprocess buffer limit (code=${result.code})`,
|
||||
error: `msd-tools output exceeded the subprocess buffer limit (code=${result.code})`,
|
||||
exitCode: 1,
|
||||
};
|
||||
}
|
||||
@@ -311,7 +311,7 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
return {
|
||||
success: false,
|
||||
output: (result.stdout || '').trim(),
|
||||
error: `gsd-tools was killed by signal (signal=${result.signal}, code=${result.code})`,
|
||||
error: `msd-tools was killed by signal (signal=${result.signal}, code=${result.code})`,
|
||||
exitCode: null,
|
||||
};
|
||||
}
|
||||
@@ -332,7 +332,7 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
return {
|
||||
success: false,
|
||||
output: (result.stdout || '').trim(),
|
||||
error: `gsd-tools failed to spawn (code=${result.code})`,
|
||||
error: `msd-tools failed to spawn (code=${result.code})`,
|
||||
exitCode: 1,
|
||||
};
|
||||
}
|
||||
@@ -359,17 +359,17 @@ function runGsdTools(args, cwd = process.cwd(), env = {}) {
|
||||
}
|
||||
|
||||
// Create a bare temp directory (no .planning/ structure)
|
||||
function createTempDir(prefix = 'gsd-test-') {
|
||||
function createTempDir(prefix = 'msd-test-') {
|
||||
return fs.mkdtempSync(path.join(require('os').tmpdir(), prefix));
|
||||
}
|
||||
|
||||
// Create temp directory structure
|
||||
function createTempProject(prefix = 'gsd-test-') {
|
||||
function createTempProject(prefix = 'msd-test-') {
|
||||
return createFixture({ prefix, planning: true, git: false });
|
||||
}
|
||||
|
||||
// Create temp directory with initialized git repo and at least one commit
|
||||
function createTempGitProject(prefix = 'gsd-test-') {
|
||||
function createTempGitProject(prefix = 'msd-test-') {
|
||||
return createFixture({ prefix, planning: true, git: true, projectDoc: true });
|
||||
}
|
||||
|
||||
@@ -716,7 +716,7 @@ async function suppressFdAsync(captureFd, fn) {
|
||||
*
|
||||
* ADR-1671's workflow fragmentization (#2930/#2932/#2993 et al.) moves whole
|
||||
* sections out of a host workflow (e.g. `plan-phase.md`) into lazily-loaded
|
||||
* step files under `gsd-core/workflows/<name>/steps/*.md`. A structural or
|
||||
* step files under `msd-core/workflows/<name>/steps/*.md`. A structural or
|
||||
* drift guard that reads the host file alone goes blind the moment a
|
||||
* section it cares about moves out — this is exactly the shape #2650's own
|
||||
* regression tests hit when #2993 relocated plan-phase.md's chunked-planning
|
||||
@@ -804,10 +804,10 @@ function parseFrontmatter(content) {
|
||||
}
|
||||
|
||||
// #3026 CR: shared `--help` output check used by bug-1818 + bug-3019 tests.
|
||||
// Render-on-help shape is `Usage: gsd-tools …\nCommands: …` — both lines
|
||||
// Render-on-help shape is `Usage: msd-tools …\nCommands: …` — both lines
|
||||
// must be present; structural test, not prose substring matching.
|
||||
function isUsageOutput(text) {
|
||||
return /Usage:\s*gsd-tools/.test(text) && /Commands:/.test(text);
|
||||
return /Usage:\s*msd-tools/.test(text) && /Commands:/.test(text);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1047,8 +1047,8 @@ async function waitFor(predicate, { timeoutMs = 10000, stepMs = 25, message = 'w
|
||||
* `_resetRuntimeWarningCacheForTests` wrappers in individual test files.
|
||||
*/
|
||||
function resetRuntimeWarningCaches() {
|
||||
const configLoader = require('../gsd-core/bin/lib/config-loader.cjs');
|
||||
const modelResolver = require('../gsd-core/bin/lib/model-resolver.cjs');
|
||||
const configLoader = require('../msd-core/bin/lib/config-loader.cjs');
|
||||
const modelResolver = require('../msd-core/bin/lib/model-resolver.cjs');
|
||||
configLoader._resetRuntimeWarningCacheForTests();
|
||||
modelResolver._resetModelPolicyWarningCacheForTests();
|
||||
modelResolver._resetModelOverrideWarningCacheForTests();
|
||||
@@ -1060,16 +1060,16 @@ function resetRuntimeWarningCaches() {
|
||||
* Single source of truth for tests that need a deterministic, session-key-free
|
||||
* and workstream/project-free process.env — save/clear before, restore after.
|
||||
* Union of the sets previously hand-duplicated in
|
||||
* tests/active-workstream-store.unit.test.cjs and tests/gsd-statusline.test.cjs
|
||||
* tests/active-workstream-store.unit.test.cjs and tests/msd-statusline.test.cjs
|
||||
* (#2850 code review finding: the two copies had already silently diverged).
|
||||
*/
|
||||
const SESSION_ENV_KEYS = [
|
||||
'GSD_SESSION_KEY', 'CODEX_THREAD_ID', 'CLAUDE_SESSION_ID', 'CLAUDE_CODE_SESSION_ID',
|
||||
'MSD_SESSION_KEY', 'CODEX_THREAD_ID', 'CLAUDE_SESSION_ID', 'CLAUDE_CODE_SESSION_ID',
|
||||
'CLAUDE_CODE_SSE_PORT',
|
||||
'OPENCODE_SESSION_ID', 'GEMINI_SESSION_ID', 'CURSOR_SESSION_ID', 'WINDSURF_SESSION_ID',
|
||||
'TERM_SESSION_ID', 'WT_SESSION', 'TMUX_PANE', 'ZELLIJ_SESSION_NAME',
|
||||
'TTY', 'SSH_TTY', 'CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS',
|
||||
'GSD_WORKSTREAM', 'GSD_PROJECT',
|
||||
'MSD_WORKSTREAM', 'MSD_PROJECT',
|
||||
];
|
||||
|
||||
function saveSessionEnv() {
|
||||
@@ -1090,48 +1090,48 @@ function clearSessionEnv() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Save + clear GSD_WORKSTREAM and GSD_PROJECT on process.env, paired with
|
||||
* Save + clear MSD_WORKSTREAM and MSD_PROJECT on process.env, paired with
|
||||
* restoreWorkstreamEnv(). planningDir() reads both directly from
|
||||
* process.env when its params are omitted, so a test asserting
|
||||
* workstream/project-scoped behavior must isolate them from ambient shell
|
||||
* state (and from whatever an earlier test in the same process left behind).
|
||||
*
|
||||
* Previously duplicated as a local isolateWorkstreamEnv()/restoreWorkstreamEnv()
|
||||
* pair in tests/phase-locator.test.cjs, and as the GSD_WORKSTREAM/GSD_PROJECT
|
||||
* pair in tests/phase-locator.test.cjs, and as the MSD_WORKSTREAM/MSD_PROJECT
|
||||
* slice of tests/model-resolver.test.cjs's broader isolateHome()/restoreHome()
|
||||
* (which still isolates HOME/USERPROFILE/GSD_HOME/GSD_RUNTIME locally — that
|
||||
* (which still isolates HOME/USERPROFILE/MSD_HOME/MSD_RUNTIME locally — that
|
||||
* part is genuinely specific to model-resolver's tests and stays there).
|
||||
*
|
||||
* Module-level save slot (not a returned snapshot) to match the exact
|
||||
* no-arg isolate()/restore() call shape both prior local copies used.
|
||||
*/
|
||||
let _origGsdWorkstream;
|
||||
let _origGsdProject;
|
||||
let _origMsdWorkstream;
|
||||
let _origMsdProject;
|
||||
|
||||
function isolateWorkstreamEnv() {
|
||||
_origGsdWorkstream = process.env.GSD_WORKSTREAM;
|
||||
_origGsdProject = process.env.GSD_PROJECT;
|
||||
delete process.env.GSD_WORKSTREAM;
|
||||
delete process.env.GSD_PROJECT;
|
||||
_origMsdWorkstream = process.env.MSD_WORKSTREAM;
|
||||
_origMsdProject = process.env.MSD_PROJECT;
|
||||
delete process.env.MSD_WORKSTREAM;
|
||||
delete process.env.MSD_PROJECT;
|
||||
}
|
||||
|
||||
function restoreWorkstreamEnv() {
|
||||
if (_origGsdWorkstream === undefined) delete process.env.GSD_WORKSTREAM;
|
||||
else process.env.GSD_WORKSTREAM = _origGsdWorkstream;
|
||||
if (_origGsdProject === undefined) delete process.env.GSD_PROJECT;
|
||||
else process.env.GSD_PROJECT = _origGsdProject;
|
||||
if (_origMsdWorkstream === undefined) delete process.env.MSD_WORKSTREAM;
|
||||
else process.env.MSD_WORKSTREAM = _origMsdWorkstream;
|
||||
if (_origMsdProject === undefined) delete process.env.MSD_PROJECT;
|
||||
else process.env.MSD_PROJECT = _origMsdProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* #3156: env for a RAW installer spawn — one that bypasses runGsdTools and so
|
||||
* #3156: env for a RAW installer spawn — one that bypasses runMsdTools and so
|
||||
* never receives TEST_ENV_BASE on its own.
|
||||
*
|
||||
* Blanking config-LOCATION vars is necessary but NOT sufficient here.
|
||||
* bin/install.js writes GSD's own user-owned store through os.homedir()
|
||||
* DIRECTLY (writeNonClaudeDefaults -> <home>/.gsd/defaults.json, #2834), and
|
||||
* os.homedir() consults no GSD variable at all — so nothing in
|
||||
* CONFIG_LOCATION_ENV_KEYS can reach it, and blanking GSD_HOME does not reach
|
||||
* it either, because a blank GSD_HOME falls back to exactly that homedir().
|
||||
* bin/install.js writes MSD's own user-owned store through os.homedir()
|
||||
* DIRECTLY (writeNonClaudeDefaults -> <home>/.msd/defaults.json, #2834), and
|
||||
* os.homedir() consults no MSD variable at all — so nothing in
|
||||
* CONFIG_LOCATION_ENV_KEYS can reach it, and blanking MSD_HOME does not reach
|
||||
* it either, because a blank MSD_HOME falls back to exactly that homedir().
|
||||
* Only a sandboxed HOME/USERPROFILE contains it.
|
||||
*
|
||||
* HOME stays deliberately OUT of TEST_ENV_BASE — blanking it would break far
|
||||
@@ -1144,7 +1144,7 @@ function restoreWorkstreamEnv() {
|
||||
*
|
||||
* SCOPE, stated because it is a real residual rather than an oversight: this is
|
||||
* one home per test-FILE process, not one per spawn. Two installer spawns in the
|
||||
* same file therefore share `.gsd` state, so a prior non-Claude install can be
|
||||
* same file therefore share `.msd` state, so a prior non-Claude install can be
|
||||
* observed by a later spawn. That is strictly better than the status quo it
|
||||
* replaces -- which shared the developer's REAL home, and all of its state --
|
||||
* and it closes the leak this helper exists for; it does not claim isolation
|
||||
@@ -1153,7 +1153,7 @@ function restoreWorkstreamEnv() {
|
||||
let installSpawnHomeDir = null;
|
||||
function installSpawnHome() {
|
||||
if (installSpawnHomeDir === null) {
|
||||
installSpawnHomeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-install-home-'));
|
||||
installSpawnHomeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-install-home-'));
|
||||
process.on('exit', () => {
|
||||
try { fs.rmSync(installSpawnHomeDir, { recursive: true, force: true }); } catch { /* best effort */ }
|
||||
});
|
||||
@@ -1198,7 +1198,7 @@ function installSpawnEnv(overrides = {}) {
|
||||
* may declare a global `home` override that resolves from `os.homedir()` rather
|
||||
* than from the sandboxed configDir — codex's skills kind (`.agents`, ADR-1239 /
|
||||
* #2088) is the live case. Without this, such a call writes to, and prunes
|
||||
* `gsd-*` entries from, the developer's REAL ~/.agents/skills.
|
||||
* `msd-*` entries from, the developer's REAL ~/.agents/skills.
|
||||
*
|
||||
* Promoted here from the identical private copies in executed-plan.test.cjs and
|
||||
* install-runtime-artifacts.test.cjs so new in-process callers have one obvious
|
||||
@@ -1213,12 +1213,12 @@ function installSpawnEnv(overrides = {}) {
|
||||
*/
|
||||
// #3712: the marker NAME is a constant, duplicated here deliberately rather than
|
||||
// required from the compiled guard. helpers.cjs is imported by ~370 test files and
|
||||
// documents (see builtLib above) that it must NOT load gsd-core/bin/lib at module
|
||||
// documents (see builtLib above) that it must NOT load msd-core/bin/lib at module
|
||||
// scope — an unbuilt tree would then fail on import alone, turning a missing
|
||||
// `npm run build:lib` into a whole-suite crash. A lazy require inside sandboxHome
|
||||
// would satisfy that too, but a bare string needs no build at all. The pairing is
|
||||
// pinned by a test so the two cannot drift.
|
||||
const TEST_HOME_SANDBOX_MARKER = 'GSD_TEST_HOME_SANDBOX';
|
||||
const TEST_HOME_SANDBOX_MARKER = 'MSD_TEST_HOME_SANDBOX';
|
||||
|
||||
function sandboxHome(t, dir) {
|
||||
const savedHome = process.env.HOME;
|
||||
@@ -1245,15 +1245,15 @@ function sandboxHome(t, dir) {
|
||||
function writePackageSourceMarkerFixture(configDir) {
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(configDir, '.gsd-source'),
|
||||
path.join(__dirname, '..', 'commands', 'gsd') + '\n',
|
||||
path.join(configDir, '.msd-source'),
|
||||
path.join(__dirname, '..', 'commands', 'msd') + '\n',
|
||||
);
|
||||
return configDir;
|
||||
}
|
||||
|
||||
/** Write one valid third-party gate into a synthetic user capability home. */
|
||||
function writeAmbientCapabilityGate(home, id, point) {
|
||||
const capDir = path.join(home, '.gsd', 'capabilities', id);
|
||||
const capDir = path.join(home, '.msd', 'capabilities', id);
|
||||
fs.mkdirSync(capDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(capDir, 'capability.json'), JSON.stringify({
|
||||
id,
|
||||
@@ -1262,7 +1262,7 @@ function writeAmbientCapabilityGate(home, id, point) {
|
||||
role: 'feature',
|
||||
tier: 'full',
|
||||
description: 'Capability outside the test fixture that must remain invisible.',
|
||||
engines: { gsd: '>=1.7.0' },
|
||||
engines: { msd: '>=1.7.0' },
|
||||
requires: [],
|
||||
runtimeCompat: { supported: ['claude'], unsupported: [] },
|
||||
skills: [],
|
||||
@@ -1294,7 +1294,7 @@ function withAmbientCapabilityHome(t, prefix, id, point) {
|
||||
return home;
|
||||
}
|
||||
|
||||
module.exports = { runGsdTools, createTempDir, createTempProject, createTempGitProject, cleanup, tmpRootCandidates, readFileNormalized, readWorkflowCombined, parseFrontmatter, isUsageOutput, captureConsole, toPosixPath, absPlanningPath, runNpm, isolatedNpmEnv, withIsolatedProcessState, delay, waitFor, resetRuntimeWarningCaches, SESSION_ENV_KEYS, saveSessionEnv, restoreSessionEnv, clearSessionEnv, isolateWorkstreamEnv, restoreWorkstreamEnv, TOOLS_PATH, SESSION_IDENTITY_ENV_KEYS, scrubConfigLocationEnv, installSpawnEnv, installSpawnHome, sandboxHome, writePackageSourceMarkerFixture, writeAmbientCapabilityGate, withAmbientCapabilityHome, TEST_HOME_SANDBOX_MARKER, mockPartialWriteThenThrow, captureFdSync, suppressFdAsync };
|
||||
module.exports = { runMsdTools, createTempDir, createTempProject, createTempGitProject, cleanup, tmpRootCandidates, readFileNormalized, readWorkflowCombined, parseFrontmatter, isUsageOutput, captureConsole, toPosixPath, absPlanningPath, runNpm, isolatedNpmEnv, withIsolatedProcessState, delay, waitFor, resetRuntimeWarningCaches, SESSION_ENV_KEYS, saveSessionEnv, restoreSessionEnv, clearSessionEnv, isolateWorkstreamEnv, restoreWorkstreamEnv, TOOLS_PATH, SESSION_IDENTITY_ENV_KEYS, scrubConfigLocationEnv, installSpawnEnv, installSpawnHome, sandboxHome, writePackageSourceMarkerFixture, writeAmbientCapabilityGate, withAmbientCapabilityHome, TEST_HOME_SANDBOX_MARKER, mockPartialWriteThenThrow, captureFdSync, suppressFdAsync };
|
||||
|
||||
// Lazy, for the reason builtLib() is lazy: reading either of these is what
|
||||
// forces the built-lib require, so a test file that needs neither can still
|
||||
|
||||
Reference in New Issue
Block a user