pi-smart-compact 7.9.1 → 7.9.2
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/dist/index.js +129 -21
- package/dist/ui/overlays.d.ts.map +1 -1
- package/dist/utils/cache.d.ts +11 -0
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/fingerprint.d.ts +12 -2
- package/dist/utils/fingerprint.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts +16 -1
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/state.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -197,6 +197,33 @@ function debug(msg, ...args) {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
// src/utils/helpers.ts
|
|
200
|
+
function validateSmartCompactConfig(sc) {
|
|
201
|
+
const VALID_PROFILES = ["light", "balanced", "aggressive"];
|
|
202
|
+
if ("profile" in sc && !VALID_PROFILES.includes(sc.profile)) {
|
|
203
|
+
warn("smart-compact config: invalid profile '" + sc.profile + "', expected light|balanced|aggressive. Using default 'balanced'.");
|
|
204
|
+
delete sc.profile;
|
|
205
|
+
}
|
|
206
|
+
if ("autoTrigger" in sc && typeof sc.autoTrigger !== "boolean") {
|
|
207
|
+
warn("smart-compact config: autoTrigger must be boolean, got " + typeof sc.autoTrigger);
|
|
208
|
+
delete sc.autoTrigger;
|
|
209
|
+
}
|
|
210
|
+
if ("backupEnabled" in sc && typeof sc.backupEnabled !== "boolean") {
|
|
211
|
+
warn("smart-compact config: backupEnabled must be boolean, got " + typeof sc.backupEnabled);
|
|
212
|
+
delete sc.backupEnabled;
|
|
213
|
+
}
|
|
214
|
+
if ("summaryModel" in sc && sc.summaryModel !== null && typeof sc.summaryModel !== "string") {
|
|
215
|
+
warn("smart-compact config: summaryModel must be string|null, got " + typeof sc.summaryModel);
|
|
216
|
+
delete sc.summaryModel;
|
|
217
|
+
}
|
|
218
|
+
if ("segmentationModel" in sc && sc.segmentationModel !== null && typeof sc.segmentationModel !== "string") {
|
|
219
|
+
warn("smart-compact config: segmentationModel must be string|null, got " + typeof sc.segmentationModel);
|
|
220
|
+
delete sc.segmentationModel;
|
|
221
|
+
}
|
|
222
|
+
if ("profiles" in sc && (typeof sc.profiles !== "object" || sc.profiles === null || Array.isArray(sc.profiles))) {
|
|
223
|
+
warn("smart-compact config: profiles must be an object, got " + typeof sc.profiles);
|
|
224
|
+
delete sc.profiles;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
200
227
|
var _cfg = null;
|
|
201
228
|
var _cfgMtime = 0;
|
|
202
229
|
function loadConfig() {
|
|
@@ -207,6 +234,7 @@ function loadConfig() {
|
|
|
207
234
|
return _cfg;
|
|
208
235
|
const raw = JSON.parse(fs.readFileSync(p, "utf-8"));
|
|
209
236
|
const sc = raw[CONFIG_KEY] ?? raw[CONFIG_KEY_ALT] ?? {};
|
|
237
|
+
validateSmartCompactConfig(sc);
|
|
210
238
|
const merged = { ...DEFAULT_CONFIG, ...sc };
|
|
211
239
|
if (sc.profiles)
|
|
212
240
|
merged.profiles = { ...PROFILES, ...sc.profiles };
|
|
@@ -372,6 +400,24 @@ function buildExtractionContext(extraction, forRange) {
|
|
|
372
400
|
].join(`
|
|
373
401
|
`);
|
|
374
402
|
}
|
|
403
|
+
function inferSessionType(extraction, report) {
|
|
404
|
+
if (report?.sessionType)
|
|
405
|
+
return report.sessionType;
|
|
406
|
+
const hasModifications = extraction.modifiedFiles.length > 0;
|
|
407
|
+
const hasUnresolvedErrors = extraction.errors.some((e) => !e.resolved);
|
|
408
|
+
const hasResolvedErrors = extraction.errors.some((e) => e.resolved);
|
|
409
|
+
const hasReadsOnly = extraction.readFiles.length > 2 && !hasModifications;
|
|
410
|
+
const hasDecisions = extraction.decisions.length > 0;
|
|
411
|
+
if (hasUnresolvedErrors && (hasModifications || hasResolvedErrors))
|
|
412
|
+
return "debugging";
|
|
413
|
+
if (hasReadsOnly && !hasDecisions)
|
|
414
|
+
return "review";
|
|
415
|
+
if (hasDecisions && !hasModifications && !hasUnresolvedErrors)
|
|
416
|
+
return "discussion";
|
|
417
|
+
if (hasModifications)
|
|
418
|
+
return "implementation";
|
|
419
|
+
return "implementation";
|
|
420
|
+
}
|
|
375
421
|
function buildExplorationContext(report) {
|
|
376
422
|
if (!report.mainGoal && !report.crossReferences.length && !report.enrichedConstraints.length)
|
|
377
423
|
return "";
|
|
@@ -649,15 +695,28 @@ function loadCachedExtraction(sessionId) {
|
|
|
649
695
|
}
|
|
650
696
|
}
|
|
651
697
|
function mergeExtractions(base, delta, baseMsgCount) {
|
|
698
|
+
const offsetErrors = delta.errors.map((e) => ({ ...e, index: e.index + baseMsgCount }));
|
|
699
|
+
const offsetDecisions = delta.decisions.map((d) => ({ ...d, index: d.index + baseMsgCount }));
|
|
700
|
+
const offsetConstraints = delta.constraints.map((c) => ({ ...c, index: c.index + baseMsgCount }));
|
|
701
|
+
const offsetTopics = delta.topics.map((t) => ({
|
|
702
|
+
...t,
|
|
703
|
+
startIndex: t.startIndex + baseMsgCount,
|
|
704
|
+
endIndex: t.endIndex + baseMsgCount
|
|
705
|
+
}));
|
|
706
|
+
const offsetTimeline = delta.timeline.map((t) => ({ ...t, index: t.index + baseMsgCount }));
|
|
707
|
+
const offsetModifiedFiles = delta.modifiedFiles.map((f) => ({
|
|
708
|
+
...f,
|
|
709
|
+
lastModifiedIndex: f.lastModifiedIndex + baseMsgCount
|
|
710
|
+
}));
|
|
652
711
|
return {
|
|
653
|
-
modifiedFiles: [...new Map([...base.modifiedFiles, ...
|
|
712
|
+
modifiedFiles: [...new Map([...base.modifiedFiles, ...offsetModifiedFiles].map((f) => [f.path, f])).values()],
|
|
654
713
|
readFiles: [...new Set([...base.readFiles, ...delta.readFiles])],
|
|
655
714
|
deletedFiles: [...new Set([...base.deletedFiles, ...delta.deletedFiles])],
|
|
656
|
-
errors: [...base.errors, ...
|
|
657
|
-
decisions: [...base.decisions, ...
|
|
658
|
-
constraints: [...base.constraints, ...
|
|
659
|
-
topics: [...base.topics, ...
|
|
660
|
-
timeline: [...base.timeline, ...
|
|
715
|
+
errors: [...base.errors, ...offsetErrors],
|
|
716
|
+
decisions: [...base.decisions, ...offsetDecisions],
|
|
717
|
+
constraints: [...base.constraints, ...offsetConstraints],
|
|
718
|
+
topics: [...base.topics, ...offsetTopics],
|
|
719
|
+
timeline: [...base.timeline, ...offsetTimeline],
|
|
661
720
|
mainGoal: delta.mainGoal ?? base.mainGoal,
|
|
662
721
|
lastUserMessages: delta.lastUserMessages.length > 0 ? delta.lastUserMessages : base.lastUserMessages,
|
|
663
722
|
lastErrors: delta.lastErrors.length > 0 ? delta.lastErrors : base.lastErrors,
|
|
@@ -1124,7 +1183,7 @@ function buildCompactionState(extraction, openLoops, report, nextActions, critic
|
|
|
1124
1183
|
})),
|
|
1125
1184
|
nextActions,
|
|
1126
1185
|
criticalContext,
|
|
1127
|
-
sessionType: report
|
|
1186
|
+
sessionType: inferSessionType(extraction, report),
|
|
1128
1187
|
compactionVersion: VERSION,
|
|
1129
1188
|
updatedAt: Date.now()
|
|
1130
1189
|
};
|
|
@@ -1392,22 +1451,73 @@ var FRAMEWORK_SIGNALS = [
|
|
|
1392
1451
|
function getFingerprintPath(projectId) {
|
|
1393
1452
|
return path5.join(FINGERPRINT_DIR, projectId + ".json");
|
|
1394
1453
|
}
|
|
1454
|
+
var NOISE_PATH_RE = /(?:node_modules|[/\\]\.pi[/\\]agent|[/\\]\.cache|[/\\]\.npm|[/\\]\.bun|[/\\]\.git[/\\])/;
|
|
1455
|
+
function isProjectPath(filePath) {
|
|
1456
|
+
return !NOISE_PATH_RE.test(filePath);
|
|
1457
|
+
}
|
|
1458
|
+
function hashProjectId(seed) {
|
|
1459
|
+
return "proj-" + crypto3.createHash("sha256").update(seed).digest("hex").slice(0, 12);
|
|
1460
|
+
}
|
|
1461
|
+
function deriveFromAbsolutePaths(paths) {
|
|
1462
|
+
const segments = paths.map((p) => p.replace(/^\/+/, "").split("/").filter(Boolean)).filter((s) => s.length >= 3);
|
|
1463
|
+
if (segments.length < 2)
|
|
1464
|
+
return deriveFromRelativePaths(paths);
|
|
1465
|
+
const dirCounts = new Map;
|
|
1466
|
+
for (const segs of segments) {
|
|
1467
|
+
for (let depth = 3;depth <= segs.length; depth++) {
|
|
1468
|
+
const prefix = segs.slice(0, depth).join("/");
|
|
1469
|
+
dirCounts.set(prefix, (dirCounts.get(prefix) ?? 0) + 1);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
const threshold = Math.ceil(segments.length * 0.5);
|
|
1473
|
+
const candidates = [...dirCounts.entries()].filter(([, count]) => count >= threshold).sort((a, b) => {
|
|
1474
|
+
const depthDiff = b[0].split("/").length - a[0].split("/").length;
|
|
1475
|
+
if (depthDiff !== 0)
|
|
1476
|
+
return depthDiff;
|
|
1477
|
+
return b[1] - a[1];
|
|
1478
|
+
});
|
|
1479
|
+
if (candidates.length)
|
|
1480
|
+
return hashProjectId(candidates[0][0]);
|
|
1481
|
+
const sorted = [...segments].sort((a, b) => a.length - b.length);
|
|
1482
|
+
let commonDepth = 0;
|
|
1483
|
+
for (let d = 0;d < sorted[0].length; d++) {
|
|
1484
|
+
if (segments.every((s) => s[d] === sorted[0][d]))
|
|
1485
|
+
commonDepth = d + 1;
|
|
1486
|
+
else
|
|
1487
|
+
break;
|
|
1488
|
+
}
|
|
1489
|
+
return hashProjectId(sorted[0].slice(0, Math.max(commonDepth, 3)).join("/"));
|
|
1490
|
+
}
|
|
1491
|
+
function deriveFromRelativePaths(paths) {
|
|
1492
|
+
const topEntries = [...new Set(paths.map((p) => p.split("/").filter(Boolean)[0]).filter(Boolean))].sort();
|
|
1493
|
+
const dir2Counts = new Map;
|
|
1494
|
+
for (const p of paths) {
|
|
1495
|
+
const segs = p.split("/").filter(Boolean);
|
|
1496
|
+
if (segs.length >= 2) {
|
|
1497
|
+
const d2 = segs.slice(0, 2).join("/");
|
|
1498
|
+
dir2Counts.set(d2, (dir2Counts.get(d2) ?? 0) + 1);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
const stableDirs = [...dir2Counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([d]) => d).sort();
|
|
1502
|
+
const fingerprint = topEntries.join(",") + "|" + stableDirs.join(",");
|
|
1503
|
+
return hashProjectId(fingerprint);
|
|
1504
|
+
}
|
|
1395
1505
|
function deriveProjectId(extraction) {
|
|
1396
1506
|
const allPaths = [
|
|
1397
1507
|
...extraction.modifiedFiles.map((f) => f.path),
|
|
1398
1508
|
...extraction.readFiles
|
|
1399
|
-
];
|
|
1509
|
+
].filter(isProjectPath);
|
|
1400
1510
|
if (!allPaths.length)
|
|
1401
1511
|
return "unknown";
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1512
|
+
const absolutePaths = allPaths.filter((p) => p.startsWith("/"));
|
|
1513
|
+
const relativePaths = allPaths.filter((p) => !p.startsWith("/"));
|
|
1514
|
+
if (absolutePaths.length >= 2) {
|
|
1515
|
+
return deriveFromAbsolutePaths(absolutePaths);
|
|
1516
|
+
}
|
|
1517
|
+
if (relativePaths.length >= 2) {
|
|
1518
|
+
return deriveFromRelativePaths(relativePaths);
|
|
1407
1519
|
}
|
|
1408
|
-
|
|
1409
|
-
const hash = crypto3.createHash("sha256").update(topRoot).digest("hex").slice(0, 12);
|
|
1410
|
-
return "proj-" + hash;
|
|
1520
|
+
return hashProjectId(allPaths.sort().join("|"));
|
|
1411
1521
|
}
|
|
1412
1522
|
function detectLanguage(extraction) {
|
|
1413
1523
|
const extCounts = new Map;
|
|
@@ -2044,7 +2154,7 @@ function chunkLlmMessages(msgs, boundaries, pc) {
|
|
|
2044
2154
|
async function singlePassCompact(convText, extraction, report, prevContext, model, auth, signal) {
|
|
2045
2155
|
const extractionCtx = buildExtractionContext(extraction);
|
|
2046
2156
|
const explorationCtx = report ? buildExplorationContext(report) : "";
|
|
2047
|
-
const sessionType = report
|
|
2157
|
+
const sessionType = inferSessionType(extraction, report);
|
|
2048
2158
|
const sessionInstruction = SESSION_TYPE_INSTRUCTIONS[sessionType] ?? SESSION_TYPE_INSTRUCTIONS.implementation;
|
|
2049
2159
|
const adaptedPrefix = SINGLE_PASS_PREFIX + `
|
|
2050
2160
|
Session-specific instructions:
|
|
@@ -2359,8 +2469,7 @@ function renderContextBar(theme, pct, tokens, barLen = 24) {
|
|
|
2359
2469
|
const filled = Math.min(barLen, Math.round(clamped / 100 * barLen));
|
|
2360
2470
|
const bar = "\u2588".repeat(filled) + "\u2591".repeat(barLen - filled);
|
|
2361
2471
|
const color = clamped > 80 ? "error" : clamped > 50 ? "warning" : "success";
|
|
2362
|
-
|
|
2363
|
-
return fg("text", " Context: ") + fg(color, bar) + fg("text", " " + clamped + "%") + fg("dim", " (" + (tokens ?? 0).toLocaleString() + "t)");
|
|
2472
|
+
return theme.fg("text", " Context: ") + theme.fg(color, bar) + theme.fg("text", " " + clamped + "%") + theme.fg("dim", " (" + (tokens ?? 0).toLocaleString() + "t)");
|
|
2364
2473
|
}
|
|
2365
2474
|
function renderTokenBar(theme, before, after, label, barLen = 30) {
|
|
2366
2475
|
const ratio = before > 0 ? after / before : 0;
|
|
@@ -2489,8 +2598,7 @@ async function showResultScreen(ctx, details, extraction) {
|
|
|
2489
2598
|
c.addChild(new Text("", 0, 0));
|
|
2490
2599
|
const methodColors = { eesv: "accent", "single-pass": "success", heuristic: "warning" };
|
|
2491
2600
|
const methodColor = methodColors[details.method] ?? "text";
|
|
2492
|
-
|
|
2493
|
-
c.addChild(new Text(theme.fg("text", " Method: ") + fg(methodColor, details.method.toUpperCase()) + theme.fg("dim", " \u2022 " + details.llmCalls + " LLM call(s) \u2022 Profile: " + details.profile), 0, 0));
|
|
2601
|
+
c.addChild(new Text(theme.fg("text", " Method: ") + theme.fg(methodColor, details.method.toUpperCase()) + theme.fg("dim", " \u2022 " + details.llmCalls + " LLM call(s) \u2022 Profile: " + details.profile), 0, 0));
|
|
2494
2602
|
if (details.model) {
|
|
2495
2603
|
c.addChild(new Text(theme.fg("dim", " Model: " + details.model), 0, 0));
|
|
2496
2604
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlays.d.ts","sourceRoot":"","sources":["../../src/ui/overlays.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAI/E,OAAO,KAAK,EACV,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAC9C,mBAAmB,EAAE,oBAAoB,EAC1C,MAAM,aAAa,CAAC;AAIrB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"overlays.d.ts","sourceRoot":"","sources":["../../src/ui/overlays.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAI/E,OAAO,KAAK,EACV,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAC9C,mBAAmB,EAAE,oBAAoB,EAC1C,MAAM,aAAa,CAAC;AAIrB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,CAS7F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,CAO5G;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,uBAAuB,EAC5B,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,GACvG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA8C7B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,uBAAuB,EAC5B,aAAa,EAAE,WAAW,EAC1B,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CA4CpC;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,uBAAuB,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAM5F;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,uBAAuB,EAC5B,OAAO,EAAE,mBAAmB,EAC5B,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAsJf;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,uBAAuB,EAC5B,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,GACvG,OAAO,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAAG,IAAI,CAAC,CAMrE"}
|
package/dist/utils/cache.d.ts
CHANGED
|
@@ -22,6 +22,17 @@ export declare function getMetricsSummary(): {
|
|
|
22
22
|
export declare function trackedComplete(phase: LLMCallMetric["phase"], model: Model<Api>, reqBody: Context, opts: CacheAwareOptions): Promise<AssistantMessage>;
|
|
23
23
|
export declare function saveCachedExtraction(sessionId: string, extraction: StructuredExtraction, msgCount: number): void;
|
|
24
24
|
export declare function loadCachedExtraction(sessionId: string): CachedExtraction | null;
|
|
25
|
+
/**
|
|
26
|
+
* Merge a delta extraction into a base extraction, offsetting all
|
|
27
|
+
* index-bearing fields so they align with the global message array.
|
|
28
|
+
*
|
|
29
|
+
* When `extractStructured` is called on `msgs.slice(cached.lastMessageIndex + 1)`
|
|
30
|
+
* the delta's indexes start at 0 in the slice — but in the full conversation
|
|
31
|
+
* they start at `baseMsgCount` (= `cached.messageCount` = `cached.lastMessageIndex + 1`).
|
|
32
|
+
*
|
|
33
|
+
* Without this offset, incremental extraction produces corrupted indexes that
|
|
34
|
+
* break timeline ordering, topic segmentation, and downstream verification.
|
|
35
|
+
*/
|
|
25
36
|
export declare function mergeExtractions(base: StructuredExtraction, delta: StructuredExtraction, baseMsgCount: number): StructuredExtraction;
|
|
26
37
|
export declare function appendMetricsLog(sessionId: string): void;
|
|
27
38
|
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG5G,OAAO,EAAY,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,gBAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAO5G,wBAAgB,mBAAmB,IAAI,MAAM,CAK5C;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAGD,wBAAgB,SAAS,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAOhH;AAKD,wBAAgB,YAAY,IAAI,IAAI,CAAyB;AAC7D,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAA4F;AAChJ,wBAAgB,UAAU,IAAI,aAAa,EAAE,CAA0B;AAEvE,wBAAgB,iBAAiB,IAAI;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAYpK;AAGD,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA2B3B;AAQD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQhH;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAQ/E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,oBAAoB,
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG5G,OAAO,EAAY,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,gBAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAO5G,wBAAgB,mBAAmB,IAAI,MAAM,CAK5C;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAGD,wBAAgB,SAAS,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAOhH;AAKD,wBAAgB,YAAY,IAAI,IAAI,CAAyB;AAC7D,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAA4F;AAChJ,wBAAgB,UAAU,IAAI,aAAa,EAAE,CAA0B;AAEvE,wBAAgB,iBAAiB,IAAI;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAYpK;AAGD,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA2B3B;AAQD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQhH;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAQ/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,oBAAoB,CA8BpI;AAGD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOxD"}
|
|
@@ -13,8 +13,18 @@ export interface ProjectFingerprint {
|
|
|
13
13
|
updatedAt: number;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Generate a project ID from file paths in the extraction.
|
|
17
|
-
*
|
|
16
|
+
* Generate a stable project ID from file paths in the extraction.
|
|
17
|
+
*
|
|
18
|
+
* Strategy (in priority order):
|
|
19
|
+
* 1. **Noise filtering** — exclude node_modules, .cache, .pi/agent, etc.
|
|
20
|
+
* 2. **Absolute paths** (≥ 2) — deep ancestor with majority vote
|
|
21
|
+
* 3. **Relative paths** (≥ 2) — directory structure fingerprint
|
|
22
|
+
* 4. **Fallback** — hash all paths together
|
|
23
|
+
*
|
|
24
|
+
* ⚠️ Breaking change: this replaces the previous shallow-root algorithm
|
|
25
|
+
* that caused cross-project contamination
|
|
26
|
+
* (e.g. hash("root") → proj-4813494d, hash("/Users") → proj-a2a0ee2c).
|
|
27
|
+
* Old fingerprint/state files will be orphaned and expire via TTL.
|
|
18
28
|
*/
|
|
19
29
|
export declare function deriveProjectId(extraction: StructuredExtraction): string;
|
|
20
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AA8ID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,oBAAoB,GAAG,MAAM,CAuBxE;AAoDD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CASnF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,oBAAoB,GAC/B,IAAI,CAuBN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,GAAG,IAAI,GAAG,MAAM,CAQlF"}
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* General helpers: config, backup, batching, preprocessing.
|
|
3
3
|
*/
|
|
4
|
-
import type { CompactConfig, ChunkSummary, LlmChunk, StructuredExtraction, ExplorationReport, SessionMessageEntry } from "../types.ts";
|
|
4
|
+
import type { CompactConfig, ChunkSummary, LlmChunk, StructuredExtraction, ExplorationReport, SessionType, SessionMessageEntry } from "../types.ts";
|
|
5
5
|
export declare function loadConfig(): CompactConfig;
|
|
6
6
|
export declare function backupConversation(convText: string, sessionId: string): string | null;
|
|
7
7
|
export declare function getPreviousCompactionContext(branch: unknown[]): string;
|
|
@@ -18,5 +18,20 @@ export declare function buildExtractionContext(extraction: StructuredExtraction,
|
|
|
18
18
|
start: number;
|
|
19
19
|
end: number;
|
|
20
20
|
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* Infer session type from extraction data when exploration report is absent.
|
|
23
|
+
*
|
|
24
|
+
* Previously defaulted blindly to "implementation", which caused review-only
|
|
25
|
+
* and discussion-only sessions to be summarized with the wrong prompt strategy.
|
|
26
|
+
*
|
|
27
|
+
* Heuristic priority:
|
|
28
|
+
* 1. If exploration report provides a classification → trust it
|
|
29
|
+
* 2. Active errors + code changes → debugging
|
|
30
|
+
* 3. Reads only, no modifications → review
|
|
31
|
+
* 4. Decisions but no code changes → discussion
|
|
32
|
+
* 5. Code modifications → implementation
|
|
33
|
+
* 6. Fallback → implementation (most common agent activity)
|
|
34
|
+
*/
|
|
35
|
+
export declare function inferSessionType(extraction: StructuredExtraction, report: ExplorationReport | null): SessionType;
|
|
21
36
|
export declare function buildExplorationContext(report: ExplorationReport): string;
|
|
22
37
|
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAsB,YAAY,EAAE,QAAQ,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA0CxK,wBAAgB,UAAU,IAAI,aAAa,CAkB1C;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUrF;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAQtE;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CA0B5F;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKhE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE,EAAE,CASjF;AAqCD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,YAAY,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM;;;;;EAYnF;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAU1H;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAC/B,WAAW,CAeb;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAYzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/utils/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/utils/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAWnH;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAKnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAe7E;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,oBAAoB,EAChC,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,WAAW,EAAE,MAAM,EAAE,EACrB,eAAe,EAAE,MAAM,EAAE,GACxB,eAAe,CAgDjB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAsBrF;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oCAAoC;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,sDAAsD;IACtD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,eAAe,CAmD7F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CA+BjE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CA2BlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAO5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAIhE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-smart-compact",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.2",
|
|
4
4
|
"description": "EESV smart compaction extension for Pi Coding Agent — deterministic extraction, exploration, synthesis, verification with redundancy pruning, project fingerprinting, and damage detection.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"CHANGELOG.md"
|
|
41
41
|
],
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "rm -rf dist && mkdir dist && bun build ./src/index.ts --outdir ./dist --target bun --external '@earendil-works/*' --external 'typebox' &&
|
|
43
|
+
"build": "rm -rf dist && mkdir dist && bun build ./src/index.ts --outdir ./dist --target bun --external '@earendil-works/*' --external 'typebox' && bunx tsc --emitDeclarationOnly --outDir dist",
|
|
44
44
|
"test": "bun test",
|
|
45
45
|
"typecheck": "bunx tsc --noEmit"
|
|
46
46
|
},
|