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.
101 lines
4.6 KiB
JavaScript
101 lines
4.6 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* runtime-brand-swap-parity.test.cjs — DEFECT.GENERATIVE-FIX family parity
|
|
* guard for the #2284(b) protected-region fix.
|
|
*
|
|
* `applyClaudeCodeBrandSwap` (src/runtime-artifact-conversion.cts) rewrites
|
|
* bare "Claude Code" self-references to a runtime's brand name EXCEPT inside
|
|
* `<runtime_compatibility>...</runtime_compatibility>` blocks, which must
|
|
* survive byte-for-byte verbatim (a runtime-comparison table that says
|
|
* "Claude Code" is describing Claude Code's own behavior, not this
|
|
* runtime's — brand-swapping it mislabels the comparison). Every
|
|
* markdown/agent converter that performs a "Claude Code" -> brand swap needs
|
|
* the SAME fix (#2284b follow-up).
|
|
*
|
|
* A per-converter regression test would only catch a REintroduction in the
|
|
* converter it targets — the exact shape of divergence CONTEXT.md's
|
|
* DEFECT.GENERATIVE-FIX names. This file instead drives every brand-swapping
|
|
* converter through ONE assertion body from a declarative table, so a NEW
|
|
* runtime converter that skips `applyClaudeCodeBrandSwap` and reintroduces a
|
|
* naive `.replace(/\bClaude Code\b/g, brand)` fails the moment it is added
|
|
* to the table below — and the floor test catches an entry silently dropped
|
|
* from the table itself.
|
|
*/
|
|
|
|
process.env.MSD_TEST_MODE = '1';
|
|
|
|
const { describe, test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const conv = require('../msd-core/bin/lib/runtime-artifact-conversion.cjs');
|
|
|
|
/**
|
|
* Every runtime converter in src/runtime-artifact-conversion.cts that
|
|
* performs a "Claude Code" -> brand swap, normalized to a uniform
|
|
* `(content) => string` shape regardless of the underlying function's real
|
|
* signature.
|
|
*/
|
|
const BRAND_SWAP_CONVERTERS = [
|
|
{ name: 'cursor', brand: 'Cursor', convert: (content) => conv.convertClaudeToCursorMarkdown(content) },
|
|
];
|
|
|
|
// Floor, not an exact count (mirrors MINIMUM_MANIFEST_FAMILIES in
|
|
// tests/helpers/install-shared.cjs): the point of this table is that a NEW
|
|
// brand-swapping converter must be added here explicitly and reviewably.
|
|
// Lowering it is a deliberate act; this only guards it from silently
|
|
// shrinking underneath a refactor.
|
|
const MINIMUM_BRAND_SWAP_CONVERTER_COUNT = 1;
|
|
|
|
const PROTECTED_BLOCK =
|
|
'<runtime_compatibility>\n| Runtime | Claude Code | Other |\n|---|---|---|\n| x | Claude Code native | y |\n</runtime_compatibility>';
|
|
|
|
function buildFixture() {
|
|
return `Before: mentions Claude Code here.\n\n${PROTECTED_BLOCK}\n\nAfter: also mentions Claude Code here.\n`;
|
|
}
|
|
|
|
describe('everyRuntimeMarkdownConverterPreservesRuntimeCompatibilityBlocks', () => {
|
|
test('the brand-swap converter table has not silently shrunk below its floor', () => {
|
|
assert.ok(
|
|
BRAND_SWAP_CONVERTERS.length >= MINIMUM_BRAND_SWAP_CONVERTER_COUNT,
|
|
`expected at least ${MINIMUM_BRAND_SWAP_CONVERTER_COUNT} brand-swapping converters in the table, `
|
|
+ `got ${BRAND_SWAP_CONVERTERS.length}`,
|
|
);
|
|
});
|
|
|
|
for (const { name, brand, convert } of BRAND_SWAP_CONVERTERS) {
|
|
test(`${name}: <runtime_compatibility> block is preserved verbatim while outside text is brand-swapped`, () => {
|
|
// Guard the table entry itself before trusting the assertions below —
|
|
// an undefined brand (a descriptor lookup that silently returned
|
|
// nothing) would make every `includes()` check below vacuously
|
|
// meaningless.
|
|
assert.strictEqual(typeof brand, 'string', `${name}: table entry must declare a string brand`);
|
|
assert.ok(brand.length > 0, `${name}: table entry brand must be non-empty`);
|
|
|
|
const result = convert(buildFixture());
|
|
|
|
assert.ok(
|
|
result.includes(PROTECTED_BLOCK),
|
|
`${name}: <runtime_compatibility> block must survive byte-for-byte verbatim`,
|
|
);
|
|
assert.ok(
|
|
result.includes(`Before: mentions ${brand} here.`),
|
|
`${name}: text BEFORE the protected block must be brand-swapped to "${brand}"`,
|
|
);
|
|
assert.ok(
|
|
result.includes(`After: also mentions ${brand} here.`),
|
|
`${name}: text AFTER the protected block must be brand-swapped to "${brand}"`,
|
|
);
|
|
// The protected block's OWN "Claude Code" occurrences must not have
|
|
// been swapped anywhere in the output — a stronger form of the
|
|
// verbatim-block assertion above, independent of exact block framing.
|
|
const claudeCodeOccurrencesInResult = (result.match(/Claude Code/g) || []).length;
|
|
assert.strictEqual(
|
|
claudeCodeOccurrencesInResult, 2,
|
|
`${name}: expected exactly the 2 "Claude Code" occurrences inside the protected block to survive `
|
|
+ `(got ${claudeCodeOccurrencesInResult} — outside occurrences must be brand-swapped away)`,
|
|
);
|
|
});
|
|
}
|
|
});
|