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

@@ -3705,29 +3705,6 @@ describe('ADR-1016 phase 5a: sample axis value assertions', () => {
assert.ok(rt.configHome.probe.length > 0, 'antigravity.configHome.probe must be non-empty');
});
test('kilo: configHome.skillsHome is present', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const rt = registry.runtimes['kilo'].runtime;
assert.ok(rt.configHome.skillsHome, 'kilo.configHome.skillsHome must be present');
assert.ok(typeof rt.configHome.skillsHome.kind === 'string', 'kilo.configHome.skillsHome.kind must be a string');
});
test('windsurf: configHome.kind === dot-home-nested with parent .codeium', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const rt = registry.runtimes['windsurf'].runtime;
assert.strictEqual(rt.configHome.kind, 'dot-home-nested', 'windsurf.configHome.kind must be "dot-home-nested"');
assert.strictEqual(rt.configHome.parent, '.codeium', 'windsurf.configHome.parent must be ".codeium"');
});
test('kimi: configHome.kind === generic-agents-root', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const rt = registry.runtimes['kimi'].runtime;
assert.strictEqual(rt.configHome.kind, 'generic-agents-root', 'kimi.configHome.kind must be "generic-agents-root"');
});
test('antigravity: hookEvents === gemini', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
@@ -3754,73 +3731,6 @@ describe('ADR-1016 phase 5a: sample axis value assertions', () => {
'opencode declares the extension-system event subset via extensionEvents (NOT hookEvents)');
});
test('kilo: hooksSurface === none, no hookEvents (registers zero lifecycle hooks)', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const rt = registry.runtimes['kilo'].runtime;
assert.strictEqual(rt.hooksSurface, 'none', 'kilo.hooksSurface must be "none" (no managed lifecycle hooks)');
assert.ok(
!Object.prototype.hasOwnProperty.call(rt, 'hookEvents'),
'kilo.runtime must NOT have hookEvents (no lifecycle hook registration)',
);
});
test('kimi: configHome.probeExists === "skills" (probe selects first candidate with skills/ dir)', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const rt = registry.runtimes['kimi'].runtime;
assert.strictEqual(
rt.configHome.probeExists, 'skills',
'kimi.configHome.probeExists must be "skills" (selects first probe candidate where <candidate>/skills exists)',
);
});
test('copilot/trae/windsurf/cline/opencode/kilo: hooksSurface none or copilot-inline/cline-rules, no hookEvents', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
// opencode and kilo register ZERO lifecycle hooks → hooksSurface none, no hookEvents
// #2095: kimi moved OUT of this group — it now has hooksSurface:'kimi-hooks-toml'
// and hookEvents:'claude' (see the dedicated kimi hooksSurface test below).
const noEventsRuntimes = ['trae', 'windsurf', 'opencode', 'kilo'];
for (const id of noEventsRuntimes) {
const rt = registry.runtimes[id].runtime;
assert.ok(
!Object.prototype.hasOwnProperty.call(rt, 'hookEvents'),
id + '.runtime must NOT have hookEvents (no hook events for this runtime)',
);
}
// cline has cline-rules surface but no hookEvents
const clineRt = registry.runtimes['cline'].runtime;
assert.strictEqual(clineRt.hooksSurface, 'cline-rules', 'cline.hooksSurface must be "cline-rules"');
assert.ok(
!Object.prototype.hasOwnProperty.call(clineRt, 'hookEvents'),
'cline.runtime must NOT have hookEvents',
);
// copilot has copilot-inline surface but no hookEvents
const copilotRt = registry.runtimes['copilot'].runtime;
assert.strictEqual(copilotRt.hooksSurface, 'copilot-inline', 'copilot.hooksSurface must be "copilot-inline"');
assert.ok(
!Object.prototype.hasOwnProperty.call(copilotRt, 'hookEvents'),
'copilot.runtime must NOT have hookEvents',
);
});
test('kimi: hooksSurface === kimi-hooks-toml, hookEvents === claude, extendedHookEvents wired (#2095)', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const kimiRt = registry.runtimes['kimi'].runtime;
assert.strictEqual(kimiRt.hooksSurface, 'kimi-hooks-toml', 'kimi.hooksSurface must be "kimi-hooks-toml"');
assert.strictEqual(kimiRt.hookEvents, 'claude', 'kimi.hookEvents must be "claude" (Kimi\'s 13 lifecycle events include exact-name equivalents for the Claude dialect)');
assert.deepStrictEqual(
[...kimiRt.extendedHookEvents].sort(),
['PreCompact', 'Stop', 'SubagentStart', 'SubagentStop'].sort(),
'kimi.extendedHookEvents must wire SubagentStop/Stop/PreCompact/SubagentStart',
);
// installSurface stays profile-marker-only — the native config.toml
// [[hooks]] write is independent of the artifact-install surface (#2095).
assert.strictEqual(kimiRt.installSurface, 'profile-marker-only', 'kimi.installSurface must remain "profile-marker-only"');
});
test('codex: hooksSurface === codex-hooks-json, cursor: hooksSurface === cursor-hooks-json', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
@@ -3841,10 +3751,10 @@ describe('ADR-1016 phase 5a: sample axis value assertions', () => {
}
});
test('tier-2 runtimes: cursor through windsurf have supportTier === 2', () => {
test('tier-2 runtimes: cursor and opencode have supportTier === 2', () => {
const { capMap } = loadAndValidate(new Set());
const registry = buildRegistry(capMap);
const tier2 = ['cursor', 'opencode', 'kilo', 'copilot', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'kimi', 'windsurf'];
const tier2 = ['cursor', 'opencode'];
for (const id of tier2) {
assert.strictEqual(
registry.runtimes[id].runtime.supportTier, 2,
@@ -4076,14 +3986,6 @@ describe('ADR-1016 phase 5a: validateArtifactLayout unit tests', () => {
assert.ok(errors.some((e) => e.includes('nesting')));
});
test('kimi-agents kind → no errors', () => {
const errors = validateArtifactLayout('test', {
global: [{ kind: 'kimi-agents', destSubpath: 'agents', prefix: 'msd', nesting: 'flat', recursive: false, converter: null }],
local: [],
});
assert.deepEqual(errors, []);
});
test('#2777: home override is accepted globally and rejected locally', () => {
const entry = {
kind: 'skills',
@@ -4178,18 +4080,6 @@ describe('FIX 3: tightened runtime validator — skillsHome recursive validation
'Expected skillsHome.env required error, got: ' + JSON.stringify(errors),
);
});
test('kilo descriptor: skillsHome passes full validation', () => {
// kilo has skillsHome: { kind: "dot-home", name: ".kilo", env: [] } — must pass
const { capMap, errors } = loadAndValidate(new Set());
const hardErrors = errors.filter((e) => !e.includes('pending-migration'));
assert.deepEqual(hardErrors, [], 'No hard errors expected for kilo, got: ' + JSON.stringify(hardErrors));
const kiloRt = capMap.get('kilo');
assert.ok(kiloRt, 'kilo must be in capMap');
assert.ok(kiloRt.runtime.configHome.skillsHome, 'kilo.configHome.skillsHome must be present');
assert.strictEqual(kiloRt.runtime.configHome.skillsHome.kind, 'dot-home');
assert.strictEqual(kiloRt.runtime.configHome.skillsHome.name, '.kilo');
});
});
describe('FIX 3: tightened runtime validator — ArtifactKind field type checks', () => {
@@ -4352,12 +4242,12 @@ describe('ADR-1016 phase 5a: closed-vocab set exports', () => {
assert.strictEqual(VALID_COMMAND_STYLES.size, 2);
});
test('VALID_HOOKS_SURFACES has exactly 8 values', () => {
test('VALID_HOOKS_SURFACES has exactly 4 values', () => {
assert.ok(VALID_HOOKS_SURFACES instanceof Set);
for (const v of ['settings-json', 'codex-hooks-json', 'cursor-hooks-json', 'copilot-inline', 'cline-rules', 'kimi-hooks-toml', 'windsurf-hooks-json', 'none']) {
for (const v of ['settings-json', 'codex-hooks-json', 'cursor-hooks-json', 'none']) {
assert.ok(VALID_HOOKS_SURFACES.has(v), 'VALID_HOOKS_SURFACES must contain "' + v + '"');
}
assert.strictEqual(VALID_HOOKS_SURFACES.size, 8);
assert.strictEqual(VALID_HOOKS_SURFACES.size, 4);
});
test('VALID_HOOK_EVENTS has exactly 2 managed-hook dialects (claude/gemini)', () => {
@@ -4370,12 +4260,12 @@ describe('ADR-1016 phase 5a: closed-vocab set exports', () => {
'opencode-subset is NOT a hookEvents value — it is the extensionEvents vocabulary (#1943)');
});
test('VALID_EXTENSION_EVENTS has the extension-system dialects (opencode/pi/hermes/kilo/none — #1943/#2091/#2093)', () => {
test('VALID_EXTENSION_EVENTS has the extension-system dialects (opencode/none — #1943)', () => {
assert.ok(VALID_EXTENSION_EVENTS instanceof Set);
for (const v of ['opencode', 'pi', 'hermes', 'kilo', 'none']) {
for (const v of ['opencode', 'none']) {
assert.ok(VALID_EXTENSION_EVENTS.has(v), 'VALID_EXTENSION_EVENTS must contain "' + v + '"');
}
assert.strictEqual(VALID_EXTENSION_EVENTS.size, 5);
assert.strictEqual(VALID_EXTENSION_EVENTS.size, 2);
});
test('VALID_SANDBOX_TIERS has exactly 2 values', () => {
@@ -4385,12 +4275,12 @@ describe('ADR-1016 phase 5a: closed-vocab set exports', () => {
assert.strictEqual(VALID_SANDBOX_TIERS.size, 2);
});
test('VALID_ARTIFACT_KIND_NAMES has exactly 4 values', () => {
test('VALID_ARTIFACT_KIND_NAMES has exactly 3 values', () => {
assert.ok(VALID_ARTIFACT_KIND_NAMES instanceof Set);
for (const v of ['commands', 'agents', 'skills', 'kimi-agents']) {
for (const v of ['commands', 'agents', 'skills']) {
assert.ok(VALID_ARTIFACT_KIND_NAMES.has(v), 'VALID_ARTIFACT_KIND_NAMES must contain "' + v + '"');
}
assert.strictEqual(VALID_ARTIFACT_KIND_NAMES.size, 4);
assert.strictEqual(VALID_ARTIFACT_KIND_NAMES.size, 3);
});
test('VALID_ARTIFACT_NESTINGS has exactly 2 values', () => {
@@ -4662,13 +4552,11 @@ describe('ADR-857 phase 5e: configFormat ↔ installSurface parity gate', () =>
});
// INSTALL_SURFACE_TO_CONFIG_FORMAT export check
test('INSTALL_SURFACE_TO_CONFIG_FORMAT covers all 7 installSurface values with correct mappings', () => {
test('INSTALL_SURFACE_TO_CONFIG_FORMAT covers all 5 installSurface values with correct mappings', () => {
assert.ok(INSTALL_SURFACE_TO_CONFIG_FORMAT instanceof Map, 'Must be a Map');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.size, 7, 'Must cover 7 installSurface values');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.size, 5, 'Must cover 5 installSurface values');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.get('settings-json'), 'settings-json');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.get('codex-toml'), 'toml');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.get('copilot-instructions'), 'markdown');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.get('cline-rules'), 'markdown-dir');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.get('cursor-hooks-json'), 'none');
assert.strictEqual(INSTALL_SURFACE_TO_CONFIG_FORMAT.get('profile-marker-only'), 'none');
// 'none' added #2103 — a runtime with no CLI install surface at all (e.g.
@@ -4898,9 +4786,9 @@ describe('ADR-857 phase 5f: cross-field consistency gate rejection tests (DEFECT
});
// Verify the new constants are well-formed
test('INSTALL_SURFACE_TO_ALLOWED_HOOKS_SURFACES covers all 7 installSurface values', () => {
test('INSTALL_SURFACE_TO_ALLOWED_HOOKS_SURFACES covers all 5 installSurface values', () => {
assert.ok(INSTALL_SURFACE_TO_ALLOWED_HOOKS_SURFACES instanceof Map, 'Must be a Map');
assert.strictEqual(INSTALL_SURFACE_TO_ALLOWED_HOOKS_SURFACES.size, 7, 'Must cover 7 installSurface values');
assert.strictEqual(INSTALL_SURFACE_TO_ALLOWED_HOOKS_SURFACES.size, 5, 'Must cover 5 installSurface values');
for (const installSurface of VALID_INSTALL_SURFACES) {
assert.ok(
INSTALL_SURFACE_TO_ALLOWED_HOOKS_SURFACES.has(installSurface),
@@ -4918,11 +4806,10 @@ describe('ADR-857 phase 5f: cross-field consistency gate rejection tests (DEFECT
}
});
test('VALID_PERMISSION_WRITERS covers exactly {opencode, kilo, antigravity}', () => {
test('VALID_PERMISSION_WRITERS covers exactly {opencode, antigravity}', () => {
assert.ok(VALID_PERMISSION_WRITERS instanceof Set, 'Must be a Set');
assert.strictEqual(VALID_PERMISSION_WRITERS.size, 3, 'Must cover 3 permission writers');
assert.strictEqual(VALID_PERMISSION_WRITERS.size, 2, 'Must cover 2 permission writers');
assert.ok(VALID_PERMISSION_WRITERS.has('opencode'), 'Must include opencode');
assert.ok(VALID_PERMISSION_WRITERS.has('kilo'), 'Must include kilo');
assert.ok(VALID_PERMISSION_WRITERS.has('antigravity'), 'Must include antigravity (#2096)');
});
@@ -7351,10 +7238,6 @@ describe('enh-1055 descriptor-drive: finishPermissionWriter passthrough', () =>
assert.strictEqual(resolveRuntimeConfigIntent('opencode').finishPermissionWriter, 'opencode');
});
test('kilo → "kilo" (descriptor permissionWriter)', () => {
assert.strictEqual(resolveRuntimeConfigIntent('kilo').finishPermissionWriter, 'kilo');
});
test('all other runtimes have finishPermissionWriter === null', () => {
const nullExpected = EXPECTED
.filter(r => r.finishPermissionWriter === null)