pi-smart-compact 7.9.0 → 7.9.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [7.9.1] - 2026-05-17
4
+
5
+ ### Fixed
6
+ - **`/smart-compact` race condition** — Added `waitForIdle()` to slash command handler. Previously the command could execute concurrently with agent streaming since extension commands bypass the input queue.
7
+ - **Tool `skipCompact` safety** — `ctx.compact()` internally calls `this.abort()`, which would kill the running agent loop if called from within a tool. Tool path now correctly keeps `skipCompact: true` and caches summary in `pendingRef` for the next natural compact.
8
+ - **Tool context-usage guard** — Tool now checks `getContextUsage()` before running and returns early with token info if context is too small.
9
+ - **Tool description enriched** — Better description and parameter hints so the agent knows when and how to call `smart_compact`.
10
+
11
+ ## [7.9.0] - 2026-05-17
12
+
13
+ ### Fixed
14
+ - **40 TypeScript strict-mode errors resolved** — `bunx tsc --noEmit` now passes cleanly with zero errors against latest `@earendil-works/pi-ai`, `pi-coding-agent`, `pi-tui` peer types.
15
+ - **`notify()` level mismatch** — `"success"` is not a valid level in `ExtensionUIContext.notify()`. All instances mapped to `"info"`.
16
+ - **`UserMessage.timestamp` mandatory** — 10 inline message objects across `explore.ts`, `synthesize.ts`, `verify.ts` were missing the required `timestamp: Date.now()` field.
17
+ - **`AgentToolResult.details` mandatory** — All tool return objects in `index.ts` now include explicit `details: undefined`.
18
+ - **`SelectList.selectedIndex` private accessor** — Replaced with `setSelectedIndex()` in `overlays.ts`.
19
+ - **`ThemeColor` union vs arbitrary string** — `theme.fg()` cast to `(c: string, t: string) => string` in overlays for dynamic color lookup.
20
+ - **`CacheAwareOptions` not assignable to `ProviderStreamOptions`** — Added explicit cast in `cache.ts`.
21
+ - **`blocks: unknown` after `Array.isArray`** — Explicit `unknown[]` typing in `extraction.ts` and `pruning.ts`.
22
+ - **`ExtensionContext` vs `ExtensionCommandContext`** — Proper `as unknown as` double-cast in `index.ts` for tool and hook contexts.
23
+ - **`apiKey?: string` (optional) used as `string`** — Extracted `apiKey` and `apiHeaders` as separate non-optional variables after guard check in `core.ts`.
24
+ - **`pendingRef.value` type narrowed to `never`** — TypeScript control flow after `pendingRef.value = null` prevented re-reading after `runSmartCompact`. Fixed with explicit cast.
25
+
26
+ ### Changed
27
+ - **`/smart-compact` command now uses `waitForIdle()`** — Prevents race condition when slash command is entered while agent is streaming. Agent finishes current turn before compaction starts.
28
+ - **Tool (`smart_compact`) keeps `skipCompact: true`** — Mid-turn compaction via `ctx.compact()` would abort the running agent loop (`this.abort()` internally). Tool prepares summary in `pendingRef` for the next natural compact to apply.
29
+ - **Tool description enriched** — Better description, parameter descriptions, and context-usage guard help the agent decide when to call smart_compact.
30
+ - **README.md updated** — version 7.9.0, module count 18, line count ~5,091, typecheck status now passing, added `logger.ts` and `type-guards.ts` to source table.
31
+
3
32
  ## [7.8.0] - 2026-05-17
4
33
 
5
34
  ### Fixed
package/README.md CHANGED
@@ -57,12 +57,12 @@ The extension keeps a short-lived pending compaction in memory, then hands that
57
57
 
58
58
  **Observed from the current codebase (`README`, `src/`, `test/`, `package.json`)**
59
59
 
60
- - **Package version:** `7.8.0`
60
+ - **Package version:** `7.9.1`
61
61
  - **Runtime entrypoint:** `dist/index.js`
62
62
  - **Source entrypoint:** `src/index.ts`
63
- - **Source modules:** 16 TypeScript files under `src/`
63
+ - **Source modules:** 18 TypeScript files under `src/`
64
64
  - **Tests:** 9 test files, **93 passing tests**
