@monotykamary/pi-vcc 0.6.1 → 0.6.3

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.
package/README.md CHANGED
@@ -199,6 +199,7 @@ pi-vcc is one of four compaction approaches in the AI coding-agent ecosystem. He
199
199
  - **Scoped recall** — default search is active lineage; use `scope:"all"` for all lineages, or `scope:"compaction:N"` / `scope:"compaction:latest"` to search within a specific compaction segment's original messages
200
200
  - **Priority error tags** — outstanding context items tagged `[ERROR]`, `[WARN]`, `[INFO]`, `[RESOLVED]` for urgency at a glance
201
201
  - **Metadata footer** — each compaction summary ends with timestamp, compression ratio, and message range
202
+ - **Compaction counter** — the post-compaction notification reports the ordinal of the just-completed compaction (e.g. `"3rd compaction"`), counted from pi-vcc compaction entries in the session file so it lines up with `scope:"compaction:N"`
202
203
  - **Cache-friendly ordering** — stable sections (goal, preferences, files, commits, anchors) come first; volatile sections (outstanding context, earlier turns, current status) come last, maximizing prompt-cacheable prefix across compactions
203
204
  - **Adaptive recall view** — search results grouped by conversation segments (turns) with match indicators (`>`) and context preservation, so the agent sees the conversational structure around each match
204
205
  - **Regex search** — `vcc_recall` supports regex patterns (`hook|inject`, `fail.*build`) and OR-ranked multi-word queries
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@monotykamary/pi-vcc",
3
- "version": "0.6.0",
3
+ "version": "0.6.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@monotykamary/pi-vcc",
9
- "version": "0.6.0",
9
+ "version": "0.6.3",
10
10
  "devDependencies": {
11
11
  "knip": "6.14.1",
12
12
  "typescript": "6.0.3"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monotykamary/pi-vcc",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Algorithmic conversation compactor for pi - transcript-preserving structured summaries, no LLM calls",
5
5
  "main": "index.ts",
6
6
  "keywords": [
@@ -15,22 +15,23 @@
15
15
  "url": "git+https://github.com/monotykamary/pi-vcc.git"
16
16
  },
17
17
  "peerDependencies": {
18
- "@earendil-works/pi-ai": "^0.79.8",
19
18
  "@earendil-works/pi-agent-core": "^0.79.8",
19
+ "@earendil-works/pi-ai": "^0.79.8",
20
20
  "@earendil-works/pi-coding-agent": "^0.79.8",
21
21
  "typebox": ">=1.1.24 <2.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "typescript": "6.0.3",
25
- "knip": "6.14.1"
26
- },
27
- "scripts": {
28
- "typecheck": "tsc --noEmit",
29
- "lint:dead": "knip"
24
+ "@types/node": "^26.0.0",
25
+ "knip": "6.14.1",
26
+ "typescript": "6.0.3"
30
27
  },
31
28
  "pi": {
32
29
  "extensions": [
33
30
  "./index.ts"
34
31
  ]
32
+ },
33
+ "scripts": {
34
+ "typecheck": "tsc --noEmit",
35
+ "lint:dead": "knip"
35
36
  }
36
- }
37
+ }
@@ -0,0 +1,3 @@
1
+ allowBuilds:
2
+ '@google/genai': false
3
+ protobufjs: false
@@ -1,5 +1,6 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
2
  import { getLastCompactionStats, PI_VCC_COMPACT_INSTRUCTION } from "../hooks/before-compact";
3
+ import { countPiVccCompactionsFromSession, ordinalSuffix } from "../core/compaction-count";
3
4
 
