@monotykamary/pi-vcc 0.3.17 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +5 -4
  2. package/npm-shrinkwrap.json +2 -2
  3. package/package.json +1 -1
  4. package/src/core/build-sections.ts +12 -131
  5. package/src/core/format.ts +4 -14
  6. package/src/core/summarize.ts +98 -22
  7. package/src/sections.ts +0 -4
  8. package/__tests__/helpers.ts +0 -135
  9. package/__tests__/root-causes.test.ts +0 -858
  10. package/demo.gif +0 -0
  11. package/knip.json +0 -4
  12. package/scripts/audit-sessions.ts +0 -88
  13. package/scripts/benchmark-real-sessions.ts +0 -25
  14. package/scripts/compare-before-after.ts +0 -36
  15. package/scripts/dump-branch-output.ts +0 -20
  16. package/tests/australian-government.test.ts +0 -479
  17. package/tests/before-compact-hook.test.ts +0 -185
  18. package/tests/before-compact.test.ts +0 -227
  19. package/tests/brief.test.ts +0 -215
  20. package/tests/build-sections.test.ts +0 -59
  21. package/tests/compile.test.ts +0 -89
  22. package/tests/content.test.ts +0 -66
  23. package/tests/deep-extraction.test.ts +0 -313
  24. package/tests/extract-goals.test.ts +0 -86
  25. package/tests/extract-preferences.test.ts +0 -30
  26. package/tests/filter-noise.test.ts +0 -61
  27. package/tests/fixtures.ts +0 -61
  28. package/tests/format-recall.test.ts +0 -87
  29. package/tests/format.test.ts +0 -73
  30. package/tests/government-domain.test.ts +0 -542
  31. package/tests/lineage.test.ts +0 -33
  32. package/tests/load-messages.test.ts +0 -49
  33. package/tests/model-threshold-hook.test.ts +0 -311
  34. package/tests/model-threshold.test.ts +0 -223
  35. package/tests/normalize.test.ts +0 -104
  36. package/tests/proactive-threshold.test.ts +0 -490
  37. package/tests/real-sessions.test.ts +0 -38
  38. package/tests/recall-expand.test.ts +0 -15
  39. package/tests/recall-scope.test.ts +0 -32
  40. package/tests/recall-tool-scope.test.ts +0 -67
  41. package/tests/render-entries.test.ts +0 -92
  42. package/tests/report.test.ts +0 -58
  43. package/tests/sanitize.test.ts +0 -24
  44. package/tests/search-entries.test.ts +0 -233
  45. package/tests/support/load-session.ts +0 -23
  46. package/tests/support/real-sessions.ts +0 -51
  47. package/tests/threshold-integration.test.ts +0 -335
