pi-smart-compact 8.0.7 → 8.0.8

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  No changes yet.
6
6
 
7
+ ## [8.0.8] - 2026-08-09
8
+
9
+ ### Fixed
10
+
11
+ - Modified-file verification now accepts exact normalized paths from canonical `Files Modified` entries before collision-safe suffix matching. Root files that share a basename with nested files, plus top-level generic or short filenames, can be deterministically repaired without weakening the zero-gap verification gate.
12
+
7
13
  ## [8.0.7] - 2026-08-08
8
14
 
9
15
  ### Fixed
@@ -8,7 +8,7 @@ import type { CompressionProfile, ProfileConfig } from "./types.ts";
8
8
  * `package.json#version`. Do not hand-edit this line for releases; bump
9
9
  * package.json and run `bun run sync-version`.
10
10
  */
11
- export declare const VERSION = "8.0.7";
11
+ export declare const VERSION = "8.0.8";
12
12
  export declare const CHARS_PER_TOKEN = 3.8;
13
13
  export declare const MIN_COMPACTION_SAVING_RATIO = 0.1;
14
14
  export declare const ESTIMATOR_ROUNDING_TOLERANCE_TOKENS = 1;
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ function effectiveBudget(configured, modeDefault) {
102
102
  }
103
103
 
104
104
  // src/constants.ts
105
- var VERSION = "8.0.7";
105
+ var VERSION = "8.0.8";
106
106
  var CHARS_PER_TOKEN = 3.8;
107
107
  var MIN_COMPACTION_SAVING_RATIO = 0.1;
108
108
  var ESTIMATOR_ROUNDING_TOLERANCE_TOKENS = 1;
@@ -8136,9 +8136,11 @@ function verifySummary(summary, extraction, continuity = null) {
8136
8136
  }
8137
8137
  }
8138
8138
  const modifiedPaths = extraction.modifiedFiles.map((file) => file.path);
