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:
@@ -169,14 +169,9 @@ describe('resolveTriggerSurface — claude', () => {
|
||||
|
||||
describe('resolveTriggerSurface — both-scope runtimes', () => {
|
||||
test('both-scope runtimes report same-kind shadowing', () => {
|
||||
// The 12 both-scope trigger-bearing runtimes excluding claude (claude has
|
||||
// its own dedicated rows above). windsurf is excluded too — its global
|
||||
// scope emits agents only, so it is NOT a both-scope trigger-bearing
|
||||
// runtime (see the dedicated windsurf test below).
|
||||
const BOTH_SCOPE_RUNTIMES = [
|
||||
'antigravity', 'augment', 'codebuddy', 'codex', 'copilot',
|
||||
'cursor', 'hermes', 'kilo', 'opencode', 'qwen', 'trae', 'zcode',
|
||||
];
|
||||
// The both-scope trigger-bearing runtimes excluding claude (claude has
|
||||
// its own dedicated rows above).
|
||||
const BOTH_SCOPE_RUNTIMES = ['antigravity', 'codex', 'cursor', 'opencode', 'zcode'];
|
||||
for (const runtime of BOTH_SCOPE_RUNTIMES) {
|
||||
const result = resolveTriggerSurface(runtime, ['global', 'local'], { stems: ['plan-phase'] });
|
||||
const group = result.filter((s) => s.trigger === 'msd-plan-phase');
|
||||
@@ -195,24 +190,9 @@ describe('resolveTriggerSurface — both-scope runtimes', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveTriggerSurface — global-only runtimes', () => {
|
||||
test('global-only runtimes report unshadowed triggers', () => {
|
||||
// cline/kimi/kimi-code declare local: [] — no special-casing, it falls
|
||||
// out of an empty local kind set even when 'local' is in `scopes`.
|
||||
for (const runtime of ['cline', 'kimi', 'kimi-code']) {
|
||||
const result = resolveTriggerSurface(runtime, ['global', 'local'], { stems: ['plan-phase'] });
|
||||
assert.ok(result.length > 0, `${runtime}: expected at least one trigger`);
|
||||
for (const s of result) {
|
||||
assert.strictEqual(s.scope, 'global', `${runtime}: unexpected non-global entry`);
|
||||
assert.strictEqual(s.shadowedBy, null, `${runtime}: global-only entry must be unshadowed`);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveTriggerSurface — no-artifact-surface runtimes', () => {
|
||||
test('runtimes with no artifact surface yield no triggers', () => {
|
||||
for (const runtime of ['pi', 'vscode']) {
|
||||
for (const runtime of ['vscode']) {
|
||||
assert.deepStrictEqual(
|
||||
resolveTriggerSurface(runtime, ['global', 'local'], { stems: ['plan-phase'] }), [],
|
||||
`${runtime}: expected no triggers`,
|
||||
@@ -221,21 +201,6 @@ describe('resolveTriggerSurface — no-artifact-surface runtimes', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveTriggerSurface — windsurf', () => {
|
||||
test('windsurf does not report a shadow it does not have', () => {
|
||||
// Global emits agents only (excluded) -> no global trigger. Local commands
|
||||
// (workflows) triggers must therefore be UNSHADOWED, not falsely reported
|
||||
// as shadowed by a global counterpart that doesn't exist.
|
||||
const result = resolveTriggerSurface('windsurf', ['global', 'local'], { stems: ['plan-phase'] });
|
||||
assert.strictEqual(result.length, 1, `expected exactly one trigger, got ${JSON.stringify(result)}`);
|
||||
const [entry] = result;
|
||||
assert.strictEqual(entry.trigger, 'msd-plan-phase');
|
||||
assert.strictEqual(entry.kind, 'commands');
|
||||
assert.strictEqual(entry.scope, 'local');
|
||||
assert.strictEqual(entry.shadowedBy, null, 'windsurf must not report a shadow it does not have');
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveTriggerSurface — agents exclusion', () => {
|
||||
test('agents are excluded from the trigger surface', () => {
|
||||
// claude local emits both commands and agents from the same source tree.
|
||||
@@ -244,17 +209,11 @@ describe('resolveTriggerSurface — agents exclusion', () => {
|
||||
assert.ok(result.some((s) => s.kind === 'commands'), 'commands must still be present');
|
||||
});
|
||||
|
||||
test('kimi-agents are excluded from the trigger surface', () => {
|
||||
const result = resolveTriggerSurface('kimi', ['global'], { stems: ['plan-phase'] });
|
||||
assert.ok(!result.some((s) => s.kind === 'kimi-agents'), 'kimi-agents must never appear in the trigger surface');
|
||||
assert.strictEqual(result.length, 1);
|
||||
assert.strictEqual(result[0].kind, 'skills');
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveTriggerSurface — nested-router runtimes (#69)', () => {
|
||||
test('nested runtimes distinguish direct from router-reachable registration', () => {
|
||||
const NESTED_ROUTER_RUNTIMES = ['cline', 'qwen', 'hermes', 'augment', 'trae'];
|
||||
const NESTED_ROUTER_RUNTIMES = ['zcode'];
|
||||
const opts = {
|
||||
stems: ['ns-plan', 'plan-phase'],
|
||||
routerStems: ['ns-plan'],
|
||||
@@ -462,20 +421,20 @@ describe('triggerPrecedence axis — validator', () => {
|
||||
|
||||
describe('triggerPrecedence axis — resolution', () => {
|
||||
test('reordering the axis changes which artifact wins', () => {
|
||||
// codebuddy declares BOTH commands and skills at the SAME scope from the
|
||||
// opencode declares BOTH commands and skills at the SAME scope from the
|
||||
// same source stems — the one runtime shape where kind precedence (not
|
||||
// scope rank) decides the winner.
|
||||
const defaultResult = resolveTriggerSurface('codebuddy', ['global'], { stems: ['plan-phase'] });
|
||||
const defaultResult = resolveTriggerSurface('opencode', ['global'], { stems: ['plan-phase'] });
|
||||
const defaultGroup = defaultResult.filter((s) => s.trigger === 'msd-plan-phase');
|
||||
const defaultWinner = defaultGroup.find((s) => s.shadowedBy === null);
|
||||
assert.ok(defaultWinner, 'expected a winner under the default precedence');
|
||||
assert.strictEqual(defaultWinner.kind, 'skills', 'default precedence (skills > commands) must pick skills');
|
||||
|
||||
const overriddenCap = JSON.parse(JSON.stringify(capabilityRegistry.runtimes.codebuddy));
|
||||
const overriddenCap = JSON.parse(JSON.stringify(capabilityRegistry.runtimes.opencode));
|
||||
overriddenCap.runtime.triggerPrecedence = ['commands', 'skills'];
|
||||
const overriddenRegistry = { runtimes: { codebuddy: overriddenCap } };
|
||||
const overriddenRegistry = { runtimes: { opencode: overriddenCap } };
|
||||
|
||||
const overriddenResult = resolveTriggerSurface('codebuddy', ['global'], { stems: ['plan-phase'], registry: overriddenRegistry });
|
||||
const overriddenResult = resolveTriggerSurface('opencode', ['global'], { stems: ['plan-phase'], registry: overriddenRegistry });
|
||||
const overriddenGroup = overriddenResult.filter((s) => s.trigger === 'msd-plan-phase');
|
||||
const overriddenWinner = overriddenGroup.find((s) => s.shadowedBy === null);
|
||||
assert.ok(overriddenWinner, 'expected a winner under the overridden precedence');
|
||||
|
||||
Reference in New Issue
Block a user