kompactor 0.7.8__tar.gz → 0.7.9__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.

Potentially problematic release.


This version of kompactor might be problematic. Click here for more details.

Files changed (42) hide show
  1. {kompactor-0.7.8 → kompactor-0.7.9}/PKG-INFO +6 -6
  2. {kompactor-0.7.8 → kompactor-0.7.9}/README.md +5 -5
  3. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/__init__.py +1 -1
  4. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/cli.py +8 -0
  5. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/hooks.py +1 -0
  6. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/installer.py +38 -0
  7. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/usage.html +1 -1
  8. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor.egg-info/PKG-INFO +6 -6
  9. {kompactor-0.7.8 → kompactor-0.7.9}/pyproject.toml +1 -1
  10. {kompactor-0.7.8 → kompactor-0.7.9}/tests/test_graph.py +2 -1
  11. {kompactor-0.7.8 → kompactor-0.7.9}/tests/test_kompactor.py +19 -0
  12. {kompactor-0.7.8 → kompactor-0.7.9}/tests/test_shell.py +1 -0
  13. {kompactor-0.7.8 → kompactor-0.7.9}/LICENSE +0 -0
  14. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/__main__.py +0 -0
  15. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/_launch.py +0 -0
  16. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/config.py +0 -0
  17. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/estimate.py +0 -0
  18. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/filters.py +0 -0
  19. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/graph.py +0 -0
  20. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/langs.py +0 -0
  21. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/outline.py +0 -0
  22. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/prove.py +0 -0
  23. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/rules.py +0 -0
  24. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/samples.py +0 -0
  25. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/server.py +0 -0
  26. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/shellwrap.py +0 -0
  27. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/fonts/OFL.txt +0 -0
  28. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/fonts/plex-mono-400.woff2 +0 -0
  29. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/fonts/plex-mono-500.woff2 +0 -0
  30. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/fonts/plex-sans-400.woff2 +0 -0
  31. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/fonts/plex-sans-500.woff2 +0 -0
  32. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/fonts/plex-sans-600.woff2 +0 -0
  33. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/static/logo-mark.svg +0 -0
  34. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/store.py +0 -0
  35. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/tokens.py +0 -0
  36. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor/ui.html +0 -0
  37. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor.egg-info/SOURCES.txt +0 -0
  38. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor.egg-info/dependency_links.txt +0 -0
  39. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor.egg-info/entry_points.txt +0 -0
  40. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor.egg-info/requires.txt +0 -0
  41. {kompactor-0.7.8 → kompactor-0.7.9}/kompactor.egg-info/top_level.txt +0 -0
  42. {kompactor-0.7.8 → kompactor-0.7.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kompactor
3
- Version: 0.7.8
3
+ Version: 0.7.9
4
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
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/amarkum/kompactor
@@ -121,8 +121,9 @@ The last step adds the status line and the shell prefix that compacts failing co
121
121
  pipx install kompactor # or: pip install kompactor · uv tool install kompactor
122
122
  kompactor setup
123
123
  ```
124
+ If your shell says `kompactor: command not found` (pip put the command in a folder that isn't on your PATH), run `python3 -m kompactor setup` once. It links `kompactor` into a folder that is already on your PATH, such as `~/.local/bin`, so the command works in every terminal from then on.
124
125
 
125
- **VS Code.** Download `kompactor-0.7.8.vsix` from [Releases](https://github.com/amarkum/kompactor/releases), install it (Extensions › `⋯` › *Install from VSIX…*), and click **Enable** when Kompactor asks.
126
+ **VS Code.** Download `kompactor-0.7.9.vsix` from [Releases](https://github.com/amarkum/kompactor/releases), install it (Extensions › `⋯` › *Install from VSIX…*), and click **Enable** when Kompactor asks.
126
127
 
127
128
  **From source:**
128
129
  ```bash
@@ -135,7 +136,7 @@ git clone https://github.com/amarkum/kompactor.git && ./kompactor/install.sh
135
136
  2. **Work as usual.** You don't call Kompactor; it acts on Claude's tool calls by itself. After each reply you'll see a line like `Kompactor: −8.2k tokens this turn`, and the status line shows the running total.
136
137
  3. **Check it's on:** run `kompactor` in a terminal (or `/kompactor` in Claude Code):
137
138
  ```
138
- Kompactor 0.7.8: ON
139
+ Kompactor 0.7.9: ON
139
140
  Connected via the Claude Code plugin. New Claude Code sessions are compacted.
140
141
  Level: Balanced (level 3 of 5). Change it: `kompactor config preset 1-5`, the dashboard, or /kompactor balanced
141
142
  Saved so far: 41.3k tokens (−38%) over 52 tool calls. Details: `kompactor gain`
@@ -375,7 +376,7 @@ Everything below happens on your machine. Kompactor makes no network requests of
375
376
 
376
377
  **What it reads.** The tool output Claude Code passes to its hooks, the files Claude reads (to outline them), your project's source (for the code graph), and the context size Claude Code gives the status line. Hooks never read your session transcripts. `kompactor estimate` and the dashboard's **Replay your history** panel read your local Claude Code session logs in `~/.claude/projects` only when you run them; the result isn't stored or sent anywhere.
377
378
 
378
- **What it writes.** `~/.kompactor/`: settings, the savings ledger, raw copies of shortened output (for `kompactor show`), the code graph index and the `~/.kompactor/bin/` launchers. History is deleted after 30 days by default. Setup edits `~/.claude/settings.json` to add Kompactor's hooks (non-plugin installs), a status line (only if you have none) and `CLAUDE_CODE_SHELL_PREFIX` (only if it isn't set), keeping a backup in `settings.json.kompactor-backup`; non-plugin installs also get the `/kompactor` skill in `~/.claude/skills`. Nothing is written to your repositories.
379
+ **What it writes.** `~/.kompactor/`: settings, the savings ledger, raw copies of shortened output (for `kompactor show`), the code graph index and the `~/.kompactor/bin/` launchers. When `kompactor` isn't on your PATH, it adds one link to that launcher in a writable folder that already is (`~/.local/bin`, `~/bin`, `/opt/homebrew/bin` or `/usr/local/bin`); it never edits shell files or replaces an existing command, and `kompactor uninstall` removes the link. History is deleted after 30 days by default. Setup edits `~/.claude/settings.json` to add Kompactor's hooks (non-plugin installs), a status line (only if you have none) and `CLAUDE_CODE_SHELL_PREFIX` (only if it isn't set), keeping a backup in `settings.json.kompactor-backup`; non-plugin installs also get the `/kompactor` skill in `~/.claude/skills`. Nothing is written to your repositories.
379
380
 
380
381
  **What it never does.** Change your permission rules or sandbox settings, change what a command does, or send your code or output anywhere. Details: [privacy policy](https://github.com/amarkum/kompactor/blob/main/PRIVACY.md).
381
382
 
@@ -383,6 +384,7 @@ Everything below happens on your machine. Kompactor makes no network requests of
383
384
 
384
385
  | Problem | What to do |
385
386
  |---|---|
387
+ | `kompactor: command not found` | pip put the command in a folder that isn't on your PATH. Run `python3 -m kompactor setup` (or `start`) once: it links `kompactor` into a writable folder already on your PATH, such as `~/.local/bin`. Claude Code plugin installs do this at the first session. |
386
388
  | No savings line after replies | Restart Claude Code after setup, then run `kompactor doctor`: it checks the installation and shows recent hook errors. The dashboard's **Self-test** panel runs every hook once. |
387
389
  | An output looks too short | Claude can fetch the original with `kompactor show <id>`, or search earlier outputs with `kompactor search "text"`. |
388
390
  | A command should never be shortened | Add it to **Never compact these commands** on the dashboard, or to `never_compact` in `.kompactor.json`. For a single run, start the command with `KOMPACTOR_RAW=1`. |
@@ -455,5 +457,3 @@ Bug reports, ideas and pull requests are welcome. See [CONTRIBUTING.md](https://
455
457
  ## License
456
458
 
457
459
  [MIT](https://github.com/amarkum/kompactor/blob/main/LICENSE) © The Kompactor authors. The dashboard uses the IBM Plex fonts under the [SIL Open Font License](https://github.com/amarkum/kompactor/blob/main/kompactor/static/fonts/OFL.txt).
458
-
459
- Built by [stackcone](https://stackcone.com). Read the story behind it: [Kompactor: Cut the Tokens Claude Code Spends on Noise](https://stackcone.com/blog/posts/kompactor-claude-code-token-saver/).
@@ -88,8 +88,9 @@ The last step adds the status line and the shell prefix that compacts failing co
88
88
  pipx install kompactor # or: pip install kompactor · uv tool install kompactor
89
89
  kompactor setup
90
90
  ```
91
+ If your shell says `kompactor: command not found` (pip put the command in a folder that isn't on your PATH), run `python3 -m kompactor setup` once. It links `kompactor` into a folder that is already on your PATH, such as `~/.local/bin`, so the command works in every terminal from then on.
91
92
 
92
- **VS Code.** Download `kompactor-0.7.8.vsix` from [Releases](https://github.com/amarkum/kompactor/releases), install it (Extensions › `⋯` › *Install from VSIX…*), and click **Enable** when Kompactor asks.
93
+ **VS Code.** Download `kompactor-0.7.9.vsix` from [Releases](https://github.com/amarkum/kompactor/releases), install it (Extensions › `⋯` › *Install from VSIX…*), and click **Enable** when Kompactor asks.
93
94
 
94
95
  **From source:**
95
96
  ```bash
@@ -102,7 +103,7 @@ git clone https://github.com/amarkum/kompactor.git && ./kompactor/install.sh
102
103
  2. **Work as usual.** You don't call Kompactor; it acts on Claude's tool calls by itself. After each reply you'll see a line like `Kompactor: −8.2k tokens this turn`, and the status line shows the running total.
103
104
  3. **Check it's on:** run `kompactor` in a terminal (or `/kompactor` in Claude Code):
104
105
  ```
105
- Kompactor 0.7.8: ON
106
+ Kompactor 0.7.9: ON
106
107
  Connected via the Claude Code plugin. New Claude Code sessions are compacted.
107
108
  Level: Balanced (level 3 of 5). Change it: `kompactor config preset 1-5`, the dashboard, or /kompactor balanced
108
109
  Saved so far: 41.3k tokens (−38%) over 52 tool calls. Details: `kompactor gain`
@@ -342,7 +343,7 @@ Everything below happens on your machine. Kompactor makes no network requests of
342
343
 
343
344
  **What it reads.** The tool output Claude Code passes to its hooks, the files Claude reads (to outline them), your project's source (for the code graph), and the context size Claude Code gives the status line. Hooks never read your session transcripts. `kompactor estimate` and the dashboard's **Replay your history** panel read your local Claude Code session logs in `~/.claude/projects` only when you run them; the result isn't stored or sent anywhere.
344
345
 
345
- **What it writes.** `~/.kompactor/`: settings, the savings ledger, raw copies of shortened output (for `kompactor show`), the code graph index and the `~/.kompactor/bin/` launchers. History is deleted after 30 days by default. Setup edits `~/.claude/settings.json` to add Kompactor's hooks (non-plugin installs), a status line (only if you have none) and `CLAUDE_CODE_SHELL_PREFIX` (only if it isn't set), keeping a backup in `settings.json.kompactor-backup`; non-plugin installs also get the `/kompactor` skill in `~/.claude/skills`. Nothing is written to your repositories.
346
+ **What it writes.** `~/.kompactor/`: settings, the savings ledger, raw copies of shortened output (for `kompactor show`), the code graph index and the `~/.kompactor/bin/` launchers. When `kompactor` isn't on your PATH, it adds one link to that launcher in a writable folder that already is (`~/.local/bin`, `~/bin`, `/opt/homebrew/bin` or `/usr/local/bin`); it never edits shell files or replaces an existing command, and `kompactor uninstall` removes the link. History is deleted after 30 days by default. Setup edits `~/.claude/settings.json` to add Kompactor's hooks (non-plugin installs), a status line (only if you have none) and `CLAUDE_CODE_SHELL_PREFIX` (only if it isn't set), keeping a backup in `settings.json.kompactor-backup`; non-plugin installs also get the `/kompactor` skill in `~/.claude/skills`. Nothing is written to your repositories.
346
347
 
347
348
  **What it never does.** Change your permission rules or sandbox settings, change what a command does, or send your code or output anywhere. Details: [privacy policy](https://github.com/amarkum/kompactor/blob/main/PRIVACY.md).
348
349
 
@@ -350,6 +351,7 @@ Everything below happens on your machine. Kompactor makes no network requests of
350
351
 
351
352
  | Problem | What to do |
352
353
  |---|---|
354
+ | `kompactor: command not found` | pip put the command in a folder that isn't on your PATH. Run `python3 -m kompactor setup` (or `start`) once: it links `kompactor` into a writable folder already on your PATH, such as `~/.local/bin`. Claude Code plugin installs do this at the first session. |
353
355
  | No savings line after replies | Restart Claude Code after setup, then run `kompactor doctor`: it checks the installation and shows recent hook errors. The dashboard's **Self-test** panel runs every hook once. |
354
356
  | An output looks too short | Claude can fetch the original with `kompactor show <id>`, or search earlier outputs with `kompactor search "text"`. |
355
357
  | A command should never be shortened | Add it to **Never compact these commands** on the dashboard, or to `never_compact` in `.kompactor.json`. For a single run, start the command with `KOMPACTOR_RAW=1`. |
@@ -422,5 +424,3 @@ Bug reports, ideas and pull requests are welcome. See [CONTRIBUTING.md](https://
422
424
  ## License
423
425
 
424
426
  [MIT](https://github.com/amarkum/kompactor/blob/main/LICENSE) © The Kompactor authors. The dashboard uses the IBM Plex fonts under the [SIL Open Font License](https://github.com/amarkum/kompactor/blob/main/kompactor/static/fonts/OFL.txt).
425
-
426
- Built by [stackcone](https://stackcone.com). Read the story behind it: [Kompactor: Cut the Tokens Claude Code Spends on Noise](https://stackcone.com/blog/posts/kompactor-claude-code-token-saver/).
@@ -1,3 +1,3 @@
1
1
  """Kompactor: cut the tokens Claude Code spends on noise."""
2
2
 
3
- __version__ = "0.7.8"
3
+ __version__ = "0.7.9"
@@ -287,6 +287,12 @@ def _prefix_note(st):
287
287
  print(f" {note}")
288
288
 
289
289
 
290
+ def _path_note(link):
291
+ if link:
292
+ where = os.path.dirname(link).replace(os.path.expanduser("~"), "~", 1)
293
+ print(f" Added the `kompactor` command to {where}, so it works in any terminal.")
294
+
295
+
290
296
  def cmd_setup(a):
291
297
  """One-step setup: enable hooks for CLI + VS Code, then open the dashboard."""
292
298
  target = installer.install(statusline=config.read_file()["general"].get("statusline", True))
@@ -295,6 +301,7 @@ def cmd_setup(a):
295
301
  print(f" Claude Code CLI: {'found' if st['claude_cli'] else 'not found'}")
296
302
  print(f" VS Code extension: {st['vscode_extension'] or 'not found'} (uses the same settings)")
297
303
  _prefix_note(st)
304
+ _path_note(installer.link_on_path())
298
305
  print("\nNext: restart Claude Code, then work as usual. The status line shows what each turn saved.")
299
306
  print(" `kompactor` shows status and how it works · `kompactor stop` turns it off · "
300
307
  "`kompactor uninstall` removes it")
@@ -342,6 +349,7 @@ def cmd_start(a):
342
349
  if not st["plugin_enabled"] and not st["hooks_installed"]:
343
350
  installer.install(statusline=config.read_file()["general"].get("statusline", True))
344
351
  print("✓ Kompactor is on: new Claude Code sessions are compacted.")
352
+ _path_note(installer.link_on_path())
345
353
  d = _dashboard()
346
354
  if not d:
347
355
  from . import server
@@ -266,6 +266,7 @@ def pre_compact(event: dict, cfg: dict) -> None:
266
266
  def session_start(event: dict, cfg: dict) -> None:
267
267
  try: # so outputs can point at `~/.kompactor/bin/kompactor` even before `kompactor setup` (plugin installs)
268
268
  installer.write_shim(only_if_changed=True)
269
+ installer.link_on_path() # and so `kompactor` works in the user's own terminal too
269
270
  except OSError:
270
271
  pass
271
272
  if event.get("source") in ("compact", "clear"):
@@ -64,6 +64,43 @@ def write_shim(only_if_changed: bool = False) -> Path:
64
64
  f.chmod(0o755)
65
65
  return d / "kompactor"
66
66
 
67
+
68
+ # Where a `kompactor` command can be linked when pip put it in a folder that isn't on PATH.
69
+ PATH_DIRS = ("~/.local/bin", "~/bin", "/opt/homebrew/bin", "/usr/local/bin")
70
+
71
+
72
+ def link_on_path(path=None, dirs=None) -> str:
73
+ """Make `kompactor` work in any terminal. A pip install into a Python whose scripts folder isn't on
74
+ PATH leaves the command unreachable, so link the stable launcher into the first writable folder of
75
+ `dirs` that is already on PATH. Never edits shell files or replaces an existing command.
76
+ Returns the link it made, or ""."""
77
+ path = os.environ.get("PATH", "") if path is None else path
78
+ dirs = PATH_DIRS if dirs is None else dirs
79
+ if os.name == "nt" or shutil.which("kompactor", path=path):
80
+ return ""
81
+ on_path = {os.path.realpath(p) for p in path.split(os.pathsep) if p}
82
+ target = write_shim(only_if_changed=True)
83
+ for d in dirs:
84
+ d = os.path.expanduser(d)
85
+ link = Path(d, "kompactor")
86
+ if os.path.realpath(d) not in on_path or not os.access(d, os.W_OK) or link.exists() or link.is_symlink():
87
+ continue
88
+ try:
89
+ link.symlink_to(target)
90
+ except OSError:
91
+ continue
92
+ return str(link)
93
+ return ""
94
+
95
+
96
+ def unlink_from_path(dirs=None) -> None:
97
+ """Remove the links link_on_path made, and only those."""
98
+ target = str(shim_dir() / "kompactor")
99
+ for d in PATH_DIRS if dirs is None else dirs:
100
+ link = Path(os.path.expanduser(d), "kompactor")
101
+ if link.is_symlink() and os.readlink(link) == target:
102
+ link.unlink()
103
+
67
104
  PREFIX_ENV = "CLAUDE_CODE_SHELL_PREFIX"
68
105
  # Claude Code runs every Bash command as `kompactor-shell '<command>'`. Only commands that look like
69
106
  # tests, builds, linters or installs start Python; the rest (and everything, if Kompactor is gone)
@@ -270,6 +307,7 @@ def install(scope: str = "user", project: str = "", statusline: bool = True, uni
270
307
  pass
271
308
  skill = skill_path(scope, project)
272
309
  if uninstall:
310
+ unlink_from_path()
273
311
  if skill.exists() and "Kompactor token saver" in skill.read_text():
274
312
  skill.unlink()
275
313
  try:
@@ -139,7 +139,7 @@ svg.chev { width: 11px; height: 11px; stroke: var(--ink-3); fill: none; stroke-w
139
139
  <pre><code>pipx install kompactor
140
140
  kompactor setup</code></pre></div>
141
141
  <div class="card"><b>VS Code</b><span class="muted">Download the extension file from the repo's Releases page, then click <b>Enable</b> when Kompactor asks.</span>
142
- <pre><code>code --install-extension kompactor-0.7.8.vsix</code></pre></div>
142
+ <pre><code>code --install-extension kompactor-0.7.9.vsix</code></pre></div>
143
143
  </div>
144
144
  <p class="muted">Windows: run <code>.\kompactor\install.ps1</code> from a clone, or use the VS Code extension. The CLI and the VS Code extension read the same <code>~/.claude/settings.json</code>, so one install covers both. A backup of that file is kept as <code>settings.json.kompactor-backup</code>.</p>
145
145
  <p class="muted">Setup adds hooks, a status line (if you don't have one) and, on macOS and Linux, Claude Code's <code>CLAUDE_CODE_SHELL_PREFIX</code> setting pointing at <code>~/.kompactor/bin/kompactor-shell</code>, which is what lets Kompactor compact failing commands. It never replaces a status line or shell prefix you already have. Restart open Claude Code sessions after setup.</p>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kompactor
3
- Version: 0.7.8
3
+ Version: 0.7.9
4
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
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/amarkum/kompactor
@@ -121,8 +121,9 @@ The last step adds the status line and the shell prefix that compacts failing co
121
121
  pipx install kompactor # or: pip install kompactor · uv tool install kompactor
122
122
  kompactor setup
123
123
  ```
124
+ If your shell says `kompactor: command not found` (pip put the command in a folder that isn't on your PATH), run `python3 -m kompactor setup` once. It links `kompactor` into a folder that is already on your PATH, such as `~/.local/bin`, so the command works in every terminal from then on.
124
125
 
125
- **VS Code.** Download `kompactor-0.7.8.vsix` from [Releases](https://github.com/amarkum/kompactor/releases), install it (Extensions › `⋯` › *Install from VSIX…*), and click **Enable** when Kompactor asks.
126
+ **VS Code.** Download `kompactor-0.7.9.vsix` from [Releases](https://github.com/amarkum/kompactor/releases), install it (Extensions › `⋯` › *Install from VSIX…*), and click **Enable** when Kompactor asks.
126
127
 
127
128
  **From source:**
128
129
  ```bash
@@ -135,7 +136,7 @@ git clone https://github.com/amarkum/kompactor.git && ./kompactor/install.sh
135
136
  2. **Work as usual.** You don't call Kompactor; it acts on Claude's tool calls by itself. After each reply you'll see a line like `Kompactor: −8.2k tokens this turn`, and the status line shows the running total.
136
137
  3. **Check it's on:** run `kompactor` in a terminal (or `/kompactor` in Claude Code):
137
138
  ```
138
- Kompactor 0.7.8: ON
139
+ Kompactor 0.7.9: ON
139
140
  Connected via the Claude Code plugin. New Claude Code sessions are compacted.
140
141
  Level: Balanced (level 3 of 5). Change it: `kompactor config preset 1-5`, the dashboard, or /kompactor balanced
141
142
  Saved so far: 41.3k tokens (−38%) over 52 tool calls. Details: `kompactor gain`
@@ -375,7 +376,7 @@ Everything below happens on your machine. Kompactor makes no network requests of
375
376
 
376
377
  **What it reads.** The tool output Claude Code passes to its hooks, the files Claude reads (to outline them), your project's source (for the code graph), and the context size Claude Code gives the status line. Hooks never read your session transcripts. `kompactor estimate` and the dashboard's **Replay your history** panel read your local Claude Code session logs in `~/.claude/projects` only when you run them; the result isn't stored or sent anywhere.
377
378
 
378
- **What it writes.** `~/.kompactor/`: settings, the savings ledger, raw copies of shortened output (for `kompactor show`), the code graph index and the `~/.kompactor/bin/` launchers. History is deleted after 30 days by default. Setup edits `~/.claude/settings.json` to add Kompactor's hooks (non-plugin installs), a status line (only if you have none) and `CLAUDE_CODE_SHELL_PREFIX` (only if it isn't set), keeping a backup in `settings.json.kompactor-backup`; non-plugin installs also get the `/kompactor` skill in `~/.claude/skills`. Nothing is written to your repositories.
379
+ **What it writes.** `~/.kompactor/`: settings, the savings ledger, raw copies of shortened output (for `kompactor show`), the code graph index and the `~/.kompactor/bin/` launchers. When `kompactor` isn't on your PATH, it adds one link to that launcher in a writable folder that already is (`~/.local/bin`, `~/bin`, `/opt/homebrew/bin` or `/usr/local/bin`); it never edits shell files or replaces an existing command, and `kompactor uninstall` removes the link. History is deleted after 30 days by default. Setup edits `~/.claude/settings.json` to add Kompactor's hooks (non-plugin installs), a status line (only if you have none) and `CLAUDE_CODE_SHELL_PREFIX` (only if it isn't set), keeping a backup in `settings.json.kompactor-backup`; non-plugin installs also get the `/kompactor` skill in `~/.claude/skills`. Nothing is written to your repositories.
379
380
 
380
381
  **What it never does.** Change your permission rules or sandbox settings, change what a command does, or send your code or output anywhere. Details: [privacy policy](https://github.com/amarkum/kompactor/blob/main/PRIVACY.md).
381
382
 
@@ -383,6 +384,7 @@ Everything below happens on your machine. Kompactor makes no network requests of
383
384
 
384
385
  | Problem | What to do |
385
386
  |---|---|
387
+ | `kompactor: command not found` | pip put the command in a folder that isn't on your PATH. Run `python3 -m kompactor setup` (or `start`) once: it links `kompactor` into a writable folder already on your PATH, such as `~/.local/bin`. Claude Code plugin installs do this at the first session. |
386
388
  | No savings line after replies | Restart Claude Code after setup, then run `kompactor doctor`: it checks the installation and shows recent hook errors. The dashboard's **Self-test** panel runs every hook once. |
387
389
  | An output looks too short | Claude can fetch the original with `kompactor show <id>`, or search earlier outputs with `kompactor search "text"`. |
388
390
  | A command should never be shortened | Add it to **Never compact these commands** on the dashboard, or to `never_compact` in `.kompactor.json`. For a single run, start the command with `KOMPACTOR_RAW=1`. |
@@ -455,5 +457,3 @@ Bug reports, ideas and pull requests are welcome. See [CONTRIBUTING.md](https://
455
457
  ## License
456
458
 
457
459
  [MIT](https://github.com/amarkum/kompactor/blob/main/LICENSE) © The Kompactor authors. The dashboard uses the IBM Plex fonts under the [SIL Open Font License](https://github.com/amarkum/kompactor/blob/main/kompactor/static/fonts/OFL.txt).
458
-
459
- Built by [stackcone](https://stackcone.com). Read the story behind it: [Kompactor: Cut the Tokens Claude Code Spends on Noise](https://stackcone.com/blog/posts/kompactor-claude-code-token-saver/).
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kompactor"
7
- version = "0.7.8"
7
+ version = "0.7.9"
8
8
  description = "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."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -11,7 +11,8 @@ from pathlib import Path
11
11
 
12
12
  os.environ.setdefault("KOMPACTOR_HOME", tempfile.mkdtemp())
13
13
 
14
- from kompactor import config, graph, hooks # noqa: E402
14
+ from kompactor import config, graph, hooks, installer # noqa: E402
15
+ installer.PATH_DIRS = () # never link `kompactor` into real PATH folders from tests
15
16
 
16
17
 
17
18
  def make_repo(files: dict) -> str:
@@ -12,6 +12,7 @@ TMP = tempfile.mkdtemp()
12
12
  os.environ["KOMPACTOR_HOME"] = os.path.join(TMP, "home")
13
13
 
14
14
  from kompactor import config, estimate, filters, hooks, installer, langs, outline, server, store, tokens # noqa: E402
15
+ installer.PATH_DIRS = () # never link `kompactor` into real PATH folders from tests
15
16
 
16
17
 
17
18
  def run_hook(name, event):
@@ -565,6 +566,24 @@ class SourceTests(unittest.TestCase):
565
566
  self.assertEqual(installer.parse_source(ssh)["clone"], ssh)
566
567
  self.assertEqual(installer.parse_source(""), {})
567
568
 
569
+ def test_command_linked_onto_path_when_missing(self):
570
+ from unittest import mock
571
+ tmp = Path(tempfile.mkdtemp())
572
+ on_path, off_path, shim = tmp / "bin", tmp / "elsewhere", tmp / "shim"
573
+ on_path.mkdir(); off_path.mkdir()
574
+ with mock.patch.object(installer, "shim_dir", return_value=shim):
575
+ # only a writable folder that is already on PATH gets the link
576
+ link = installer.link_on_path(path=str(on_path), dirs=(str(off_path), str(on_path)))
577
+ self.assertEqual(link, str(on_path / "kompactor"))
578
+ self.assertEqual(os.readlink(link), str(shim / "kompactor"))
579
+ self.assertEqual(installer.link_on_path(path=str(on_path), dirs=(str(on_path),)), "") # already there
580
+ installer.unlink_from_path(dirs=(str(on_path),))
581
+ self.assertFalse(Path(link).is_symlink())
582
+ (on_path / "kompactor").write_text("someone else's") # never replaced
583
+ self.assertEqual(installer.link_on_path(path=str(on_path), dirs=(str(on_path),)), "")
584
+ installer.unlink_from_path(dirs=(str(on_path),))
585
+ self.assertTrue((on_path / "kompactor").exists())
586
+
568
587
  def test_source_defaults_to_the_public_repo(self):
569
588
  self.assertEqual(installer.source("")["marketplace"], "amarkum/kompactor")
570
589
  self.assertEqual(installer.source("acme/kompactor")["clone"], "https://github.com/acme/kompactor.git") # a fork
@@ -20,6 +20,7 @@ ROOT = Path(__file__).resolve().parent.parent
20
20
  sys.path.insert(0, str(ROOT))
21
21
 
22
22
  from kompactor import filters, hooks, installer, shellwrap, tokens # noqa: E402
23
+ installer.PATH_DIRS = () # never link `kompactor` into real PATH folders from tests
23
24
 
24
25
  PASSING = "".join(f"tests/test_mod.py::test_case_{i} PASSED{' ' * 30}[{i // 5:3d}%]\n" for i in range(500))
25
26
  FAILURE = ("=================================== FAILURES ===================================\n"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes