import { describe, it } from "node:test"; import assert from "node:assert/strict"; import { registerPreviewContextCommand } from "../../src/handlers/preview-context.js"; import { MEMORY_POLICY_PROMPT, MEMORY_POLICY_PROMPT_COMPACT } from "../../src/constants.js"; describe("registerPreviewContextCommand", () => { function setup(opts: { memoryBlock?: string; projectBlock?: string; projectName?: string; withProjectStore?: boolean; memoryMode?: "policy-only" | "legacy-inject"; memoryPolicyStyle?: "full" | "compact" | "custom" | "none"; memoryPolicyCustomText?: string; }) { const commands: { name: string; handler: Function }[] = []; const notifyCalls: { message: string; severity: string }[] = []; const mockPi = { registerCommand: (name: string, conf: any) => { commands.push({ name, handler: conf.handler }); }, } as any; const store = { formatForSystemPrompt: () => opts.memoryBlock ?? "", } as any; const projectStore = opts.withProjectStore ? ({ formatProjectBlock: () => opts.projectBlock ?? "" } as any) : null; registerPreviewContextCommand( mockPi, store, projectStore, opts.projectName ?? "demo-project", { memoryMode: opts.memoryMode ?? "policy-only", memoryPolicyStyle: opts.memoryPolicyStyle, memoryPolicyCustomText: opts.memoryPolicyCustomText, }, ); return { handler: commands[0].handler, notifyCalls, ctx: { ui: { notify: (message: string, severity: string) => { notifyCalls.push({ message, severity }); }, }, }, }; } it("registers /memory-preview-context", () => { const { handler } = setup({}); assert.ok(typeof handler === "function"); }); it("shows policy-only context by default", async () => { const { handler, ctx, notifyCalls } = setup({ memoryBlock: "MEM", projectBlock: "PROJECT", withProjectStore: true, }); await handler({}, ctx); assert.strictEqual(notifyCalls.length, 1); const out = notifyCalls[0].message; assert.match(out, /Mode: policy-only/); assert.match(out, /Policy style: full/); assert.match(out, /Full Markdown memories are NOT injected/); assert.match(out, /memory_search/); assert.match(out, /target="failure"/); assert.ok(out.includes(MEMORY_POLICY_PROMPT)); assert.match(out, /Blocks shown: 1/); }); it("shows compact policy context when configured", async () => { const { handler, ctx, notifyCalls } = setup({ memoryPolicyStyle: "compact", }); await handler({}, ctx); const out = notifyCalls[0].message; assert.match(out, /Policy style: compact/); assert.ok(out.includes(MEMORY_POLICY_PROMPT_COMPACT)); assert.match(out, /Blocks shown: 1/); }); it("shows custom policy context when configured", async () => { const customText = "Custom preview policy."; const { handler, ctx, notifyCalls } = setup({ memoryPolicyStyle: "custom", memoryPolicyCustomText: customText, }); await handler({}, ctx); const out = notifyCalls[0].message; assert.match(out, /Policy style: custom/); assert.ok(out.includes(customText)); assert.match(out, /Blocks shown: 1/); }); it("shows no injected policy context when policy style is none", async () => { const { handler, ctx, notifyCalls } = setup({ memoryPolicyStyle: "none", }); await handler({}, ctx); const out = notifyCalls[0].message; assert.match(out, /Policy style: none/); assert.match(out, /No memory policy context is injected/); assert.doesNotMatch(out, //); assert.match(out, /Blocks shown: 0/); }); it("shows all available blocks in legacy mode", async () => { const { handler, ctx, notifyCalls } = setup({ memoryBlock: "MEM", projectBlock: "PROJECT", withProjectStore: true, projectName: "pi-hermes-memory", memoryMode: "legacy-inject", }); await handler({}, ctx); assert.strictEqual(notifyCalls.length, 1); const out = notifyCalls[0].message; assert.match(out, /Injected Context Preview/); assert.match(out, /MEMORY \+ USER \+ RECENT FAILURES/); assert.match(out, /PROJECT MEMORY \(pi-hermes-memory\)/); assert.match(out, /Blocks shown: 2/); }); it("shows empty-state guidance when no blocks exist", async () => { const { handler, ctx, notifyCalls } = setup({ memoryBlock: "", projectBlock: "", withProjectStore: false, memoryMode: "legacy-inject", }); await handler({}, ctx); const out = notifyCalls[0].message; assert.match(out, /No memory context blocks are currently injected/); assert.match(out, /Blocks shown: 0/); }); });