Skip to content

Commit 9dafe0b

Browse files
committed
feat: v5.5.0 — bash compression on by default, security hardening
Bash Output Compression now ships ON for all users. 16 handlers cover git, pytest, jest, npm, lint, logs, tree, docker, kubectl, sqlite3, du/df/wc, and build tools. Disable with TOKEN_OPTIMIZER_BASH_COMPRESS=0. Security hardening for default-ON: - Remove printenv from whitelist (dumps all env vars including secrets) - Remove docker exec from whitelist (not read-only, arbitrary container commands) - Add kubectl guard blocking 'kubectl get secrets' resource type Also: remove outdated 'Unknown skill: plugin' README section, sync dashboard.html V5_FEATURES_FALLBACK with measure.py source of truth, fix dashboard toggle handler to use per-feature defaults, update welcome screen text, update all SVGs from yellow/opt-in to green/on.
1 parent 021eb31 commit 9dafe0b

9 files changed

Lines changed: 42 additions & 56 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"name": "token-optimizer",
1414
"source": "./",
1515
"description": "Audit, fix, and monitor Claude Code context window usage. Find the ghost tokens.",
16-
"version": "5.4.26",
16+
"version": "5.5.0",
1717
"author": {
1818
"name": "Alex Greenshpun",
1919
"url": "https://linkedin.com/in/alexgreensh"

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
},
88
"homepage": "https://github.com/alexgreensh/token-optimizer",
99
"repository": "https://github.com/alexgreensh/token-optimizer",
10-
"version": "5.4.26",
10+
"version": "5.5.0",
1111
"license": "PolyForm-Noncommercial-1.0.0",
1212
"keywords": ["token", "optimization", "context", "audit", "cost", "coach"]
1313
}

README.md

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
</p>
44

55
<p align="center">
6-
<a href="https://github.com/alexgreensh/token-optimizer/releases"><img src="https://img.shields.io/badge/version-5.4.26-green" alt="Version 5.4.26"></a>
6+
<a href="https://github.com/alexgreensh/token-optimizer/releases"><img src="https://img.shields.io/badge/version-5.5.0-green" alt="Version 5.5.0"></a>
77
<a href="https://github.com/alexgreensh/token-optimizer"><img src="https://img.shields.io/badge/Claude_Code-Plugin-blueviolet" alt="Claude Code Plugin"></a>
88
<a href="https://github.com/alexgreensh/token-optimizer/tree/main/openclaw"><img src="https://img.shields.io/badge/OpenClaw-v2.3.0-brightgreen" alt="OpenClaw v2.3.0"></a>
99
<a href="https://github.com/alexgreensh/token-optimizer/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-PolyForm%20Noncommercial-blue.svg" alt="License: PolyForm Noncommercial"></a>
@@ -51,19 +51,6 @@ Then in Claude Code: `/token-optimizer`
5151

