pi-smart-compact 7.7.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +408 -402
  3. package/dist/constants.d.ts +45 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/core.d.ts +27 -0
  6. package/dist/core.d.ts.map +1 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +316 -154
  10. package/dist/phases/explore.d.ts +35 -0
  11. package/dist/phases/explore.d.ts.map +1 -0
  12. package/dist/phases/synthesize.d.ts +23 -0
  13. package/dist/phases/synthesize.d.ts.map +1 -0
  14. package/dist/phases/verify.d.ts +16 -0
  15. package/dist/phases/verify.d.ts.map +1 -0
  16. package/dist/types.d.ts +265 -0
  17. package/dist/types.d.ts.map +1 -0
  18. package/dist/ui/overlays.d.ts +29 -0
  19. package/dist/ui/overlays.d.ts.map +1 -0
  20. package/dist/utils/cache.d.ts +27 -0
  21. package/dist/utils/cache.d.ts.map +1 -0
  22. package/dist/utils/damage.d.ts +28 -0
  23. package/dist/utils/damage.d.ts.map +1 -0
  24. package/dist/utils/extraction.d.ts +27 -0
  25. package/dist/utils/extraction.d.ts.map +1 -0
  26. package/dist/utils/fingerprint.d.ts +32 -0
  27. package/dist/utils/fingerprint.d.ts.map +1 -0
  28. package/dist/utils/helpers.d.ts +22 -0
  29. package/dist/utils/helpers.d.ts.map +1 -0
  30. package/dist/utils/logger.d.ts +8 -0
  31. package/dist/utils/logger.d.ts.map +1 -0
  32. package/dist/utils/pruning.d.ts +19 -0
  33. package/dist/utils/pruning.d.ts.map +1 -0
  34. package/dist/utils/state.d.ts +62 -0
  35. package/dist/utils/state.d.ts.map +1 -0
  36. package/dist/utils/tokens.d.ts +8 -0
  37. package/dist/utils/tokens.d.ts.map +1 -0
  38. package/dist/utils/type-guards.d.ts +26 -0
  39. package/dist/utils/type-guards.d.ts.map +1 -0
  40. package/docs/assets/pi-smart-compact.png +0 -0
  41. package/package.json +10 -2
