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:
@@ -40,7 +40,7 @@ const {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import runtimeArtifactConversion = require('./runtime-artifact-conversion.cjs');
|
||||
const conversionExports = runtimeArtifactConversion as Record<string, unknown> & {
|
||||
readGsdCommandNames?: () => string[];
|
||||
readMsdCommandNames?: () => string[];
|
||||
};
|
||||
// #2875 Part 2 (J8): shared model-override precedence resolver — see its
|
||||
// module doc for why kilo/opencode MUST resolve through this ONE function
|
||||
@@ -219,7 +219,7 @@ function installedManifestIsComplete(
|
||||
// observed here. Same-user mutation after resolution is outside #4132's
|
||||
// threat model and would require a broader snapshot/transaction design.
|
||||
const io = installFs();
|
||||
const manifestPath = path.join(runtimeConfigDir, 'gsd-file-manifest.json');
|
||||
const manifestPath = path.join(runtimeConfigDir, 'msd-file-manifest.json');
|
||||
if (!io.existsSync(manifestPath)) return false;
|
||||
if (!isPhysicallyConfinedTo(runtimeConfigDir, manifestPath)) return false;
|
||||
|
||||
@@ -228,8 +228,8 @@ function installedManifestIsComplete(
|
||||
if (manifest.manifestVersion === null) return false;
|
||||
const keys = Object.keys(manifest.files);
|
||||
const prefixes: string[] = [];
|
||||
if (required.has('commands')) prefixes.push('gsd-core/commands/gsd/');
|
||||
if (required.has('agents')) prefixes.push('gsd-core/agents/');
|
||||
if (required.has('commands')) prefixes.push('msd-core/commands/msd/');
|
||||
if (required.has('agents')) prefixes.push('msd-core/agents/');
|
||||
|
||||
for (const prefix of prefixes) {
|
||||
const expected = keys.filter((key) => key.startsWith(prefix));
|
||||
@@ -328,7 +328,7 @@ function providersShareRequiredRoots(
|
||||
}
|
||||
|
||||
function markerProvider(runtimeConfigDir: string): RuntimeSurfaceSourceProvider | null {
|
||||
const markerPath = path.join(runtimeConfigDir, '.gsd-source');
|
||||
const markerPath = path.join(runtimeConfigDir, '.msd-source');
|
||||
try {
|
||||
if (!installFs().existsSync(markerPath)) return null;
|
||||
const markerStat = installFs().lstatSync(markerPath);
|
||||
@@ -359,7 +359,7 @@ function packageProvider(required: ReadonlySet<RuntimeSurfaceSourceClass>): Runt
|
||||
for (let i = 0; i < 6; i++) {
|
||||
const candidate: RuntimeSurfaceSourceProvider = {
|
||||
kind: 'package',
|
||||
commandsRoot: path.join(dir, 'commands', 'gsd'),
|
||||
commandsRoot: path.join(dir, 'commands', 'msd'),
|
||||
agentsRoot: path.join(dir, 'agents'),
|
||||
};
|
||||
if (providerHasRequiredClasses(candidate, required, false)) return candidate;
|
||||
@@ -390,8 +390,8 @@ function resolveSourceProvider(
|
||||
if (runtimeConfigDir && scope === 'global') {
|
||||
const installed: RuntimeSurfaceSourceProvider = {
|
||||
kind: 'installed',
|
||||
commandsRoot: path.join(runtimeConfigDir, 'gsd-core', 'commands', 'gsd'),
|
||||
agentsRoot: path.join(runtimeConfigDir, 'gsd-core', 'agents'),
|
||||
commandsRoot: path.join(runtimeConfigDir, 'msd-core', 'commands', 'msd'),
|
||||
agentsRoot: path.join(runtimeConfigDir, 'msd-core', 'agents'),
|
||||
};
|
||||
if (providerHasRequiredClasses(installed, required, true, runtimeConfigDir)) return installed;
|
||||
rejectedInstalled = installed;
|
||||
@@ -417,7 +417,7 @@ function resolveSourceProvider(
|
||||
|
||||
throw new Error(
|
||||
`Runtime Surface source is unavailable or incomplete for ${[...required].sort().join('+')}; ` +
|
||||
'install or upgrade gsd-core before materializing this surface.',
|
||||
'install or upgrade msd-core before materializing this surface.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ function agentsKind(destSubpath: string, prefix: string, configDir: string, sour
|
||||
prefix,
|
||||
// #2995: a `converter: null` agents entry (claude local, zcode) previously
|
||||
// staged via stageAgentsForProfile — a RAW byte copy that never reads content
|
||||
// into JS, so gsd:section markers shipped verbatim. Route through the
|
||||
// into JS, so msd:section markers shipped verbatim. Route through the
|
||||
// composing stager with an identity converter instead: same output as the raw
|
||||
// copy for an unmarked agent, markers stripped for a marked one. Routing both
|
||||
// agent kinds through the stager collapses what were five independent agent
|
||||
@@ -494,7 +494,7 @@ function agentsKind(destSubpath: string, prefix: string, configDir: string, sour
|
||||
* or malformed descriptor naming an Object-prototype member (`"constructor"`,
|
||||
* `"toString"`, `"hasOwnProperty"`, ...) resolves to that member instead of
|
||||
* throwing, producing garbage staged content rather than a loud failure —
|
||||
* pre-existing, but promoted from the `/gsd-surface`-only path to the real
|
||||
* pre-existing, but promoted from the `/msd-surface`-only path to the real
|
||||
* install path for seven runtimes by #2875 Part 2's agents-bypass closure.
|
||||
* Required lazily (call-time, not module-top) to avoid a load-time circular
|
||||
* require, the same pattern install-engine.cts's `_hostBehaviors` already
|
||||
@@ -531,7 +531,7 @@ function _resolveNamedConverter(converterName: string, kindLabel: string): (...a
|
||||
* during staging, writing flat `${name}.md` files to the staged directory.
|
||||
*
|
||||
* Agent filenames are preserved verbatim (the prefix is already embedded in the
|
||||
* agent stem — e.g. `gsd-planner.md`).
|
||||
* agent stem — e.g. `msd-planner.md`).
|
||||
*
|
||||
* #1173 SCOPE, updated by #2875 Part 2 (the agents-bypass closure) — measured
|
||||
* against the tree, not the ADR-3574 framing that preceded it:
|
||||
@@ -544,8 +544,8 @@ function _resolveNamedConverter(converterName: string, kindLabel: string): (...a
|
||||
* `hostBehaviors.agentFileExtension`), the cross-cutting path-prefix rewrite +
|
||||
* attribution (`stageAgentsForRuntimeWithConverter` already applies
|
||||
* `applyAgentPathRewrites` -> `processAttribution` when `agentCtx` is
|
||||
* present), and stale-file cleanup (`_removeGsdEntries` prunes every
|
||||
* `gsd-`-prefixed entry in a kind's destSubpath, broader than the loop's own
|
||||
* present), and stale-file cleanup (`_removeMsdEntries` prunes every
|
||||
* `msd-`-prefixed entry in a kind's destSubpath, broader than the loop's own
|
||||
* extension-gated check).
|
||||
*
|
||||
* The fourth — config-reading steps — was the real gap, and #2875 Part 2
|
||||
@@ -588,7 +588,7 @@ function _resolveNamedConverter(converterName: string, kindLabel: string): (...a
|
||||
* added at claude-local's own call site to cover that scope too — the
|
||||
* install-tree golden fixture (`tests/fixtures/install-tree/claude-local.json`)
|
||||
* is what caught the gap when it was first missed.
|
||||
* 2. **`/gsd:surface` / `applySurface` activation.** Confirmed convergent,
|
||||
* 2. **`/msd:surface` / `applySurface` activation.** Confirmed convergent,
|
||||
* not merely non-broken: for all six runtimes (claude, cline, codex,
|
||||
* hermes, kilo, opencode), staging via `applySurface` into a freshly
|
||||
* wiped `agents/` directory produces byte-identical output (including
|
||||
@@ -602,7 +602,7 @@ function _resolveNamedConverter(converterName: string, kindLabel: string): (...a
|
||||
* (it fell through the inline loop's generic `else if` branch, same as
|
||||
* claude, with no dedicated dialect arm — caught by the same golden fixture).
|
||||
*
|
||||
* Codex's `config.toml [agents.gsd-*]` strip (`bin/install.js`, under
|
||||
* Codex's `config.toml [agents.msd-*]` strip (`bin/install.js`, under
|
||||
* `isMinimalMode` + `hostBehaviors.tomlConfigInstall`) remains the one
|
||||
* genuinely out-of-scope constraint: it mutates a host config file, not the
|
||||
* agents directory, and no descriptor kind models host-config mutation. It
|
||||
@@ -613,7 +613,7 @@ function _resolveNamedConverter(converterName: string, kindLabel: string): (...a
|
||||
* @param destSubpath destination subpath within configDir (e.g. 'agents')
|
||||
* @param prefix filename prefix (informational; not applied here)
|
||||
* @param converterName name of converter function in Runtime Artifact Conversion exports
|
||||
* @param configDir runtime config dir (for .gsd-source marker resolution)
|
||||
* @param configDir runtime config dir (for .msd-source marker resolution)
|
||||
*/
|
||||
function convertedAgentsKind(
|
||||
destSubpath: string,
|
||||
@@ -649,8 +649,8 @@ function convertedAgentsKind(
|
||||
let converter: (content: string, isGlobal?: boolean, meta?: { agentName: string }) => string;
|
||||
if (needsModelOverride) {
|
||||
const overrideTargetDir = agentCtx?.targetDir ?? configDir;
|
||||
const modelOverrides = installModelOverrideResolver.readGsdEffectiveModelOverrides(overrideTargetDir);
|
||||
const runtimeResolver = installModelOverrideResolver.readGsdRuntimeProfileResolver(overrideTargetDir);
|
||||
const modelOverrides = installModelOverrideResolver.readMsdEffectiveModelOverrides(overrideTargetDir);
|
||||
const runtimeResolver = installModelOverrideResolver.readMsdRuntimeProfileResolver(overrideTargetDir);
|
||||
// #3706: the resolved reasoning effort, threaded exactly as the model is —
|
||||
// config read ONCE per stage(), per-agent value resolved per file.
|
||||
//
|
||||
@@ -660,14 +660,14 @@ function convertedAgentsKind(
|
||||
// resolution yields no value" has no trigger and would stamp `variant:`
|
||||
// into every generated agent file for every existing install. OpenCode's
|
||||
// built-in variant sets are provider-specific upstream (Anthropic ships
|
||||
// only `high`/`max`), so a level GSD resolved is not guaranteed to name a
|
||||
// only `high`/`max`), so a level MSD resolved is not guaranteed to name a
|
||||
// variant the user's provider actually has — emitting one unasked-for is
|
||||
// the risk this gate avoids. #1156's rule for `model: inherit` is the
|
||||
// precedent: do not emit a key the runtime may not understand.
|
||||
//
|
||||
// OpenCode only; the kilo converter ignores the field (no EFFORT_ARGV.kilo).
|
||||
const effortConfig = converterName === 'convertClaudeToOpencodeFrontmatter'
|
||||
? installEffortResolver.readGsdEffectiveEffortConfig(overrideTargetDir)
|
||||
? installEffortResolver.readMsdEffectiveEffortConfig(overrideTargetDir)
|
||||
: null;
|
||||
converter = (content, _isGlobal, meta) => {
|
||||
const modelOverride = meta
|
||||
@@ -741,12 +741,12 @@ function kimiAgentsKind(destSubpath: string, prefix: string, configDir: string,
|
||||
}
|
||||
}
|
||||
|
||||
const rootAgent = `---\nname: gsd\ndescription: Run GSD workflows in Kimi CLI.\ntools: Agent\n---\n\n# GSD for Kimi CLI\n\nCoordinate installed /skill:gsd-* workflows and route work to generated GSD subagents when a workflow requires an agent handoff.\n`;
|
||||
const rootAgent = `---\nname: msd\ndescription: Run MSD workflows in Kimi CLI.\ntools: Agent\n---\n\n# MSD for Kimi CLI\n\nCoordinate installed /skill:msd-* workflows and route work to generated MSD subagents when a workflow requires an agent handoff.\n`;
|
||||
const artifacts = buildKimiAgentArtifacts({ rootAgent, subagents });
|
||||
const stageDir = mkInstallTempDir('gsd-kimi-agents-');
|
||||
const stageDir = mkInstallTempDir('msd-kimi-agents-');
|
||||
installProfiles.STAGED_DIRS.add(stageDir);
|
||||
installFs().writeFileSync(path.join(stageDir, 'gsd.yaml'), artifacts.root.yaml);
|
||||
installFs().writeFileSync(path.join(stageDir, 'gsd.md'), artifacts.root.prompt);
|
||||
installFs().writeFileSync(path.join(stageDir, 'msd.yaml'), artifacts.root.yaml);
|
||||
installFs().writeFileSync(path.join(stageDir, 'msd.md'), artifacts.root.prompt);
|
||||
const subagentsDir = path.join(stageDir, 'subagents');
|
||||
installFs().mkdirSync(subagentsDir, { recursive: true });
|
||||
for (const artifact of artifacts.subagents) {
|
||||
@@ -765,7 +765,7 @@ function kimiAgentsKind(destSubpath: string, prefix: string, configDir: string,
|
||||
* @param prefix
|
||||
* @param converterName name of converter function in Runtime Artifact Conversion exports
|
||||
* @param runtime canonical runtime ID (gates Hermes/Qwen branding in converter)
|
||||
* @param configDir runtime config dir (for .gsd-source marker resolution)
|
||||
* @param configDir runtime config dir (for .msd-source marker resolution)
|
||||
* @param nested if true, nest concrete skills under their ns-* routers (#69)
|
||||
* @param scope install scope; converted to isGlobal and passed as 5th positional
|
||||
* arg so scope-aware converters (antigravity, copilot) can choose
|
||||
@@ -800,8 +800,8 @@ function skillsKind(
|
||||
// `runtime` for the claude/kimi/cline converters, so the scope-aware
|
||||
// converters (antigravity, copilot) read isGlobal from position 5 to avoid
|
||||
// colliding with `runtime` and always taking the global branch.
|
||||
const cmdNames = conversionExports.readGsdCommandNames
|
||||
? conversionExports.readGsdCommandNames()
|
||||
const cmdNames = conversionExports.readMsdCommandNames
|
||||
? conversionExports.readMsdCommandNames()
|
||||
: [];
|
||||
// #2870: same judgment as convertedAgentsKind above — `scope` is this
|
||||
// function's own parameter (default `'global'`, so it is never
|
||||
@@ -837,9 +837,9 @@ function skillsKind(
|
||||
* handles prefix logic via the existing layout machinery.
|
||||
*
|
||||
* @param destSubpath destination subpath within configDir (e.g. 'commands')
|
||||
* @param prefix filename prefix, e.g. 'gsd-'
|
||||
* @param prefix filename prefix, e.g. 'msd-'
|
||||
* @param converterName name of converter function in Runtime Artifact Conversion exports
|
||||
* @param configDir runtime config dir (for .gsd-source marker resolution)
|
||||
* @param configDir runtime config dir (for .msd-source marker resolution)
|
||||
*/
|
||||
function convertedCommandsKind(
|
||||
destSubpath: string,
|
||||
@@ -895,7 +895,7 @@ function convertedCommandsKind(
|
||||
// claude — https://code.claude.com/docs/en/skills + anthropics/claude-code#28266
|
||||
// (one-level scan under ~/.claude/skills — but Skill-tool errors on unknown
|
||||
// names rather than re-routing via the router; concrete skills must be
|
||||
// at the top level so Skill(skill="gsd-plan-phase") succeeds)
|
||||
// at the top level so Skill(skill="msd-plan-phase") succeeds)
|
||||
//
|
||||
// FLAT (nested-scan behaviour unconfirmed → conservative):
|
||||
// codex — developers.openai.com/codex/skills/
|
||||
@@ -1058,15 +1058,15 @@ function resolveRuntimeArtifactLayoutFromRegistry(
|
||||
// Widens this module from PLACEMENT (resolveRuntimeArtifactLayout, above —
|
||||
// untouched, still 7 callers) to TRIGGER resolution: "what does a user type"
|
||||
// rather than "where does a file land". A new function, not a widened
|
||||
// signature — see .gsd/phase/feat-2871-trigger-resolution/40-design.md.
|
||||
// signature — see .msd/phase/feat-2871-trigger-resolution/40-design.md.
|
||||
//
|
||||
// Only `commands` and `skills` are trigger-bearing. `agents` / `kimi-agents`
|
||||
// are a SEPARATE dispatch interface point (subagent invocation via
|
||||
// `subagent_type` / named dispatch, never a `/gsd-<name>` a user types) — see
|
||||
// `subagent_type` / named dispatch, never a `/msd-<name>` a user types) — see
|
||||
// 40-design.md's "agents are not trigger-bearing" correction to ADR-2866.
|
||||
// Excluding them here is deliberate, not an oversight: including `agents`
|
||||
// would misreport windsurf (whose global scope emits agents only) as fully
|
||||
// shadowing its local `/gsd-*` surface, when in fact nothing shadows it.
|
||||
// shadowing its local `/msd-*` surface, when in fact nothing shadows it.
|
||||
|
||||
/** The trigger-bearing subset of ArtifactKindName — mirrors
|
||||
* VALID_TRIGGER_PRECEDENCE_KINDS in capability-validator.cjs (kept as two
|
||||
@@ -1094,7 +1094,7 @@ interface TriggerShadower {
|
||||
}
|
||||
|
||||
interface TriggerSurface {
|
||||
/** What the user types, e.g. `gsd-plan-phase`. Always `${prefix}${stem}` —
|
||||
/** What the user types, e.g. `msd-plan-phase`. Always `${prefix}${stem}` —
|
||||
* unaffected by the destPath branch below (see `destPath`). */
|
||||
trigger: string;
|
||||
kind: TriggerKindName;
|
||||
@@ -1172,8 +1172,8 @@ function getDefaultTriggerPrecedence(): string[] {
|
||||
/**
|
||||
* True when a `commands` kind entry is namespaced by its destination
|
||||
* directory rather than by a filename prefix — i.e. `destSubpath`'s basename
|
||||
* equals `prefix` with its trailing hyphen stripped (e.g. `commands/gsd` +
|
||||
* `gsd-`). When true, `_copyStaged` (`install-engine.cts`) and `surface.cts`
|
||||
* equals `prefix` with its trailing hyphen stripped (e.g. `commands/msd` +
|
||||
* `msd-`). When true, `_copyStaged` (`install-engine.cts`) and `surface.cts`
|
||||
* both write the bare stem filename (no prefix) because the directory itself
|
||||
* already carries the namespace; `resolveTriggerSurface` mirrors that in its
|
||||
* own `destPath` computation. Single source of truth for the three sites
|
||||
@@ -1229,7 +1229,7 @@ function isHigherPriority(a: TriggerSurface, b: TriggerSurface, precedenceRank:
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the `/gsd-<name>`-style trigger surface for a runtime: what the
|
||||
* Resolve the `/msd-<name>`-style trigger surface for a runtime: what the
|
||||
* user types, at which scope, whether it wins or is shadowed, and (for
|
||||
* nested-router runtimes) whether the host registers it directly or only
|
||||
* reaches it through a router. Pure — no filesystem, no mutation of `scopes`
|
||||
|
||||
Reference in New Issue
Block a user