5252
> **Please enable auto-update after installing.** Claude Code ships third-party marketplaces with auto-update **off by default**, and plugin authors cannot change that default. So you won't get bug fixes automatically unless you turn it on. In Claude Code: `/plugin`**Marketplaces** tab → select `alexgreensh-token-optimizer`**Enable auto-update**. One-time, 10 seconds, and you'll never miss a fix again. Token Optimizer also prints a one-time reminder on your first SessionStart so you don't forget.
5353
54-
<details>
55-
<summary><h3>Seeing <code>Unknown skill: plugin</code>?</h3></summary>
56-
57-
That means your Claude Code is out of date. The `/plugin` command was added in a recent Claude Code release. Update first:
58-
59-
- **Homebrew**: `brew upgrade claude-code`
60-
- **npm**: `npm update -g @anthropic-ai/claude-code`
61-
- **Native installer**: re-run the install command from [claude.com/product/claude-code](https://claude.com/product/claude-code)
62-
63-
Then restart Claude Code and re-run the two `/plugin` commands above.
64-
65-
</details>
66-
6754
<details>
6855
<summary><h3>Windows users: read this first</h3></summary>
6956

@@ -180,7 +167,7 @@ Lighter users see proportional savings. Structural audit wins (unused skills, du
180167
<details>
181168
<summary>🎯 <strong>Can Token Optimizer degrade my context quality?</strong></summary>
182169

183-
No. Structural optimization only removes genuinely unused components (skills you never invoke, duplicate configs, orphaned memory entries). Active Compression features are independently toggleable, and the lossy ones (like Bash Compression) are OFF by default. The 7-signal quality score actively tracks degradation, so if anything ever hurt quality, the score would show it.
170+
No. Structural optimization only removes genuinely unused components (skills you never invoke, duplicate configs, orphaned memory entries). Active Compression features are independently toggleable, and the lossy ones (like Bash Compression) can be disabled with a single command or env var. The 7-signal quality score actively tracks degradation, so if anything ever hurt quality, the score would show it.
184171
</details>
185172

186173
<details>
@@ -205,7 +192,7 @@ No network calls. No analytics. No opt-out telemetry because there's nothing to
205192
<details>
206193
<summary>🛟 <strong>Can it hurt my session?</strong></summary>
207194

208-
No. All hooks are non-blocking with fail-open design. If a Token Optimizer script ever errors, your command runs normally. Compression is opt-in. Checkpoints are additive. Quality scoring is read-only measurement.
195+
No. All hooks are non-blocking with fail-open design. If a Token Optimizer script ever errors, your command runs normally. Compression features are all individually toggleable. Checkpoints are additive. Quality scoring is read-only measurement.
209196
</details>
210197

211198
<details>
@@ -337,8 +324,8 @@ Token Optimizer no longer just measures context bloat. It actively reduces it. F
337324

338325
![v5 Active Compression overview](skills/token-optimizer/assets/v5-hero.svg)
339326

340-
**On by default**: Quality Nudges, Loop Detection, Delta Mode.
341-
**Opt-in**: Bash Compression (7 handlers as of v5.1.0) and Structure Map Beta.
327+
**On by default**: Quality Nudges, Loop Detection, Delta Mode, Bash Compression (16 handlers).
328+
**Opt-in**: Structure Map Beta (local measurement only).
342329

343330
All five features are independently toggleable from the Manage tab in the dashboard, via CLI (`measure.py v5 enable|disable <feature>`), or with environment variables.
344331

@@ -348,7 +335,7 @@ All five features are independently toggleable from the Manage tab in the dashbo
348335
| Loop Detection | ON | ~8% (caught loops) | None |
349336
| Delta Mode | ON | ~20% (smart re-reads) | Low |
350337
| Structure Map Beta (local measurement) | OFF (opt-in) | Measurement only | None |
351-
| Bash Compression | OFF (opt-in) | ~10% (CLI output) | Moderate |
338+
| Bash Compression | ON | ~10% (CLI output) | Low |
352339

353340
> **Privacy note**: Every feature runs 100% on your machine. Nothing is ever sent anywhere. No analytics endpoint, no phone-home, no cloud sync. "Measurement" and "beta telemetry" always mean local-only SQLite writes to a file you own, and you can inspect, export, or delete that file at any time. Token Optimizer has zero network calls by design.
354341
@@ -402,7 +389,7 @@ Writes measurement events to your local SQLite database when a code file is read
402389

403390
![Bash Output Compression: git status and pytest before/after](skills/token-optimizer/assets/v5-bash-compression.svg)
404391

405-
### Bash Output Compression (OFF, opt-in, lossy)
392+
### Bash Output Compression (ON by default, lossy)
406393

407394
Rewrites common CLI commands to return compressed summaries instead of verbose output. v5.1.0 ships seven new handlers covering the command families that eat the most context: lint (rule-code grouping for eslint, ruff, flake8, shellcheck, rubocop, golangci-lint), log tails (adjacent-duplicate collapse), tree (depth-2 truncation), docker build and pull (progress filtering), long listings (pip list, npm ls, docker ps, with top-N plus tail marker), JS/TS/Go build output (error-and-summary view), and test runner routing (cypress, playwright, mocha, karma all route through the unified pytest compressor).
408395

@@ -414,9 +401,9 @@ Together with the existing git and pytest handlers, that's full coverage for ~90
414401

415402
**Security**: `shell=True` is never used. Credentials (AWS keys, GitHub PATs, Slack tokens, Stripe keys, OpenAI keys, HTTP basic-auth URLs) are scanned pre-compression and preserved verbatim. Multilingual error lines survive the preservation path. Partial output on timeout is returned raw, never compressed.
416403

417-
**How to enable**: `measure.py v5 enable bash_compress` or `TOKEN_OPTIMIZER_BASH_COMPRESS=1`
404+
**How to disable**: `measure.py v5 disable bash_compress` or `TOKEN_OPTIMIZER_BASH_COMPRESS=0`
418405

419-
**Risk**: moderate. Compression is lossy by design. For routine checks this is fine. For careful diff review or debugging specific test failures, it could hide information. OFF by default, opt-in only.
406+
**Risk**: low. Compression is lossy by design. For routine checks this is fine. For careful diff review or debugging specific test failures, disable temporarily with the command above.
420407

421408
### Managing v5 features
422409

@@ -437,7 +424,7 @@ python3 measure.py compression-stats # see actual measured savings fr
437424
TOKEN_OPTIMIZER_QUALITY_NUDGES=0 # kill switch for nudges
438425
TOKEN_OPTIMIZER_LOOP_DETECTION=0 # kill switch for loop detection
439426
TOKEN_OPTIMIZER_READ_CACHE_DELTA=1 # enable delta mode
440-
TOKEN_OPTIMIZER_BASH_COMPRESS=1 # enable bash compression
427+
TOKEN_OPTIMIZER_BASH_COMPRESS=0 # disable bash compression
441428
TOKEN_OPTIMIZER_STRUCTURE_MAP=beta # enable beta telemetry
442429
```
443430

@@ -576,7 +563,7 @@ Hover help on every column explains `Cache`, `TTL`, `Pacing`, `Cache R`, and `Ca
576563
| Structural waste audit | Deep, per-component | Summary only | No | No |
577564
| Quality degradation tracking | 7-signal score with grades | Capacity % only | No | No |
578565
| Compaction survival | Progressive checkpoints plus restore | No | Session guide only | No |
579-
| Runtime output compression | 30+ CLI commands, credential-safe, opt-in where lossy | No | Yes | Yes, always-on (cannot disable) |
566+
| Runtime output compression | 16 CLI handlers, credential-safe, individually toggleable | No | Yes | Yes, always-on (cannot disable) |
580567
| Measures if compression actually helped | Yes, local telemetry with before/after tokens | No | No | No |
581568
| Read deduplication and smart diff on re-reads | Yes | No | No | No |
582569
| Behavioral coaching and model routing | 9 detectors, cost-ranked subagent breakdown | Basic suggestions | No | No |

skills/token-optimizer/assets/dashboard.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,12 +2186,12 @@ <h3>Prompt Preview</h3>
21862186
env_var: 'TOKEN_OPTIMIZER_STRUCTURE_MAP'
21872187
},
21882188
bash_compress: {
2189-
default: false, recommended: false, impact_pct: 10, risk_level: 'moderate',
2189+
default: true, recommended: true, impact_pct: 10, risk_level: 'low',
21902190
label: 'Bash Output Compression',
21912191
what: "Rewrites 'git status', 'pytest', 'npm install' etc. to return compressed summaries instead of verbose output.",
21922192
value: "Strips hundreds of lines of test/build/git output down to just the essentials. Best for sessions with lots of CLI commands.",
21932193
how: "A PreToolUse hook intercepts safe read-only commands and routes them through a compression wrapper. Only whitelisted commands (git status/log/diff, pytest, jest, npm install, ls) are touched. Compound commands (anything with &&, ;, |, $()) are never touched.",
2194-
risk: "Moderate. Compression is lossy by design: 'git diff' truncates to 30 lines on large diffs, 'pytest' shows pass/fail counts but strips individual passing tests, 'git log' drops merge commit details. For routine checks this is fine. For careful diff review or debugging specific test failures, it could hide information. OFF by default -- opt-in only.",
2194+
risk: "Low. Compression is lossy by design: 'git diff' truncates to 30 lines on large diffs, 'pytest' shows pass/fail counts but strips individual passing tests, 'git log' drops merge commit details. For routine checks this is fine. For careful diff review or debugging specific test failures, set TOKEN_OPTIMIZER_BASH_COMPRESS=0 to disable temporarily.",
21952195
env_var: 'TOKEN_OPTIMIZER_BASH_COMPRESS'
21962196
}
21972197
};

skills/token-optimizer/assets/real-savings.svg

Lines changed: 1 addition & 1 deletion
Loading

skills/token-optimizer/assets/v5-bash-compression.svg

Lines changed: 1 addition & 1 deletion
Loading

skills/token-optimizer/assets/v5-hero.svg

Lines changed: 6 additions & 6 deletions
Loading

skills/token-optimizer/scripts/bash_hook.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- JSON output = rewrite command via updatedInput
1010
- Any error = exit silently (fail open)
1111
12-
Controlled by: TOKEN_OPTIMIZER_BASH_COMPRESS=1 (default: OFF)
12+
Controlled by: TOKEN_OPTIMIZER_BASH_COMPRESS=0 to disable (default: ON)
1313
"""
1414

1515
import json
@@ -48,7 +48,7 @@
4848
# v5.1 extended test runners (read-only test execution)
4949
"mocha", "karma",
5050
# v5.5 read-only utilities
51-
"sqlite3", "wc", "du", "df", "printenv",
51+
"sqlite3", "wc", "du", "df",
5252
})
5353
_WHITELIST_COMPOUND = {
5454
("git", "status"), ("git", "log"), ("git", "diff"), ("git", "show"), ("git", "branch"),
@@ -83,7 +83,6 @@
8383
("npx", "mocha"),
8484
("npx", "karma"),
8585
# v5.5 docker/kubectl read-only inspection
86-
("docker", "exec"),
8786
("docker", "logs"),
8887
("docker", "inspect"),
8988
("kubectl", "get"),
@@ -136,9 +135,9 @@ def _is_whitelisted(command_str):
136135
if (cmd, subcmd) in _WHITELIST_COMPOUND:
137136
if cmd == "git" and subcmd in _GIT_WRITE_SUBCMDS:
138137
return False
139-
if cmd == "docker" and subcmd == "exec":
138+
if cmd == "kubectl":
140139
remaining = tokens[cmd_start + 2:]
141-
if any(arg in ("-it", "-i", "-t") for arg in remaining):
140+
if any(arg in ("secret", "secrets") for arg in remaining):
142141
return False
143142
return True
144143

@@ -166,8 +165,8 @@ def _is_whitelisted(command_str):
166165

167166

168167
def _is_bash_compress_enabled():
169-
"""Check if bash compression is enabled. Default OFF — opt-in via flag/env."""
170-
return is_v5_flag_enabled("v5_bash_compress", "TOKEN_OPTIMIZER_BASH_COMPRESS", default=False)
168+
"""Check if bash compression is enabled. Default ON since v5.5."""
169+
return is_v5_flag_enabled("v5_bash_compress", "TOKEN_OPTIMIZER_BASH_COMPRESS", default=True)
171170

172171

173172
def main():

0 commit comments

Comments
 (0)