package/README.md CHANGED
@@ -1,248 +1,418 @@
1
- # Smart Compact
1
+ # pi-smart-compact
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/pi-smart-compact.svg)](https://www.npmjs.com/package/pi-smart-compact)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
5
5
  [![GitHub](https://img.shields.io/badge/GitHub-alpertarhan%2Fpi--smart--compact-blue)](https://github.com/alpertarhan/pi-smart-compact)
6
6
 
7
- > Intelligent, verification-oriented conversation compaction for the [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent).
7
+ <p align="center">
8
+ <img src="./docs/assets/pi-smart-compact.png" alt="pi-smart-compact" width="760" />
9
+ </p>
8
10
 
9
- **Smart Compact** is a Pi extension that compresses long coding sessions by preserving the *working state* of the conversation - not just the words. Instead of blindly truncating old messages, it extracts verified facts, explores ambiguous areas when needed, synthesizes a structured summary, and checks that the result still covers the important parts of the session.
11
+ > Verification-oriented smart compaction for the [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent).
10
12
 
11
- In practice, that means your agent keeps the things that actually matter:
13
+ `pi-smart-compact` replaces blind conversation trimming with a structured compaction pipeline that tries to preserve the agent's working state: goal, files, errors, decisions, constraints, open loops, and cross-compaction deltas.
12
14
 
13
- - the real goal
14
- - exact file paths
15
- - unresolved errors
16
- - decisions already made
17
- - constraints and preferences
18
- - follow-up work still pending
19
- - **open loops** — unresolved tasks that survive compaction
20
- - **delta since last compaction** — what changed, what resolved, what's new
21
- - **structured state** — machine-readable JSON alongside the Markdown summary
15
+ It is built around an **EESV** pipeline:
16
+
17
+ **Extract Explore → Synthesize → Verify**
22
18
 
23
19
  ---
24
20
 
25
21
  ## Table of Contents
26
22
 
27
- - [Why this exists](#why-this-exists)
28
- - [What makes it different](#what-makes-it-different)
29
- - [Design philosophy](#design-philosophy)
30
- - [Inspiration](#inspiration)
31
- - [How it works](#how-it-works)
32
- - [Key capabilities](#key-capabilities)
23
+ - [What this project is](#what-this-project-is)
24
+ - [Current repository snapshot](#current-repository-snapshot)
25
+ - [Visual identity](#visual-identity)
26
+ - [Why it exists](#why-it-exists)
27
+ - [Architecture flow](#architecture-flow)
28
+ - [Execution model](#execution-model)
29
+ - [Repository layout](#repository-layout)
30
+ - [Runtime artifacts](#runtime-artifacts)
33
31
  - [Installation](#installation)
34
- - [Quick start](#quick-start)
32
+ - [Usage](#usage)
35
33
  - [Configuration](#configuration)
36
- - [Output format](#output-format)
37
- - [Architecture details](#architecture-details)
38
- - [Quality and safety controls](#quality-and-safety-controls)
39
- - [Compatibility](#compatibility)
34
+ - [Output contract](#output-contract)
35
+ - [Quality controls](#quality-controls)
36
+ - [Current caveats](#current-caveats)
40
37
  - [Development](#development)
41
- - [Limitations](#limitations)
42
- - [Contributing](#contributing)
43
38
  - [License](#license)
44
39
 
45
40
  ---
46
41
 
47
- ## Why this exists
42
+ ## What this project is
48
43
 
49
- Large coding sessions have a very specific failure mode: the context window fills up, compaction happens, and the agent loses the operational memory required to continue well.
44
+ This package is a **Pi extension** that registers three integration surfaces:
50
45
 
51
- Typical summaries often miss at least one of these:
46
+ | Surface | Where | Purpose |
47
+ | --- | --- | --- |
48
+ | Slash command | `/smart-compact` | Manual compaction, interactive or direct |
49
+ | Session hook | `session_before_compact` | Auto-trigger smart compaction before Pi's default compaction |
50
+ | Tool | `smart_compact` | Agent-callable compaction that stages a pending summary |
52
51
 
53
- - which files were actually changed
54
- - whether an error was resolved or only retried
55
- - what the user explicitly asked for
56
- - which architectural decision already won
57
- - what still needs to happen next
52
+ The extension keeps a short-lived pending compaction in memory, then hands that summary back to Pi when compaction is applied.
58
53
 
59
- For a coding agent, these omissions are expensive. They lead to redundant reads, repeated questions, contradictory edits, or unfinished follow-up work.
54
+ ---
60
55
 
61
- **Smart Compact** is built to reduce those failures.
56
+ ## Current repository snapshot
62
57
 
63
- ---
58
+ **Observed from the current codebase (`README`, `src/`, `test/`, `package.json`)**
64
59
 
65
- ## What makes it different
60
+ - **Package version:** `7.9.1`
61
+ - **Runtime entrypoint:** `dist/index.js`
62
+ - **Source entrypoint:** `src/index.ts`
63
+ - **Source modules:** 18 TypeScript files under `src/`
64
+ - **Tests:** 9 test files, **93 passing tests**
65
+ - **Approx repo footprint:** ~5,091 lines across `src/` + `test/`
66
+ - **Documentation asset:** `docs/assets/pi-smart-compact.png`
67
+ - **Published package files:** `dist/`, `docs/`, `README.md`, `LICENSE`, `CHANGELOG.md`
66
68
 
67
- Smart Compact is not just "another summary prompt." It is a **multi-stage compaction pipeline** with deterministic extraction, targeted exploration, structured synthesis, and verification.
69
+ ### Current command health
68
70
 
69
- That design gives it a few practical advantages over plain truncation or one-shot summarization:
71
+ | Command | Status | Notes |
72
+ | --- | --- | --- |
73
+ | `bun test` | ✅ Pass | 93/93 tests passing |
74
+ | `bun run build` | ✅ Pass | Bundles `src/index.ts` to `dist/index.js` |
75
+ | `bun run typecheck` | ✅ Pass | Strict TypeScript compatibility clean |
70
76
 
71
- - **Deterministic first, LLM second** - verified facts are extracted before any model call
72
- - **Cheaper when possible** - simple sessions skip exploration entirely
73
- - **Safer by default** - summaries are checked for missing files, errors, constraints, and fabricated paths
74
- - **More agent-friendly** - output is structured around goal, progress, decisions, files, next steps, and critical context
75
- - **Better continuity** - follow-up work survives compaction more reliably
77
+ So the project is currently **buildable, tested, and typecheck-clean**.
76
78
 
77
79
  ---
78
80
 
79
- ## Design philosophy
81
+ ## Visual identity
80
82
 
81
- Smart Compact is built around a few core principles:
83
+ The repository image used by this `README.md` now lives at:
82
84
 
83
- ### 1. Accuracy over style
84
- A beautiful summary that invents a file path is worse than a plain summary that is correct.
85
+ - `docs/assets/pi-smart-compact.png`
85
86
 
86
- ### 2. Determinism before generation
87
- Anything we can extract mechanically from the conversation should not be guessed by an LLM.
87
+ The asset is now a cleaned transparent `PNG` instead of a checkerboard/transparent-preview render, so it displays correctly inside GitHub `README.md`.
88
88
 
89
- ### 3. Preserve working state, not transcript fidelity
90
- The goal is not to recreate the whole conversation. The goal is to preserve the information needed to continue the work correctly.
89
+ This keeps documentation assets separate from `src/` implementation code and `test/` fixtures while still shipping the image with the package via `package.json` `files`.
91
90
 
92
- ### 4. Spend tokens where they matter
93
- Easy sessions should stay cheap. Complex sessions should get deeper exploration and better synthesis.
91
+ ---
94
92
 
95
- ### 5. Optimize for real coding sessions
96
- This extension is designed for implementation, debugging, review, and discussion workflows inside Pi - not for generic meeting notes.
93
+ ## Why it exists
94
+
95
+ Default compaction usually loses exactly the things a coding agent needs most:
96
+
97
+ - which files were actually modified
98
+ - which errors are still unresolved
99
+ - what the user explicitly asked for
100
+ - what decisions already won
101
+ - what still needs to happen next
102
+
103
+ `pi-smart-compact` tries to preserve that operational state instead of producing a generic prose summary.
97
104
 
98
105
  ---
99
106
 
100
- ## Inspiration
107
+ ## Architecture flow
108
+
109
+ ```mermaid
110
+ flowchart TD
111
+ A["Entry points<br/>/smart-compact<br/>session_before_compact<br/>smart_compact tool"] --> B["Load config and resolve models<br/>loadConfig()<br/>summaryModel / segmentationModel"]
112
+ B --> C{"Context >= 5000 tokens?"}
113
+ C -- No --> C1["Exit early"]
114
+ C -- Yes --> D["Read current branch<br/>keep recent tail by profile<br/>smartKeepBoundary()"]
115
+ D --> E["Pre-processing<br/>pruneRedundant()<br/>serializeConversation()<br/>backupConversation()<br/>getPreviousCompactionContext()"]
116
+ E --> F["Phase 1: Extract<br/>extractStructured()<br/>files, errors, decisions, constraints,<br/>heuristic topics, timeline, goal"]
117
+ F --> G["Cross-session helpers<br/>load or save cached extraction<br/>deriveProjectId()<br/>loadProjectFingerprint()"]
118
+ G --> H{"Compacted text below singlePassMaxTokens?"}
119
+ H -- Yes --> I["Single-pass path<br/>singlePassCompact()"]
120
+ H -- No --> J{"shouldExplore()?"}
121
+ J -- Yes --> K["Phase 2: Explore<br/>exploreConversation()<br/>tool probe -> tool loop<br/>or direct JSON fallback"]
122
+ J -- No --> L["Skip exploration<br/>use heuristic boundaries only"]
123
+ K --> M["Merge LLM boundaries<br/>with heuristic boundaries"]
124
+ L --> N["chunkLlmMessages()"]
125
+ M --> N
126
+ N --> O["createBatches()<br/>provider-aware concurrency"]
127
+ O --> P["Phase 3: Synthesize<br/>summarizeBatch() per batch<br/>assembleLLM() or assembleFallback()"]
128
+ I --> Q["Phase 4: Verify<br/>verifySummary()"]
129
+ P --> Q
130
+ Q --> R{"Quality score below 85?"}
131
+ R -- No --> S["Accept summary"]
132
+ R -- Yes --> T["patchDeterministic()"]
133
+ T --> U{"Still below 75?"}
134
+ U -- No --> S
135
+ U -- Yes --> V["patchSummary() via LLM"]
136
+ V --> S
137
+ S --> W["Post-processing<br/>extractOpenLoops()<br/>buildCompactionState()<br/>computeDelta()<br/>inject sections"]
138
+ W --> X["Persist artifacts<br/>project fingerprint<br/>compaction state<br/>metrics log<br/>damage report"]
139
+ X --> Y["Store pending compaction<br/>in memory<br/>TTL: 5 minutes"]
140
+ Y --> Z["ctx.compact() now<br/>or next tree compact consumes it"]
141
+ ```
101
142
 
102
- This project is informed by the broader **context engineering** and **agentic context management** space.
143
+ ---
103
144
 
104
- In particular, the design is influenced by:
145
+ ## Execution model
105
146
 
106
- - long-context summarization patterns used in agent systems
107
- - deterministic-plus-LLM hybrid pipelines
108
- - structured memory preservation for coding workflows
109
- - ideas popularized in the ecosystem by people such as **Greg Kamradt** around context quality, retrieval discipline, and practical LLM memory design
147
+ ### 1. Entry and model resolution
110
148
 
111
- Smart Compact is **not** a copy of any single project. It is a Pi-native implementation focused specifically on coding-agent conversations, with strong emphasis on verified facts, exact code references, and safe continuation after compaction.
149
+ `src/index.ts` is the extension boundary.
112
150
 
113
- ---
151
+ It does four jobs:
114
152
 
115
- ## How it works
153
+ 1. registers `/smart-compact`
154
+ 2. registers `session_before_compact`
155
+ 3. registers `smart_compact`
156
+ 4. keeps a shared in-memory `pendingRef` and `isRunning` lock
116
157
 
117
- Smart Compact uses an **EESV** pipeline:
158
+ Model resolution order is effectively:
118
159
 
119
- ```text
120
- Extract Explore Synthesize → Verify
121
- ```
160
+ - explicit command model argument, if provided
161
+ - configured `summaryModel`, if resolvable
162
+ - current session model
163
+ - first available model in the registry
122
164
 
123
- | Phase | Purpose | Typical LLM cost |
124
- | --- | --- | --- |
125
- | **Extract** | Deterministically mine files, errors, decisions, constraints, and topic boundaries | **0 calls** |
126
- | **Explore** | Investigate ambiguous areas with tools and improve topic understanding | 0-8 calls |
127
- | **Synthesize** | Build batch summaries and merge them into one structured compaction summary | N+1 calls |
128
- | **Verify** | Check coverage, detect hallucinations, patch missing facts deterministically first | 0-1 calls |
165
+ `segmentationModel` falls back to the summary model unless explicitly configured.
129
166
 
130
- ### Before EESV
167
+ ### 2. Context gate and keep window
131
168
 
132
- Smart Compact first performs lightweight preprocessing:
169
+ `src/core.ts` is the pipeline orchestrator.
133
170
 
134
- - **redundancy pruning**
135
- - **project fingerprint loading**
136
- - **incremental extraction cache lookup**
171
+ Before compaction starts it:
137
172
 
138
- ### After EESV
173
+ - checks `MIN_TOKEN_THRESHOLD = 5000`
174
+ - reads the current session branch
175
+ - keeps the most recent tail according to the selected profile
176
+ - nudges the keep boundary with `smartKeepBoundary()` if adjacent messages appear to reference the same file
139
177
 
140
- It can also record quality signals for future analysis:
178
+ ### 3. Pre-processing
141
179
 
142
- - re-reads after compaction
143
- - user complaints
144
- - weak continuity indicators
180
+ Before any summarization, the pipeline performs:
145
181
 
146
- ---
182
+ - **redundancy pruning** via `src/utils/pruning.ts`
183
+ - **conversation backup** via `backupConversation()`
184
+ - **previous compaction context injection** via `getPreviousCompactionContext()`
185
+ - **incremental extraction cache lookup** via `src/utils/cache.ts`
186
+ - **project fingerprint lookup** via `src/utils/fingerprint.ts`
147
187
 
148
- ## Key capabilities
188
+ ### 4. Phase 1 — Extract
149
189
 
150
- ### Deterministic extraction
151
- Before asking any model to summarize anything, Smart Compact extracts:
190
+ `src/utils/extraction.ts` is the deterministic core.
152
191
 
153
- - modified, read, and deleted files
154
- - error chains and retry attempts
155
- - explicit and implicit decisions
156
- - user constraints and preferences
192
+ It extracts, with zero LLM calls:
193
+
194
+ - modified files
195
+ - read files
196
+ - deleted files
197
+ - tool and bash-like errors
198
+ - retry / resolution signals
199
+ - explicit decisions from `ask_user`
200
+ - implicit user choices
201
+ - English and Turkish constraints
157
202
  - heuristic topic segments
158
- - main goal and recent user signals
203
+ - timeline events
204
+ - main goal
205
+ - recent user messages
206
+ - recent error snippets
207
+
208
+ It also builds **open loops** from:
159
209
 
160
- ### Adaptive exploration
161
- Not every session needs expensive model-driven exploration.
210
+ - unresolved errors
211
+ - follow-up language
212
+ - blocked/waiting language
213
+ - retried-but-unresolved failures
162
214
 
163
- Simple sessions can skip Phase 2 entirely when they have:
215
+ ### 5. Phase 2 Explore
164
216
 
165
- - few topics
166
- - few unresolved errors
167
- - few decisions
168
- - limited cross-directory work
217
+ `src/phases/explore.ts` adds targeted LLM exploration only when complexity justifies it.
169
218
 
170
- ### Open Loops detection
171
- Every compaction identifies unresolved work and tracks it as **open loops**:
219
+ Exploration is skipped for simple sessions when the extraction stays below these heuristics:
172
220
 
173
- - **bugfix** unresolved errors from tool calls
174
- - **follow-up** user mentions of pending next steps
175
- - **blocked** dependencies waiting on external input
176
- - **retry** retried but still-unresolved failures
221
+ - `<= 3` topics
222
+ - `<= 1` unresolved error
223
+ - `<= 2` decisions
224
+ - `<= 2` directory groups touched
177
225
 
178
- Each loop gets a stable ID, priority, and file references. They appear in both the Markdown summary and the structured JSON state.
226
+ If exploration runs, it can use these tools:
179
227
 
180
- ### Cross-compaction tracking
181
- Smart Compact persists structured state between compactions. On the next compaction, it loads the previous state and computes a **delta**:
228
+ - `get_message_range`
229
+ - `search_conversation`
230
+ - `get_recent_user_messages`
231
+ - `get_context_around`
232
+ - `get_file_changes`
233
+ - `get_error_chain`
182
234
 
183
- - which open loops were resolved
184
- - which are still persistent
185
- - which decisions carried over
186
- - which errors were fixed vs newly introduced
187
- - which files are newly modified
188
- - whether the goal shifted
235
+ If the provider cannot or does not use tools, exploration falls back to a direct JSON analysis prompt.
189
236
 
190
- This means every compaction builds on the last one not from scratch.
237
+ ### 6. Phase 3Synthesize
191
238
 
192
- ### Structured JSON state output
193
- Alongside the human-readable Markdown summary, Smart Compact produces a machine-readable `CompactionState` JSON object:
239
+ `src/phases/synthesize.ts` supports two paths:
194
240
 
195
- - goal, decisions, constraints
196
- - modified/read/deleted files
197
- - unresolved and resolved errors
198
- - open loops with stable IDs
199
- - next actions and critical context
200
- - session type and version
241
+ #### Single-pass
242
+ Used when the pruned conversation fits under the profile's `singlePassMaxTokens`.
201
243
 
202
- This structured state enables better verification, follow-up tracking, and future retrieval integration.
244
+ #### Hierarchical
245
+ Used for larger sessions:
246
+
247
+ - merge heuristic and exploratory boundaries
248
+ - chunk messages with `chunkLlmMessages()`
249
+ - batch chunks with `createBatches()`
250
+ - summarize each batch with `summarizeBatch()`
251
+ - assemble a final summary with `assembleLLM()`
252
+ - fall back to `assembleFallback()` if assembly fails
253
+
254
+ Important synthesis behaviors already present in code:
255
+
256
+ - **decision propagation** into later batch prompts
257
+ - **session-type-specific prompting**
258
+ - **topic-level budget hints** during assembly pre-processing
259
+ - **provider-aware batch concurrency** from `src/utils/tokens.ts`
260
+
261
+ ### 7. Phase 4 — Verify
203
262
 
204
- ### Decision propagation
205
- Batch summaries receive decisions from earlier segments, reducing a common failure mode where later summaries "forget" what was decided earlier.
263
+ `src/phases/verify.ts` scores the summary against deterministic extraction data.
264
+
265
+ It checks for:
266
+
267
+ - missing modified files
268
+ - missing unresolved errors
269
+ - missing high-confidence constraints
270
+ - missing goal coverage
271
+ - missing required sections
272
+ - suspicious fabricated file references
273
+ - done/unresolved inconsistency
274
+ - missing explicit decisions
275
+ - missing open-loop coverage when unresolved errors exist
206
276
 
207
- ### Verification-oriented synthesis
208
- The final summary is checked against extracted facts. If important information is missing, Smart Compact tries to patch it deterministically before spending another LLM call.
277
+ Repair strategy is intentionally ordered:
209
278
 
210
- ### Redundancy pruning
211
- Input is reduced by removing or compressing low-value patterns such as:
279
+ 1. no patch if score is acceptable
280
+ 2. deterministic patch first
281
+ 3. LLM patch only if deterministic patch is insufficient
212
282
 
213
- - duplicate file reads
214
- - repetitive failure chains
215
- - empty acknowledgments
216
- - oversized tool outputs
283
+ ### 8. Post-processing and persistence
217
284
 
218
- ### Cross-session project context
219
- The extension keeps a small project fingerprint so later compactions can reuse context such as:
285
+ After verification, the pipeline:
220
286
 
221
- - dominant language
222
- - likely framework
223
- - important directories
224
- - recently relevant files
287
+ - extracts open loops
288
+ - injects `## Open Loops`
289
+ - builds a machine-readable `CompactionState`
290
+ - loads previous compaction state
291
+ - computes delta across compactions
292
+ - injects `## Changes Since Last Compaction`
293
+ - saves project fingerprint
294
+ - saves compaction state
295
+ - appends metrics log
296
+ - attempts post-compaction damage detection
225
297
 
226
- ### Auto-triggered compaction
227
- When enabled, Smart Compact hooks into Pi's `session_before_compact` event and can replace default blind compaction with a smarter summary.
298
+ ### 9. Applying compaction
299
+
300
+ The extension stores the result in an in-memory pending object containing:
301
+
302
+ - summary
303
+ - first kept entry id
304
+ - tokens before compaction
305
+ - details payload
306
+ - structured compaction state
307
+
308
+ That pending summary is valid for **5 minutes** and is consumed by:
309
+
310
+ - immediate `ctx.compact()` in the slash-command flow, or
311
+ - the next `session_before_compact` hook call in tool-driven flows
312
+
313
+ ---
314
+
315
+ ## Repository layout
316
+
317
+ ### Top-level
318
+
319
+ ```text
320
+ .
321
+ ├── CHANGELOG.md
322
+ ├── DEVPLAN.md
323
+ ├── LICENSE
324
+ ├── README.md
325
+ ├── dist/
326
+ │ └── index.js
327
+ ├── docs/
328
+ │ └── assets/
329
+ │ └── pi-smart-compact.png
330
+ ├── package.json
331
+ ├── src/
332
+ ├── test/
333
+ └── tsconfig.json
334
+ ```
335
+
336
+ ### Source modules
337
+
338
+ | File | Role |
339
+ | --- | --- |
340
+ | `src/index.ts` | Extension registration: command, hook, tool |
341
+ | `src/core.ts` | End-to-end pipeline orchestration |
342
+ | `src/constants.ts` | Version, prompts, profiles, thresholds, config keys |
343
+ | `src/types.ts` | Shared types and guards |
344
+ | `src/phases/explore.ts` | Exploration phase, tool loop, JSON fallback |
345
+ | `src/phases/synthesize.ts` | Chunking, batching, single-pass and hierarchical synthesis |
346
+ | `src/phases/verify.ts` | Verification, deterministic patch, LLM patch |
347
+ | `src/ui/overlays.ts` | 2-step picker UI, progress notices, result screen |
348
+ | `src/utils/cache.ts` | Metrics, cache-aware LLM options, extraction cache |
349
+ | `src/utils/damage.ts` | Post-compaction regression signal detection |
350
+ | `src/utils/extraction.ts` | Deterministic extraction and open-loop detection |
351
+ | `src/utils/logger.ts` | Centralized logging with shared prefix |
352
+ | `src/utils/fingerprint.ts` | Cross-session project fingerprinting |
353
+ | `src/utils/helpers.ts` | Config loading, backups, batching, prompt helpers |
354
+ | `src/utils/pruning.ts` | Redundancy pruning before compaction |
355
+ | `src/utils/state.ts` | Compaction state persistence and delta logic |
356
+ | `src/utils/tokens.ts` | Provider capabilities and token estimation |
357
+ | `src/utils/type-guards.ts` | Shared type guard functions |
358
+
359
+ ### Tests
360
+
361
+ | Test file | Coverage |
362
+ | --- | --- |
363
+ | `test/extraction.test.ts` | deterministic extraction |
364
+ | `test/exploration.test.ts` | exploration parsing and gating |
365
+ | `test/eval.test.ts` | gold scenarios, delta evaluation, fabrication safety |
366
+ | `test/fingerprint.test.ts` | project fingerprint helpers |
367
+ | `test/pruning.test.ts` | redundancy pruning |
368
+ | `test/semantic-compact.test.ts` | legacy-name regression coverage |
369
+ | `test/state.test.ts` | open loops, state, delta, persistence |
370
+ | `test/tokens.test.ts` | token estimation and provider caps |
371
+ | `test/verify.test.ts` | verification and patching |
372
+
373
+ ---
374
+
375
+ ## Runtime artifacts
376
+
377
+ The current code writes to these paths at runtime:
378
+
379
+ | Artifact | Path |
380
+ | --- | --- |
381
+ | Settings file | `~/.pi/agent/settings.json` |
382
+ | Conversation backups | `~/.pi/agent/compact-backups/` |
383
+ | Extraction cache | `~/.pi/agent/.cache/compact-extraction-<session>.json` |
384
+ | Metrics log | `~/.pi/agent/.cache/compact-metrics.jsonl` |
385
+ | Project fingerprints | `~/.pi/agent/.cache/smart-compact/projects/<projectId>.json` |
386
+ | Compaction states | `~/.pi/agent/.cache/smart-compact/states/<projectId>.json` |
387
+ | Damage reports | `~/.pi/agent/.cache/smart-compact/damage-reports.jsonl` |
388
+
389
+ ### TTLs currently implemented
390
+
391
+ | Item | TTL |
392
+ | --- | --- |
393
+ | pending in-memory compaction | 5 minutes |
394
+ | exploration tool-support cache | 30 minutes |
395
+ | extraction cache | 1 hour |
396
+ | compaction state | 7 days |
397
+ | project fingerprint | 30 days |
228
398
 
229
399
  ---
230
400
 
231
401
  ## Installation
232
402
 
233
- ### Recommended: install as a Pi package
403
+ ### npm / Pi package
234
404
 
235
405
  ```bash
236
406
  pi install npm:pi-smart-compact
237
407
  ```
238
408
 
239
- ### Or install from GitHub
409
+ ### GitHub
240
410
 
241
411
  ```bash
242
412
  pi install git:github.com/alpertarhan/pi-smart-compact
243
413
  ```
244
414
 
245
- ### Or work on it locally
415
+ ### Local development
246
416
 
247
417
  ```bash
248
418
  cd ~/.pi/agent/extensions
@@ -252,51 +422,39 @@ bun install
252
422
  bun run build
253
423
  ```
254
424
 
255
- The published package loads the compiled extension entry at **`dist/index.js`**. Source code lives in `src/`, but the package manifest points Pi at `./dist/index.js` for distribution.
256
-
257
425
  ---
258
426
 
259
- ## Quick start
427
+ ## Usage
260
428
 
261
- ### Slash command
429
+ ### Interactive
262
430
 
263
431
  ```bash
264
432
  /smart-compact
265
433
  ```
266
434
 
267
- This opens the interactive picker and lets you choose:
435
+ With no arguments, the extension opens a **2-step TUI**:
268
436
 
269
- - model
270
- - compression profile
437
+ 1. model selection
438
+ 2. profile selection
271
439
 
272
- ### Direct usage
440
+ ### Direct command examples
273
441
 
274
442
  ```bash
275
443
  /smart-compact anthropic/claude-sonnet-4 balanced
276
- ```
277
-
278
- ### Dry run
279
-
280
- ```bash
281
444
  /smart-compact dry-run
282
- ```
283
-
284
- ### Verbose mode
285
-
286
- ```bash
287
445
  /smart-compact debug
446
+ /smart-compact "focus on auth changes and unresolved follow-up work"
288
447
  ```
289
448
 
290
- ### Add steering / follow-up emphasis
449
+ Argument parsing in the current code supports:
291
450
 
292
- ```bash
293
- /smart-compact "focus on auth changes and remaining follow-up work"
294
- ```
451
+ - model ids containing `/`
452
+ - profiles: `light`, `balanced`, `aggressive`
453
+ - flags: `verbose`, `debug`, `dry-run`
454
+ - remaining free text as a user steering note
295
455
 
296
456
  ### Tool usage
297
457
 
298
- Smart Compact also registers an agent-callable tool:
299
-
300
458
  ```json
301
459
  {
302
460
  "name": "smart_compact",
@@ -308,6 +466,12 @@ Smart Compact also registers an agent-callable tool:
308
466
  }
309
467
  ```
310
468
 
469
+ Tool behavior is slightly different from the slash command:
470
+
471
+ - it generates a pending smart summary
472
+ - it does **not** immediately compact when `skipCompact` is used internally
473
+ - it expects the next tree compaction to consume the pending result within 5 minutes
474
+
311
475
  ---
312
476
 
313
477
  ## Configuration
@@ -332,28 +496,29 @@ Add this to `~/.pi/agent/settings.json`:
332
496
  }
333
497
  ```
334
498
 
335
- ### Supported options
336
-
337
- | Option | Type | Default | Meaning |
338
- | --- | --- | --- | --- |
339
- | `profile` | `"light" \| "balanced" \| "aggressive"` | `"balanced"` | Default compaction profile |
340
- | `summaryModel` | `string \| null` | `null` | Override summarization model |
341
- | `segmentationModel` | `string \| null` | `null` | Override exploration model |
342
- | `autoTrigger` | `boolean` | `true` | Run automatically before Pi's built-in compaction |
343
- | `backupEnabled` | `boolean` | `true` | Save a backup before compaction |
344
- | `profiles` | `object` | built-in defaults | Override per-profile budgets |
345
-
346
- ### Profiles
499
+ ### Supported keys
347
500
 
348
- | Profile | Summary budget | Keep recent | Best for |
349
- | --- | --- | --- | --- |
350
- | **light** | 10K | 30K | sessions where more detail should survive |
351
- | **balanced** | 6K | 20K | general daily development |
352
- | **aggressive** | 3K | 10K | large contexts and faster reduction |
501
+ | Key | Type | Default |
502
+ | --- | --- | --- |
503
+ | `profile` | `light \| balanced \| aggressive` | `balanced` |
504
+ | `summaryModel` | `string \| null` | `null` |
505
+ | `segmentationModel` | `string \| null` | `null` |
506
+ | `autoTrigger` | `boolean` | `true` |
507
+ | `backupEnabled` | `boolean` | `true` |
508
+ | `backupDir` | `string` | `~/.pi/agent/compact-backups` |
509
+ | `profiles` | partial per-profile overrides | built-ins |
510
+
511
+ ### Profiles currently shipped
512
+
513
+ | Profile | Summary budget | Keep recent | Min chunk | Max chunk | Single-pass max | Batch max |
514
+ | --- | ---: | ---: | ---: | ---: | ---: | ---: |
515
+ | `light` | 10000 | 30000 | 800 | 12000 | 40000 | 30000 |
516
+ | `balanced` | 6000 | 20000 | 500 | 8000 | 30000 | 24000 |
517
+ | `aggressive` | 3000 | 10000 | 300 | 6000 | 20000 | 18000 |
353
518
 
354
519
  ### Backward compatibility
355
520
 
356
- For migration safety, the extension still accepts the older config key:
521
+ The code still accepts the old config key:
357
522
 
358
523
  - `semanticCompact`
359
524
 
@@ -363,9 +528,9 @@ but the current key is:
363
528
 
364
529
  ---
365
530
 
366
- ## Output format
531
+ ## Output contract
367
532
 
368
- Smart Compact produces structured Markdown designed to be both human-readable and useful to the agent:
533
+ The generated Markdown is expected to follow this structure:
369
534
 
370
535
  ```markdown
371
536
  ## Goal
@@ -384,213 +549,90 @@ Smart Compact produces structured Markdown designed to be both human-readable an
384
549
  ## Topics Covered
385
550
  ```
386
551
 
387
- New sections:
388
-
389
- - **Open Loops** — unresolved tasks with priority and file references
390
- - **Changes Since Last Compaction** — delta from previous compaction state
391
-
392
- The format is intentionally opinionated. It is optimized to preserve:
393
-
394
- - actionable state
395
- - exact references
396
- - unresolved issues
397
- - open loops and follow-up integrity
398
- - state transitions across compactions
399
- - clear continuation paths
400
-
401
- ### Structured JSON output
402
-
403
- In addition to Markdown, Smart Compact produces a structured `CompactionState` object accessible in compaction details:
404
-
405
- ```json
406
- {
407
- "goal": "Build auth module",
408
- "decisions": [{ "id": "decision-1", "summary": "Use JWT", "type": "explicit" }],
409
- "constraints": [{ "id": "constraint-1", "text": "Must use TypeScript", "category": "requirement" }],
410
- "modifiedFiles": ["src/auth.ts"],
411
- "unresolvedErrors": [],
412
- "openLoops": [{ "id": "loop-1", "type": "follow-up", "priority": "normal", "summary": "add tests" }],
413
- "resolvedErrors": [{ "id": "error-1", "message": "login returns undefined", "tool": "bash" }],
414
- "nextActions": ["Add unit tests for auth"],
415
- "sessionType": "implementation",
416
- "compactionVersion": "7.7.0"
417
- }
418
- ```
419
-
420
- ---
421
-
422
- ## Architecture details
423
-
424
- ## 1) Extract
425
-
426
- The extraction phase performs zero-LLM analysis on message structure.
552
+ The extension also builds a structured `CompactionState` object containing:
427
553
 
428
- It identifies:
429
-
430
- - file operations from tool calls and tool results
431
- - no-op edits (`applied: 0`, `no changes`)
432
- - tool errors and bash-like failures
433
- - retries and likely resolutions
434
- - explicit `ask_user` decisions
435
- - implicit user choices such as "use X instead of Y"
436
- - English and Turkish constraint language
437
- - topic boundaries from file transitions, error density, and user shift cues
438
-
439
- ## 2) Explore
440
-
441
- Exploration is only used when the session is complex enough to justify it.
442
-
443
- When active, the model can use tools such as:
444
-
445
- - `get_message_range`
446
- - `search_conversation`
447
- - `get_recent_user_messages`
448
- - `get_context_around`
449
- - `get_file_changes`
450
- - `get_error_chain`
451
-
452
- This phase helps refine:
453
-
454
- - topic boundaries
455
- - cross-topic relationships
456
- - missing constraints
457
- - completion state
458
- - narrative continuity
459
-
460
- ## 3) Synthesize
461
-
462
- Synthesis supports two modes:
463
-
464
- ### Single-pass
465
- Used when the compacted portion is small enough.
466
-
467
- ### Hierarchical
468
- Used for larger sessions:
469
-
470
- - chunk messages into segments
471
- - summarize segments in batches
472
- - propagate prior decisions forward
473
- - merge summaries into one final structured summary
474
-
475
- ## 4) Verify
476
-
477
- Verification checks the final summary against deterministic extraction data.
478
-
479
- It looks for issues such as:
480
-
481
- - missing modified files
482
- - missing unresolved errors
483
- - missing strong constraints
484
- - missing explicit decisions
485
- - missing Open Loops section when unresolved errors exist
486
- - suspicious file references not seen in the conversation
487
- - structural omissions
488
-
489
- If needed, Smart Compact applies:
554
+ - goal
555
+ - decisions
556
+ - constraints
557
+ - modified/read/deleted files
558
+ - unresolved/resolved errors
559
+ - open loops
560
+ - topics
561
+ - next actions
562
+ - critical context
563
+ - session type
564
+ - compaction version
490
565
 
491
- 1. **deterministic patching first**
492
- 2. **LLM patching only if necessary**
566
+ This state is persisted on disk and reused for delta tracking on later compactions.
493
567
 
494
568
  ---
495
569
 
496
- ## Quality and safety controls
497
-
498
- ### Exact-name discipline
499
- Prompts explicitly tell the model to preserve exact file paths, identifiers, and verified facts.
500
-
501
- ### Immutable context framing
502
- Deterministically extracted facts are presented as ground truth during assembly.
570
+ ## Quality controls
503
571
 
504
- ### Verification-first fallback strategy
505
- The extension prefers:
572
+ The current codebase includes these safeguards:
506
573
 
507
- - no patch
508
- - deterministic patch
509
- - LLM patch as last resort
510
-
511
- ### Backups
512
- Conversation backups can be written before compaction.
513
-
514
- ### Metrics
515
- The pipeline tracks:
516
-
517
- - call counts
518
- - input/output token volume
519
- - cache hit rate
520
- - average latency
521
-
522
- ### Incremental extraction cache
523
- Structured extraction results are cached per session to avoid reprocessing unchanged history.
524
-
525
- ### Cross-compaction state persistence
526
- After each compaction, the structured state is persisted to disk. On the next compaction, Smart Compact:
527
-
528
- 1. loads the previous state
529
- 2. computes a delta (resolved loops, new errors, goal shifts, etc.)
530
- 3. injects `## Changes Since Last Compaction` into the summary
531
- 4. saves the updated state for the next cycle
532
-
533
- This creates a **compaction memory chain** — every compaction builds on the last.
574
+ - deterministic extraction before any summarization
575
+ - adaptive exploration skip for simple sessions
576
+ - project fingerprint reuse across sessions
577
+ - incremental extraction cache
578
+ - provider-aware token estimation and concurrency
579
+ - deterministic verification scoring
580
+ - deterministic patch before LLM patch
581
+ - hallucinated file-reference detection
582
+ - open-loop injection
583
+ - cross-compaction delta injection
584
+ - post-compaction damage detection
585
+ - backup creation before compaction
586
+ - metrics logging for LLM cost/latency/cache usage
534
587
 
535
588
  ---
536
589
 
537
- ## Compatibility
538
-
539
- Smart Compact is designed as a standalone Pi extension, but it is also intended to fit naturally into richer Pi setups.
590
+ ## Current caveats
540
591
 
541
- It should be a good conceptual fit alongside workflow-oriented extensions and packages such as:
592
+ To keep this README aligned with the repository's **actual** current state:
542
593
 
543
- - `pi-agent-flow`
544
- - `pi-simplify`
545
- - `pi-lens`
546
-
547
- As always with Pi packages, review interactions in your own environment if you combine multiple extensions that hook into related session flows.
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`).
548
597
 
549
598
  ---
550
599
 
551
600
  ## Development
552
601
 
553
- ### Project structure
602
+ ### Install
554
603
 
555
- ```text
556
- src/ TypeScript source
557
- dist/ compiled package entry for distribution
558
- test/ Bun tests
559
- README.md package documentation
604
+ ```bash
605
+ bun install
560
606
  ```
561
607
 
562
- ### Test suite
563
-
564
- Smart Compact has **91 tests** across 9 files, including:
565
-
566
- - **Unit tests** — extraction, tokens, verification, pruning, fingerprint, exploration
567
- - **State tests** — open loops, compaction state, delta computation, state persistence
568
- - **Evaluation harness** — 5 gold conversation scenarios with expected extraction results, delta evaluation across compactions, and fabrication safety checks
608
+ ### Test
569
609
 
570
610
  ```bash
571
- bun test # run all 91 tests
572
- bun test test/eval.test.ts # evaluation harness only
611
+ bun test
612
+ bun test test/eval.test.ts
573
613
  ```
574
614
 
575
- ### Local commands
615
+ ### Build
576
616
 
577
617
  ```bash
578
- bun install
579
618
  bun run build
580
- bun run typecheck
581
619
  ```
582
620
 
583
- ### Build output
621
+ Current build command:
584
622
 
585
- Published builds use:
623
+ ```bash
624
+ rm -rf dist && mkdir dist && bun build ./src/index.ts --outdir ./dist --target bun --external '@earendil-works/*' --external 'typebox'
625
+ ```
586
626
 
587
- - `dist/index.js`
627
+ ### Typecheck
588
628
 
589
- This keeps the distributed package aligned with common npm packaging expectations while preserving a TypeScript-first source layout during development.
629
+ ```bash
630
+ bun run typecheck
631
+ ```
590
632
 
591
- ### Local package path
633
+ At the moment, this command passes cleanly.
592
634
 
593
- If you are developing inside Pi directly, this project commonly lives at:
635
+ ### Typical local path inside Pi
594
636
 
595
637
  ```text
596
638
  ~/.pi/agent/extensions/pi-smart-compact
@@ -598,42 +640,6 @@ If you are developing inside Pi directly, this project commonly lives at:
598
640
 
599
641
  ---
600
642
 
601
- ## Limitations
602
-
603
- Smart Compact is strong, but it is not magic.
604
-
605
- A few honest limitations:
606
-
607
- - it still depends on model quality during exploration and synthesis
608
- - very noisy sessions can still produce weaker summaries than ideal
609
- - verification is strong for extracted facts, but not a formal proof system
610
- - project fingerprints are intentionally lightweight, not a full memory database
611
- - token estimates are calibrated heuristics, not exact provider tokenizers
612
-
613
- ---
614
-
615
- ## Contributing
616
-
617
- Issues, suggestions, and pull requests are welcome.
618
-
619
- If you contribute, the best changes tend to be:
620
-
621
- - measurable
622
- - easy to validate with tests
623
- - explicit about quality/cost trade-offs
624
- - careful about hallucination risk and continuation quality
625
-
626
- Typical flow:
627
-
628
- ```bash
629
- git checkout -b feat/my-change
630
- bun test
631
- bun run build
632
- git commit -m "feat: ..."
633
- ```
634
-
635
- ---
636
-
637
643
  ## License
638
644
 
639
645
  MIT © [Alper Tarhan](https://github.com/alpertarhan)