chisle 3.0.0 → 3.2.0
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.
- package/.claude-plugin/plugin.json +1 -1
- package/.clinerules/chisle.md +15 -8
- package/.cursor/rules/chisle.mdc +16 -9
- package/.github/copilot-instructions.md +15 -8
- package/.kiro/steering/chisle.md +15 -8
- package/.windsurf/rules/chisle.md +15 -8
- package/AGENTS.md +12 -3
- package/README.md +111 -60
- package/bin/install.js +144 -49
- package/commands/chisle-audit.toml +1 -1
- package/commands/chisle-help.toml +1 -1
- package/commands/chisle-review.toml +1 -1
- package/hooks/chisle-compress-output.js +26 -12
- package/hooks/chisle-mode-tracker.js +6 -32
- package/hooks/chisle-mode.js +19 -0
- package/package.json +13 -6
- package/pi-extension/index.js +188 -0
- package/rules/chisle-activate.md +1 -1
- package/skills/chisle/SKILL.md +19 -11
- package/skills/chisle-audit/SKILL.md +4 -4
- package/skills/chisle-help/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<h1 align="center">Chisle</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<em>Your AI talks less, builds less, reads less
|
|
8
|
+
<em>Your AI talks less, builds less, reads less, and says more. Like a senior dev who bills by the syllable.</em>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
16
|
<a href="https://www.npmjs.com/package/chisle"><img src="https://img.shields.io/npm/v/chisle?style=flat-square&color=d78a3c" alt="npm version"></a>
|
|
17
|
-
<img src="https://img.shields.io/badge/works%20with-
|
|
17
|
+
<img src="https://img.shields.io/badge/works%20with-9%20agents-d78a3c?style=flat-square" alt="Works with 9 agents">
|
|
18
18
|
<a href="https://github.com/JayPokale/Chisle/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/JayPokale/Chisle/test.yml?style=flat-square&label=CI" alt="CI"></a>
|
|
19
19
|
<img src="https://img.shields.io/badge/deps-0-2da44e?style=flat-square" alt="Zero deps">
|
|
20
20
|
<img src="https://img.shields.io/badge/license-MIT-d78a3c?style=flat-square" alt="MIT">
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
</p>
|
|
27
27
|
|
|
28
28
|
<p align="center">
|
|
29
|
-
<a href="https://chisle.jaypokale.me"><strong>chisle.jaypokale.me</strong></a>
|
|
29
|
+
<a href="https://chisle.jaypokale.me"><strong>chisle.jaypokale.me</strong></a> is the site version of this README, with fewer words
|
|
30
30
|
</p>
|
|
31
31
|
|
|
32
32
|
---
|
|
33
33
|
|
|
34
|
-
"Add debounce to a search input that currently fires an API call on every keystroke." Same model, same prompt, one difference
|
|
34
|
+
"Add debounce to a search input that currently fires an API call on every keystroke." Same model, same prompt, one difference: the injected ruleset. Both answers below are the **verbatim committed output** from [`benchmarks/results/raw/`](benchmarks/results/raw/):
|
|
35
35
|
|
|
36
36
|
<table>
|
|
37
|
-
<tr><th align="left" width="50%">bare agent
|
|
37
|
+
<tr><th align="left" width="50%">bare agent: 142 lines, 1506 tokens</th><th align="left" width="50%">Chisle: 35 lines, 602 tokens</th></tr>
|
|
38
38
|
<tr valign="top"><td>
|
|
39
39
|
|
|
40
40
|
Opens with *"Let me show you the most common approaches"*, then ships a reusable generic `useDebounce<T>` hook in its own file…
|
|
@@ -55,7 +55,7 @@ export function useDebounce<T>(
|
|
|
55
55
|
|
|
56
56
|
</td><td>
|
|
57
57
|
|
|
58
|
-
Asks which framework, then answers the question that was actually asked
|
|
58
|
+
Asks which framework, then answers the question that was actually asked: `setTimeout` in the effect you already have, no new file, no generic:
|
|
59
59
|
|
|
60
60
|
```jsx
|
|
61
61
|
useEffect(() => {
|
|
@@ -71,7 +71,7 @@ Then two lines on why it works, and *"use `lodash.debounce` if already installed
|
|
|
71
71
|
</td></tr>
|
|
72
72
|
</table>
|
|
73
73
|
|
|
74
|
-
Not golfed
|
|
74
|
+
Not golfed, **boring**. Same behaviour, one less abstraction, no second file, and it names the dependency you might already have instead of reinventing it.
|
|
75
75
|
|
|
76
76
|
Most efficiency tools compress one thing. Chisle compresses **three**:
|
|
77
77
|
|
|
@@ -79,30 +79,30 @@ Most efficiency tools compress one thing. Chisle compresses **three**:
|
|
|
79
79
|
|---|---|---|
|
|
80
80
|
| **Output: prose** | filler, hedging, manufactured structure | zero-fluff ruleset, injected per session |
|
|
81
81
|
| **Output: code** | speculative abstractions, unrequested boilerplate | YAGNI efficiency ladder |
|
|
82
|
-
| **Input: context** | oversized tool output flooding the window | `PostToolUse`
|
|
82
|
+
| **Input: context** | oversized tool output flooding the window | Claude `PostToolUse` / Pi `tool_result`: scrub, elide, dedup, plus prevention rules |
|
|
83
83
|
|
|
84
84
|
Where each one attaches to a session:
|
|
85
85
|
|
|
86
86
|
```mermaid
|
|
87
87
|
flowchart LR
|
|
88
88
|
subgraph S["Session start"]
|
|
89
|
-
H1["
|
|
89
|
+
H1["Ruleset injection<br/>once per active session"]
|
|
90
90
|
end
|
|
91
91
|
subgraph T["Every turn"]
|
|
92
|
-
H2["
|
|
92
|
+
H2["Mode tracking<br/>Claude + Pi"]
|
|
93
93
|
end
|
|
94
94
|
subgraph L["Every tool call"]
|
|
95
|
-
H3["PostToolUse
|
|
95
|
+
H3["PostToolUse / tool_result<br/>scrub → elide → dedup"]
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
H1 --> M(["Model"])
|
|
99
99
|
H2 --> M
|
|
100
100
|
M -->|writes| O["Output:<br/>terser prose,<br/>YAGNI-first code"]
|
|
101
|
-
M -->|calls a tool| TOOL[["Bash /
|
|
101
|
+
M -->|calls a tool| TOOL[["Bash / grep / web / extension tools"]]
|
|
102
102
|
TOOL -->|raw output| H3
|
|
103
103
|
H3 -->|"compressed, rebuilt into<br/>the tool's own shape"| M
|
|
104
104
|
|
|
105
|
-
RE["Read / Edit"] -.->|"never touched
|
|
105
|
+
RE["Read / Edit / Write"] -.->|"never touched,<br/>exact bytes feed later edits"| M
|
|
106
106
|
|
|
107
107
|
style M fill:#1f2937,stroke:#d78a3c,color:#e6edf3
|
|
108
108
|
style O fill:#14532d,stroke:#2da44e,color:#e6edf3
|
|
@@ -110,19 +110,19 @@ flowchart LR
|
|
|
110
110
|
style RE fill:#3f1d1d,stroke:#cf3b3b,color:#e6edf3
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
The loop on the right is the input axis: tool output is billed again on *every* later request in the session, so shrinking it once pays repeatedly. `Read` and `
|
|
113
|
+
The loop on the right is the input axis: tool output is billed again on *every* later request in the session, so shrinking it once pays repeatedly. `Read`, `Edit`, and `Write` are deliberately outside it.
|
|
114
114
|
|
|
115
115
|
<p align="center">
|
|
116
|
-
<img src="assets/thumbnail.png" width="820" alt="Chisle
|
|
116
|
+
<img src="assets/thumbnail.png" width="820" alt="Chisle: less tokens, same results. Four parts: output compressor (compress noisy tool outputs), context diet (read only what's actually relevant), terse persona (short, focused, YAGNI-first), YAGNI ladder (do less, reuse more, build only when needed).">
|
|
117
117
|
</p>
|
|
118
118
|
|
|
119
|
-
Every "be concise" tool has a worst day
|
|
119
|
+
Every "be concise" tool has a worst day, the day it makes the model write *more* than no tool at all. Across 20 measured tasks over two suites, the specialists had that day **6** and **8** times, blowing up to **424%** of the baseline. Chisle had it **once**, capped at 173%, and that one failure was root-caused, fixed in the ruleset, and re-validated live at 93%, with the whole investigation [committed to the repo](benchmarks/results/2026-07-07-verify-rerun.md). Think of it as downside insurance for your token bill: not always the single cheapest answer, always the smallest worst case, from the only tool in this class that publishes its own failures. [Why not caveman or ponytail? →](docs/comparison.md)
|
|
120
120
|
|
|
121
121
|
---
|
|
122
122
|
|
|
123
123
|
## Install
|
|
124
124
|
|
|
125
|
-
One command. Auto-detects your agents (Claude Code, Cursor, Windsurf, Cline, Kiro, Codex, Gemini, Copilot) and wires each one. `--uninstall` puts everything back.
|
|
125
|
+
One command. Auto-detects your agents (Claude Code, Pi, Cursor, Windsurf, Cline, Kiro, Codex, Gemini, Copilot) and wires each one. `--uninstall` puts everything back.
|
|
126
126
|
|
|
127
127
|
```bash
|
|
128
128
|
npx chisle
|
|
@@ -138,13 +138,13 @@ curl -fsSL https://raw.githubusercontent.com/JayPokale/Chisle/main/install.sh |
|
|
|
138
138
|
irm https://raw.githubusercontent.com/JayPokale/Chisle/main/install.ps1 | iex
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
Preview first with `npx chisle --dry-run`, scope with `--only claude`, see everything with `npx chisle --help`. Remove with `npx chisle --uninstall`.
|
|
141
|
+
Preview first with `npx chisle --dry-run`, scope with `--only claude` or `--only pi`, see everything with `npx chisle --help`. Remove with `npx chisle --uninstall`.
|
|
142
142
|
|
|
143
|
-
**Requirements:** Node ≥18 (installer / `npx`) · Claude Code for `/chisle` toggling and input-side compression
|
|
143
|
+
**Requirements:** Node ≥18 (installer / `npx`) · Claude Code or Pi for `/chisle` toggling and input-side compression. The always-on ruleset still ships to every other agent.
|
|
144
144
|
|
|
145
145
|
### Upgrading
|
|
146
146
|
|
|
147
|
-
Same command as installing
|
|
147
|
+
Same command as installing. It is idempotent and overwrites the previous copy:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
150
|
npx chisle # npm / standalone install
|
|
@@ -158,7 +158,7 @@ releases stay quiet on purpose.
|
|
|
158
158
|
Upgrading to 3.0.0 from 2.x needs nothing: a `lite`/`full`/`ultra` value in
|
|
159
159
|
`CHISLE_DEFAULT_MODE` or `config.json` is no longer meaningful, falls through to
|
|
160
160
|
the default, and Chisle stays active. It says so once so the setting is not
|
|
161
|
-
ignored silently
|
|
161
|
+
ignored silently. Replace it with `on`/`off` or delete it.
|
|
162
162
|
|
|
163
163
|
### Claude Code plugin (marketplace)
|
|
164
164
|
|
|
@@ -167,17 +167,46 @@ claude plugin marketplace add JayPokale/Chisle # register the marketplace
|
|
|
167
167
|
claude plugin install chisle@chisle # enable the plugin
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
+
### Pi package
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
pi install npm:chisle
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The package loads the zero-dependency extension and `chisle` skill globally. Pi extensions run with your user permissions; review the source before installation. Project-local installs (`pi install -l npm:chisle`) load only after you trust that project.
|
|
177
|
+
|
|
178
|
+
### Where the savings show up
|
|
179
|
+
|
|
180
|
+
Two places, both measured rather than estimated:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npx chisle --stats # what the compressor has saved, cumulative
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
chisle: tool-output savings
|
|
188
|
+
|
|
189
|
+
saved: 88,967 chars (~22,241 tokens)
|
|
190
|
+
outputs: 18 compressed, 4,943 chars each on average
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
In Claude Code the statusline badge carries the same number live: `[CHISLE] ⇣22k tok`. Pi shows it in the footer for the current session.
|
|
194
|
+
|
|
195
|
+
This is the **input axis only**, and deliberately so. Chars elided have a real baseline, since the hook knows exactly what it cut. The output axis has none: there is no way to know what the model would have written without the ruleset, which is why that half is measured with A/B benchmark arms instead of a counter. A number that blended the two would be inventing the interesting half.
|
|
196
|
+
|
|
170
197
|
### See what it would do, before it does it
|
|
171
198
|
|
|
172
199
|
```bash
|
|
173
200
|
npx chisle --dry-run # prints every file it would touch, changes nothing
|
|
201
|
+
npx chisle --stats # prints what it has saved, changes nothing
|
|
174
202
|
```
|
|
175
203
|
|
|
176
|
-
Want the savings measured on your own work rather than ours? Clone the repo and replay the compressor over
|
|
204
|
+
Want the savings measured on your own work rather than ours? Clone the repo and replay the compressor over local transcripts. It reads them locally, writes nothing, and reports the input the hook would have stripped:
|
|
177
205
|
|
|
178
206
|
```bash
|
|
179
207
|
git clone https://github.com/JayPokale/Chisle && cd Chisle
|
|
180
|
-
node benchmarks/replay-compress.js
|
|
208
|
+
node benchmarks/replay-compress.js # Claude Code
|
|
209
|
+
node benchmarks/replay-compress.js pi # Pi; marginal over Pi's native truncation
|
|
181
210
|
```
|
|
182
211
|
|
|
183
212
|
---
|
|
@@ -186,7 +215,7 @@ node benchmarks/replay-compress.js
|
|
|
186
215
|
|
|
187
216
|
Nothing here is estimated. Every figure below is recomputed from committed raw data; the 2026-07-07 [verification writeup](benchmarks/results/2026-07-07-verify-rerun.md) re-derived the old claims from scratch, re-ran the whole suite against the competitors' **installed plugins**, and retired the one claim that didn't survive.
|
|
188
217
|
|
|
189
|
-
### Output axis
|
|
218
|
+
### Output axis: vs caveman & ponytail, 20 live tasks
|
|
190
219
|
|
|
191
220
|
**59+ live model runs** across two suites (June 4-arm matrix on Haiku + Sonnet sweep; July re-verification run). Arms differ only in the injected system prompt. Billed output tokens vs the no-tool baseline:
|
|
192
221
|
|
|
@@ -199,10 +228,10 @@ Nothing here is estimated. Every figure below is recomputed from committed raw d
|
|
|
199
228
|
Chisle wins all four columns: it cut the total 20-task bill **nearly in half** while the specialists managed 20–32%, and it did so with the smallest worst day and a twentieth the backfire rate.
|
|
200
229
|
|
|
201
230
|
<p align="center">
|
|
202
|
-
<img src="assets/benchmark.svg" width="820" alt="Total billed output across 20 tasks as percent of the no-tool baseline. caveman 80% (worst day 424%, backfired 6), ponytail 68% (worst day 227%, backfired 8), Chisle 52% (worst day 173%, backfired 1
|
|
231
|
+
<img src="assets/benchmark.svg" width="820" alt="Total billed output across 20 tasks as percent of the no-tool baseline. caveman 80% (worst day 424%, backfired 6), ponytail 68% (worst day 227%, backfired 8), Chisle 52% (worst day 173%, backfired 1, root-caused and fixed).">
|
|
203
232
|
</p>
|
|
204
233
|
|
|
205
|
-
The bar is the whole 20-task bill; the badge is each tool's worst single day. caveman's worst day cost **4.2×** a bare model; ponytail's
|
|
234
|
+
The bar is the whole 20-task bill; the badge is each tool's worst single day. caveman's worst day cost **4.2×** a bare model; ponytail's, a tool whose entire job is writing less, **2.3×**. Chisle's worst day was 1.7×, it happened once, and the fix is measured and merged.
|
|
206
235
|
|
|
207
236
|
In the July run all 24 answers, every arm, **graded correct**: nobody here buys token savings with wrong answers.
|
|
208
237
|
|
|
@@ -215,35 +244,35 @@ Across all 20 cells, split by what the prompt actually asks for:
|
|
|
215
244
|
| **coding** (wants working code) | 12 | 74% | 59% | **44%** |
|
|
216
245
|
| **non-coding** (wants an explanation) | 8 | 103% | 104% | **87%** |
|
|
217
246
|
|
|
218
|
-
Code is where the YAGNI ladder has something to bite on: an abstraction to skip, a stdlib call to reach for, a file not to create. Chisle bills **44%** of a bare model there
|
|
247
|
+
Code is where the YAGNI ladder has something to bite on: an abstraction to skip, a stdlib call to reach for, a file not to create. Chisle bills **44%** of a bare model there, a third less than ponytail, which is the closest thing to a dedicated lazy-code tool.
|
|
219
248
|
|
|
220
|
-
On explanation-only prompts the picture is worse for everyone. Both specialists land **above 100
|
|
249
|
+
On explanation-only prompts the picture is worse for everyone. Both specialists land **above 100%**: a tool whose job is writing less made the model write *more* than using nothing at all. Chisle is the only arm that stays under water (87%), which is a smaller win than the coding number and worth saying plainly.
|
|
221
250
|
|
|
222
251
|
This does revise a claim the earlier Sonnet writeup made. On that suite's three prose prompts caveman was leaner (44% vs 52%), and that still holds *for those cells*. Pooled across all eight non-coding cells it does not: caveman is at 103%. The prose win was suite-specific, not general.
|
|
223
252
|
|
|
224
253
|
#### Task by task
|
|
225
254
|
|
|
226
|
-
Averages hide the interesting part, so here is every cell of the June suite
|
|
255
|
+
Averages hide the interesting part, so here is every cell of the June suite, same six prompts, every arm, no cherry-picking:
|
|
227
256
|
|
|
228
257
|
<p align="center">
|
|
229
258
|
<img src="assets/per-task.svg" width="820" alt="Billed output per task as a percent of the no-tool baseline across the six-task June suite: Chisle is leanest on five of six, caveman wins the cache task at 8% versus Chisle's 12%.">
|
|
230
259
|
</p>
|
|
231
260
|
|
|
232
|
-
Chisle is leanest on **5 of 6**. caveman takes `cache` (8% vs our 12%)
|
|
261
|
+
Chisle is leanest on **5 of 6**. caveman takes `cache` (8% vs our 12%) by answering in prose where we still emit working code, which is the trade you would want on a task that asked for code. Note the two prose rows where ponytail lands **above** 100%: a tool built to write less made the model write *more* than using no tool at all. That is the failure mode the worst-case column above is really about.
|
|
233
262
|
|
|
234
263
|
#### The headline average is hiding the good part
|
|
235
264
|
|
|
236
|
-
Split the same 20 cells at their median baseline
|
|
265
|
+
Split the same 20 cells at their median baseline, short answers below and long answers above, and the tools separate sharply:
|
|
237
266
|
|
|
238
267
|
<p align="center">
|
|
239
268
|
<img src="assets/by-size.svg" width="820" alt="Total billed output split by answer size. On short answers caveman and Chisle are level at about 84% of baseline and ponytail is above 100%. On long answers Chisle drops to about 45% while caveman is 79% and ponytail 59%.">
|
|
240
269
|
</p>
|
|
241
270
|
|
|
242
|
-
On **short** answers Chisle and caveman are level (84% each)
|
|
271
|
+
On **short** answers Chisle and caveman are level (84% each), because there is not much to cut in a three-line reply, and the ruleset overhead is proportionally at its worst. On **long** answers Chisle drops to **45%** while caveman only reaches 79%. The 52% headline is the blend of the two, so it understates the case where it matters and overstates the case where it doesn't.
|
|
243
272
|
|
|
244
|
-
The effect is not driven by one lucky cell. Dropping the `cache` outlier (the row where the baseline invented 150 lines against a codebase it never saw) *widens* the gap on long answers: caveman degrades to **116
|
|
273
|
+
The effect is not driven by one lucky cell. Dropping the `cache` outlier (the row where the baseline invented 150 lines against a codebase it never saw) *widens* the gap on long answers: caveman degrades to **116%**, worse than using no tool, while Chisle holds at **65%**.
|
|
245
274
|
|
|
246
|
-
Two honest limits. Per-task rank correlation between baseline size and leanness is weak (Spearman ρ = −0.15), so this is a difference between aggregate bills, not a tidy per-task law
|
|
275
|
+
Two honest limits. Per-task rank correlation between baseline size and leanness is weak (Spearman ρ = −0.15), so this is a difference between aggregate bills, not a tidy per-task law. With n=10 a side, treat it as a strong signal rather than a settled result. And much of the widening gap comes from the specialists getting *worse* on long answers, not only from Chisle getting better.
|
|
247
276
|
|
|
248
277
|
#### Size or kind? Both, and they're tangled
|
|
249
278
|
|
|
@@ -260,11 +289,11 @@ Coding prompts average ~1129 baseline tokens against ~393 for explanation prompt
|
|
|
260
289
|
<img src="assets/by-kind.svg" width="820" alt="Billed output by task kind crossed with answer size. Code and short: caveman 62%, ponytail 116%, Chisle 70%. Code and long: caveman 76%, ponytail 52%, Chisle 41%. Explanation and short: caveman 104%, ponytail 98%, Chisle 96%. Explanation and long: caveman 103%, ponytail 111%, Chisle 77%.">
|
|
261
290
|
</p>
|
|
262
291
|
|
|
263
|
-
Size matters *within* each kind
|
|
292
|
+
Size matters *within* each kind: coding goes 70% → 41% and non-coding 96% → 77%, so it isn't merely code in disguise. But the cells are thin, and the non-coding "long" bucket spans only 522–542 tokens, which is barely long at all.
|
|
264
293
|
|
|
265
294
|
The one row Chisle loses is **short coding**, where caveman takes it 62% to 70%. That is the honest shape of it: on a small code question there is little to skip, and the ruleset costs more than the ladder saves. The tool earns its keep on the long ones.
|
|
266
295
|
|
|
267
|
-
`SUITE=large` exists to fill the thin cells
|
|
296
|
+
`SUITE=large` exists to fill the thin cells, see [below](#see-what-it-would-do-before-it-does-it).
|
|
268
297
|
|
|
269
298
|
These prompts were never designed to test this, which is the real caveat. To probe it directly:
|
|
270
299
|
|
|
@@ -278,32 +307,54 @@ SUITE=large bash benchmarks/run-live.sh <model> benchmarks/results/raw-large
|
|
|
278
307
|
|---|:---:|:---:|:---:|:---:|:---:|
|
|
279
308
|
| caveman | ✅ | ❌ | ❌ | ❌ 424% | ❌ |
|
|
280
309
|
| ponytail | ❌ | ✅ | ❌ | ❌ 227% | ❌ |
|
|
281
|
-
| headroom | ❌ | ❌ | ✅ proxy |
|
|
310
|
+
| headroom | ❌ | ❌ | ✅ proxy | n/a | ❌ |
|
|
282
311
|
| **Chisle** | ✅ | ✅ | ✅ hook | **173%, 1/20** | ✅ |
|
|
283
312
|
|
|
284
313
|
The row that matters is the last one. Every tool here looks good on its best day; the numbers above are the only ones in this class published alongside the run that went wrong. [Full comparison →](docs/comparison.md)
|
|
285
314
|
|
|
286
|
-
### Input axis
|
|
315
|
+
### Input axis: tool-output compression (Claude Code + Pi)
|
|
287
316
|
|
|
288
|
-
Measured over 171 real sessions ([receipts](benchmarks/results/2026-07-07-input-axis.md)): tool output is **67.5%** of context content, and every byte of it is re-billed on *every subsequent request* in the session (median: 171 requests). A `PostToolUse` hook shrinks it before the model reads it
|
|
317
|
+
Measured over 171 real sessions ([receipts](benchmarks/results/2026-07-07-input-axis.md)): tool output is **67.5%** of context content, and every byte of it is re-billed on *every subsequent request* in the session (median: 171 requests). A `PostToolUse` hook shrinks it before the model reads it: deterministic, zero LLM, zero network:
|
|
289
318
|
|
|
290
319
|
| tier | what it does | loss |
|
|
291
320
|
|---|---|---|
|
|
292
321
|
| **scrub** | strips ANSI escapes, collapses blank runs and `line repeated N×` | none |
|
|
293
322
|
| **elide** | oversized output → head + tail, error-like lines salvaged from the cut | bounded, guarded |
|
|
294
|
-
| **dedup** | byte-identical repeat of a tool's previous output (same session) → one-line marker | none
|
|
323
|
+
| **dedup** | byte-identical repeat of a tool's previous output (same session) → one-line marker | none, the copy is already in context |
|
|
295
324
|
|
|
296
|
-
Replayed over the same 171 sessions: **~61k tokens** saved one-shot, ~46% off every eligible output
|
|
325
|
+
Replayed over the same 171 Claude Code sessions: **~61k tokens** saved one-shot, ~46% off every eligible output: a floor, not an estimate, since each saved byte also stops being re-sent on every later request. Correctness rules: allowlist only (`Bash`, `Agent`, `WebFetch`, `WebSearch`, `Grep`, `Glob`, `mcp__*`), never `Read`/`Edit`, whose exact bytes feed later edits. Honest ledger: dedup scored **0 hits** on this corpus (rtk-filtered at source); it's kept for the test-rerun case, kill-switchable, and labeled speculative until it earns a number.
|
|
326
|
+
|
|
327
|
+
Pi already truncates built-in output at 50KB/2,000 lines. Replay over 8,044 persisted Pi results measured the compressor's **marginal** saving after that truncation: **27.4% of tool-output chars** ([receipt + raw live Pi arm](benchmarks/results/2026-09-11-pi.md)). Pi compresses `bash`, `powershell`, `grep`, `find`, `ls`, MCP, and explicitly allowlisted extension-tool results; `read`/`edit`/`write` remain untouched. `CHISLE_COMPRESS_TOOLS` supplies the same explicit override for runtime and replay. Runtime dedup only compares earlier turns, so concurrently completed sibling calls cannot dedup one another.
|
|
297
328
|
|
|
298
329
|
```bash
|
|
299
|
-
node benchmarks/replay-compress.js
|
|
330
|
+
node benchmarks/replay-compress.js # Claude Code
|
|
331
|
+
node benchmarks/replay-compress.js pi # Pi
|
|
300
332
|
```
|
|
301
333
|
|
|
302
|
-
Outputs over 8k chars are elided. `stop chisle`, `CHISLE_COMPRESS=0`, `CHISLE_COMPRESS_SCRUB=0`, `CHISLE_COMPRESS_DEDUP=0
|
|
334
|
+
Outputs over 8k chars are elided. `stop chisle`, `CHISLE_COMPRESS=0`, `CHISLE_COMPRESS_SCRUB=0`, `CHISLE_COMPRESS_DEDUP=0`. Every tier has an off switch.
|
|
335
|
+
|
|
336
|
+
### Pi arm: where the output axis lost
|
|
337
|
+
|
|
338
|
+
Six tasks, Pi 0.85.1 on `openai-codex/gpt-5.5`, as % of the vanilla no-tool baseline. Lower is better, bold is the winner of the row:
|
|
339
|
+
|
|
340
|
+
| segment | vanilla | caveman | ponytail | **Chisle** |
|
|
341
|
+
|---|--:|--:|--:|--:|
|
|
342
|
+
| coding billed tokens | 100% | 87% | **49%** | 73% |
|
|
343
|
+
| non-coding billed tokens | 100% | 43% | 76% | **39%** |
|
|
344
|
+
| **all billed tokens** | 100% | 72% | **59%** | 61% |
|
|
345
|
+
| all visible-answer tokens | 100% | 56% | 49% | **37%** |
|
|
346
|
+
| all answer lines | 100% | 75% | 38% | **37%** |
|
|
347
|
+
| tasks correct | 5/6 | 5/6 | 5/6 | 5/6 |
|
|
348
|
+
|
|
349
|
+
**Chisle lost billed output here.** ponytail used 63 fewer tokens over the six tasks. Publishing that is the point of this section.
|
|
350
|
+
|
|
351
|
+
The coding gap is one task. Chisle leads 4 of 6 tasks outright; `auth-bug` alone accounts for 283 of the 337-token coding gap. On that task Chisle produced the shortest answer of any arm (377 chars to ponytail's 632) and was the only arm to find the real defect: ponytail flipped `>` to `>=`, while Chisle identified the seconds-versus-milliseconds unit mismatch behind it. The grader scored every arm as failing regardless, which says more about that task than about the tools.
|
|
352
|
+
|
|
353
|
+
Six tasks, one model, one run. Raw events and per-task cells: [`benchmarks/results/raw-pi/`](benchmarks/results/raw-pi/).
|
|
303
354
|
|
|
304
|
-
### Prevention
|
|
355
|
+
### Prevention: the context diet
|
|
305
356
|
|
|
306
|
-
The biggest context whale (whole-file `Read`s
|
|
357
|
+
The biggest context whale (whole-file `Read`s, 5.6M chars in the measured corpus) can't be compressed without breaking later edits. So the ruleset attacks it upstream, in every agent: grep for the symbol first, read only the matching region, narrow at the source (`ls dir` not `ls -R`, pipe long output through `tail`/`grep`), never re-read what's already in context.
|
|
307
358
|
|
|
308
359
|
---
|
|
309
360
|
|
|
@@ -313,7 +364,7 @@ The biggest context whale (whole-file `Read`s — 5.6M chars in the measured cor
|
|
|
313
364
|
> New object ref each render. Inline object prop = new ref = re-render. `useMemo`.
|
|
314
365
|
|
|
315
366
|
**"Add a cache for API responses."**
|
|
316
|
-
> `@lru_cache(maxsize=1000)` on the fetch fn. Skipped a custom cache class
|
|
367
|
+
> `@lru_cache(maxsize=1000)` on the fetch fn. Skipped a custom cache class; add one when `lru_cache` measurably falls short.
|
|
317
368
|
|
|
318
369
|
---
|
|
319
370
|
|
|
@@ -327,7 +378,7 @@ The biggest context whale (whole-file `Read`s — 5.6M chars in the measured cor
|
|
|
327
378
|
| `stop chisle` | Deactivate (ruleset *and* input-side compression) |
|
|
328
379
|
| `normal mode` | Deactivate |
|
|
329
380
|
|
|
330
|
-
Natural language works too: "activate chisle", "chisle mode", "chislify this". Code symbols, function/API names, and error strings stay verbatim
|
|
381
|
+
Natural language works too: "activate chisle", "chisle mode", "chislify this". Code symbols, function/API names, and error strings stay verbatim, so only the noise around them compresses.
|
|
331
382
|
|
|
332
383
|
---
|
|
333
384
|
|
|
@@ -359,9 +410,9 @@ flowchart TD
|
|
|
359
410
|
style R fill:#1f2937,stroke:#8b949e,color:#e6edf3
|
|
360
411
|
```
|
|
361
412
|
|
|
362
|
-
The ladder runs **after** reading, never instead of it. Note the exit: every rung lands on the same obligation
|
|
413
|
+
The ladder runs **after** reading, never instead of it. Note the exit: every rung lands on the same obligation: say what you skipped, so "later" doesn't quietly become "never".
|
|
363
414
|
|
|
364
|
-
The ladder runs *after* reading the code
|
|
415
|
+
The ladder runs *after* reading the code, lazy about the solution and never about understanding. Lazy is not negligent: trust-boundary validation, data-loss handling, security, and accessibility are never on the chopping block.
|
|
365
416
|
|
|
366
417
|
Mark deliberate simplifications so "later" doesn't quietly become "never":
|
|
367
418
|
|
|
@@ -374,7 +425,7 @@ Mark deliberate simplifications so "later" doesn't quietly become "never":
|
|
|
374
425
|
|
|
375
426
|
## Config
|
|
376
427
|
|
|
377
|
-
**On by default.** After install, Chisle activates automatically every session
|
|
428
|
+
**On by default.** After install, Chisle activates automatically every session, with no `/chisle` needed. Set `off` to stay dormant until you type `/chisle`:
|
|
378
429
|
|
|
379
430
|
```bash
|
|
380
431
|
# env var (highest priority)
|
|
@@ -396,22 +447,22 @@ Chisle borrows the best published token-saving techniques and implements the one
|
|
|
396
447
|
|---|---|---|
|
|
397
448
|
| Prose compression persona | [caveman](https://github.com/JuliusBrussee/caveman) | ✅ + code judgment it lacks |
|
|
398
449
|
| YAGNI/lazy-code ruleset | [ponytail](https://github.com/dietrichgebert/ponytail) | ✅ + prose discipline it lacks |
|
|
399
|
-
| Tool-output elision (head/tail) | [headroom](https://github.com/headroomlabs-ai/headroom)-style, proxy-free | ✅ hook, no proxy
|
|
450
|
+
| Tool-output elision (head/tail) | [headroom](https://github.com/headroomlabs-ai/headroom)-style, proxy-free | ✅ hook, no proxy, works on subscription OAuth |
|
|
400
451
|
| ANSI strip / log crush / dedup | headroom transforms | ✅ scrub + dedup tiers |
|
|
401
|
-
| Command rewriting at the source | RTK-style `PreToolUse` ([writeup](https://andrewpatterson.dev/posts/token-savings-rtk-headroom/)) | ❌ stacks
|
|
402
|
-
| MCP/codebase-graph indexing | context-mode, [token-optimizer-mcp](https://github.com/ooples/token-optimizer-mcp) | ❌ stacks
|
|
452
|
+
| Command rewriting at the source | RTK-style `PreToolUse` ([writeup](https://andrewpatterson.dev/posts/token-savings-rtk-headroom/)) | ❌ stacks; RTK shrinks at source, Chisle catches what it can't reach (subagents, MCP, web) |
|
|
453
|
+
| MCP/codebase-graph indexing | context-mode, [token-optimizer-mcp](https://github.com/ooples/token-optimizer-mcp) | ❌ stacks, orthogonal layer |
|
|
403
454
|
| CLAUDE.md dieting | [community guides](https://www.firecrawl.dev/blog/claude-code-token-efficiency) | ✅ `/chisle-audit` flags bloated docs/config prose |
|
|
404
455
|
|
|
405
456
|
## Multi-agent
|
|
406
457
|
|
|
407
|
-
|
|
458
|
+
Ships to nine agents: Claude Code and Pi get both axes, live `/chisle` toggling, and a status badge; Cursor, Windsurf, Cline, Kiro, Codex, Gemini, and Copilot get the always-on ruleset. Per-agent static copies come from `scripts/build-rules.js`; Pi uses its package extension plus the Agent Skills standard. See [`docs/agent-portability.md`](./docs/agent-portability.md).
|
|
408
459
|
|
|
409
460
|
## FAQ
|
|
410
461
|
|
|
411
462
|
**Doesn't injecting a persona every turn cost tokens?**
|
|
412
|
-
|
|
463
|
+
Claude Code uses a ruleset at session start (~1.6k tokens) plus a ~50-token reminder per turn. Pi injects one persistent rules message only when project `AGENTS.md` does not already provide it; resume/reload does not duplicate it, and compaction restores it only if removed.
|
|
413
464
|
|
|
414
|
-
Worth reading the dissent before you take that on faith: [@enc0ded](https://github.com/enc0ded) measured 173 of their own sessions ([#2](https://github.com/JayPokale/Chisle/issues/2)) and found the injection overhead roughly cancelling the compressor's savings
|
|
465
|
+
Worth reading the dissent before you take that on faith: [@enc0ded](https://github.com/enc0ded) measured 173 of their own sessions ([#2](https://github.com/JayPokale/Chisle/issues/2)) and found the injection overhead roughly cancelling the compressor's savings, because the ruleset was being re-sent on every resume and clear, not just at startup. That re-injection is fixed, which removes most of the overhead they measured, but their wider point stands: prose is only ~25% of what the model emits, so the ceiling on the output axis is lower than the headline suggests, and on a one-line throwaway prompt the overhead still exceeds the saving.
|
|
415
466
|
|
|
416
467
|
**Will it golf my code into clever one-liners?**
|
|
417
468
|
No. Boring over clever. Deletion beats addition; obfuscation isn't deletion.
|
|
@@ -420,10 +471,10 @@ No. Boring over clever. Deletion beats addition; obfuscation isn't deletion.
|
|
|
420
471
|
Never. Input validation, data-loss handling, security, and accessibility are off the table. Lazy about solutions, not about reading the problem.
|
|
421
472
|
|
|
422
473
|
**Can the output compressor eat a line I needed?**
|
|
423
|
-
Designed not to: allowlist keeps `Read`/`Edit` exact, error-looking lines are salvaged from any elided region, dedup only fires on byte-identical same-session repeats, and every tier has a kill switch. If it still bites you, file an issue
|
|
474
|
+
Designed not to: allowlist keeps `Read`/`Edit` exact, error-looking lines are salvaged from any elided region, dedup only fires on byte-identical same-session repeats, and every tier has a kill switch. If it still bites you, file an issue. That's a bug, not the design.
|
|
424
475
|
|
|
425
476
|
**Should the star count worry me?**
|
|
426
|
-
Everyone starts at zero. Run `npx chisle --dry-run`, see what it'd do, decide. And if the receipts convinced you, [a star](https://github.com/JayPokale/Chisle/stargazers) is how the next person finds them
|
|
477
|
+
Everyone starts at zero. Run `npx chisle --dry-run`, see what it'd do, decide. And if the receipts convinced you, [a star](https://github.com/JayPokale/Chisle/stargazers) is how the next person finds them, and it's also the only payment a zero-dep MIT tool will ever ask for.
|
|
427
478
|
|
|
428
479
|
→ [More FAQ and competitor comparison](docs/comparison.md)
|
|
429
480
|
|
|
@@ -433,7 +484,7 @@ Everyone starts at zero. Run `npx chisle --dry-run`, see what it'd do, decide. A
|
|
|
433
484
|
|
|
434
485
|
See [CONTRIBUTING.md](CONTRIBUTING.md). Edit the skill (`skills/chisle/SKILL.md`) **and** the condensed rule body in `scripts/build-rules.js`, regenerate copies and chart, run the tests. CI enforces all three.
|
|
435
486
|
|
|
436
|
-
Built by [Jay Pokale](https://github.com/JayPokale) with [Claude](https://claude.com/claude-code), [Antigravity](https://antigravity.google), and [Codex](https://openai.com/blog/openai-codex/) as co-engineers
|
|
487
|
+
Built by [Jay Pokale](https://github.com/JayPokale) with [Claude](https://claude.com/claude-code), [Antigravity](https://antigravity.google), and [Codex](https://openai.com/blog/openai-codex/) as co-engineers: the input-compression hook, the benchmark verification, and several of the bug hunts documented in the changelog were pair-work.
|
|
437
488
|
|
|
438
489
|
```bash
|
|
439
490
|
npm test # 67 tests: flag safety, tracker, settings merge, installer, compressor
|
|
@@ -460,5 +511,5 @@ npm test # 67 tests: flag safety, tracker, settings merge, installer, compres
|
|
|
460
511
|
---
|
|
461
512
|
|
|
462
513
|
<p align="center">
|
|
463
|
-
Saved you tokens? <a href="https://github.com/JayPokale/Chisle">⭐ Star the repo</a
|
|
514
|
+
Saved you tokens? <a href="https://github.com/JayPokale/Chisle">⭐ Star the repo</a>. It costs zero tokens and keeps the benchmarks running.
|
|
464
515
|
</p>
|