@@ -1,61 +0,0 @@
1
- import { describe, it, expect } from "bun:test";
2
- import { filterNoise } from "../src/core/filter-noise";
3
- import type { NormalizedBlock } from "../src/types";
4
-
5
- describe("filterNoise", () => {
6
- it("removes thinking blocks", () => {
7
- const blocks: NormalizedBlock[] = [
8
- { kind: "thinking", text: "hmm", redacted: false },
9
- { kind: "assistant", text: "hello" },
10
- ];
11
- expect(filterNoise(blocks)).toEqual([{ kind: "assistant", text: "hello" }]);
12
- });
13
-
14
- it("removes noise tool calls and results", () => {
15
- const blocks: NormalizedBlock[] = [
16
- { kind: "tool_call", name: "TodoWrite", args: {} },
17
- { kind: "tool_result", name: "TodoWrite", text: "ok", isError: false },
18
- { kind: "tool_call", name: "Read", args: { path: "x.ts" } },
19
- ];
20
- const result = filterNoise(blocks);
21
- expect(result).toHaveLength(1);
22
- expect(result[0]).toEqual({ kind: "tool_call", name: "Read", args: { path: "x.ts" } });
23
- });
24
-
25
- it("removes user blocks that are pure XML wrappers", () => {
26
- const blocks: NormalizedBlock[] = [
27
- { kind: "user", text: "<system-reminder>some noise</system-reminder>" },
28
- { kind: "user", text: "Fix the bug" },
29
- ];
30
- const result = filterNoise(blocks);
31
- expect(result).toHaveLength(1);
32
- expect(result[0]).toEqual({ kind: "user", text: "Fix the bug" });
33
- });
34
-
35
- it("cleans XML wrappers from user text but keeps real content", () => {
36
- const blocks: NormalizedBlock[] = [
37
- { kind: "user", text: "<system-reminder>noise</system-reminder>\nFix the login" },
38
- ];
39
- const result = filterNoise(blocks);
40
- expect(result).toHaveLength(1);
41
- expect((result[0] as any).text).toBe("Fix the login");
42
- });
43
-
44
- it("removes known noise strings", () => {
45
- const blocks: NormalizedBlock[] = [
46
- { kind: "user", text: "Continue from where you left off." },
47
- { kind: "user", text: "real task" },
48
- ];
49
- const result = filterNoise(blocks);
50
- expect(result).toHaveLength(1);
51
- expect((result[0] as any).text).toBe("real task");
52
- });
53
-
54
- it("preserves non-noise tool calls", () => {
55
- const blocks: NormalizedBlock[] = [
56
- { kind: "tool_call", name: "Edit", args: { path: "a.ts" } },
57
- { kind: "tool_result", name: "Edit", text: "ok", isError: false },
58
- ];
59
- expect(filterNoise(blocks)).toHaveLength(2);
60
- });
61
- });
package/tests/fixtures.ts DELETED
@@ -1,61 +0,0 @@
1
- import type { Message } from "@earendil-works/pi-ai";
2
-
3
- const ts = Date.now();
4
- const assistBase = {
5
- api: "messages" as any,
6
- provider: "anthropic" as any,
7
- model: "test",
8
- usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
9
- timestamp: ts,
10
- };
11
-
12
- export const userMsg = (text: string): Message => ({
13
- role: "user",
14
- content: text,
15
- timestamp: ts,
16
- });
17
-
18
- export const assistantText = (text: string): Message => ({
19
- role: "assistant",
20
- content: [{ type: "text", text }],
21
- ...assistBase,
22
- stopReason: "stop",
23
- });
24
-
25
- export const assistantWithThinking = (
26
- text: string,
27
- thinking: string,
28
- ): Message => ({
29
- role: "assistant",
30
- content: [
31
- { type: "thinking", thinking },
32
- { type: "text", text },
33
- ],
34
- ...assistBase,
35
- stopReason: "stop",
36
- });
37
-
38
- export const assistantWithToolCall = (
39
- name: string,
40
- args: Record<string, unknown>,
41
- ): Message => ({
42
- role: "assistant",
43
- content: [{ type: "toolCall", id: "tc_1", name, arguments: args }],
44
- ...assistBase,
45
- stopReason: "toolUse",
46
- });
47
-
48
- export const toolResult = (
49
- name: string,
50
- text: string,
51
- isError = false,
52
- ): Message => ({
53
- role: "toolResult",
54
- toolCallId: "tc_1",
55
- toolName: name,
56
- content: [{ type: "text", text }],
57
- isError,
58
- timestamp: ts,
59
- });
60
-
61
-
@@ -1,87 +0,0 @@
1
- import { describe, it, expect } from "bun:test";
2
- import { formatRecallOutput } from "../src/core/format-recall";
3
- import type { SearchHit } from "../src/core/search-entries";
4
-
5
- describe("formatRecallOutput", () => {
6
- it("shows no-match message with query", () => {
7
- const r = formatRecallOutput([], "xyz");
8
- expect(r).toContain('No matches for "xyz"');
9
- });
10
-
11
- it("shows no-entries message without query", () => {
12
- expect(formatRecallOutput([])).toContain("No entries");
13
- });
14
-
15
- describe("browse mode (no query)", () => {
16
- it("formats entries with index and role", () => {
17
- const entries: SearchHit[] = [
18
- { index: 0, role: "user", summary: "hello" },
19
- ];
20
- const r = formatRecallOutput(entries);
21
- expect(r).toContain("#0 [user] hello");
22
- });
23
-
24
- it("shows session history header", () => {
25
- const entries: SearchHit[] = [
26
- { index: 0, role: "user", summary: "a" },
27
- { index: 1, role: "assistant", summary: "b" },
28
- ];
29
- const r = formatRecallOutput(entries);
30
- expect(r).toContain("Session history (2 entries)");
31
- });
32
- });
33
-
34
- describe("search mode (with query)", () => {
35
- it("shows match count with query", () => {
36
- const entries: SearchHit[] = [
37
- { index: 2, role: "assistant", summary: "done", snippet: "done" },
38
- ];
39
- const r = formatRecallOutput(entries, "done");
40
- expect(r).toContain('Found 1 matches for "done"');
41
- });
42
-
43
- it("groups entries into segments by turn", () => {
44
- // Segments are split on user/bash boundaries
45
- const entries: SearchHit[] = [
46
- // Segment 1: user + assistant + tool_result (only user matches)
47
- { index: 0, role: "user", summary: "fix auth", snippet: "fix auth" },
48
- { index: 1, role: "assistant", summary: "checking...", snippet: undefined },
49
- { index: 2, role: "tool_result", summary: "file not found", snippet: undefined },
50
- // Segment 2: second user turn (assistant matches)
51
- { index: 3, role: "user", summary: "check the logs", snippet: undefined },
52
- { index: 4, role: "assistant", summary: "found the auth bug", snippet: "auth bug" },
53
- ];
54
- const r = formatRecallOutput(entries, "auth");
55
- expect(r).toContain("--- #0-#2 (1/3 entries match) ---");
56
- expect(r).toContain("> #0 [user] fix auth");
57
- expect(r).toContain(" #1 [assistant] checking...");
58
- expect(r).toContain("--- #3-#4 (1/2 entries match) ---");
59
- expect(r).toContain("> #4 [assistant] auth bug");
60
- });
61
-
62
- it("shows segment context for adjacent turns", () => {
63
- // Single match — adjacent segments shown as context
64
- const entries: SearchHit[] = [
65
- { index: 0, role: "user", summary: "hello", snippet: undefined },
66
- { index: 1, role: "assistant", summary: "hi", snippet: undefined },
67
- { index: 2, role: "user", summary: "fix auth", snippet: "fix auth" },
68
- { index: 3, role: "assistant", summary: "done", snippet: undefined },
69
- { index: 4, role: "user", summary: "thanks", snippet: undefined },
70
- ];
71
- const r = formatRecallOutput(entries, "auth");
72
- expect(r).toMatch(/---/);
73
- expect(r).toContain("fix auth");
74
- });
75
-
76
- it("handles entries without snippet (assume all matched)", () => {
77
- const entries: SearchHit[] = [
78
- { index: 0, role: "user", summary: "hello" },
79
- { index: 1, role: "assistant", summary: "world" },
80
- ];
81
- const r = formatRecallOutput(entries, "search term");
82
- expect(r).toContain('Found 2 matches for "search term"');
83
- expect(r).toContain("> #0 [user] hello");
84
- expect(r).toContain("> #1 [assistant] world");
85
- });
86
- });
87
- });
@@ -1,73 +0,0 @@
1
- import { describe, it, expect } from "bun:test";
2
- import { formatSummary } from "../src/core/format";
3
- import type { SectionData } from "../src/sections";
4
-
5
- const empty: SectionData = {
6
- sessionGoal: [],
7
- outstandingContext: [],
8
- filesAndChanges: [],
9
- commits: [],
10
- userPreferences: [],
11
- typeCatalog: [],
12
- symbolChanges: [],
13
- briefTranscript: "",
14
- transcriptEntries: [],
15
- };
16
-
17
- describe("formatSummary", () => {
18
- it("returns empty string for all-empty sections", () => {
19
- expect(formatSummary(empty)).toBe("");
20
- });
21
-
22
- it("formats a single header section", () => {
23
- const data = {
24
- ...empty,
25
- sessionGoal: ["fix auth bug"],
26
- };
27
- const r = formatSummary(data);
28
- expect(r).toContain("[Session Goal]");
29
- expect(r).toContain("- fix auth bug");
30
- });
31
-
32
- it("separates header and brief transcript with ---", () => {
33
- const data = {
34
- ...empty,
35
- sessionGoal: ["goal"],
36
- briefTranscript: "[user]\ndo something",
37
- };
38
- const r = formatSummary(data);
39
- expect(r).toContain("[Session Goal]");
40
- expect(r).toContain("---");
41
- expect(r).toContain("[user]\ndo something");
42
- });
43
-
44
- it("renders brief transcript alone when no header sections", () => {
45
- const data = {
46
- ...empty,
47
- briefTranscript: "[user]\nhi\n\n[assistant]\nhello",
48
- };
49
- const r = formatSummary(data);
50
- expect(r).toContain("[user]\nhi\n\n[assistant]\nhello");
51
- });
52
-
53
- it("joins multiple header sections with blank line", () => {
54
- const data = {
55
- ...empty,
56
- sessionGoal: ["goal"],
57
- outstandingContext: ["blocker"],
58
- };
59
- const r = formatSummary(data);
60
- expect(r).toContain("[Session Goal]");
61
- expect(r).toContain("[Outstanding Context]");
62
- expect(r).toContain("\n\n");
63
- });
64
-
65
- it("wraps long lines so compaction TUI rendering stays bounded", () => {
66
- const data = {
67
- ...empty,
68
- briefTranscript: `[assistant]\n${"word ".repeat(80)}`,
69
- };
70
- const r = formatSummary(data);
71
- expect(Math.max(...r.split("\n").map((line) => line.length))).toBeLessThanOrEqual(120);
72
- });
73
- });