kompactor 0.5.0__tar.gz

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 (42) hide show
  1. kompactor-0.5.0/LICENSE +21 -0
  2. kompactor-0.5.0/PKG-INFO +274 -0
  3. kompactor-0.5.0/README.md +251 -0
  4. kompactor-0.5.0/kompactor/__init__.py +3 -0
  5. kompactor-0.5.0/kompactor/__main__.py +4 -0
  6. kompactor-0.5.0/kompactor/_launch.py +22 -0
  7. kompactor-0.5.0/kompactor/cli.py +446 -0
  8. kompactor-0.5.0/kompactor/config.py +231 -0
  9. kompactor-0.5.0/kompactor/estimate.py +145 -0
  10. kompactor-0.5.0/kompactor/filters.py +617 -0
  11. kompactor-0.5.0/kompactor/graph.py +1398 -0
  12. kompactor-0.5.0/kompactor/hooks.py +353 -0
  13. kompactor-0.5.0/kompactor/installer.py +344 -0
  14. kompactor-0.5.0/kompactor/langs.py +102 -0
  15. kompactor-0.5.0/kompactor/outline.py +274 -0
  16. kompactor-0.5.0/kompactor/prove.py +317 -0
  17. kompactor-0.5.0/kompactor/rules.py +54 -0
  18. kompactor-0.5.0/kompactor/samples.py +217 -0
  19. kompactor-0.5.0/kompactor/server.py +301 -0
  20. kompactor-0.5.0/kompactor/shellwrap.py +149 -0
  21. kompactor-0.5.0/kompactor/static/fonts/OFL.txt +93 -0
  22. kompactor-0.5.0/kompactor/static/fonts/plex-mono-400.woff2 +0 -0
  23. kompactor-0.5.0/kompactor/static/fonts/plex-mono-500.woff2 +0 -0
  24. kompactor-0.5.0/kompactor/static/fonts/plex-sans-400.woff2 +0 -0
  25. kompactor-0.5.0/kompactor/static/fonts/plex-sans-500.woff2 +0 -0
  26. kompactor-0.5.0/kompactor/static/fonts/plex-sans-600.woff2 +0 -0
  27. kompactor-0.5.0/kompactor/static/logo-mark.svg +5 -0
  28. kompactor-0.5.0/kompactor/static/usage.html +342 -0
  29. kompactor-0.5.0/kompactor/store.py +213 -0
  30. kompactor-0.5.0/kompactor/tokens.py +29 -0
  31. kompactor-0.5.0/kompactor/ui.html +749 -0
  32. kompactor-0.5.0/kompactor.egg-info/PKG-INFO +274 -0
  33. kompactor-0.5.0/kompactor.egg-info/SOURCES.txt +40 -0
  34. kompactor-0.5.0/kompactor.egg-info/dependency_links.txt +1 -0
  35. kompactor-0.5.0/kompactor.egg-info/entry_points.txt +2 -0
  36. kompactor-0.5.0/kompactor.egg-info/requires.txt +3 -0
  37. kompactor-0.5.0/kompactor.egg-info/top_level.txt +1 -0
  38. kompactor-0.5.0/pyproject.toml +42 -0
  39. kompactor-0.5.0/setup.cfg +4 -0
  40. kompactor-0.5.0/tests/test_graph.py +367 -0
  41. kompactor-0.5.0/tests/test_kompactor.py +572 -0
  42. kompactor-0.5.0/tests/test_shell.py +278 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 The Kompactor authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.4
