Repository navigation
v2.7.1
Token-Saver 2.7.1
Security and correctness release. Five audit-flagged bugs fixed (one of them
a genuine secret-leak path), plus a full pass to bring the shipped docs back
in line with the actual code.
Security fixes
-
Redacted secrets could leak back to the model. The compression-ratio
gate exists to discard a processor's output and fall back to the raw input
when the result isn't smaller bymin_compression_ratio. For.env
secret redaction, "the result" isAPI_KEY=***and "the raw input" is the
secret in the clear — so a short secret that didn't shrink the output
enough was silently returned unredacted. A second, independent leak
existed in the mismatch-fallback path, which re-ran the generic processor
on the original unredacted output instead of the already-redacted one.
Both paths are now short-circuited whenever a processor reports it
redacted something for that call. Two regression tests cover both leak
paths, plus a control test confirming ordinary compression is unaffected. -
A cloned repo could achieve code execution or disable secret redaction.
.token-saver.jsonis auto-discovered by walking up from the current
directory — including a repo you just cloned and haven't reviewed yet.
user_processors_diris imported as Python on the next Bash command, so a
project-level config could previously get arbitrary code to run.
disabled_processorsandredaction_allowlistcould silently turn off
the redaction safety net. All three keys are now only honored from the
global~/.token-saver/config.jsonor environment variables, never from
a project file.
Correctness fixes
BuildOutputProcessorno longer reports "Build succeeded." on a failed
run when the failure text doesn't contain a literal "error" — e.g.
jest's bareFAIL, make'sFailure N, ninja/rollup wording. Processors
can now opt into seeing the real exit code as a last-resort signal.- Fixed false-positive "critical" lines pushing real errors out of
capped output. The critical-line matcher was one case-insensitive pattern
that also matched ordinary words like "Extracting" or "Entry"; it's now
split into a case-insensitive vocabulary pattern and a case-sensitive
symbol pattern (errno/signal names, bareEprefix). - Fixed silently dropped output in chained commands. A chain segment
with no trailing newline (e.g.printfwithout\n) could glue the next
segment's boundary marker onto the same line, breaking the split and
losing that segment's output with no warning. - Hardened command-eligibility detection:
2>&1-style file-descriptor
duplication is no longer mistaken for a real redirection (more commands
are now eligible for compression); an unquoted background&, an
unquoted non-continuation newline, and open shell constructs
(for/while/if/case/select) are now correctly excluded. The
rewritten command is also syntax-checked with a real shell-ncheck
before it runs, falling back to the original, uncompressed command if the
rewrite wouldn't parse.
Documentation
The shipped docs had drifted from the actual code in several places users
would hit directly:
skills/token-saver-config/SKILL.mddocumented atoken-saver config set
subcommand that doesn't exist, and four config keys/defaults that were
wrong or invented. Rewritten to match the real config precedence and
defaults.commands/token-saver-stats.md's documented fallback command crashed
withModuleNotFoundError. Fixed to use the bundled CLI wrapper.- README's "Complete Parameter List" had drifted on most of its rows
(e.g.min_input_lengthdocumented as200, actually1). Every row is
now regenerated fromsrc/config.py's real defaults, and a new test
(tests/test_readme_config_sync.py) fails CI on the next drift instead
of waiting for another audit. - "Zero added latency" replaced with a measured ~60ms/command overhead.
- The
.envredaction claim is now precise:.env.production,.env.local,
etc. are redacted; bare.env,.env.example,.env.templateare
intentionally left untouched. - The Before/After compression table now uses the same figures the CI
ratchet (tests/compression_baselines.json) actually locks in, instead of
numbers that had quietly drifted from what the engine measures today. - README substantially expanded: table of contents, quick start,
who-it's-for, worked real-output examples per tool, a full CLI reference,
tuning recipes, an expanded security section, measured performance
numbers, an FAQ, and a troubleshooting section.
Verification
Full suite: 1,319 passed, 12 skipped. ruff check, ruff format --check,
and mypy all clean. Compression ratchet unchanged — no baseline
regeneration needed.
Upgrading
token-saver updateor, for a manual install:
cd token-saver && git pull && python3 install.py --target claudeNo config or data migration is required.