Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/sources/claude-code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,66 @@ describe("claude-code source adapter", () => {
expect(searchableProjection).not.toContain("attachment text must not leak");
});

test("sync skips malformed and unsupported records without leaking format-drift text", async () => {
const { root } = writeClaudeFixture("format-drift", [
"{this is not json",
claudeLine({
type: "system",
sessionId: "unsupported-session-must-not-win",
cwd: "/tmp/unsupported-cwd-must-not-win",
timestamp: "1999-01-01T00:00:00.000Z",
message: { content: "unsupported claude text must not leak" },
}),
claudeLine({
type: "user",
sessionId: "format-drift-session",
cwd: "/tmp/claude-format-cwd",
timestamp: "2026-06-10T00:00:00.000Z",
message: { content: "accepted claude format drift needle" },
}),
"{\"type\":\"assistant\",\"message\":",
claudeLine({
type: "assistant",
sessionId: "format-drift-session",
cwd: "/tmp/claude-format-cwd",
timestamp: "2026-06-10T00:00:01.000Z",
message: {
content: [
{ type: "text", text: "accepted claude format drift answer" },
{ type: "attachment", text: "format drift attachment must not leak" },
],
},
}),
]);
const dbPath = join(root, "index.sqlite");

const summary = await syncSessions({
dbPath,
sourceId: "claude-code",
selector: { source: "claude-code", kind: "all", root },
});

expect(summary.errors).toBe(0);
expect(summary.added).toBe(1);
expect(summary.coverage.sourceFileCount).toBe(1);
expect(summary.coverage.indexedSessionCount).toBe(1);

const foundAccepted = findSessions(dbPath, "accepted claude format drift needle", 10, { source: "claude-code", kind: "all", root }, { sourceId: "claude-code" });
expect(foundAccepted.results.map((result) => result.sessionUuid)).toEqual(["claude-code:format-drift-session"]);

const foundUnsupported = findSessions(dbPath, "unsupported claude text", 10, { source: "claude-code", kind: "all", root }, { sourceId: "claude-code" });
expect(foundUnsupported.results).toEqual([]);

const page = getMessagePage(dbPath, "claude-code:format-drift-session", 0, 10);
expect(page.session.cwd).toBe("/tmp/claude-format-cwd");
expect(page.messages.map((message) => message.contentText)).toEqual([
"accepted claude format drift needle",
"accepted claude format drift answer",
]);
expect(JSON.stringify(page)).not.toContain("unsupported claude text must not leak");
expect(JSON.stringify(page)).not.toContain("format drift attachment must not leak");
});

test("ignores skipped records when deriving inventory grouping dates and snapshot file metadata", async () => {
const { root, filePath } = writeClaudeFixture("inventory-policy", [
claudeLine({
Expand Down
58 changes: 58 additions & 0 deletions src/sources/pi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,64 @@ describe("pi source adapter", () => {
expect(searchableProjection).not.toContain("tool call must not leak");
});

test("sync skips malformed and unsupported records without leaking format-drift text", async () => {
const { root } = writePiFixture("format-drift", [
"{this is not json",
piLine({ type: "session", id: "pi-format-drift-session", cwd: "/tmp/pi-format-cwd", timestamp: "2026-06-10T00:00:00.000Z" }),
piLine({ type: "future_event", timestamp: "1999-01-01T00:00:00.000Z", text: "unsupported pi text must not leak" }),
piLine({
type: "message",
timestamp: "2026-06-10T00:00:01.000Z",
message: { role: "user", content: [{ type: "text", text: "accepted pi format drift needle" }], timestamp: "2026-06-10T00:00:01.000Z" },
}),
"{\"type\":\"message\",\"message\":",
piLine({
type: "message",
timestamp: "2026-06-10T00:00:02.000Z",
message: {
role: "assistant",
content: [
{ type: "text", text: "accepted pi format drift answer" },
{ type: "toolCall", name: "bash", arguments: { command: "format drift tool call must not leak" } },
],
timestamp: "2026-06-10T00:00:02.000Z",
},
}),
piLine({ type: "compaction", id: "c1", timestamp: "2026-06-10T00:00:03.000Z", summary: "accepted pi format drift summary" }),
]);
const dbPath = join(root, "index.sqlite");

const summary = await syncSessions({
dbPath,
sourceId: "pi",
selector: { source: "pi", kind: "all", root },
});

expect(summary.errors).toBe(0);
expect(summary.added).toBe(1);
expect(summary.coverage.sourceFileCount).toBe(1);
expect(summary.coverage.indexedSessionCount).toBe(1);

const foundAccepted = findSessions(dbPath, "accepted pi format drift needle", 10, { source: "pi", kind: "all", root }, { sourceId: "pi" });
expect(foundAccepted.results.map((result) => result.sessionUuid)).toEqual(["pi:pi-format-drift-session"]);

const foundCompaction = findSessions(dbPath, "accepted pi format drift summary", 10, { source: "pi", kind: "all", root }, { sourceId: "pi" });
expect(foundCompaction.results.map((result) => result.sessionUuid)).toEqual(["pi:pi-format-drift-session"]);
expect(foundCompaction.results[0]?.matchSource).toBe("session");

const foundUnsupported = findSessions(dbPath, "unsupported pi text", 10, { source: "pi", kind: "all", root }, { sourceId: "pi" });
expect(foundUnsupported.results).toEqual([]);

const page = getMessagePage(dbPath, "pi:pi-format-drift-session", 0, 10);
expect(page.session.cwd).toBe("/tmp/pi-format-cwd");
expect(page.messages.map((message) => message.contentText)).toEqual([
"accepted pi format drift needle",
"accepted pi format drift answer",
]);
expect(JSON.stringify(page)).not.toContain("unsupported pi text must not leak");
expect(JSON.stringify(page)).not.toContain("format drift tool call must not leak");
});

test("uses the latest Pi model_change as session model", async () => {
const { filePath } = writePiFixture("latest-model", [
piLine({ type: "session", id: "pi-model-session", cwd: "/tmp/pi-model-cwd", timestamp: "2026-06-06T00:00:00.000Z" }),
Expand Down