65
- - **Approx repo footprint:** ~5,053 lines across `src/` + `test/`
65
+ - **Approx repo footprint:** ~5,091 lines across `src/` + `test/`
66
66
  - **Documentation asset:** `docs/assets/pi-smart-compact.png`
67
67
  - **Published package files:** `dist/`, `docs/`, `README.md`, `LICENSE`, `CHANGELOG.md`
68
68
 
@@ -72,9 +72,9 @@ The extension keeps a short-lived pending compaction in memory, then hands that
72
72
  | --- | --- | --- |
73
73
  | `bun test` | ✅ Pass | 93/93 tests passing |
74
74
  | `bun run build` | ✅ Pass | Bundles `src/index.ts` to `dist/index.js` |
75
- | `bun run typecheck` | ⚠️ Fails | Current repo has TypeScript compatibility issues against the installed Pi typings / `.ts` import style |
75
+ | `bun run typecheck` | Pass | Strict TypeScript compatibility clean |
76
76
 
77
- So the project is currently **buildable and tested**, but **not fully typecheck-clean**.
77
+ So the project is currently **buildable, tested, and typecheck-clean**.
78
78
 
79
79
  ---
80
80
 
@@ -348,11 +348,13 @@ That pending summary is valid for **5 minutes** and is consumed by:
348
348
  | `src/utils/cache.ts` | Metrics, cache-aware LLM options, extraction cache |
349
349
  | `src/utils/damage.ts` | Post-compaction regression signal detection |
350
350
  | `src/utils/extraction.ts` | Deterministic extraction and open-loop detection |
351
+ | `src/utils/logger.ts` | Centralized logging with shared prefix |
351
352
  | `src/utils/fingerprint.ts` | Cross-session project fingerprinting |
352
353
  | `src/utils/helpers.ts` | Config loading, backups, batching, prompt helpers |
353
354
  | `src/utils/pruning.ts` | Redundancy pruning before compaction |
354
355
  | `src/utils/state.ts` | Compaction state persistence and delta logic |
355
356
  | `src/utils/tokens.ts` | Provider capabilities and token estimation |
357
+ | `src/utils/type-guards.ts` | Shared type guard functions |
356
358
 
357
359
  ### Tests
358
360
 
@@ -589,10 +591,9 @@ The current codebase includes these safeguards:
589
591
 
590
592
  To keep this README aligned with the repository's **actual** current state:
591
593
 
592
- 1. **`bun run typecheck` is currently failing.** The repo builds with Bun and passes tests, but strict TypeScript compatibility is not clean right now.
593
- 2. **One legacy test filename remains:** `test/semantic-compact.test.ts`.
594
- 3. **The package is published from `dist/`, not directly from `src/`.** Source and tests are not included in the package tarball.
595
- 4. **The extension depends on Pi runtime APIs and peer packages** (`@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, `typebox`).
594
+ 1. **One legacy test filename remains:** `test/semantic-compact.test.ts`.
595
+ 2. **The package is published from `dist/`**, not directly from `src/`. Source and tests are not included in the package tarball.
596
+ 3. **The extension depends on Pi runtime APIs and peer packages** (`@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, `typebox`).
596
597
 
597
598
  ---
598
599
 
@@ -629,7 +630,7 @@ rm -rf dist && mkdir dist && bun build ./src/index.ts --outdir ./dist --target b
629
630
  bun run typecheck
