Change the default-hidden message categories from [thinking, hook_progress] to [tool_result, system_message, hook_progress, file_snapshot]. This hides the verbose machine-oriented categories by default while keeping thinking blocks visible — they contain useful reasoning context that users typically want to see. Also rename the "summary" category label from "Summaries" to "Compactions" to better reflect what Claude's summary messages actually represent (context-window compaction artifacts). Tests updated to match the new defaults: the filter test now asserts that tool_result, system_message, hook_progress, and file_snapshot are all excluded, producing 5 visible messages instead of the previous 7. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
145 lines
5.2 KiB
TypeScript
145 lines
5.2 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import type { ParsedMessage, MessageCategory } from "../../src/shared/types.js";
|
|
import { ALL_CATEGORIES, DEFAULT_HIDDEN_CATEGORIES } from "../../src/shared/types.js";
|
|
|
|
// Replicate the filter logic to test it in isolation
|
|
function filterMessages(
|
|
messages: ParsedMessage[],
|
|
enabledCategories: Set<MessageCategory>,
|
|
redactedUuids: Set<string> = new Set()
|
|
): ParsedMessage[] {
|
|
return messages.filter(
|
|
(m) => enabledCategories.has(m.category) && !redactedUuids.has(m.uuid)
|
|
);
|
|
}
|
|
|
|
function makeMsg(uuid: string, category: MessageCategory): ParsedMessage {
|
|
return { uuid, category, content: `Content for ${uuid}`, rawIndex: 0 };
|
|
}
|
|
|
|
describe("filters", () => {
|
|
const messages: ParsedMessage[] = [
|
|
makeMsg("1", "user_message"),
|
|
makeMsg("2", "assistant_text"),
|
|
makeMsg("3", "thinking"),
|
|
makeMsg("4", "tool_call"),
|
|
makeMsg("5", "tool_result"),
|
|
makeMsg("6", "system_message"),
|
|
makeMsg("7", "hook_progress"),
|
|
makeMsg("8", "file_snapshot"),
|
|
makeMsg("9", "summary"),
|
|
];
|
|
|
|
it("correctly includes messages by enabled category", () => {
|
|
const enabled = new Set<MessageCategory>(["user_message", "assistant_text"]);
|
|
const filtered = filterMessages(messages, enabled);
|
|
expect(filtered).toHaveLength(2);
|
|
expect(filtered.map((m) => m.category)).toEqual([
|
|
"user_message",
|
|
"assistant_text",
|
|
]);
|
|
});
|
|
|
|
it("correctly excludes messages by disabled category", () => {
|
|
const enabled = new Set<MessageCategory>(ALL_CATEGORIES);
|
|
enabled.delete("thinking");
|
|
const filtered = filterMessages(messages, enabled);
|
|
expect(filtered).toHaveLength(8);
|
|
expect(filtered.find((m) => m.category === "thinking")).toBeUndefined();
|
|
});
|
|
|
|
it("default filter state hides tool_result, system, hooks, and snapshots", () => {
|
|
const defaultEnabled = new Set(ALL_CATEGORIES);
|
|
for (const cat of DEFAULT_HIDDEN_CATEGORIES) {
|
|
defaultEnabled.delete(cat);
|
|
}
|
|
const filtered = filterMessages(messages, defaultEnabled);
|
|
expect(filtered.find((m) => m.category === "tool_result")).toBeUndefined();
|
|
expect(filtered.find((m) => m.category === "system_message")).toBeUndefined();
|
|
expect(filtered.find((m) => m.category === "hook_progress")).toBeUndefined();
|
|
expect(filtered.find((m) => m.category === "file_snapshot")).toBeUndefined();
|
|
expect(filtered).toHaveLength(5);
|
|
});
|
|
|
|
it("all-off filter returns empty array", () => {
|
|
const filtered = filterMessages(messages, new Set());
|
|
expect(filtered).toEqual([]);
|
|
});
|
|
|
|
it("all-on filter returns all messages", () => {
|
|
const filtered = filterMessages(messages, new Set(ALL_CATEGORIES));
|
|
expect(filtered).toHaveLength(9);
|
|
});
|
|
|
|
it("excludes redacted messages", () => {
|
|
const enabled = new Set(ALL_CATEGORIES);
|
|
const redacted = new Set(["1", "3"]);
|
|
const filtered = filterMessages(messages, enabled, redacted);
|
|
expect(filtered).toHaveLength(7);
|
|
expect(filtered.find((m) => m.uuid === "1")).toBeUndefined();
|
|
expect(filtered.find((m) => m.uuid === "3")).toBeUndefined();
|
|
});
|
|
|
|
it("getMatchCount returns count of messages matching search query", () => {
|
|
const lowerQuery = "content for 1";
|
|
const count = messages.filter((m) =>
|
|
m.content.toLowerCase().includes(lowerQuery)
|
|
).length;
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
it("getMatchCount returns 0 for empty query", () => {
|
|
const lowerQuery = "";
|
|
const count = lowerQuery
|
|
? messages.filter((m) => m.content.toLowerCase().includes(lowerQuery)).length
|
|
: 0;
|
|
expect(count).toBe(0);
|
|
});
|
|
|
|
it("conversation preset includes only user and assistant messages", () => {
|
|
const preset: MessageCategory[] = ["user_message", "assistant_text"];
|
|
const enabled = new Set(preset);
|
|
const filtered = filterMessages(messages, enabled);
|
|
expect(filtered).toHaveLength(2);
|
|
expect(filtered.every((m) => m.category === "user_message" || m.category === "assistant_text")).toBe(true);
|
|
});
|
|
|
|
it("debug preset includes only tool calls and results", () => {
|
|
const preset: MessageCategory[] = ["tool_call", "tool_result"];
|
|
const enabled = new Set(preset);
|
|
const filtered = filterMessages(messages, enabled);
|
|
expect(filtered).toHaveLength(2);
|
|
expect(filtered.every((m) => m.category === "tool_call" || m.category === "tool_result")).toBe(true);
|
|
});
|
|
|
|
it("category counts are computed correctly", () => {
|
|
const counts: Record<string, number> = {};
|
|
for (const cat of ALL_CATEGORIES) {
|
|
counts[cat] = 0;
|
|
}
|
|
for (const msg of messages) {
|
|
counts[msg.category]++;
|
|
}
|
|
expect(counts["user_message"]).toBe(1);
|
|
expect(counts["assistant_text"]).toBe(1);
|
|
expect(counts["thinking"]).toBe(1);
|
|
expect(Object.values(counts).reduce((a, b) => a + b, 0)).toBe(9);
|
|
});
|
|
|
|
it("category counts exclude redacted messages", () => {
|
|
const redacted = new Set(["1", "2"]);
|
|
const counts: Record<string, number> = {};
|
|
for (const cat of ALL_CATEGORIES) {
|
|
counts[cat] = 0;
|
|
}
|
|
for (const msg of messages) {
|
|
if (!redacted.has(msg.uuid)) {
|
|
counts[msg.category]++;
|
|
}
|
|
}
|
|
expect(counts["user_message"]).toBe(0);
|
|
expect(counts["assistant_text"]).toBe(0);
|
|
expect(Object.values(counts).reduce((a, b) => a + b, 0)).toBe(7);
|
|
});
|
|
});
|