4
5
  const formatTokens = (n: number): string => {
5
6
  if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;
@@ -14,13 +15,17 @@ export const registerPiVccCommand = (pi: ExtensionAPI) => {
14
15
  customInstructions: PI_VCC_COMPACT_INSTRUCTION,
15
16
  onComplete: () => {
16
17
  const stats = getLastCompactionStats();
18
+ const count = countPiVccCompactionsFromSession(ctx.sessionManager);
19
+ const compactionLabel = count > 0
20
+ ? ` (${count}${ordinalSuffix(count)} compaction)`
21
+ : "";
17
22
  if (stats) {
18
23
  ctx.ui.notify(
19
- `pi-vcc: ${stats.summarized} source entries processed; tail kept ${stats.kept} (~${formatTokens(stats.keptTokensEst)} tok).`,
24
+ `pi-vcc: ${stats.summarized} source entries processed; tail kept ${stats.kept} (~${formatTokens(stats.keptTokensEst)} tok).${compactionLabel}`,
20
25
  "info",
21
26
  );
22
27
  } else {
23
- ctx.ui.notify("Compacted with pi-vcc", "info");
28
+ ctx.ui.notify(`Compacted with pi-vcc${compactionLabel}`, "info");
24
29
  }
25
30
  },
26
31
  onError: (err) => {
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Count pi-vcc compactions in the session.
3
+ *
4
+ * Compaction entries are persisted to the session file as
5
+ * `{ type: "compaction", details: { compactor: "pi-vcc", ... } }`.
6
+ * `session_compact` fires after the new compaction entry has been appended,
7
+ * so counting entries at that point includes the just-completed compaction —
8
+ * meaning the count doubles as the 1-based ordinal of the latest one.
9
+ *
10
+ * `getEntries()` returns the full append-only session (all lineages), which
11
+ * matches the `compaction:N` indexing scheme used by vcc_recall — so the
12
+ * ordinal shown in the notification lines up with `scope:"compaction:N"`.
13
+ */
14
+
15
+ export const ordinalSuffix = (n: number): string => {
16
+ const last = n % 10;
17
+ const lastTwo = n % 100;
18
+ if (lastTwo >= 11 && lastTwo <= 13) return "th";
19
+ if (last === 1) return "st";
20
+ if (last === 2) return "nd";
21
+ if (last === 3) return "rd";
22
+ return "th";
23
+ };
24
+
25
+ interface SessionManagerLike {
26
+ getEntries?: () => any[];
27
+ }
28
+
29
+ /** Total pi-vcc compactions in the session (includes the just-completed one). */
30
+ export const countPiVccCompactions = (entries: any[]): number => {
31
+ let total = 0;
32
+ for (const e of entries) {
33
+ if (e?.type === "compaction" && e?.details?.compactor === "pi-vcc") total++;
34
+ }
35
+ return total;
36
+ };
37
+
38
+ export const countPiVccCompactionsFromSession = (
39
+ sessionManager: SessionManagerLike | undefined,
40
+ ): number => {
41
+ try {
42
+ const entries = sessionManager?.getEntries?.() ?? [];
43
+ return countPiVccCompactions(entries);
44
+ } catch {
45
+ return 0;
46
+ }
47
+ };
@@ -3,6 +3,7 @@ import { writeFileSync } from "fs";
3
3
  import { compile, type CompileInput } from "../core/summarize";
4
4
  import { loadSettings, type PiVccSettings } from "../core/settings";
5
5
  import { triggerInvisibleContinue } from "../core/invisible-continue";
6
+ import { countPiVccCompactionsFromSession, ordinalSuffix } from "../core/compaction-count";
6
7
  import type { PiVccCompactionDetails } from "../details";
7
8
 
8
9
  export const PI_VCC_COMPACT_INSTRUCTION = "__pi_vcc__";
@@ -489,11 +490,15 @@ export const registerBeforeCompactHook = (pi: ExtensionAPI) => {
489
490
  // /pi-vcc path uses its own onComplete callback in the command handler.
490
491
  if (!lastCompactWasPiVcc) {
491
492
  const stats = lastStats;
493
+ const count = countPiVccCompactionsFromSession(ctx?.sessionManager as any);
494
+ const compactionLabel = count > 0
495
+ ? ` (${count}${ordinalSuffix(count)} compaction)`
496
+ : "";
492
497
  if (stats) {
493
498
  setTimeout(() => {
494
499
  try {
495
500
  ctx?.ui?.notify?.(
496
- `pi-vcc: ${stats.summarized} source entries processed; tail kept ${stats.kept} (~${formatTokens(stats.keptTokensEst)} tok).`,
501
+ `pi-vcc: ${stats.summarized} source entries processed; tail kept ${stats.kept} (~${formatTokens(stats.keptTokensEst)} tok).${compactionLabel}`,
497
502
  "info",
498
503
  );
499
504
  } catch {}