refactor: drop 12 runtimes, keep Claude, Codex, OpenCode, Cursor, ZCode, Antigravity

Removes kilo, kimi, kimi-code, copilot, windsurf, augment, trae, qwen, hermes,
cline, codebuddy and pi end to end: capability descriptors, installer branches
and converters (bin/install.js 14.9k -> 11.2k lines), TypeScript converters,
hook surfaces and runtime homes, review lanes qwen/kimi-code, the two pi
migrations, Kimi payload normalization in the hook guards, dead hostBehaviors
vocabulary, launcher home probes, fixtures, runtime-specific tests and the
prose that presented them as supported.

Installer output for the six kept runtimes is byte-identical to before the
prune. The Kimi tool-vocabulary tests in workflow-guard, read-guard and
read-injection-scanner are left in place pending a decision.
This commit is contained in:
Jakub Zych
2026-10-06 20:02:40 +02:00
parent 12ee75a509
commit 6cfa0c55d2
509 changed files with 1869 additions and 47737 deletions

View File

@@ -1,7 +1,7 @@
/**
* Stale-bake guard tests (#1688, follow-up to #1650).
*
* Regression contract: on a static-frontmatter runtime (codex/opencode/kilo), if
* Regression contract: on a static-frontmatter runtime (codex/opencode), if
* `.planning/config.json` or `~/.msd/defaults.json` was edited AFTER the
* installed agent files were baked, `warnIfStaleBake` MUST emit a single
* stderr warning naming the config path and the remediation command. Before
@@ -71,13 +71,6 @@ describe('stale-bake-guard.detectStaleBake (pure decision)', () => {
);
});
test('kilo runtime honored symmetrically with opencode/codex (#2093)', () => {
assert.deepEqual(
detectStaleBake({ runtime: 'kilo', configMtimeMs: AGENT_MS + 5000, agentMtimeMs: AGENT_MS }),
{ stale: true, deltaMs: 5000 },
);
});
test('non-finite mtimes rejected (NaN / Infinity)', () => {
assert.equal(detectStaleBake({ runtime: 'opencode', configMtimeMs: NaN, agentMtimeMs: AGENT_MS }), null);
assert.equal(detectStaleBake({ runtime: 'opencode', configMtimeMs: Infinity, agentMtimeMs: AGENT_MS }), null);
@@ -122,12 +115,6 @@ describe('stale-bake-guard.formatStaleBakeWarning (pure formatter)', () => {
assert.doesNotMatch(w, /--opencode/);
});
test('kilo warning uses --kilo flag (not --opencode/--codex) (#2093)', () => {
const w = formatStaleBakeWarning({ runtime: 'kilo', configPath: '/x', configMtimeMs: 1_700_000_000_000, agentMtimeMs: 1 });
assert.match(w, /msd install --kilo/);
assert.doesNotMatch(w, /--opencode/);
assert.doesNotMatch(w, /--codex\b/);
});
});
// ---------------------------------------------------------------------------
@@ -175,12 +162,6 @@ describe('stale-bake-guard.resolveAgentDir (env-var aware)', () => {
test('codex honors CODEX_HOME', () => {
assert.equal(posix(resolveAgentDir('codex', { env: { CODEX_HOME: '/custom/cx' }, homedir: () => '/H' })), '/custom/cx/agents');
});
test('kilo default lands under ~/.config/kilo/agents (#2093)', () => {
assert.equal(posix(resolveAgentDir('kilo', { env: {}, homedir: () => '/H' })), '/H/.config/kilo/agents');
});
test('kilo honors KILO_CONFIG_DIR (#2093)', () => {
assert.equal(posix(resolveAgentDir('kilo', { env: { KILO_CONFIG_DIR: '/custom/ko' }, homedir: () => '/H' })), '/custom/ko/agents');
});
test('unsupported runtime → null', () => {
assert.equal(resolveAgentDir('gemini', { env: {}, homedir: () => '/H' }), null);
});
@@ -236,9 +217,6 @@ describe('stale-bake-guard.warnIfStaleBake (orchestrator, fixtures)', () => {
function cxEnv(agentParentDir) {
return { CODEX_HOME: agentParentDir };
}
function koEnv(agentParentDir) {
return { KILO_CONFIG_DIR: agentParentDir };
}
test('claude runtime → no warning even when config is newer than agents', () => {
// OpenCode agent dir shape so the runtime path resolves, but runtime is claude.
@@ -271,28 +249,6 @@ describe('stale-bake-guard.warnIfStaleBake (orchestrator, fixtures)', () => {
assert.match(chunks[0], /msd install --codex/);
});
// #2093: kilo bakes model: like opencode (same static-frontmatter constraint).
test('kilo: config NEWER than agents → warning written with --kilo flag', () => {
const agentParent = path.join(tmpRoot, 'ko-config');
const agentDir = path.join(agentParent, 'agents');
setupProject({ runtime: 'kilo', configMtime: NEWER, agentDir, agentMtime: OLDER });
const wrote = warnIfStaleBake(tmpRoot, { stderr: stderrStub, homedir: () => tmpRoot, env: koEnv(agentParent) });
assert.equal(wrote, true);
assert.equal(chunks.length, 1);
assert.match(chunks[0], /model config in .*config\.json changed since agents were last baked/);
assert.match(chunks[0], /'kilo'/);
assert.match(chunks[0], /msd install --kilo/);
});
test('kilo: config OLDER than agents → no warning (boundary limit-1)', () => {
const agentParent = path.join(tmpRoot, 'ko-config');
const agentDir = path.join(agentParent, 'agents');
setupProject({ runtime: 'kilo', configMtime: OLDER, agentDir, agentMtime: NEWER });
const wrote = warnIfStaleBake(tmpRoot, { stderr: stderrStub, homedir: () => tmpRoot, env: koEnv(agentParent) });
assert.equal(wrote, false);
assert.deepEqual(chunks, []);
});
test('opencode: config OLDER than agents → no warning (boundary limit-1)', () => {
const agentParent = path.join(tmpRoot, 'oc-config');
const agentDir = path.join(agentParent, 'agents');
@@ -429,8 +385,8 @@ describe('stale-bake-guard parity with bin/install.js bake paths', () => {
return;
}
test('STATIC_FRONTMATTER_RUNTIMES is exactly codex + kilo + opencode (no silent drift)', () => {
assert.deepEqual([...STATIC_FRONTMATTER_RUNTIMES].sort(), ['codex', 'kilo', 'opencode']);
test('STATIC_FRONTMATTER_RUNTIMES is exactly codex + opencode (no silent drift)', () => {
assert.deepEqual([...STATIC_FRONTMATTER_RUNTIMES].sort(), ['codex', 'opencode']);
});
test('opencode converter bakes a model: line when modelOverride is provided', () => {
@@ -442,23 +398,6 @@ describe('stale-bake-guard parity with bin/install.js bake paths', () => {
);
});
// #2093: kilo bakes model: the same way opencode does (same static-frontmatter constraint).
test('kilo converter bakes a model: line when modelOverride is provided', () => {
const sample = '---\nname: msd-executor\ndescription: x\nmodel: sonnet\ntools: Read\n---\nbody\n';
const out = install.convertClaudeToKiloFrontmatter(sample, { isAgent: true, modelOverride: 'anthropic/claude-sonnet-5' });
assert.ok(
typeof out === 'string' && out.includes('model: anthropic/claude-sonnet-5'),
'kilo converter no longer bakes modelOverride — STATIC_FRONTMATTER_RUNTIMES is stale vs bin/install.js',
);
});
test('kilo converter omits model: when no override (stale-bake fallback shape)', () => {
const sample = '---\nname: msd-executor\ndescription: x\nmodel: sonnet\ntools: Read\n---\nbody\n';
const out = install.convertClaudeToKiloFrontmatter(sample, { isAgent: true });
assert.ok(typeof out === 'string', 'converter must return a string');
assert.doesNotMatch(out, /^model:/m, 'no-override path should not emit a model: line');
});
test('opencode converter omits model: when no override (stale-bake fallback shape)', () => {
const sample = '---\nname: msd-executor\ndescription: x\nmodel: sonnet\ntools: Read\n---\nbody\n';
const out = install.convertClaudeToOpencodeFrontmatter(sample, { isAgent: true });