@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 +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +10 -9
- package/pnpm-workspace.yaml +3 -0
- package/src/commands/pi-vcc.ts +7 -2
- package/src/core/compaction-count.ts +47 -0
- package/src/hooks/before-compact.ts +6 -1
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
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monotykamary/pi-vcc",
|
|
3
|
-
"version": "0.6.
|
|
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.
|
|
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.
|
|
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
|
-
"
|
|
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
|
+
}
|
package/src/commands/pi-vcc.ts
CHANGED
|
@@ -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(
|
|
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 {}
|