630
631
  ```
631
632
 
632
- At the moment, this command is expected to report errors.
633
+ At the moment, this command passes cleanly.
633
634
 
634
635
  ### Typical local path inside Pi
635
636
 
@@ -2,7 +2,7 @@
2
2
  * Constants, prompts, and profile defaults.
3
3
  */
4
4
  import type { CompressionProfile, ProfileConfig } from "./types.ts";
5
- export declare const VERSION = "7.9.0";
5
+ export declare const VERSION = "7.9.1";
6
6
  export declare const CHARS_PER_TOKEN = 3.8;
7
7
  export declare const COMPACT_SYSTEM_PREFIX: string;
8
8
  export declare const PROFILES: Record<CompressionProfile, ProfileConfig>;
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EACV,kBAAkB,EAAE,iBAAiB,EAEtC,MAAM,YAAY,CAAC;AAsBpB,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,uBAAuB,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE;QAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,SAAS,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8V9E"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EACV,kBAAkB,EAAE,iBAAiB,EAEtC,MAAM,YAAY,CAAC;AAsBpB,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,uBAAuB,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE;QAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,SAAS,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgW9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,iCAAiC,CAAC;AAwC7F,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,QA0H7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,iCAAiC,CAAC;AAwC7F,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,QA2I7D"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // src/constants.ts
3
- var VERSION = "7.9.0";
3
+ var VERSION = "7.9.1";
4
4
  var CHARS_PER_TOKEN = 3.8;
5
5
  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.";
6
6
  var PROFILES = {
@@ -782,7 +782,8 @@ function catalogErrors(msgs, _tcIdx) {
782
782
  for (const err of errors) {
783
783
  for (let j = err.index + 1;j < Math.min(msgs.length, err.index + 6); j++) {
784
784
  if (msgs[j]?.role === "assistant") {
785
- const blocks = Array.isArray(msgs[j]?.content) ? msgs[j].content : [];
785
+ const rawBlocks = msgs[j]?.content;
786
+ const blocks = Array.isArray(rawBlocks) ? rawBlocks : [];
786
787
  for (const b of blocks) {
787
788
  if (isToolCallBlock(b) && b.name === err.tool) {
788
789
  err.retryAttempted = true;
@@ -1312,7 +1313,8 @@ function pruneRedundant(msgs) {
1312
1313
  for (let idx = 0;idx < msgs.length; idx++) {
1313
1314
  if (msgs[idx].role !== "assistant")
1314
1315
  continue;
1315
- const blocks = Array.isArray(msgs[idx].content) ? msgs[idx].content : [];
1316
+ const rawBlocks = msgs[idx].content;
1317
+ const blocks = Array.isArray(rawBlocks) ? rawBlocks : [];
1316
1318
  const hasToolCall = blocks.some((b) => isToolCallBlock(b));
1317
1319
  if (hasToolCall)
1318
1320
  continue;
@@ -1832,7 +1834,7 @@ async function exploreConversation(llmMessages, extraction, model, auth, prevSum
1832
1834
  }
1833
1835
  const probeResp = await trackedComplete("explore", model, {
1834
1836
  systemPrompt: COMPACT_SYSTEM_PREFIX,
1835
- messages: [{ role: "user", content: [{ type: "text", text: userContent }] }],
1837
+ messages: [{ role: "user", content: [{ type: "text", text: userContent }], timestamp: Date.now() }],
1836
1838
  tools: EXPLORATION_TOOLS
1837
1839
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, signal }, model.provider));
1838
1840
  const toolCalls = probeResp.content.filter((c) => c.type === "toolCall");
@@ -1929,7 +1931,7 @@ User steering: ` + userNote : "");
1929
1931
  try {
1930
1932
  const resp = await trackedComplete("explore-retry", model, {
1931
1933
  systemPrompt: COMPACT_SYSTEM_PREFIX,
1932
- messages: [{ role: "user", content: [{ type: "text", text: retryPrompt }] }]
1934
+ messages: [{ role: "user", content: [{ type: "text", text: retryPrompt }], timestamp: Date.now() }]
1933
1935
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, maxTokens: Math.min(4096, getProviderCaps(model.provider).maxOutputTokens), signal }, model.provider));
1934
1936
  const text = resp.content.filter((c) => c.type === "text").map((c) => c.text).join("").trim();
1935
1937
  return parseExplorationReport(text, llmMessages);