2
+ Name: kompactor
3
+ Version: 0.5.0
4
+ Summary: Cut the tokens Claude Code spends on noise: compacted command output (failing runs included), outline-first reads, a local code graph, and per-turn savings.
5
+ License-Expression: MIT
6
+ Project-URL: Repository, https://github.com/amarkum/kompactor
7
+ Project-URL: Issues, https://github.com/amarkum/kompactor/issues
8
+ Keywords: claude,claude-code,tokens,context,llm,hooks,code-graph
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Software Development
16
+ Classifier: Topic :: Utilities
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Provides-Extra: exact
21
+ Requires-Dist: tiktoken>=0.7; extra == "exact"
22
+ Dynamic: license-file
23
+
24
+ <p align="center">
25
+ <picture>
26
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/amarkum/kompactor/main/docs/brand/kompactor-logo-dark.png">
27
+ <img src="https://raw.githubusercontent.com/amarkum/kompactor/main/docs/brand/kompactor-logo-light.png" alt="Kompactor" width="240">
28
+ </picture>
29
+ </p>
30
+
31
+ <p align="center"><b>Cut the tokens Claude Code spends on noise.</b><br>
32
+ Choose quality vs tokens on a dashboard, and see what every turn saved.</p>
33
+
34
+ <p align="center">Claude Code CLI and VS Code · Python, Go, TypeScript, React · Python standard library only · MIT</p>
35
+
36
+ ---
37
+
38
+ Most of a Claude Code session's tokens aren't your prompt or Claude's answer. They're tool output: test runs, installs, `git log`, whole-file reads. That output is sent again on every later turn until the context is compacted. Kompactor shrinks it before Claude reads it. It keeps every error, failing test, your own stack frames and the summary lines. It also gives Claude a local code graph and short rules for terser replies and smaller diffs.
39
+
40
+ **Measured in real Claude Code sessions** on Flask, Cobra, SWR, ky and zustand: **−16% tokens, −10% cost, −22% output tokens** at the default level, with the same answers (27/27 correct with and without).
41
+ Failing test runs and code search saved the most: **−33% tokens** on a Go test failure, **−32%** finding code in a TypeScript repo, and **−37% cost** on a vitest failure.
42
+ [Full results](#evidence)
43
+
44
+ ![Kompactor dashboard: savings per turn](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/dashboard-overview.png)
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install kompactor
50
+ kompactor setup
51
+ ```
52
+
53
+ Setup enables Kompactor for Claude Code and opens the dashboard; restart Claude Code afterwards. Kompactor needs Python 3.9 or newer and nothing else. `pipx install kompactor` or `uv tool install kompactor` keep it in its own environment, and `pip install -U kompactor` updates it.
54
+
55
+ The CLI and the VS Code extension read the same `~/.claude/settings.json`, so one install covers both. Setup adds Kompactor's hooks, a status line (only if you don't have one) and the `/kompactor` skill. On macOS and Linux it also sets `CLAUDE_CODE_SHELL_PREFIX`. It never replaces a status line or shell prefix you already have, and it keeps a backup in `settings.json.kompactor-backup`. `kompactor install --uninstall` removes all of it.
56
+
57
+ **As a Claude Code plugin.** Run these in any Claude Code session, one at a time:
58
+ ```
59
+ /plugin marketplace add amarkum/kompactor
60
+ /plugin install kompactor@kompactor
61
+ /kompactor setup
62
+ ```
63
+ The last step adds the status line and the shell prefix that compacts failing commands, which a plugin can't set itself. `claude plugin update kompactor@kompactor` updates it.
64
+
65
+ **VS Code.** Install the extension file from [`dist/`](https://github.com/amarkum/kompactor/tree/main/dist) (`code --install-extension kompactor-0.5.0.vsix`, or Extensions › `⋯` › *Install from VSIX…*), then click **Enable** when Kompactor asks. The status bar starts showing savings.
66
+
67
+ **Without pip** (macOS, Linux): `git clone https://github.com/amarkum/kompactor.git && ./kompactor/install.sh`. On Windows, run `.\kompactor\install.ps1` from the clone.
68
+
69
+ ## What it does
70
+
71
+ | When | Kompactor | How |
72
+ |---|---|---|
73
+ | Claude runs a command | Drops passing tests, progress bars, download chatter, library stack frames and lock-file diffs. Keeps errors, failures, your frames and summaries. The raw output is stashed (`kompactor show <id>`). | `PostToolUse` hook |
74
+ | A command **fails** | Claude Code skips output hooks when a command exits non-zero, and cuts the output to its first and last ~5K characters, usually losing the failures at the end. Kompactor's shell prefix runs tests, builds, linters and installs to completion, compacts them, and passes the exit code through. Your permission rules still apply to Claude's original command. | `CLAUDE_CODE_SHELL_PREFIX` |
75
+ | A command prints over ~30K chars | Claude Code saves it to a file and shows Claude a 2 KB preview. Kompactor compacts the whole saved output instead. | `PostToolUse` hook |
76
+ | Claude opens a big source file | Returns its outline first: symbols with line ranges, signatures, who imports it and which tests cover it. Claude then reads only what it needs, and repeating the read returns the whole file. Unchanged re-reads get a one-line note. | `PreToolUse` hook |
77
+ | Claude first searches or reads code | A budgeted map of the most depended-on modules, given once (sessions that only run commands don't pay for it). | `PostToolUse` context |
78
+ | Anytime | A local code graph for Python, Go, TypeScript, JavaScript and React: find code by topic, callers, impact of a change with the tests to run, import cycles, dead code. | `kompactor graph …`, dashboard |
79
+ | Every reply, subagents too | Two dials. Prose: answer first, no preamble or recap. Code: change nothing if possible, reuse before writing, smallest diff, one focused test, never cut validation or security. 0 to 177 tokens of rules, depending on level. | `SessionStart`, `SubagentStart` |
80
+ | After each turn | What the turn saved, in the reply, the CLI status line, the VS Code status bar and the dashboard. | `Stop` hook |
81
+
82
+ Kompactor never changes what a command does. It can't strand Claude: every trimmed output has a raw copy, and every blocked read is "deny once, allow on retry". Every hook fails open.
83
+
84
+ ## Quality vs tokens
85
+
86
+ ![Quality vs tokens with a live preview](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/dashboard-quality.png)
87
+
88
+ One level sets every option. Every option can also be changed on its own, globally or per project, on the dashboard. There's no config file to edit.
89
+
90
+ | Level | What Claude gets | Rules injected |
91
+ |---|---|---:|
92
+ | 1 Max quality | Almost everything. Only outputs over ~1.5k tokens are touched, and only pure noise is removed. Failing commands are compacted too, gently. | 0 |
93
+ | 2 Quality | Noisy commands compacted, passing tests hidden, one-line `git log`, outlines for files over 800 lines. Answer-first replies. | 72 |
94
+ | 3 **Balanced** (default) | Outlines from 400 lines, library frames trimmed, a 500-token code map, lean-code rules. | 156 |
95
+ | 4 Savings | Tighter caps, 3 lines of diff context, outlines from 250 lines, test-runner banners dropped, shorter prose. | 176 |
96
+ | 5 Max savings | 80-line caps, 1 line of diff context, outlines from 150 lines, telegraphic prose. | 177 |
97
+
98
+ Change the level from the dashboard (`kompactor ui`, or **Kompactor: Open Dashboard** in VS Code), the VS Code status bar, or in Claude Code chat (`/kompactor max savings`, `/kompactor balanced`). A repo can have its own level under **Projects & languages**.
99
+
100
+ To give everyone who works in a repo the same level, commit a `.kompactor.json` next to the code:
101
+ ```json
102
+ { "preset": 4, "overrides": { "never_compact": ["terraform plan"] } }
103
+ ```
104
+ `preset` is the level (1 Max quality to 5 Max savings); `overrides` sets any option by the names in `kompactor config`. The repo's file beats your global level, and your own choice for that project still wins.
105
+
106
+ ## See the savings, per turn
107
+
108
+ | Where | What you see |
109
+ |---|---|
110
+ | Claude Code, after each reply | `Kompactor: −8.2k tokens this turn (13.1k › 4.9k, −63%) · session −41k · context ≈31% smaller` |
111
+ | CLI status line | `Kompactor −41.3k · ctx −31% · last turn −8.2k · Balanced` |
112
+ | VS Code status bar | Running savings. Each turn flashes its saving, and hovering shows details. |
113
+ | Dashboard | Per-turn chart, biggest wins, savings by feature and by project. |
114
+ | `kompactor estimate` | Replays your past sessions through the current settings: the share of tool output, billed tokens and cost Kompactor would have saved. |
115
+
116
+ The numbers are conservative. Savings count only what Claude would really have read. When Claude Code would have truncated an output anyway, only the truncated size counts. When Claude reads a whole file after its outline, the outline's saving is reversed.
117
+
118
+ ## Code graph
119
+
120
+ ![Code graph: module map and a query](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/dashboard-graph.png)
121
+
122
+ `kompactor graph build` indexes a repo in about a second (Flask: 85 files in 0.33 s). It runs in the background at session start and after edits. Nothing is sent anywhere and nothing is written to the repo.
123
+
124
+ ```
125
+ kompactor graph query "session cookie" find code by topic, with line ranges and who uses it
126
+ kompactor graph impact createStore files that use it, files that only import its module, tests to run
127
+ kompactor graph explain Name one symbol: signature, callers, callees, tests
128
+ kompactor graph callers / deps / path who calls it, what it imports, how two modules connect
129
+ kompactor graph report core modules, entry points, import cycles, tests by module
130
+ kompactor graph unused dead-code candidates (exported-but-unused listed separately)
131
+ ```
132
+
133
+ `/kompactor review`, `/kompactor audit` and `/kompactor debt` in chat use the graph to find duplicated helpers, dead code and shortcuts.
134
+
135
+ ## How it compares
136
+
137
+ Kompactor borrows the best idea from each of these tools: graphify's code graph, ponytail's lean-code ladder, caveman's terse prose, rtk's command filters, context-mode's raw-output stash, and the symbol-level reads of token-savior and code-review-graph. It then fixes the gaps that independent tests found. Researched in October 2026 from each project's repo and the independent tests linked below.
138
+
139
+ **Features** (Yes, Partly, or —):
140
+
141
+ | | Kompactor | [graphify](https://github.com/Graphify-Labs/graphify) | [ponytail](https://github.com/DietrichGebert/ponytail) | [caveman](https://github.com/JuliusBrussee/caveman) | [rtk](https://github.com/rtk-ai/rtk) | [token-savior](https://github.com/Mibayy/token-savior) | [context-mode](https://github.com/mksglu/context-mode) | [code-review-graph](https://github.com/tirth8205/code-review-graph) |
142
+ |---|---|---|---|---|---|---|---|---|
143
+ | Compacts command output | **Yes**, incl. failing runs | — | — | Partly (v4 proxy) | Yes, 100+ commands | Partly (opt-in) | Yes (sandbox) | — |
144
+ | Outline / symbol-level reads | **Yes**, automatic | Partly (strict mode) | Partly | Partly | Partly (`rtk read`) | Yes (MCP) | — | Yes (MCP) |
145
+ | Code graph and change impact | **Yes** (Py, Go, TS, React) | Yes, plus docs and images via an LLM | — | — | — | Yes | — | Yes |
146
+ | Terse-prose rules | **Yes**, 4 levels | — | Partly | Yes | — | — | — | — |
147
+ | Lean-code rules | **Yes** | — | Yes | Partly | — | Partly | — | — |
148
+ | Quality vs tokens control | **Yes**: 5 levels, every option, per project | Flags and env vars | 3 levels | Levels | TOML | Profiles | — | Partly |
149
+ | Per-turn savings shown | **Yes**: reply, status line, VS Code, dashboard | — | Partly (not in VS Code) | — | On demand (`rtk gain`) | — | Yes | Partly |
150
+ | Settings dashboard | **Yes** | Graph export | Yes | Partly | Partly | Yes | Hosted | Partly |
151
+ | VS Code | **Yes**, with its own extension | Yes | Partly | Yes | Yes | Partly | Yes | Yes |
152
+ | Real A/B evidence in the repo | **Yes**, with cost and correctness | Corpus ÷ answer ratio | Yes | Yes | — | Withdrawn, then partial | — | Upper bound |
153
+ | Dependencies | **None** (Python 3.9+ stdlib) | Python 3.10+, LLM for docs | Node | npm CLI, telemetry on by default | Rust binary | pip, MCP | MCP server (ELv2) | pip, tree-sitter |
154
+
155
+ **What happened when others measured them:**
156
+
157
+ | Tool | Activation in practice | Its own instructions | Independent result |
158
+ |---|---|---|---|
159
+ | **Kompactor** | Hooks act on every tool call, so Claude doesn't have to choose to use them | 0–177 tokens of rules + a 63-token skill entry | −16% tokens, −10% cost, 27/27 correct ([evidence](#evidence); self-run, reproducible with `kompactor prove`) |
160
+ | graphify | Nudges Claude to query the graph. An 87-session analysis found 4% of nudges followed; the nudges cost about 651k tokens against 176k from graphify's own answers ([#3435](https://github.com/Graphify-Labs/graphify/issues/3435)) | ~11k-token skill | 7.3× on code-only questions in one test. The 71.5× headline divided the whole corpus by one answer and has been dropped from its README |
161
+ | ponytail | Hooks inject its rules. As a plain skill it activated in 0 of 10 runs | Rules + a codebase map at each start | Cost −10.3%, code −15%, quality unchanged ([JetBrains](https://blog.jetbrains.com/ai/2026/07/ponytail-skill-claude-tested/), ~80 tasks) |
162
+ | caveman | Hooks inject its rules | ~1,160 tokens | Output −8.5%, cost ≈ −10% per task ([JetBrains](https://blog.jetbrains.com/ai/2026/07/speak-to-ai-agents-like-cavemen-tosave-tokens/)) |
163
+ | rtk | A hook rewrites commands; the rewrites bypass permission rules (rtk #4644) | None | Cost +7.6% at low effort, ±0% at high ([JetBrains](https://blog.jetbrains.com/ai/2026/07/rtk-claude-code-token-savings/), 86 tasks). `rtk gain` counts all raw output, and reported 96.2M tokens saved while the bill rose |
164
+ | token-savior | Only when Claude calls its MCP tools: 1 of 143 sessions in a re-measurement it later withdrew | ~1.5k tokens of tool schemas (15 tools) and up | −43% tokens, −13% cost in one run ([computingforgeeks](https://computingforgeeks.com/reduce-claude-code-token-usage-tools/)) |
165
+ | context-mode | Hooks route big outputs into its sandbox; retrieval is via MCP | 11 tool schemas | No independent measurement found |
166
+ | code-review-graph | Only when Claude calls its MCP tools | 30 tool schemas | −5% in one run ([computingforgeeks](https://computingforgeeks.com/reduce-claude-code-token-usage-tools/)) |
167
+
168
+ **Where Kompactor is better**
169
+ - **It works without being asked.** Graph tools and MCP servers save nothing when Claude doesn't call them, and the data above shows how often that happens. Kompactor's savings come from hooks on every tool call. In the A/B runs, Claude never had to run a Kompactor command for them to apply.
170
+ - **It handles the failing run.** That's where the noisiest output is, and where Claude Code itself drops the useful part. rtk handles failures too, but by rewriting commands, which bypasses your permission rules. Kompactor acts after the permission check, on Claude's original command, with the exit code unchanged.
171
+ - **Its own instructions are small.** 156 tokens at the default level, against ~1,160 for caveman and an ~11k-token skill for graphify. The code map only appears once Claude starts exploring code.
172
+ - **Its savings numbers are honest.** It counts what Claude would actually have read, not raw output size, and it reverses a saving when Claude reads the full file anyway.
173
+ - **It's proven on cost and correctness, not just token counts.** `kompactor prove` reruns the same tasks with and without Kompactor in real Claude Code sessions, and the results are in this repo.
174
+ - **One control covers every layer**, from a dashboard, with a live preview of exactly what Claude would see.
175
+
176
+ **Where others are stronger**
177
+ - graphify builds a multimodal graph: docs, PDFs and images through an LLM, about 40 languages, Obsidian and Neo4j exports. Kompactor's graph covers Python, Go, TypeScript, JavaScript and React code only.
178
+ - rtk has native filters for 100+ commands at under 10 ms each. Kompactor's filters cover the common dev commands and run in Python (50–100 ms per hook).
179
+ - context-mode runs code in a sandbox and indexes huge outputs such as Playwright snapshots. token-savior keeps memory across sessions. Kompactor does neither.
180
+
181
+ ## Evidence
182
+
183
+ `kompactor prove` runs each task in real headless Claude Code sessions (`claude -p`). Each task runs 3 times without Kompactor and 3 times with it, interleaved, with the same prompt, tools, turn limit and budget cap. Kompactor runs as an installed plugin at the default level. Tokens are input + cache writes + cache reads + output across every API call, and cost is Claude Code's own figure.
184
+
185
+ | Task | Repo | Tokens | Cost | Turns | Correct (without › with) |
186
+ |---|---|---:|---:|---|---|
187
+ | Find the failing Go test and its error | Cobra | **−33%** | **−18%** | 3.3 › 2.0 | 3/3 › 3/3 |
188
+ | Find how requests are deduplicated | SWR | **−32%** | −12% | 3.0 › 2.0 | 3/3 › 3/3 |
189
+ | Find where the session cookie is signed | Flask | **−26%** | −11% | 3.7 › 2.7 | 3/3 › 3/3 |
190
+ | Find the flag-group validation function | Cobra | −24% | −6% | 2.7 › 2.3 | 3/3 › 3/3 |
191
+ | Most-changed files in the last 40 commits | Flask | −16% | +4% | 3.7 › 3.0 | 3/3 › 3/3 |
192
+ | Find the failing vitest test (`--reporter=verbose`) | zustand | −7% | **−37%** | 2.0 › 2.0 | 3/3 › 3/3 |
193
+ | Type-check and list errors | ky | +1% | −2% | 2.0 › 2.0 | 3/3 › 3/3 |
194
+ | Find the failing pytest tests | Flask | +1% | +3% | 2.0 › 2.0 | 3/3 › 3/3 |
195
+ | What does changing `createStore` affect | zustand | +17% | +4% | 2.0 › 2.3 | 3/3 › 3/3 |
196
+ | **Total (54 sessions)** | | **−16%** | **−10%** | | **27/27 › 27/27** |
197
+
198
+ The same 27 Kompactor sessions were also run at both ends of the quality-vs-tokens range, against the same baseline:
199
+
200
+ | Level | Tokens | Cost | Output tokens | Correct |
201
+ |---|---:|---:|---:|---|
202
+ | 1 Max quality | +3% | −1% | 0% | 27/27 |
203
+ | 3 Balanced (default) | **−16%** | **−10%** | **−22%** | 27/27 |
204
+ | 5 Max savings | −12% | −10% | −22% | 27/27 |
205
+
206
+ What the numbers show:
207
+ - **The wins come from avoided turns.** Every turn re-sends the whole context. The vitest failure was 32K characters of passing tests; Kompactor handed Claude 1K characters with the failure, at 37% lower cost. On the Go failure, Claude got the answer in one run instead of piping through `tail` and `grep` three or four times. On code search, the code map and outlines saved a turn.
208
+ - **Levels show up per command more than per session.** Max quality barely touches output, so it's close to neutral. Balanced and Max savings land within run-to-run noise of each other here, because most of every session is Claude Code's own fixed context, and turns saved matter more than how hard each output is squeezed. The difference shows per command (next table).
209
+ - **Short sessions pay a small fixed cost.** On 2-turn tasks whose output was already small, Kompactor's rules and skill entry add about 1%. One of three `createStore` runs took an extra turn, which is the +17%.
210
+ - **Two experiments shaped the defaults.** Telling Claude not to pipe output through `tail` cost **+33%** tokens before the shell prefix existed, and **−9%** with it, so that rule is only on while the prefix is active. An earlier Max-savings round lost 2 of 27 answers when the 80-line cap cut a list Claude had asked for with `git log --format`; output Claude shapes itself is now kept verbatim ([notes](https://github.com/amarkum/kompactor/blob/main/evidence/README.md)).
211
+
212
+ Full report: [evidence/REPORT.md](https://github.com/amarkum/kompactor/blob/main/evidence/REPORT.md). Every session's tokens, tool calls and answers: [evidence/results.json](https://github.com/amarkum/kompactor/blob/main/evidence/results.json). To see exactly what Claude received in each arm for the same failing test run (15,617 vs 1,039 characters), read [evidence/EXAMPLE.md](https://github.com/amarkum/kompactor/blob/main/evidence/EXAMPLE.md).
213
+
214
+ ### Command output, measured directly
215
+
216
+ Tokens Claude receives for single commands on real repos (`bench/bench.py`):
217
+
218
+ | Repo | Command | Raw | Balanced | Max savings |
219
+ |---|---|---:|---:|---:|
220
+ | Flask | `pytest -v tests` (1 failure, 482 passed) | 9,842 | 1,138 (**−88%**) | 696 (**−93%**) |
221
+ | Flask | `grep -rn 'def ' src` | 8,492 | 3,230 (−62%) | 1,323 (−84%) |
222
+ | Flask | `git log -n 40` | 1,457 | 598 (−59%) | 598 (−59%) |
223
+ | ky | `npm install` (fresh) | ~33,000 | 469 (**−99%**) | 451 (−99%) |
224
+ | ky | `grep -rn await source` | 2,938 | 1,653 (−44%) | 1,058 (−64%) |
225
+ | Flask | Read `src/flask/app.py` (1,625 lines) › outline | 14,084 | 1,490 (−89%) | 1,490 (−89%) |
226
+ | ky | Read `source/core/Ky.ts` (1,376 lines) › outline | 12,452 | 919 (−93%) | 919 (−93%) |
227
+
228
+ ## Languages
229
+
230
+ Kompactor detects each repo's languages (`pyproject.toml` › Python, `go.mod` › Go, `tsconfig.json`/`package.json` › TypeScript, a `react` or `next` dependency › React). You can also pin them in the dashboard.
231
+
232
+ | | Python | Go | TypeScript / React |
233
+ |---|---|---|---|
234
+ | Library stack frames collapsed | `site-packages`, stdlib, `.venv` | `GOROOT`, `runtime/`, `pkg/mod` | `node_modules`, `node:internal`, `react-dom`, `next/dist` |
235
+ | Generated files (outline instead of a full read) | `*_pb2.py`, migrations | `*.pb.go`, `*_gen.go`, `zz_generated*`, mocks | `*.d.ts`, `*.min.js`, `dist/`, `.next/` |
236
+ | Lock files collapsed in diffs | `poetry.lock`, `uv.lock`, `Pipfile.lock` | `go.sum` | `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` |
237
+ | Test runners | pytest, unittest, tox, nox | `go test`, gotestsum | jest, vitest, mocha, playwright |
238
+ | Code graph | `ast`: classes, functions, decorators, imports, calls | packages, structs, interfaces, methods | components, hooks, JSX renders, `tsconfig` paths, workspace packages |
239
+
240
+ ## Commands
241
+
242
+ ```
243
+ kompactor setup enable for Claude Code (CLI + VS Code) and open the dashboard
244
+ (plugin installs: /kompactor setup in Claude Code)
245
+ kompactor ui the dashboard
246
+ kompactor presets list levels kompactor config preset 4 change level
247
+ kompactor gain savings so far kompactor estimate replay past sessions
248
+ kompactor graph <action> query, impact, explain, callers, deps, path, report, unused
249
+ kompactor show ID / search TEXT raw outputs Kompactor compacted
250
+ kompactor prove A/B test Kompactor in real Claude Code sessions
251
+ kompactor doctor check the installation (the dashboard's self-test runs every hook)
252
+ kompactor install --uninstall remove hooks, status line and shell prefix
253
+ ```
254
+
255
+ The [usage guide](https://github.com/amarkum/kompactor/blob/main/docs/usage.html) covers setup, levels, the graph, troubleshooting and FAQs. It's also built into the dashboard (`kompactor ui`) as **Guide**.
256
+
257
+ ![The usage guide](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/guide.png)
258
+
259
+ ## Development
260
+
261
+ ```bash
262
+ python -m unittest discover tests # 80 tests, including the real shell prefix run as Claude Code runs it
263
+ node vscode/test/smoke.js # VS Code extension against a mock API
264
+ ./scripts/build-vsix.sh # › dist/kompactor-<version>.vsix
265
+ python -m kompactor prove --tasks bench/tasks.json --repos <folder with the bench repos> --reps 3
266
+ ```
267
+
268
+ To release, run `python scripts/bump_version.py X.Y.Z` and `./scripts/build-vsix.sh`, commit, and push the tag `vX.Y.Z`. The *Publish to PyPI* workflow runs the tests and publishes the package with PyPI trusted publishing.
269
+
270
+ How Claude Code's hooks behave on success, failure and very long output, and why Kompactor uses a shell prefix rather than rewriting commands, is written up in [docs/SPEC.md](https://github.com/amarkum/kompactor/blob/main/docs/SPEC.md).
271
+
272
+ **About the name.** Kompactor was called Kompact until version 0.4. It was renamed because an unrelated PyPI package, `kompact`, installs a `kompact` command, and Claude could have run that one instead. Installing Kompactor replaces an old Kompact install's hooks, status line, shell prefix and skill, and leaves other tools' settings alone.
273
+
274
+ MIT licensed.
@@ -0,0 +1,251 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/amarkum/kompactor/main/docs/brand/kompactor-logo-dark.png">
4
+ <img src="https://raw.githubusercontent.com/amarkum/kompactor/main/docs/brand/kompactor-logo-light.png" alt="Kompactor" width="240">
5
+ </picture>
6
+ </p>
7
+
8
+ <p align="center"><b>Cut the tokens Claude Code spends on noise.</b><br>
9
+ Choose quality vs tokens on a dashboard, and see what every turn saved.</p>
10
+
11
+ <p align="center">Claude Code CLI and VS Code · Python, Go, TypeScript, React · Python standard library only · MIT</p>
12
+
13
+ ---
14
+
15
+ Most of a Claude Code session's tokens aren't your prompt or Claude's answer. They're tool output: test runs, installs, `git log`, whole-file reads. That output is sent again on every later turn until the context is compacted. Kompactor shrinks it before Claude reads it. It keeps every error, failing test, your own stack frames and the summary lines. It also gives Claude a local code graph and short rules for terser replies and smaller diffs.
16
+
17
+ **Measured in real Claude Code sessions** on Flask, Cobra, SWR, ky and zustand: **−16% tokens, −10% cost, −22% output tokens** at the default level, with the same answers (27/27 correct with and without).
18
+ Failing test runs and code search saved the most: **−33% tokens** on a Go test failure, **−32%** finding code in a TypeScript repo, and **−37% cost** on a vitest failure.
19
+ [Full results](#evidence)
20
+
21
+ ![Kompactor dashboard: savings per turn](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/dashboard-overview.png)
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ pip install kompactor
27
+ kompactor setup
28
+ ```
29
+
30
+ Setup enables Kompactor for Claude Code and opens the dashboard; restart Claude Code afterwards. Kompactor needs Python 3.9 or newer and nothing else. `pipx install kompactor` or `uv tool install kompactor` keep it in its own environment, and `pip install -U kompactor` updates it.
31
+
32
+ The CLI and the VS Code extension read the same `~/.claude/settings.json`, so one install covers both. Setup adds Kompactor's hooks, a status line (only if you don't have one) and the `/kompactor` skill. On macOS and Linux it also sets `CLAUDE_CODE_SHELL_PREFIX`. It never replaces a status line or shell prefix you already have, and it keeps a backup in `settings.json.kompactor-backup`. `kompactor install --uninstall` removes all of it.
33
+
34
+ **As a Claude Code plugin.** Run these in any Claude Code session, one at a time:
35
+ ```
36
+ /plugin marketplace add amarkum/kompactor
37
+ /plugin install kompactor@kompactor
38
+ /kompactor setup
39
+ ```
40
+ The last step adds the status line and the shell prefix that compacts failing commands, which a plugin can't set itself. `claude plugin update kompactor@kompactor` updates it.
41
+
42
+ **VS Code.** Install the extension file from [`dist/`](https://github.com/amarkum/kompactor/tree/main/dist) (`code --install-extension kompactor-0.5.0.vsix`, or Extensions › `⋯` › *Install from VSIX…*), then click **Enable** when Kompactor asks. The status bar starts showing savings.
43
+
44
+ **Without pip** (macOS, Linux): `git clone https://github.com/amarkum/kompactor.git && ./kompactor/install.sh`. On Windows, run `.\kompactor\install.ps1` from the clone.
45
+
46
+ ## What it does
47
+
48
+ | When | Kompactor | How |
49
+ |---|---|---|
50
+ | Claude runs a command | Drops passing tests, progress bars, download chatter, library stack frames and lock-file diffs. Keeps errors, failures, your frames and summaries. The raw output is stashed (`kompactor show <id>`). | `PostToolUse` hook |
51
+ | A command **fails** | Claude Code skips output hooks when a command exits non-zero, and cuts the output to its first and last ~5K characters, usually losing the failures at the end. Kompactor's shell prefix runs tests, builds, linters and installs to completion, compacts them, and passes the exit code through. Your permission rules still apply to Claude's original command. | `CLAUDE_CODE_SHELL_PREFIX` |
52
+ | A command prints over ~30K chars | Claude Code saves it to a file and shows Claude a 2 KB preview. Kompactor compacts the whole saved output instead. | `PostToolUse` hook |
53
+ | Claude opens a big source file | Returns its outline first: symbols with line ranges, signatures, who imports it and which tests cover it. Claude then reads only what it needs, and repeating the read returns the whole file. Unchanged re-reads get a one-line note. | `PreToolUse` hook |
54
+ | Claude first searches or reads code | A budgeted map of the most depended-on modules, given once (sessions that only run commands don't pay for it). | `PostToolUse` context |
55
+ | Anytime | A local code graph for Python, Go, TypeScript, JavaScript and React: find code by topic, callers, impact of a change with the tests to run, import cycles, dead code. | `kompactor graph …`, dashboard |
56
+ | Every reply, subagents too | Two dials. Prose: answer first, no preamble or recap. Code: change nothing if possible, reuse before writing, smallest diff, one focused test, never cut validation or security. 0 to 177 tokens of rules, depending on level. | `SessionStart`, `SubagentStart` |
57
+ | After each turn | What the turn saved, in the reply, the CLI status line, the VS Code status bar and the dashboard. | `Stop` hook |
58
+
59
+ Kompactor never changes what a command does. It can't strand Claude: every trimmed output has a raw copy, and every blocked read is "deny once, allow on retry". Every hook fails open.
60
+
61
+ ## Quality vs tokens
62
+
63
+ ![Quality vs tokens with a live preview](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/dashboard-quality.png)
64
+
65
+ One level sets every option. Every option can also be changed on its own, globally or per project, on the dashboard. There's no config file to edit.
66
+
67
+ | Level | What Claude gets | Rules injected |
68
+ |---|---|---:|
69
+ | 1 Max quality | Almost everything. Only outputs over ~1.5k tokens are touched, and only pure noise is removed. Failing commands are compacted too, gently. | 0 |
70
+ | 2 Quality | Noisy commands compacted, passing tests hidden, one-line `git log`, outlines for files over 800 lines. Answer-first replies. | 72 |
71
+ | 3 **Balanced** (default) | Outlines from 400 lines, library frames trimmed, a 500-token code map, lean-code rules. | 156 |
72
+ | 4 Savings | Tighter caps, 3 lines of diff context, outlines from 250 lines, test-runner banners dropped, shorter prose. | 176 |
73
+ | 5 Max savings | 80-line caps, 1 line of diff context, outlines from 150 lines, telegraphic prose. | 177 |
74
+
75
+ Change the level from the dashboard (`kompactor ui`, or **Kompactor: Open Dashboard** in VS Code), the VS Code status bar, or in Claude Code chat (`/kompactor max savings`, `/kompactor balanced`). A repo can have its own level under **Projects & languages**.
76
+
77
+ To give everyone who works in a repo the same level, commit a `.kompactor.json` next to the code:
78
+ ```json
79
+ { "preset": 4, "overrides": { "never_compact": ["terraform plan"] } }
80
+ ```
81
+ `preset` is the level (1 Max quality to 5 Max savings); `overrides` sets any option by the names in `kompactor config`. The repo's file beats your global level, and your own choice for that project still wins.
82
+
83
+ ## See the savings, per turn
84
+
85
+ | Where | What you see |
86
+ |---|---|
87
+ | Claude Code, after each reply | `Kompactor: −8.2k tokens this turn (13.1k › 4.9k, −63%) · session −41k · context ≈31% smaller` |
88
+ | CLI status line | `Kompactor −41.3k · ctx −31% · last turn −8.2k · Balanced` |
89
+ | VS Code status bar | Running savings. Each turn flashes its saving, and hovering shows details. |
90
+ | Dashboard | Per-turn chart, biggest wins, savings by feature and by project. |
91
+ | `kompactor estimate` | Replays your past sessions through the current settings: the share of tool output, billed tokens and cost Kompactor would have saved. |
92
+
93
+ The numbers are conservative. Savings count only what Claude would really have read. When Claude Code would have truncated an output anyway, only the truncated size counts. When Claude reads a whole file after its outline, the outline's saving is reversed.
94
+
95
+ ## Code graph
96
+
97
+ ![Code graph: module map and a query](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/dashboard-graph.png)
98
+
99
+ `kompactor graph build` indexes a repo in about a second (Flask: 85 files in 0.33 s). It runs in the background at session start and after edits. Nothing is sent anywhere and nothing is written to the repo.
100
+
101
+ ```
102
+ kompactor graph query "session cookie" find code by topic, with line ranges and who uses it
103
+ kompactor graph impact createStore files that use it, files that only import its module, tests to run
104
+ kompactor graph explain Name one symbol: signature, callers, callees, tests
105
+ kompactor graph callers / deps / path who calls it, what it imports, how two modules connect
106
+ kompactor graph report core modules, entry points, import cycles, tests by module
107
+ kompactor graph unused dead-code candidates (exported-but-unused listed separately)
108
+ ```
109
+
110
+ `/kompactor review`, `/kompactor audit` and `/kompactor debt` in chat use the graph to find duplicated helpers, dead code and shortcuts.
111
+
112
+ ## How it compares
113
+
114
+ Kompactor borrows the best idea from each of these tools: graphify's code graph, ponytail's lean-code ladder, caveman's terse prose, rtk's command filters, context-mode's raw-output stash, and the symbol-level reads of token-savior and code-review-graph. It then fixes the gaps that independent tests found. Researched in October 2026 from each project's repo and the independent tests linked below.
115
+
116
+ **Features** (Yes, Partly, or —):
117
+
118
+ | | Kompactor | [graphify](https://github.com/Graphify-Labs/graphify) | [ponytail](https://github.com/DietrichGebert/ponytail) | [caveman](https://github.com/JuliusBrussee/caveman) | [rtk](https://github.com/rtk-ai/rtk) | [token-savior](https://github.com/Mibayy/token-savior) | [context-mode](https://github.com/mksglu/context-mode) | [code-review-graph](https://github.com/tirth8205/code-review-graph) |
119
+ |---|---|---|---|---|---|---|---|---|
120
+ | Compacts command output | **Yes**, incl. failing runs | — | — | Partly (v4 proxy) | Yes, 100+ commands | Partly (opt-in) | Yes (sandbox) | — |
121
+ | Outline / symbol-level reads | **Yes**, automatic | Partly (strict mode) | Partly | Partly | Partly (`rtk read`) | Yes (MCP) | — | Yes (MCP) |
122
+ | Code graph and change impact | **Yes** (Py, Go, TS, React) | Yes, plus docs and images via an LLM | — | — | — | Yes | — | Yes |
123
+ | Terse-prose rules | **Yes**, 4 levels | — | Partly | Yes | — | — | — | — |
124
+ | Lean-code rules | **Yes** | — | Yes | Partly | — | Partly | — | — |
125
+ | Quality vs tokens control | **Yes**: 5 levels, every option, per project | Flags and env vars | 3 levels | Levels | TOML | Profiles | — | Partly |
126
+ | Per-turn savings shown | **Yes**: reply, status line, VS Code, dashboard | — | Partly (not in VS Code) | — | On demand (`rtk gain`) | — | Yes | Partly |
127
+ | Settings dashboard | **Yes** | Graph export | Yes | Partly | Partly | Yes | Hosted | Partly |
128
+ | VS Code | **Yes**, with its own extension | Yes | Partly | Yes | Yes | Partly | Yes | Yes |
129
+ | Real A/B evidence in the repo | **Yes**, with cost and correctness | Corpus ÷ answer ratio | Yes | Yes | — | Withdrawn, then partial | — | Upper bound |
130
+ | Dependencies | **None** (Python 3.9+ stdlib) | Python 3.10+, LLM for docs | Node | npm CLI, telemetry on by default | Rust binary | pip, MCP | MCP server (ELv2) | pip, tree-sitter |
131
+
132
+ **What happened when others measured them:**
133
+
134
+ | Tool | Activation in practice | Its own instructions | Independent result |
135
+ |---|---|---|---|
136
+ | **Kompactor** | Hooks act on every tool call, so Claude doesn't have to choose to use them | 0–177 tokens of rules + a 63-token skill entry | −16% tokens, −10% cost, 27/27 correct ([evidence](#evidence); self-run, reproducible with `kompactor prove`) |
137
+ | graphify | Nudges Claude to query the graph. An 87-session analysis found 4% of nudges followed; the nudges cost about 651k tokens against 176k from graphify's own answers ([#3435](https://github.com/Graphify-Labs/graphify/issues/3435)) | ~11k-token skill | 7.3× on code-only questions in one test. The 71.5× headline divided the whole corpus by one answer and has been dropped from its README |
138
+ | ponytail | Hooks inject its rules. As a plain skill it activated in 0 of 10 runs | Rules + a codebase map at each start | Cost −10.3%, code −15%, quality unchanged ([JetBrains](https://blog.jetbrains.com/ai/2026/07/ponytail-skill-claude-tested/), ~80 tasks) |
139
+ | caveman | Hooks inject its rules | ~1,160 tokens | Output −8.5%, cost ≈ −10% per task ([JetBrains](https://blog.jetbrains.com/ai/2026/07/speak-to-ai-agents-like-cavemen-tosave-tokens/)) |
140
+ | rtk | A hook rewrites commands; the rewrites bypass permission rules (rtk #4644) | None | Cost +7.6% at low effort, ±0% at high ([JetBrains](https://blog.jetbrains.com/ai/2026/07/rtk-claude-code-token-savings/), 86 tasks). `rtk gain` counts all raw output, and reported 96.2M tokens saved while the bill rose |
141
+ | token-savior | Only when Claude calls its MCP tools: 1 of 143 sessions in a re-measurement it later withdrew | ~1.5k tokens of tool schemas (15 tools) and up | −43% tokens, −13% cost in one run ([computingforgeeks](https://computingforgeeks.com/reduce-claude-code-token-usage-tools/)) |
142
+ | context-mode | Hooks route big outputs into its sandbox; retrieval is via MCP | 11 tool schemas | No independent measurement found |
143
+ | code-review-graph | Only when Claude calls its MCP tools | 30 tool schemas | −5% in one run ([computingforgeeks](https://computingforgeeks.com/reduce-claude-code-token-usage-tools/)) |
144
+
145
+ **Where Kompactor is better**
146
+ - **It works without being asked.** Graph tools and MCP servers save nothing when Claude doesn't call them, and the data above shows how often that happens. Kompactor's savings come from hooks on every tool call. In the A/B runs, Claude never had to run a Kompactor command for them to apply.
147
+ - **It handles the failing run.** That's where the noisiest output is, and where Claude Code itself drops the useful part. rtk handles failures too, but by rewriting commands, which bypasses your permission rules. Kompactor acts after the permission check, on Claude's original command, with the exit code unchanged.
148
+ - **Its own instructions are small.** 156 tokens at the default level, against ~1,160 for caveman and an ~11k-token skill for graphify. The code map only appears once Claude starts exploring code.
149
+ - **Its savings numbers are honest.** It counts what Claude would actually have read, not raw output size, and it reverses a saving when Claude reads the full file anyway.
150
+ - **It's proven on cost and correctness, not just token counts.** `kompactor prove` reruns the same tasks with and without Kompactor in real Claude Code sessions, and the results are in this repo.
151
+ - **One control covers every layer**, from a dashboard, with a live preview of exactly what Claude would see.
152
+
153
+ **Where others are stronger**
154
+ - graphify builds a multimodal graph: docs, PDFs and images through an LLM, about 40 languages, Obsidian and Neo4j exports. Kompactor's graph covers Python, Go, TypeScript, JavaScript and React code only.
155
+ - rtk has native filters for 100+ commands at under 10 ms each. Kompactor's filters cover the common dev commands and run in Python (50–100 ms per hook).
156
+ - context-mode runs code in a sandbox and indexes huge outputs such as Playwright snapshots. token-savior keeps memory across sessions. Kompactor does neither.
157
+
158
+ ## Evidence
159
+
160
+ `kompactor prove` runs each task in real headless Claude Code sessions (`claude -p`). Each task runs 3 times without Kompactor and 3 times with it, interleaved, with the same prompt, tools, turn limit and budget cap. Kompactor runs as an installed plugin at the default level. Tokens are input + cache writes + cache reads + output across every API call, and cost is Claude Code's own figure.
161
+
162
+ | Task | Repo | Tokens | Cost | Turns | Correct (without › with) |
163
+ |---|---|---:|---:|---|---|
164
+ | Find the failing Go test and its error | Cobra | **−33%** | **−18%** | 3.3 › 2.0 | 3/3 › 3/3 |
165
+ | Find how requests are deduplicated | SWR | **−32%** | −12% | 3.0 › 2.0 | 3/3 › 3/3 |
166
+ | Find where the session cookie is signed | Flask | **−26%** | −11% | 3.7 › 2.7 | 3/3 › 3/3 |
167
+ | Find the flag-group validation function | Cobra | −24% | −6% | 2.7 › 2.3 | 3/3 › 3/3 |
168
+ | Most-changed files in the last 40 commits | Flask | −16% | +4% | 3.7 › 3.0 | 3/3 › 3/3 |
169
+ | Find the failing vitest test (`--reporter=verbose`) | zustand | −7% | **−37%** | 2.0 › 2.0 | 3/3 › 3/3 |
170
+ | Type-check and list errors | ky | +1% | −2% | 2.0 › 2.0 | 3/3 › 3/3 |
171
+ | Find the failing pytest tests | Flask | +1% | +3% | 2.0 › 2.0 | 3/3 › 3/3 |
172
+ | What does changing `createStore` affect | zustand | +17% | +4% | 2.0 › 2.3 | 3/3 › 3/3 |
173
+ | **Total (54 sessions)** | | **−16%** | **−10%** | | **27/27 › 27/27** |
174
+
175
+ The same 27 Kompactor sessions were also run at both ends of the quality-vs-tokens range, against the same baseline:
176
+
177
+ | Level | Tokens | Cost | Output tokens | Correct |
178
+ |---|---:|---:|---:|---|
179
+ | 1 Max quality | +3% | −1% | 0% | 27/27 |
180
+ | 3 Balanced (default) | **−16%** | **−10%** | **−22%** | 27/27 |
181
+ | 5 Max savings | −12% | −10% | −22% | 27/27 |
182
+
183
+ What the numbers show:
184
+ - **The wins come from avoided turns.** Every turn re-sends the whole context. The vitest failure was 32K characters of passing tests; Kompactor handed Claude 1K characters with the failure, at 37% lower cost. On the Go failure, Claude got the answer in one run instead of piping through `tail` and `grep` three or four times. On code search, the code map and outlines saved a turn.
185
+ - **Levels show up per command more than per session.** Max quality barely touches output, so it's close to neutral. Balanced and Max savings land within run-to-run noise of each other here, because most of every session is Claude Code's own fixed context, and turns saved matter more than how hard each output is squeezed. The difference shows per command (next table).
186
+ - **Short sessions pay a small fixed cost.** On 2-turn tasks whose output was already small, Kompactor's rules and skill entry add about 1%. One of three `createStore` runs took an extra turn, which is the +17%.
187
+ - **Two experiments shaped the defaults.** Telling Claude not to pipe output through `tail` cost **+33%** tokens before the shell prefix existed, and **−9%** with it, so that rule is only on while the prefix is active. An earlier Max-savings round lost 2 of 27 answers when the 80-line cap cut a list Claude had asked for with `git log --format`; output Claude shapes itself is now kept verbatim ([notes](https://github.com/amarkum/kompactor/blob/main/evidence/README.md)).
188
+
189
+ Full report: [evidence/REPORT.md](https://github.com/amarkum/kompactor/blob/main/evidence/REPORT.md). Every session's tokens, tool calls and answers: [evidence/results.json](https://github.com/amarkum/kompactor/blob/main/evidence/results.json). To see exactly what Claude received in each arm for the same failing test run (15,617 vs 1,039 characters), read [evidence/EXAMPLE.md](https://github.com/amarkum/kompactor/blob/main/evidence/EXAMPLE.md).
190
+
191
+ ### Command output, measured directly
192
+
193
+ Tokens Claude receives for single commands on real repos (`bench/bench.py`):
194
+
195
+ | Repo | Command | Raw | Balanced | Max savings |
196
+ |---|---|---:|---:|---:|
197
+ | Flask | `pytest -v tests` (1 failure, 482 passed) | 9,842 | 1,138 (**−88%**) | 696 (**−93%**) |
198
+ | Flask | `grep -rn 'def ' src` | 8,492 | 3,230 (−62%) | 1,323 (−84%) |
199
+ | Flask | `git log -n 40` | 1,457 | 598 (−59%) | 598 (−59%) |
200
+ | ky | `npm install` (fresh) | ~33,000 | 469 (**−99%**) | 451 (−99%) |
201
+ | ky | `grep -rn await source` | 2,938 | 1,653 (−44%) | 1,058 (−64%) |
202
+ | Flask | Read `src/flask/app.py` (1,625 lines) › outline | 14,084 | 1,490 (−89%) | 1,490 (−89%) |
203
+ | ky | Read `source/core/Ky.ts` (1,376 lines) › outline | 12,452 | 919 (−93%) | 919 (−93%) |
204
+
205
+ ## Languages
206
+
207
+ Kompactor detects each repo's languages (`pyproject.toml` › Python, `go.mod` › Go, `tsconfig.json`/`package.json` › TypeScript, a `react` or `next` dependency › React). You can also pin them in the dashboard.
208
+
209
+ | | Python | Go | TypeScript / React |
210
+ |---|---|---|---|
211
+ | Library stack frames collapsed | `site-packages`, stdlib, `.venv` | `GOROOT`, `runtime/`, `pkg/mod` | `node_modules`, `node:internal`, `react-dom`, `next/dist` |
212
+ | Generated files (outline instead of a full read) | `*_pb2.py`, migrations | `*.pb.go`, `*_gen.go`, `zz_generated*`, mocks | `*.d.ts`, `*.min.js`, `dist/`, `.next/` |
213
+ | Lock files collapsed in diffs | `poetry.lock`, `uv.lock`, `Pipfile.lock` | `go.sum` | `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` |
214
+ | Test runners | pytest, unittest, tox, nox | `go test`, gotestsum | jest, vitest, mocha, playwright |
215
+ | Code graph | `ast`: classes, functions, decorators, imports, calls | packages, structs, interfaces, methods | components, hooks, JSX renders, `tsconfig` paths, workspace packages |
216
+
217
+ ## Commands
218
+
219
+ ```
220
+ kompactor setup enable for Claude Code (CLI + VS Code) and open the dashboard
221
+ (plugin installs: /kompactor setup in Claude Code)
222
+ kompactor ui the dashboard
223
+ kompactor presets list levels kompactor config preset 4 change level
224
+ kompactor gain savings so far kompactor estimate replay past sessions
225
+ kompactor graph <action> query, impact, explain, callers, deps, path, report, unused
226
+ kompactor show ID / search TEXT raw outputs Kompactor compacted
227
+ kompactor prove A/B test Kompactor in real Claude Code sessions
228
+ kompactor doctor check the installation (the dashboard's self-test runs every hook)
229
+ kompactor install --uninstall remove hooks, status line and shell prefix
230
+ ```
231
+
232
+ The [usage guide](https://github.com/amarkum/kompactor/blob/main/docs/usage.html) covers setup, levels, the graph, troubleshooting and FAQs. It's also built into the dashboard (`kompactor ui`) as **Guide**.
233
+
234
+ ![The usage guide](https://raw.githubusercontent.com/amarkum/kompactor/main/docs/guide.png)
235
+
236
+ ## Development
237
+
238
+ ```bash
239
+ python -m unittest discover tests # 80 tests, including the real shell prefix run as Claude Code runs it
240
+ node vscode/test/smoke.js # VS Code extension against a mock API
241
+ ./scripts/build-vsix.sh # › dist/kompactor-<version>.vsix
242
+ python -m kompactor prove --tasks bench/tasks.json --repos <folder with the bench repos> --reps 3
243
+ ```
244
+
245
+ To release, run `python scripts/bump_version.py X.Y.Z` and `./scripts/build-vsix.sh`, commit, and push the tag `vX.Y.Z`. The *Publish to PyPI* workflow runs the tests and publishes the package with PyPI trusted publishing.
246
+
247
+ How Claude Code's hooks behave on success, failure and very long output, and why Kompactor uses a shell prefix rather than rewriting commands, is written up in [docs/SPEC.md](https://github.com/amarkum/kompactor/blob/main/docs/SPEC.md).
248
+
249
+ **About the name.** Kompactor was called Kompact until version 0.4. It was renamed because an unrelated PyPI package, `kompact`, installs a `kompact` command, and Claude could have run that one instead. Installing Kompactor replaces an old Kompact install's hooks, status line, shell prefix and skill, and leaves other tools' settings alone.
250
+
251
+ MIT licensed.
@@ -0,0 +1,3 @@
1
+ """Kompactor: cut the tokens Claude Code spends on noise."""
2
+
3
+ __version__ = "0.5.0"
@@ -0,0 +1,4 @@
1
+ import sys
2
+ from .cli import main
3
+
4
+ sys.exit(main())
@@ -0,0 +1,22 @@
1
+ """Path-independent entry point: `python /path/to/kompactor/_launch.py ...`.
2
+
3
+ Hooks call Kompactor through this file so they work the same whether Kompactor was
4
+ pip-installed, cloned, or bundled inside the VS Code extension."""
5
+
6
+ import os
7
+ import sys
8
+
9
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ if len(sys.argv) == 4 and sys.argv[1] == "shell":
12
+ # Shell prefix (kompactor-shell): if Kompactor can't even load, run the command untouched.
13
+ _shell, _full = sys.argv[2], sys.argv[3]
14
+ try:
15
+ from kompactor import shellwrap
16
+ except BaseException:
17
+ os.execvp(_shell, [_shell, "-c", _full])
18
+ sys.exit(shellwrap.main([_shell, _full]))
19
+
20
+ from kompactor.cli import main # noqa: E402
21
+
22
+ sys.exit(main())