8139
+ const listedModifiedPaths = new Set((findSection(parsed, "files-modified")?.body ?? "").split(`
8140
+ `).map((line) => line.replace(/^\s*(?:[-*+]|\d+[.)])\s+/, "").replace(/^\[[ x]\]\s+/i, "").trim()).map((line) => line.startsWith("`") && line.endsWith("`") ? line.slice(1, -1) : line).filter(Boolean).map(normalizePath));
8139
8141
  for (const file of extraction.modifiedFiles) {
8140
8142
  const needles = buildUniquePathNeedles(file.path, modifiedPaths);
8141
- if (!needles.some((needle) => lower.includes(needle))) {
8143
+ if (!listedModifiedPaths.has(normalizePath(file.path)) && !needles.some((needle) => lower.includes(needle))) {
8142
8144
  gaps.push({ kind: "missing-file", path: file.path });
8143
8145
  score -= 5;
8144
8146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/phases/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAW9G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAYlE;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAOpF;AAED,wFAAwF;AACxF,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAO3D;CACF;AAqID,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAI1E;AAED,qGAAqG;AACrG,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,SAAS,SAAI,GACZ;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAgB7E;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,GACxC,kBAAkB,CAqJpB;AAED,iHAAiH;AACjH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EAAE,EACvB,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,GACxC,MAAM,CAwFR;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,EACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EAAE,MAAM,CAAC,EAAE,WAAW,EAC5F,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/phases/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAW9G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAYlE;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAOpF;AAED,wFAAwF;AACxF,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAO3D;CACF;AAqID,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAI1E;AAED,qGAAqG;AACrG,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,SAAS,SAAI,GACZ;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAgB7E;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,GACxC,kBAAkB,CAgKpB;AAED,iHAAiH;AACjH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EAAE,EACvB,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,GACxC,MAAM,CAwFR;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,EACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EAAE,MAAM,CAAC,EAAE,WAAW,EAC5F,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
@@ -156,7 +156,7 @@ function formatProviderEvaluation(report) {
156
156
  import fs2 from "fs";
157
157
 
158
158
  // src/constants.ts
159
- var VERSION = "8.0.7";
159
+ var VERSION = "8.0.8";
160
160
  var COMPACT_SYSTEM_PREFIX = "You are an expert conversation summarizer for a coding agent. " + "Produce structured markdown summaries. " + "Follow output format exactly. " + "Use EXACT names \u2014 never paraphrase code identifiers. " + "Trust deterministic extraction data over intuition.";
161
161
  var PROFILES = {
162
162
  light: {
@@ -138,7 +138,7 @@ function getLlmClient() {
138
138
  }
139
139
 
140
140
  // src/constants.ts
141
- var VERSION = "8.0.7";
141
+ var VERSION = "8.0.8";
142
142
  var COMPACT_SYSTEM_PREFIX = "You are an expert conversation summarizer for a coding agent. " + "Produce structured markdown summaries. " + "Follow output format exactly. " + "Use EXACT names \u2014 never paraphrase code identifiers. " + "Trust deterministic extraction data over intuition.";
143
143
  var PROFILES = {
144
144
  light: {
@@ -1227,9 +1227,11 @@ function verifySummary(summary, extraction, continuity = null) {
1227
1227
  }
1228
1228
  }
1229
1229
  const modifiedPaths = extraction.modifiedFiles.map((file) => file.path);
1230
+ const listedModifiedPaths = new Set((findSection(parsed, "files-modified")?.body ?? "").split(`
1231
+ `).map((line) => line.replace(/^\s*(?:[-*+]|\d+[.)])\s+/, "").replace(/^\[[ x]\]\s+/i, "").trim()).map((line) => line.startsWith("`") && line.endsWith("`") ? line.slice(1, -1) : line).filter(Boolean).map(normalizePath));
1230
1232
  for (const file of extraction.modifiedFiles) {
1231
1233
  const needles = buildUniquePathNeedles(file.path, modifiedPaths);
1232
- if (!needles.some((needle) => lower.includes(needle))) {
1234
+ if (!listedModifiedPaths.has(normalizePath(file.path)) && !needles.some((needle) => lower.includes(needle))) {
1233
1235
  gaps.push({ kind: "missing-file", path: file.path });
1234
1236
  score -= 5;
1235
1237
  }
@@ -2,7 +2,7 @@
2
2
  var __require = import.meta.require;
3
3
 
4
4
  // src/constants.ts
5
- var VERSION = "8.0.7";
5
+ var VERSION = "8.0.8";
6
6
  var COMPACT_SYSTEM_PREFIX = "You are an expert conversation summarizer for a coding agent. " + "Produce structured markdown summaries. " + "Follow output format exactly. " + "Use EXACT names \u2014 never paraphrase code identifiers. " + "Trust deterministic extraction data over intuition.";
7
7
  var PROFILES = {
8
8
  light: {
@@ -34,6 +34,13 @@
34
34
  export declare const GENERIC_BASENAMES: ReadonlySet<string>;
35
35
  /** Bare basenames shorter than this are also dropped (too weak a signal). */
36
36
  export declare const MIN_BARE_BASENAME_LEN = 5;
37
+ /**
38
+ * Build the suffix-needle list for a path. Returns an empty array for the
39
+ * empty path; otherwise the longest needle is always the full normalized
40
+ * path. All needles are lowercased so substring matching can be done with
41
+ * `errorMessage.toLowerCase().includes(needle)` cheaply.
42
+ */
43
+ export declare function normalizePath(filePath: string): string;
37
44
  export declare function buildPathNeedles(filePath: string): string[];
38
45
  /**
39
46
  * Return only suffixes that identify exactly one path in the supplied set.
@@ -1 +1 @@
1
- {"version":3,"file":"file-needles.d.ts","sourceRoot":"","sources":["../../src/utils/file-needles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAIhD,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAYvC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB3D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAU9F;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAMxF"}
1
+ {"version":3,"file":"file-needles.d.ts","sourceRoot":"","sources":["../../src/utils/file-needles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAIhD,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB3D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAU9F;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAMxF"}
@@ -1,6 +1,6 @@
1
1
  # Migrating from v7 to v8
2
2
 
3
- This guide applies to the stable `8.0.7` release.
3
+ This guide applies to the stable `8.0.8` release.
4
4
 
5
5
  ## Compatibility
6
6
 
@@ -105,7 +105,7 @@ scrubbing, using 0600 files in a 0700 directory. Retention only prunes
105
105
  marker-owned backups.
106
106
 
107
107
  1. Back up `~/.pi/agent/settings.json` and the Smart Compact cache directory.
108
- 2. Install the exact stable version: `pi install npm:pi-smart-compact@8.0.7`.
108
+ 2. Install the exact stable version: `pi install npm:pi-smart-compact@8.0.8`.
109
109
  3. Leave all model routes null initially.
110
110
  4. Keep `telemetryChannel: "stable"` unless intentionally running a separate
111
111
  canary cohort.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-smart-compact",
3
- "version": "8.0.7",
3
+ "version": "8.0.8",
4
4
  "description": "Verification-oriented smart compaction extension for Pi Coding Agent — deterministic extraction, exploration, synthesis, verification, metrics, and safety checks.",
5
5
  "packageManager": "bun@1.3.14",
6
6
  "engines": {