MCPcopy Create free account
hub / github.com/SethGammon/Citadel / main

Function main

scripts/test-hook-events.js:15–66  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

13
14const OPENCODE_FIXTURE = path.join(__dirname, 'fixtures', 'opencode-hook-events.json');
15
16function fail(message) {
17 console.error(message);
18 process.exit(1);
19}
20
21// A hook must not be able to tell which runtime it is running under. For every
22// fixture pair, the opencode payload and the equivalent Claude Code payload have
23// to reduce to the same envelope fields.
24function assertOpencodeEquivalence() {
25 const fixture = JSON.parse(fs.readFileSync(OPENCODE_FIXTURE, 'utf8'));
26 assert(fixture.equivalents.length > 0, 'opencode fixture has no equivalence cases');
27
28 for (const item of fixture.equivalents) {
29 const opencode = normalizeOpencodeHookInput(item.opencode);
30 const claude = normalizeClaudeHookInput(item.claude);
31
32 for (const [field, expected] of Object.entries(item.expect)) {
33 assert.deepStrictEqual(
34 opencode[field], expected,
35 `${item.name}: opencode ${field} mismatch`,
36 );
37 assert.deepStrictEqual(
38 claude[field], expected,
39 `${item.name}: claude ${field} mismatch (fixture pair is not equivalent)`,
40 );
41 }
42
43 assert.equal(opencode.runtime, 'opencode', `${item.name}: runtime mismatch`);
44 assert.equal(
45 opencode.native_event_name, item.opencode.hook_event_name,
46 `${item.name}: native event name must be preserved for skip reporting`,
47 );
48 // The untouched payload has to survive: the plugin adapter mutates
49 // opencode's own args object in place, which is the only mutation opencode
50 // honors, so it cannot be handed a normalized copy.
51 assert.strictEqual(opencode.raw, item.opencode, `${item.name}: raw payload must be the caller's object`);
52 }
53
54 // The fixture's mapped list and the shipped map must not drift apart.
55 assert.deepStrictEqual(
56 Object.keys(normalizeEvent.OPENCODE_EVENT_MAP).sort(),
57 [...fixture.mapped].sort(),
58 'opencode event map and fixture mapped list have drifted',
59 );
60
61 // Events we chose not to map must stay unmapped. Any of these silently
62 // acquiring a Citadel event id would misreport the runtime's lifecycle.
63 for (const native of Object.keys(fixture.deliberatelyUnmapped)) {
64 assert.equal(
65 normalizeEvent.OPENCODE_EVENT_MAP[native], undefined,
66 `${native} must stay unmapped: ${fixture.deliberatelyUnmapped[native]}`,
67 );
68 // An unmapped name passes through rather than becoming a wrong event id.
69 assert.equal(

Callers 1

Calls 4

normalizeCodexHookInputFunction · 0.85
normalizeClaudeHookInputFunction · 0.85
toLegacyHookPayloadFunction · 0.85
failFunction · 0.70

Tested by

no test coverage detected