moving
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled

This commit is contained in:
Oleg Maslov
2026-09-02 10:10:29 +02:00
commit 0c3e2ead3b
3841 changed files with 970576 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
import { describe, expect, it } from 'vitest';
import { encodeFrame, frameToSavePayload, type HookFrame } from '../src/frame-encoder.js';
import type { HookEvent } from '../src/hook-event-types.js';
function event(overrides: Partial<HookEvent> = {}): HookEvent {
return {
eventType: 'user-prompt-submit',
source: 'claude-code',
cwd: '/proj/foo',
timestamp_iso: '2026-04-28T10:00:00.000Z',
payload: {},
...overrides,
};
}
describe('encodeFrame', () => {
it('encodes a basic event with content from payload.content', () => {
const frame = encodeFrame(event({ payload: { content: 'hi there' } }));
expect(frame.content).toBe('hi there');
expect(frame.source).toBe('claude-code');
expect(frame.metadata.cwd).toBe('/proj/foo');
expect(frame.metadata.event_type).toBe('user-prompt-submit');
expect(frame.metadata.timestamp_iso).toBe('2026-04-28T10:00:00.000Z');
});
it('falls back to payload.text / payload.prompt / payload.message', () => {
expect(encodeFrame(event({ payload: { text: 't' } })).content).toBe('t');
expect(encodeFrame(event({ payload: { prompt: 'p' } })).content).toBe('p');
expect(encodeFrame(event({ payload: { message: 'm' } })).content).toBe('m');
});
it('classifies importance from content by default', () => {
expect(encodeFrame(event({ payload: { content: 'always run lint' } })).importance).toBe('critical');
expect(encodeFrame(event({ payload: { content: 'we decided X' } })).importance).toBe('important');
// Commit 1.4: substantive default raised from 'temporary' to 'normal'.
expect(encodeFrame(event({ payload: { content: 'hello' } })).importance).toBe('normal');
});
it('importance override beats classifier', () => {
const frame = encodeFrame(event({ payload: { content: 'hello' } }), { importance: 'critical' });
expect(frame.importance).toBe('critical');
});
it('extracts scope from payload.session_id (or aliases)', () => {
expect(encodeFrame(event({ payload: { session_id: 'abc' } })).scope).toBe('abc');
expect(encodeFrame(event({ payload: { sessionId: 'def' } })).scope).toBe('def');
});
it('falls back to scope="default" when no session id is present', () => {
expect(encodeFrame(event({ payload: {} })).scope).toBe('default');
});
it('scope option overrides payload-derived scope', () => {
const frame = encodeFrame(event({ payload: { session_id: 'a' } }), { scope: 'b' });
expect(frame.scope).toBe('b');
});
it('includes optional metadata only when present', () => {
const withProj = encodeFrame(event({ payload: { content: 'x', project: 'waggle' } }));
expect(withProj.metadata.project).toBe('waggle');
const withoutProj = encodeFrame(event({ payload: { content: 'x' } }));
expect(withoutProj.metadata.project).toBeUndefined();
});
it('attaches parent id when supplied', () => {
const frame = encodeFrame(event({ payload: { content: 'x' } }), { parent: 'frame-7' });
expect(frame.parent).toBe('frame-7');
});
it('omits parent when not supplied', () => {
const frame = encodeFrame(event({ payload: { content: 'x' } }));
expect(frame.parent).toBeUndefined();
});
it('content option overrides payload extraction', () => {
const frame = encodeFrame(event({ payload: { content: 'original' } }), { content: 'override' });
expect(frame.content).toBe('override');
});
});
describe('frameToSavePayload (Commit 1.4)', () => {
function makeFrame(overrides: Partial<HookFrame> = {}): HookFrame {
return {
content: 'the actual content',
importance: 'normal',
scope: 'sess-123',
source: 'claude-code',
metadata: {
cwd: '/proj',
timestamp_iso: '2026-04-28T10:00:00.000Z',
event_type: 'user-prompt-submit',
},
...overrides,
};
}
it('embeds session/source/event in a content prefix and defaults source to "system"', () => {
const out = frameToSavePayload(makeFrame());
expect(out.content).toBe('[hm session:sess-123 src:claude-code event:user-prompt-submit] the actual content');
expect(out.importance).toBe('normal');
expect(out.source).toBe('system');
});
it('drops session token when scope is "default"', () => {
const out = frameToSavePayload(makeFrame({ scope: 'default' }));
expect(out.content).not.toContain('session:');
expect(out.content).toContain('src:claude-code');
});
it('includes parent token when present', () => {
const out = frameToSavePayload(makeFrame({ parent: 'frame-99' }));
expect(out.content).toContain('parent:frame-99');
});
it('includes project token from metadata when present', () => {
const out = frameToSavePayload(makeFrame({ metadata: {
cwd: '/proj',
timestamp_iso: '2026-04-28T10:00:00.000Z',
event_type: 'stop',
project: 'waggle-os',
}}));
expect(out.content).toContain('project:waggle-os');
});
it('mcpSource override is honoured', () => {
const out = frameToSavePayload(makeFrame(), { mcpSource: 'agent_inferred' });
expect(out.source).toBe('agent_inferred');
});
it('omits prefix entirely when no metadata tokens would be added', () => {
const minimalFrame: HookFrame = {
content: 'plain',
importance: 'normal',
scope: 'default',
source: 'claude-code',
metadata: { cwd: '/p', timestamp_iso: 't' }, // no event_type, no project
};
const out = frameToSavePayload(minimalFrame);
// src token is always present, so we still get a prefix:
expect(out.content).toBe('[hm src:claude-code] plain');
});
});