@@ -1967,7 +1969,7 @@ Output ONLY JSON: {"mainGoal":"...","sessionType":"implementation|review|debuggi
1967
1969
  try {
1968
1970
  const resp = await trackedComplete("explore-direct", model, {
1969
1971
  systemPrompt: COMPACT_SYSTEM_PREFIX,
1970
- messages: [{ role: "user", content: [{ type: "text", text: prompt }] }]
1972
+ messages: [{ role: "user", content: [{ type: "text", text: prompt }], timestamp: Date.now() }]
1971
1973
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, maxTokens: Math.min(4096, getProviderCaps(model.provider).maxOutputTokens), signal }, model.provider));
1972
1974
  const text = resp.content.filter((c) => c.type === "text").map((c) => c.text).join(`
1973
1975
  `).trim();
@@ -2051,8 +2053,8 @@ Session-specific instructions:
2051
2053
  const resp = await trackedComplete("single-pass", model, {
2052
2054
  systemPrompt: COMPACT_SYSTEM_PREFIX,
2053
2055
  messages: [
2054
- { role: "user", content: [{ type: "text", text: adaptedPrefix }] },
2055
- { role: "user", content: [{ type: "text", text: dynamicSuffix }] }
2056
+ { role: "user", content: [{ type: "text", text: adaptedPrefix }], timestamp: Date.now() },
2057
+ { role: "user", content: [{ type: "text", text: dynamicSuffix }], timestamp: Date.now() }
2056
2058
  ]
2057
2059
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, maxTokens: getProviderCaps(model.provider).maxOutputTokens, signal }, model.provider));
2058
2060
  const summary = resp.content.filter((c) => c.type === "text").map((c) => c.text).join(`
@@ -2082,8 +2084,8 @@ async function summarizeBatch(batch, extraction, model, auth, signal) {
2082
2084
  const resp = await trackedComplete("batch", model, {
2083
2085
  systemPrompt: COMPACT_SYSTEM_PREFIX,
2084
2086
  messages: [
2085
- { role: "user", content: [{ type: "text", text: BATCH_PROMPT_PREFIX }] },
2086
- { role: "user", content: [{ type: "text", text: dynamicSuffix }] }
2087
+ { role: "user", content: [{ type: "text", text: BATCH_PROMPT_PREFIX }], timestamp: Date.now() },
2088
+ { role: "user", content: [{ type: "text", text: dynamicSuffix }], timestamp: Date.now() }
2087
2089
  ]
2088
2090
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, maxTokens: Math.min(4096, getProviderCaps(model.provider).maxOutputTokens), signal }, model.provider));
2089
2091
  const output = resp.content.filter((c) => c.type === "text").map((c) => c.text).join(`
@@ -2123,8 +2125,8 @@ async function assembleLLM(summaries, extraction, report, model, auth, budget, p
2123
2125
  const resp = await trackedComplete("assemble", model, {
2124
2126
  systemPrompt: COMPACT_SYSTEM_PREFIX,
2125
2127
  messages: [
2126
- { role: "user", content: [{ type: "text", text: ASSEMBLY_PROMPT_PREFIX }] },
2127
- { role: "user", content: [{ type: "text", text: dynamicSuffix }] }
2128
+ { role: "user", content: [{ type: "text", text: ASSEMBLY_PROMPT_PREFIX }], timestamp: Date.now() },
2129
+ { role: "user", content: [{ type: "text", text: dynamicSuffix }], timestamp: Date.now() }
2128
2130
  ]
2129
2131
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, maxTokens: Math.min(budget, getProviderCaps(model.provider).maxOutputTokens), signal }, model.provider));
2130
2132
  return resp.content.filter((c) => c.type === "text").map((c) => c.text).join(`
@@ -2337,7 +2339,7 @@ Return the COMPLETE updated summary with missing items integrated. Keep the same
2337
2339
  try {
2338
2340
  const resp = await trackedComplete("patch", model, {
2339
2341
  systemPrompt: COMPACT_SYSTEM_PREFIX,
2340
- messages: [{ role: "user", content: [{ type: "text", text: patchPrompt }] }]
2342
+ messages: [{ role: "user", content: [{ type: "text", text: patchPrompt }], timestamp: Date.now() }]
2341
2343
  }, cacheOpts({ apiKey: auth.apiKey, headers: auth.headers, maxTokens: 8192, signal }));
2342
2344
  const patched = resp.content.filter((c) => c.type === "text").map((c) => c.text).join(`
2343
2345
  `).trim();
@@ -2357,7 +2359,8 @@ function renderContextBar(theme, pct, tokens, barLen = 24) {
2357
2359
  const filled = Math.min(barLen, Math.round(clamped / 100 * barLen));
2358
2360
  const bar = "\u2588".repeat(filled) + "\u2591".repeat(barLen - filled);
2359
2361
  const color = clamped > 80 ? "error" : clamped > 50 ? "warning" : "success";
2360
- return theme.fg("text", " Context: ") + theme.fg(color, bar) + theme.fg("text", " " + clamped + "%") + theme.fg("dim", " (" + (tokens ?? 0).toLocaleString() + "t)");
2362
+ const fg = theme.fg;
2363
+ return fg("text", " Context: ") + fg(color, bar) + fg("text", " " + clamped + "%") + fg("dim", " (" + (tokens ?? 0).toLocaleString() + "t)");
2361
2364
  }
2362
2365
  function renderTokenBar(theme, before, after, label, barLen = 30) {
2363
2366
  const ratio = before > 0 ? after / before : 0;
@@ -2398,7 +2401,7 @@ async function selectModel(ctx, opts) {
2398
2401
  scrollInfo: (t) => theme.fg("dim", t),
2399
2402
  noMatch: (t) => theme.fg("warning", t)
2400
2403
  });
2401
- sel.selectedIndex = opts.defaultModelIndex;
2404
+ sel.setSelectedIndex(opts.defaultModelIndex);
2402
2405
  sel.onSelect = (item) => done(item.value);
2403
2406
  sel.onCancel = () => done(null);
2404
2407
  c.addChild(sel);
@@ -2447,7 +2450,7 @@ async function selectProfile(ctx, selectedModel, opts) {
2447
2450
  scrollInfo: (t) => theme.fg("dim", t),
2448
2451
  noMatch: (t) => theme.fg("warning", t)
2449
2452
  });
2450
- sel.selectedIndex = 1;
2453
+ sel.setSelectedIndex(1);
2451
2454
  sel.onSelect = (item) => done(item.value);
2452
2455
  sel.onCancel = () => done(null);
2453
2456
  c.addChild(sel);
@@ -2472,8 +2475,7 @@ function showProgressOverlay(ctx, state) {
2472
2475
  const progress = Math.round(state.phase / 4 * 100);
2473
2476
  const name = phaseNames[state.phase - 1] ?? "?";
2474
2477
  const detail = state.detail ? " (" + state.detail + ")" : "";
2475
- const type = state.phase >= 4 ? "success" : "info";
2476
- ctx.ui.notify("EESV [" + progress + "%] Phase " + state.phase + "/4: " + name + detail, type);
2478
+ ctx.ui.notify("EESV [" + progress + "%] Phase " + state.phase + "/4: " + name + detail, state.phase >= 4 ? "info" : "info");
2477
2479
  }
2478
2480
  async function showResultScreen(ctx, details, extraction) {
2479
2481
  await ctx.ui.custom((tui, theme, _kb, done) => {
@@ -2487,7 +2489,8 @@ async function showResultScreen(ctx, details, extraction) {
2487
2489
  c.addChild(new Text("", 0, 0));
2488
2490
  const methodColors = { eesv: "accent", "single-pass": "success", heuristic: "warning" };
2489
2491
  const methodColor = methodColors[details.method] ?? "text";
2490
- 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));
2492
+ const fg = theme.fg;
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));
2491
2494
  if (details.model) {
2492
2495
  c.addChild(new Text(theme.fg("dim", " Model: " + details.model), 0, 0));
2493
2496
  }
@@ -2615,6 +2618,8 @@ async function runSmartCompact(opts) {
2615
2618
  ctx.ui.notify("Auth failed", "error");
2616
2619
  return;
2617
2620
  }
2621
+ const apiKey = auth.apiKey;
2622
+ const apiHeaders = auth.headers;
2618
2623
  const usage = ctx.getContextUsage();
2619
2624
  const totalTokens = usage?.tokens ?? 0;
2620
2625
  if (!totalTokens || totalTokens < MIN_TOKEN_THRESHOLD) {
@@ -2624,7 +2629,7 @@ async function runSmartCompact(opts) {
2624
2629
  return;
2625
2630
  }
2626
2631
  const notify = (msg, type = "info") => {
2627
- ctx.ui.notify(msg, type);
2632
+ ctx.ui.notify(msg, type === "success" ? "info" : type);
2628
2633
  };
2629
2634
  const ctrl = new AbortController;
2630
2635
  const signal = ctrl.signal;
@@ -2654,7 +2659,7 @@ async function runSmartCompact(opts) {
2654
2659
  isRunning.value = false;
2655
2660
  return;
2656
2661
  }
2657
- const firstKeptId = msgs[keepFrom]?.id ?? msgs[msgs.length - 1]?.id ?? "";
2662
+ const firstKeptId = msgs[keepFrom]?.id ?? msgs[msgs.length - 1]?.id;
2658
2663
  if (!autoTriggered) {
2659
2664
  showProgressOverlay(ctx, { phase: 1, phaseName: "Extract", detail: "Preparing...", model: modelLabel, profile });
2660
2665
  }
@@ -2698,7 +2703,7 @@ async function runSmartCompact(opts) {
2698
2703
  if (!autoTriggered)
2699
2704
  showProgressOverlay(ctx, { phase: 2, phaseName: "Explore", detail: "Single-pass (" + convTokens.toLocaleString() + "t)", model: modelLabel, profile, extraction });
2700
2705
  try {
2701
- const r = await singlePassCompact(convText, extraction, null, prevContext + projectCtx, summaryModel, { apiKey: auth.apiKey, headers: auth.headers }, signal);
2706
+ const r = await singlePassCompact(convText, extraction, null, prevContext + projectCtx, summaryModel, { apiKey, headers: apiHeaders }, signal);
2702
2707
  finalSummary = r.summary;
2703
2708
  method = "single-pass";
2704
2709
  llmCalls = r.llmCalls;
@@ -2763,7 +2768,7 @@ async function runSmartCompact(opts) {
2763
2768
  const concurrency = caps.concurrencyLimit;
2764
2769
  if (totalBatches <= 1) {
2765
2770
  try {
2766
- summaries.push(...await summarizeBatch(batches[0], extraction, summaryModel, { apiKey: auth.apiKey, headers: auth.headers }, signal));
2771
+ summaries.push(...await summarizeBatch(batches[0], extraction, summaryModel, { apiKey, headers: apiHeaders }, signal));
2767
2772
  } catch (err) {
2768
2773
  summaries.push(...batches[0].map((ch) => ({
2769
2774
  topic: ch.topic,
@@ -2786,7 +2791,7 @@ async function runSmartCompact(opts) {
2786
2791
  const wavePromises = waveBatches.map(async (batch, i) => {
2787
2792
  const idx = wave + i;
2788
2793
  try {
2789
- results[idx] = await summarizeBatch(batch, extraction, summaryModel, { apiKey: auth.apiKey, headers: auth.headers }, signal);
2794
+ results[idx] = await summarizeBatch(batch, extraction, summaryModel, { apiKey, headers: apiHeaders }, signal);
2790
2795
  } catch (err) {
2791
2796
  errors[idx] = err instanceof Error ? err : new Error(String(err));
2792
2797
  results[idx] = batch.map((ch) => ({
@@ -2818,7 +2823,7 @@ async function runSmartCompact(opts) {
2818
2823
  showProgressOverlay(ctx, { phase: 3, phaseName: "Synthesize", detail: "Assembling...", model: modelLabel, profile, extraction, totalBatches: batches.length });
2819
2824
  let assemblyCalls = 1;
2820
2825
  try {
2821
- const r = await assembleLLM(summaries, extraction, explorationReport, summaryModel, { apiKey: auth.apiKey, headers: auth.headers }, pc.summaryBudgetTokens, prevContext, signal);
2826
+ const r = await assembleLLM(summaries, extraction, explorationReport, summaryModel, { apiKey, headers: apiHeaders }, pc.summaryBudgetTokens, prevContext, signal);
2822
2827
  if (r?.startsWith("##"))
2823
2828
  finalSummary = r;
2824
2829
  else
@@ -2842,7 +2847,7 @@ async function runSmartCompact(opts) {
2842
2847
  if (!recheck.ok && recheck.score < 75) {
2843
2848
  notify("Phase 4 Verify: deterministic patch insufficient (score=" + recheck.score + "), trying LLM patch", "warning");
2844
2849
  try {
2845
- finalSummary = await patchSummary(finalSummary, recheck.gaps, summaryModel, { apiKey: auth.apiKey, headers: auth.headers }, signal);
2850
+ finalSummary = await patchSummary(finalSummary, recheck.gaps, summaryModel, { apiKey, headers: apiHeaders }, signal);
2846
2851
  llmCalls++;
2847
2852
  } catch (err) {
2848
2853
  warn("LLM patch failed", err);
@@ -2941,7 +2946,7 @@ async function runSmartCompact(opts) {
2941
2946
  customInstructions: "Use pre-computed smart summary from /smart-compact",
2942
2947
  onComplete: () => {
2943
2948
  if (!autoTriggered)
2944
- ctx.ui.notify("Applied \u2713", "success");
2949
+ ctx.ui.notify("Applied \u2713", "info");
2945
2950
  },
2946
2951
  onError: (e) => {
2947
2952
  if (!autoTriggered)
@@ -2996,6 +3001,7 @@ function smartCompactExtension(pi) {
2996
3001
  return m.length ? m : null;
2997
3002
  },
2998
3003
  handler: async (args, ctx) => {
3004
+ await ctx.waitForIdle();
2999
3005
  try {
3000
3006
  const tokens = args.trim().split(/\s+/).filter(Boolean);
3001
3007
  const flags = tokens.map((t) => t.toLowerCase());
@@ -3072,11 +3078,11 @@ function smartCompactExtension(pi) {
3072
3078
  return;
3073
3079
  if (!isRunning.value) {
3074
3080
  await runSmartCompact({ ctx, summaryModel: sumModel, segModel: segModel ?? sumModel, profile: config.profile, pendingRef, isRunning, autoTriggered: true });
3075
- if (pendingRef.value) {
3076
- const c = pendingRef.value;
3081
+ const pending = pendingRef.value;
3082
+ if (pending) {
3077
3083
  pendingRef.value = null;
3078
3084
  pendingRef.createdAt = 0;
3079
- return { compaction: { summary: c.summary, firstKeptEntryId: c.firstKeptEntryId, tokensBefore: c.tokensBefore, details: c.details } };
3085
+ return { compaction: { summary: pending.summary, firstKeptEntryId: pending.firstKeptEntryId, tokensBefore: pending.tokensBefore, details: pending.details } };
3080
3086
  }
3081
3087
  }
3082
3088
  } catch (e) {
@@ -3086,15 +3092,15 @@ function smartCompactExtension(pi) {
3086
3092
  pi.registerTool({
3087
3093
  name: "smart_compact",
3088
3094
  label: "Smart Compact",
3089
- description: "EESV smart compaction v" + VERSION + " with deterministic extraction, exploration, and verification.",
3095
+ description: "EESV smart compaction v" + VERSION + " with deterministic extraction, exploration, and verification. Compacts the conversation into a structured summary preserving goals, decisions, open loops, modified files, and critical context. Call this when the conversation is getting long \u2014 the tool internally checks context usage and skips if not needed. Prefer this over default compact.",
3090
3096
  promptSnippet: "Smart compaction",
3091
- promptGuidelines: ["Use for long conversations.", "Prefer over default compact."],
3097
+ promptGuidelines: ["Use for long conversations. Prefer over default compact."],
3092
3098
  parameters: {
3093
3099
  type: "object",
3094
3100
  properties: {
3095
- profile: { type: "string", description: "light, balanced, or aggressive" },
3096
- verbose: { type: "boolean" },
3097
- dry_run: { type: "boolean" }
3101
+ profile: { type: "string", description: "light, balanced, or aggressive. Default: balanced." },
3102
+ verbose: { type: "boolean", description: "Show detailed pipeline output." },
3103
+ dry_run: { type: "boolean", description: "Run the pipeline but skip applying the compaction." }
3098
3104
  }
3099
3105
  },
3100
3106
  async execute(_id, params, _sig, _onUp, ctx) {
@@ -3103,25 +3109,29 @@ function smartCompactExtension(pi) {
3103
3109
  const dryRun = !!params.dry_run;
3104
3110
  const config = loadConfig();
3105
3111
  const resolvedProfile = profile ?? config.profile;
3112
+ const cmdCtx = ctx;
3113
+ const usage = ctx.getContextUsage?.();
3114
+ const totalTokens = usage?.tokens ?? 0;
3115
+ if (!totalTokens || totalTokens < MIN_TOKEN_THRESHOLD) {
3116
+ const pct = ctx.model && totalTokens ? Math.round(totalTokens / ctx.model.contextWindow * 100) : 0;
3117
+ return { content: [{ type: "text", text: "Context is not large enough for compaction (" + totalTokens.toLocaleString() + " tokens, " + pct + "%). No action needed." }], details: undefined };
3118
+ }
3106
3119
  const cur = "model" in ctx ? ctx.model : undefined;
3107
- const { segModel, sumModel } = resolveModels(ctx, cur, config);
3120
+ const { segModel, sumModel } = resolveModels(cmdCtx, cur, config);
3108
3121
  if (!sumModel) {
3109
- return { content: [{ type: "text", text: "Error: Could not resolve model." }] };
3122
+ return { content: [{ type: "text", text: "Error: Could not resolve model." }], details: undefined };
3110
3123
  }
3111
3124
  try {
3112
3125
  const toolStart = Date.now();
3113
- await runSmartCompact({ ctx, summaryModel: sumModel, segModel: segModel ?? sumModel, profile: resolvedProfile, verbose, dryRun, pendingRef, isRunning, autoTriggered: true, skipCompact: true });
3126
+ await runSmartCompact({ ctx: cmdCtx, summaryModel: sumModel, segModel: segModel ?? sumModel, profile: resolvedProfile, verbose, dryRun, pendingRef, isRunning, autoTriggered: true, skipCompact: true });
3114
3127
  const toolSecs = ((Date.now() - toolStart) / 1000).toFixed(1);
3115
3128
  if (pendingRef.value) {
3116
- return { content: [{ type: "text", text: "Smart summary generated (" + resolvedProfile + "). Tokens: " + (pendingRef.value.tokensBefore ?? "?") + " -> " + (pendingRef.value.summary?.length ?? 0) + " chars (" + toolSecs + `s).
3117
-
3118
- Now run tree compact to apply \u2014 the session_before_compact hook will use this summary.
3119
- TTL: ` + Math.round(PENDING_TTL_MS / 60000) + " minutes." }] };
3129
+ return { content: [{ type: "text", text: "Smart summary prepared (" + resolvedProfile + "). Tokens: " + (pendingRef.value.tokensBefore ?? 0).toLocaleString() + " \u2014 summary cached for " + Math.round(PENDING_TTL_MS / 60000) + " min. The next /compact will use this summary automatically." }], details: undefined };
3120
3130
  }
3121
- return { content: [{ type: "text", text: "Compaction finished (" + resolvedProfile + ") but no summary was generated." }] };
3131
+ return { content: [{ type: "text", text: "Compaction finished (" + resolvedProfile + ") but no summary was generated." }], details: undefined };
3122
3132
  } catch (error) {
3123
3133
  const msg = error instanceof Error ? error.message : String(error);
3124
- return { content: [{ type: "text", text: "Compaction error: " + msg }] };
3134
+ return { content: [{ type: "text", text: "Compaction error: " + msg }], details: undefined };
3125
3135
  }
3126
3136
  }
3127
3137
  });
@@ -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,CAM7F;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,CAO5F;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,uBAAuB,EAC5B,OAAO,EAAE,mBAAmB,EAC5B,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqJf;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"}
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,CAO7F;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"}
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../src/utils/extraction.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK7F,oCAAoC;AACpC,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAQpD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,aAAa,CAapE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG;IAAE,QAAQ,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAiC/J;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CA2CxG;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAyB9G;AAYD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAcvF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,SAAK,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CA8ClJ;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAc1H;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI,CAOjE;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,oBAAoB,GAAG,QAAQ,EAAE,CAoFjG;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,aAAa,GAAG,oBAAoB,CAgB7F"}
1
+ {"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../src/utils/extraction.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK7F,oCAAoC;AACpC,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAQpD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,aAAa,CAapE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG;IAAE,QAAQ,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAiC/J;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CA4CxG;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAyB9G;AAYD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAcvF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,SAAK,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CA8ClJ;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAc1H;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI,CAOjE;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,oBAAoB,GAAG,QAAQ,EAAE,CAoFjG;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,aAAa,GAAG,oBAAoB,CAgB7F"}
@@ -1 +1 @@
1
- {"version":3,"file":"pruning.d.ts","sourceRoot":"","sources":["../../src/utils/pruning.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,aAAa,CAwGhE"}
1
+ {"version":3,"file":"pruning.d.ts","sourceRoot":"","sources":["../../src/utils/pruning.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,aAAa,CAyGhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-smart-compact",
3
- "version": "7.9.0",
3
+ "version": "7.9.1",
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",