claude-token-saver 3.42.0 โ†’ 3.42.2

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/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  ---
19
19
 
20
- # Sprag (claude-token-saver)
20
+ # Sprag (sprag)
21
21
 
22
22
  **Shows what it saved, on two lines.** It moves the easy work your expensive model keeps repeating onto cheaper ones, and turns documents the model cannot read into Markdown. Both figures are ledger entries rather than estimates, and whichever saved more takes the top line. Zero dependencies, one-line install.
23
23
 
@@ -25,6 +25,8 @@
25
25
 
26
26
  ```bash
27
27
  npm i -g sprag-cli # or: npm i -g claude-token-saver (same package, old name)
28
+ # already have claude-token-saver? switching names needs a swap (same bins):
29
+ # npm uninstall -g claude-token-saver && npm i -g sprag-cli
28
30
  ```
29
31
 
30
32
  Four numbers are the whole pitch.
@@ -69,14 +71,14 @@ The two savings figures are never added together, because they answer different
69
71
 
70
72
  ```bash
71
73
  npm uninstall -g claude-cache-monitor # (previous-package users only)
72
- npm i -g claude-token-saver
74
+ npm i -g sprag-cli
73
75
  ```
74
76
 
75
- The statusline appears at the bottom of Claude Code right away. If auto-registration was skipped (`--ignore-scripts`, sudo, sandboxed installs), run `claude-token-saver install`.
77
+ The statusline appears at the bottom of Claude Code right away. If auto-registration was skipped (`--ignore-scripts`, sudo, sandboxed installs), run `sprag install`.
76
78
 
77
79
  One install sets up everything: **statusline, Skill, SessionStart hook, the ๐Ÿ…ท Harness (5 principles), and a first route-scan.** The harness and the Korean writing guidance **show what they add and ask before enabling it.** The harness is **appended** to `~/.claude/CLAUDE.md` as a marked block (your existing content is backed up and preserved) and is left alone if one is already there.
78
80
 
79
- Outside a terminal โ€” npm `postinstall`, CI, piped stdin โ€” the question is skipped and the old defaults apply. Use `--yes` or `--no-input` to skip it deliberately, `CTS_NO_HARNESS=1 npm i -g claude-token-saver` to skip the harness entirely, and `claude-token-saver harness uninit --global` to undo it.
81
+ Outside a terminal โ€” npm `postinstall`, CI, piped stdin โ€” the question is skipped and the old defaults apply. Use `--yes` or `--no-input` to skip it deliberately, `CTS_NO_HARNESS=1 npm i -g sprag-cli` to skip the harness entirely, and `sprag harness uninit --global` to undo it.
80
82
 
81
83
  > โš ๏ธ Avoid `sudo` global installs โ€” the Skill lands in root's `~/.claude` instead of yours. Use nvm/fnm/Volta or `npm config set prefix ~/.npm-global`.
82
84
 
@@ -86,7 +88,7 @@ Everything that costs nothing until it is needed is on after a plain install. Th
86
88
 
87
89
  | Feature | After install | How to turn it off |
88
90
  |---|---|---|
89
- | statusline (diagnostic chips, savings ledger) | on | `claude-token-saver uninstall` |
91
+ | statusline (diagnostic chips, savings ledger) | on | `sprag uninstall` |
90
92
  | `/claude-token-saver` Skill | on | same |
91
93
  | SessionStart hook (route-scan refresh) | on | same |
92
94
  | UserPromptSubmit hook (brief injection) | on | same |
@@ -117,7 +119,7 @@ Every delegated run is recorded like this:
117
119
  ```
118
120
 
119
121
  ```bash
120
- $ claude-token-saver route-scan savings # trace every dollar back to its rule
122
+ $ sprag route-scan savings # trace every dollar back to its rule
121
123
 
122
124
  ๐Ÿ”€ Routing saved, lifetime $2.09 (last 7d $1.40 ยท 30d $2.09)
123
125
 
@@ -164,10 +166,10 @@ Teams shipping routing products have turned the feature off for exactly this rea
164
166
  So this tool never touches the main session's model. It delegates to **subagents only**, which leaves the main session's cache intact and runs the delegated work on a cheap model in its own context. That is why the savings are not cancelled out by cache loss.
165
167
 
166
168
  ```bash
167
- npm i -g claude-token-saver@latest
168
- claude-token-saver route-scan # find delegation candidates in your own history (0 LLM calls)
169
- claude-token-saver route-scan rules # list promoted rules ยท rm <N> to remove
170
- claude-token-saver route-scan savings # audit every dollar the routing saved
169
+ npm i -g sprag-cli@latest
170
+ sprag route-scan # find delegation candidates in your own history (0 LLM calls)
171
+ sprag route-scan rules # list promoted rules ยท rm <N> to remove
172
+ sprag route-scan savings # audit every dollar the routing saved
171
173
  ```
172
174
 
173
175
  Thresholds come from **your own last-14-day distribution (p25/p75)**, not someone else's benchmark.
@@ -212,7 +214,7 @@ Chips โ€” `๐Ÿšจ 5H/7D NN%` (cap imminent) ยท `โš  Ctx 500k+` (a single request a
212
214
 
213
215
  ### When a chip appears
214
216
 
215
- Run the `/claude-token-saver` Skill inside Claude โ€” or just say the chip wording ("5H cap is up", "cache miss") and it auto-activates. The Skill surfaces the **root-cause code + step-by-step fix**. When a cap is imminent, run `claude-token-saver handoff` to back up your work state to markdown and continue in a fresh session.
217
+ Run the `/claude-token-saver` Skill inside Claude โ€” or just say the chip wording ("5H cap is up", "cache miss") and it auto-activates. The Skill surfaces the **root-cause code + step-by-step fix**. When a cap is imminent, run `sprag handoff` to back up your work state to markdown and continue in a fresh session.
216
218
 
217
219
  ## Commands
218
220
 
@@ -220,27 +222,27 @@ Run these in your shell (inside Claude Code, the `/claude-token-saver` Skill is
220
222
 
221
223
  | Command | What it does |
222
224
  |---|---|
223
- | `claude-token-saver` | Last-1-day diagnostic report (`--days N` / `--hours N`) |
224
- | `claude-token-saver last` | Most recent warning + remediation |
225
- | `claude-token-saver history` | Last 7 days of warning transitions |
226
- | `claude-token-saver handoff` | Back work up to `HANDOFF-*.md` before a cap blocks you |
227
- | `claude-token-saver mode [keywords...]` | Output config (`icon`/`text`, `en`/`ko`, `1h`โ€“`30d` window, โ€ฆ) |
228
- | `claude-token-saver harness ...` | ๐Ÿ…ท Harness management (below) |
229
- | `claude-token-saver route-scan` | Detect recurring easy work on expensive models โ†’ propose haiku-delegation ratchet rules (below) |
230
- | `claude-token-saver route-scan savings` | The routing-savings ledger โ€” per-model-change rollup + per-run log (the evidence behind the figure) |
231
- | `claude-token-saver compact-window` | Warn when a 1M-context session has no auto-compact cap โ†’ pin 400k with `set` (below) |
232
- | `claude-token-saver korean on\|off\|status` | Inject Korean writing guidance at session start and install the write-time check (below) |
233
- | `claude-token-saver cohesion on\|off\|status\|show` | Inject English cohesion guidance (sentence-connection rules) at session start |
234
- | `claude-token-saver korean lint block\|warn\|off` | How the write-time check handles findings |
235
- | `claude-token-saver korean lint scope all\|prose` | Check every text file, or documents only |
236
- | `claude-token-saver doc2md on\|off` | Convert attached documents to Markdown before the model reads them (below) |
237
- | `claude-token-saver doc2md <file>` | Convert one file by hand. Diagnostic: it prints the refusal reason instead of swallowing it |
238
- | `claude-token-saver mode ttl=5m\|1h\|auto` | Pin the cache TTL bucket. The default `auto` trusts the measured split, then falls back to gateway detection |
239
- | `claude-token-saver --version` | Print the installed version |
240
- | `claude-token-saver update-check` | Is a newer version out? (`--refresh` to ask now, `--dismiss` to mute this version's offer) |
241
- | `claude-token-saver upgrade` | Install the latest release with the package manager that installed this copy (`--print` shows the command only) |
242
- | `claude-token-saver install` | Manually register Skill + statusline |
243
- | `claude-token-saver uninstall [--purge]` | Remove the hooks, statusline and skill it registered. Recorded savings are kept unless `--purge` is given |
225
+ | `sprag` | Last-1-day diagnostic report (`--days N` / `--hours N`) |
226
+ | `sprag last` | Most recent warning + remediation |
227
+ | `sprag history` | Last 7 days of warning transitions |
228
+ | `sprag handoff` | Back work up to `HANDOFF-*.md` before a cap blocks you |
229
+ | `sprag mode [keywords...]` | Output config (`icon`/`text`, `en`/`ko`, `1h`โ€“`30d` window, โ€ฆ) |
230
+ | `sprag harness ...` | ๐Ÿ…ท Harness management (below) |
231
+ | `sprag route-scan` | Detect recurring easy work on expensive models โ†’ propose haiku-delegation ratchet rules (below) |
232
+ | `sprag route-scan savings` | The routing-savings ledger โ€” per-model-change rollup + per-run log (the evidence behind the figure) |
233
+ | `sprag compact-window` | Warn when a 1M-context session has no auto-compact cap โ†’ pin 400k with `set` (below) |
234
+ | `sprag korean on\|off\|status` | Inject Korean writing guidance at session start and install the write-time check (below) |
235
+ | `sprag cohesion on\|off\|status\|show` | Inject English cohesion guidance (sentence-connection rules) at session start |
236
+ | `sprag korean lint block\|warn\|off` | How the write-time check handles findings |
237
+ | `sprag korean lint scope all\|prose` | Check every text file, or documents only |
238
+ | `sprag doc2md on\|off` | Convert attached documents to Markdown before the model reads them (below) |
239
+ | `sprag doc2md <file>` | Convert one file by hand. Diagnostic: it prints the refusal reason instead of swallowing it |
240
+ | `sprag mode ttl=5m\|1h\|auto` | Pin the cache TTL bucket. The default `auto` trusts the measured split, then falls back to gateway detection |
241
+ | `sprag --version` | Print the installed version |
242
+ | `sprag update-check` | Is a newer version out? (`--refresh` to ask now, `--dismiss` to mute this version's offer) |
243
+ | `sprag upgrade` | Install the latest release with the package manager that installed this copy (`--print` shows the command only) |
244
+ | `sprag install` | Manually register Skill + statusline |
245
+ | `sprag uninstall [--purge]` | Remove the hooks, statusline and skill it registered. Recorded savings are kept unless `--purge` is given |
244
246
 
245
247
  The output language is decided once, at install time: a terminal install proposes the system locale and asks whether to use Korean, while an unattended install records what the locale says. Once recorded it is never asked again, not even on an upgrade. Change it later with `mode ko` / `mode en`, or pin it for a scripted install with `CTS_LANG=ko` / `CTS_LANG=en`. Statusline chips stay symbolic either way.
246
248
 
@@ -268,8 +270,8 @@ The output language is decided once, at install time: a terminal install propose
268
270
  A statusline cannot open a dialog, and it re-renders every ~300ms, so it can never touch the network while drawing. The notification is therefore split in two:
269
271
 
270
272
  - **The statusline tells you.** Up to date: a quiet gray `v3.24.0` at the tail. Newer release out: `โฌ† v3.24.0 โ†’ 3.25.0` in yellow, moved to the front. Never red โ€” nothing is broken.
271
- - **Session start asks you.** On a new session or `/clear`, the SessionStart hook injects one line telling the model a newer version exists and to ask before installing anything. Only after you agree does it run `claude-token-saver upgrade`.
272
- - **Declining sticks.** `claude-token-saver update-check --dismiss` mutes the offer for that version; the next release asks again. The statusline chip stays โ€” you declined the question, not the fact.
273
+ - **Session start asks you.** On a new session or `/clear`, the SessionStart hook injects one line telling the model a newer version exists and to ask before installing anything. Only after you agree does it run `sprag upgrade`.
274
+ - **Declining sticks.** `sprag update-check --dismiss` mutes the offer for that version; the next release asks again. The statusline chip stays โ€” you declined the question, not the fact.
273
275
 
274
276
  The registry lookup runs at most once every 24h in a detached background process and only ever writes a cache file (`update-check.json`) โ€” the same shape npm's `update-notifier` uses. A failed check still stamps its timestamp, so an offline machine backs off instead of retrying on every render. Turn checks off entirely with `CTS_NO_UPDATE_CHECK=1` or `NO_UPDATE_NOTIFIER`.
275
277
 
@@ -278,15 +280,15 @@ The registry lookup runs at most once every 24h in a detached background process
278
280
  Bootstrap five engineering principles (Ratchet ยท Evidence ยท PEV ยท Structured Task ยท Default Safe Path) into `CLAUDE.md` with one command; the statusline scores it as `๐Ÿ…ท 5/5`. When the same error keeps recurring, a `๐Ÿ…ทโš  ratchet?` nudge appears so you can promote it to a rule.
279
281
 
280
282
  ```bash
281
- claude-token-saver harness init # this project
282
- claude-token-saver harness init --global # ~/.claude/CLAUDE.md โ€” every project
283
- claude-token-saver harness check # current score (global fallback honored)
284
- claude-token-saver harness analyze # run the transcript analysis manually (no hook needed); refreshes harness-state.json
285
- claude-token-saver harness promote <N> --project|--global # warning #N โ†’ ratchet rule (scope required)
286
- claude-token-saver harness promote "<rule text>" --project|--global # register your own hand-written rules the same way
287
- claude-token-saver harness pull # register the package's curated ratchet rules into your global ratchet (opt-in, dedupes)
288
- claude-token-saver harness list / rm <N> # view / delete rules (auto .bak)
289
- claude-token-saver harness off | on # toggle the ๐Ÿ…ท chip
283
+ sprag harness init # this project
284
+ sprag harness init --global # ~/.claude/CLAUDE.md โ€” every project
285
+ sprag harness check # current score (global fallback honored)
286
+ sprag harness analyze # run the transcript analysis manually (no hook needed); refreshes harness-state.json
287
+ sprag harness promote <N> --project|--global # warning #N โ†’ ratchet rule (scope required)
288
+ sprag harness promote "<rule text>" --project|--global # register your own hand-written rules the same way
289
+ sprag harness pull # register the package's curated ratchet rules into your global ratchet (opt-in, dedupes)
290
+ sprag harness list / rm <N> # view / delete rules (auto .bak)
291
+ sprag harness off | on # toggle the ๐Ÿ…ท chip
290
292
  ```
291
293
 
292
294
  - `promote` **requires** `--project`/`--global` in non-TTY contexts (scripts, LLM calls) โ€” a scope choice is never silently made for the caller.
@@ -316,11 +318,11 @@ Claude Code compacts when usage approaches `min(autoCompactWindow, model max con
316
318
  **200k sessions are never warned** โ€” their window is already at or below 200k, so the setting cannot change anything.
317
319
 
318
320
  ```bash
319
- claude-token-saver compact-window # status (model, window, value, source)
320
- claude-token-saver compact-window set --global # pin 500k (mid-band) in ~/.claude/settings.json
321
- claude-token-saver compact-window set --project # pin it in <root>/.claude/settings.json
322
- claude-token-saver compact-window set --global --value 600k # explicit value (100kโ€“1M)
323
- claude-token-saver compact-window off | on # toggle the warning
321
+ sprag compact-window # status (model, window, value, source)
322
+ sprag compact-window set --global # pin 500k (mid-band) in ~/.claude/settings.json
323
+ sprag compact-window set --project # pin it in <root>/.claude/settings.json
324
+ sprag compact-window set --global --value 600k # explicit value (100kโ€“1M)
325
+ sprag compact-window off | on # toggle the warning
324
326
  ```
325
327
 
326
328
  - On a 1M model with the value unset or above 700k, the statusline shows `๐Ÿ…ทโš  compact-window?` and the session briefing hands the model the exact registration command.
@@ -342,11 +344,11 @@ Three design pillars:
342
344
  3. Promoted rules live in a tool-owned file (`.claude/ratchet-model.md`) that **refreshes itself every scan**, and a `โš  rule-health` flag fires when a delegated category's error rate climbs โ€” rules report their own staleness
343
345
 
344
346
  ```bash
345
- claude-token-saver route-scan # scan (24h cache) + tiered candidates
346
- claude-token-saver harness promote R1 --project # promote candidate R1 to a model-fitting rule
347
- claude-token-saver route-scan dismiss 1 # not interested โ€” won't resurface
348
- claude-token-saver route-scan rules # list model-fitting rules (rm <N> to remove)
349
- claude-token-saver route-scan savings # the savings ledger โ€” which rule moved work off which model, onto which
347
+ sprag route-scan # scan (24h cache) + tiered candidates
348
+ sprag harness promote R1 --project # promote candidate R1 to a model-fitting rule
349
+ sprag route-scan dismiss 1 # not interested โ€” won't resurface
350
+ sprag route-scan rules # list model-fitting rules (rm <N> to remove)
351
+ sprag route-scan savings # the savings ledger โ€” which rule moved work off which model, onto which
350
352
  ```
351
353
 
352
354
  Dig deeper: **tier criteria & research evidence** โ†’ [docs/TIER_CRITERIA.md](./docs/TIER_CRITERIA.md) (Korean) ยท **rule-file mechanics, scan triggers, subagent setup** โ†’ [docs/ROUTE_SCAN.md](./docs/ROUTE_SCAN.md) (Korean + English)
@@ -387,11 +389,11 @@ The model-fitting ratchet (`ratchet-model.md`) **starts empty.** A rule exists o
387
389
  **How they get registered:** in the first session after an install or upgrade, the SessionStart hook hands the pending presets to the model, which walks the user through them **one at a time**. Each answer runs one of these immediately:
388
390
 
389
391
  ```bash
390
- claude-token-saver seed # pending presets + recorded answers
391
- claude-token-saver seed accept <id> --global|--project # register one (scope required)
392
- claude-token-saver seed accept all --global # when the user says "register them all"
393
- claude-token-saver seed skip <id> # decline โ€” never offered again
394
- claude-token-saver seed reset # clear the answers and offer everything again
392
+ sprag seed # pending presets + recorded answers
393
+ sprag seed accept <id> --global|--project # register one (scope required)
394
+ sprag seed accept all --global # when the user says "register them all"
395
+ sprag seed skip <id> # decline โ€” never offered again
396
+ sprag seed reset # clear the answers and offer everything again
395
397
  ```
396
398
 
397
399
  - **Nothing is written without a yes to that specific rule.** A declined rule stays declined across upgrades; a later release only surfaces the presets it actually added.
@@ -404,10 +406,10 @@ claude-token-saver seed reset # clear the answers a
404
406
  Injects guidance that corrects how Claude writes Korean (dropped sentence parts, noun-stopped sentences, translationese, em-dash overuse) **once per session.**
405
407
 
406
408
  ```bash
407
- claude-token-saver korean on # on, for every project
408
- claude-token-saver korean status # state, cost, provenance
409
- claude-token-saver korean show # print the guidance itself
410
- claude-token-saver korean off # off
409
+ sprag korean on # on, for every project
410
+ sprag korean status # state, cost, provenance
411
+ sprag korean show # print the guidance itself
412
+ sprag korean off # off
411
413
  ```
412
414
 
413
415
  Claude Code's output styles can do the same thing, but an output style is **a single global slot**: turning it on takes that slot away from anything else and has to be configured per machine. This ships the guidance inside the package and delivers it through the SessionStart hook that is already installed, so it **applies wherever the CLI is installed and leaves the output-style slot free.** It survives `/clear`, because the hook fires again.
@@ -442,7 +444,7 @@ It adds three layers:
442
444
  - **AI-writing tics**: automatic intensifiers ("๋‹ค์–‘ํ•œ", "ํ•ต์‹ฌ์ ์ธ"), signpost sentences, rhetorical question-then-answer, unconditionally upbeat endings.
443
445
  - **Cohesion** โ€” how sentences connect, which no regex can check. The research finding that shapes this section: surface connectives (conjunctions, demonstratives) correlate *negatively or not at all* with judged text quality, while elaboration โ€” the next sentence picking up and unpacking what the previous one introduced โ€” is the only connection type with a positive correlation. So the guidance says: when a transition feels rough, fix the information order (given before new), don't add a connective.
444
446
 
445
- **Most of the cohesion layer is not Korean-specific.** Given-before-new ordering (the "given-new contract"), one clear referent per pronoun, keeping one subject per paragraph, bridging sentences instead of leaping, and merging choppy repetitive sentences into a modifier-plus-core structure apply to English prose the same way โ€” the studies happen to be about Korean learners, but the principles they validate are the standard cohesion model from text linguistics. If you write English deliverables with Claude, run `claude-token-saver cohesion on` โ€” it injects exactly those five rules as a standalone English block (~0.5k tokens per session), no Korean feature required. While `korean on` is active the block is suppressed, because the Korean supplement already carries the same rules.
447
+ **Most of the cohesion layer is not Korean-specific.** Given-before-new ordering (the "given-new contract"), one clear referent per pronoun, keeping one subject per paragraph, bridging sentences instead of leaping, and merging choppy repetitive sentences into a modifier-plus-core structure apply to English prose the same way โ€” the studies happen to be about Korean learners, but the principles they validate are the standard cohesion model from text linguistics. If you write English deliverables with Claude, run `sprag cohesion on` โ€” it injects exactly those five rules as a standalone English block (~0.5k tokens per session), no Korean feature required. While `korean on` is active the block is suppressed, because the Korean supplement already carries the same rules.
446
448
 
447
449
  A final subsection lists what must **not** be "corrected": settled domain terms, formal register, and verbatim quotations โ€” every lint finding is a request to confirm, not a verdict.
448
450
 
@@ -453,14 +455,14 @@ Injecting the guidance once at session start turned out to be half the job. The
453
455
  From v3.24.0 `korean on` also installs a PostToolUse hook. It opens the file the model just wrote, runs the clauses a machine can decide, and hands any findings back. The file is already saved, so nothing is lost โ€” the model fixes it on the spot.
454
456
 
455
457
  ```bash
456
- claude-token-saver korean lint block # default: findings are handed back as blocking feedback
457
- claude-token-saver korean lint warn # print findings, do not block
458
- claude-token-saver korean lint off # disable the check
458
+ sprag korean lint block # default: findings are handed back as blocking feedback
459
+ sprag korean lint warn # print findings, do not block
460
+ sprag korean lint off # disable the check
459
461
 
460
- claude-token-saver korean lint scope all # default: every text file the session writes
461
- claude-token-saver korean lint scope prose # documents only
462
+ sprag korean lint scope all # default: every text file the session writes
463
+ sprag korean lint scope prose # documents only
462
464
 
463
- claude-token-saver korean lint docs/*.md # check files already on disk
465
+ sprag korean lint docs/*.md # check files already on disk
464
466
  ```
465
467
 
466
468
  Checked: 15 figurative phrases, translationese markers, separators (`โ€”`ยท`ใ…ก`ยท`|`), three or more `์˜` particles in one phrase, and a period after a nominal ending. Clauses that need judgement stay with the guidance text.
@@ -475,7 +477,7 @@ Alongside the writing guidance, one more line is injected: **non-ASCII strings i
475
477
 
476
478
  When the model puts Korean into a Write or Edit parameter as escapes, those escapes are sometimes not decoded into code points at all: the literal text `ํ•œ` lands in the file. The artifact carries mojibake, and the model keeps editing on top of it without noticing that what it wrote and what the file holds have diverged. Not writing escapes in the first place removes the path entirely, so the rule blocks the input instead of repairing the output.
477
479
 
478
- This line lives in claude-token-saver's own framing paragraph, not in the vendored fluent-korean text. It governs encoding rather than style, and the vendored wording is kept unmodified. For the same reason it carries no exceptions, unlike the style rules that skip code and commit messages. It adds roughly 60 tokens per session.
480
+ This line lives in sprag's own framing paragraph, not in the vendored fluent-korean text. It governs encoding rather than style, and the vendored wording is kept unmodified. For the same reason it carries no exceptions, unlike the style rules that skip code and commit messages. It adds roughly 60 tokens per session.
479
481
 
480
482
  > **Evidence**
481
483
  > The same failure is reported against Claude Code: [#12417, unicode handling regression](https://github.com/anthropics/claude-code/issues/12417) and [#26141, Edit silently corrupting unicode](https://github.com/anthropics/claude-code/issues/26141).
@@ -507,10 +509,10 @@ Three situations, three different interception points:
507
509
  That second row is measured, not assumed: a `.pdf` Read fires the hook, and a `.pptx` Read in the same session leaves no hook log entry at all.
508
510
 
509
511
  ```bash
510
- claude-token-saver doc2md on # register the hooks (the converter installs itself)
511
- claude-token-saver doc2md # check converter + hook registration
512
- claude-token-saver doc2md report.pptx # convert by hand and see the result
513
- claude-token-saver doc2md install-converter # only to get the install out of the way early
512
+ sprag doc2md on # register the hooks (the converter installs itself)
513
+ sprag doc2md # check converter + hook registration
514
+ sprag doc2md report.pptx # convert by hand and see the result
515
+ sprag doc2md install-converter # only to get the install out of the way early
514
516
  ```
515
517
 
516
518
  **The converter installs itself.** Any rollout step a person has to be told about is a step some of them skip, so the converter installs in the background the moment a document first shows up, and converts as soon as it is ready. Measured: about 30s for the first document (15s install plus markitdown's first import), then 3.7s for a new document and 0.1s on a cache hit. The `.fig` parser installs in half a second on the first Figma file.
@@ -623,7 +625,7 @@ The model is told to ask for an unlocked copy. This tool never asks for or store
623
625
  - The `.fig` parser installs through `npm.cmd` via the shell, and the package spec dropped its caret (`openfig-core@0.4.x`): in cmd.exe `^` is the escape character and never reaches npm.
624
626
  - The background install and every child process set `windowsHide`, so no console window appears in the middle of someone's prompt.
625
627
 
626
- `claude-token-saver doc2md --clean` empties the conversion cache; `doc2md off` removes the hook. Removal filters for this tool's own entry, so anything else you registered under `PreToolUse` stays.
628
+ `sprag doc2md --clean` empties the conversion cache; `doc2md off` removes the hook. Removal filters for this tool's own entry, so anything else you registered under `PreToolUse` stays.
627
629
 
628
630
  ## ๐ŸŒ Behind a gateway (Bedrock / Vertex)
629
631
 
@@ -638,7 +640,7 @@ Since v3.26.0 the gateway is detected from the model ids in the transcript, whic
638
640
  - Delegated runs dropped for an unpriceable model id show as `๐Ÿ”€ N unresolved` instead of nothing, which used to be indistinguishable from never having delegated.
639
641
  - Environment variables set to a `foundation-model` ARN now resolve. An opaque `application-inference-profile` id still does not: guessing at it is how wrong prices enter the ledger.
640
642
 
641
- If the detection is wrong, pin it with `claude-token-saver mode ttl=5m` (or `ttl=1h`). An explicit value outranks the measurement.
643
+ If the detection is wrong, pin it with `sprag mode ttl=5m` (or `ttl=1h`). An explicit value outranks the measurement.
642
644
 
643
645
  ### LiteLLM: your key budget stands in for the missing 5h/7d caps (v3.35.0)
644
646
 
@@ -648,7 +650,7 @@ Behind a LiteLLM proxy (Bedrock and friends), Claude Code's stdin never carries
648
650
  - The proxy is asked via `GET /key/info` and `GET /user/info` โ€” only the calling key's own data. Renders read a cache file; a detached background process refreshes it every 5 minutes (same shape as the update check), so the statusline never waits on the network.
649
651
  - Budget source priority follows real-world usage: the **team-membership budget** (`team_memberships[].spend` + its linked budget table row) first, then the key's own `max_budget`, then the internal-user budget. Verified against a Dockerized LiteLLM, including memberships whose budget diverges from the team max into a separate budget-table row.
650
652
  - Unlimited keys (no `max_budget`) get no gauge. The `๐Ÿ’ต` monthly-spend segment still shows, since it comes from session logs.
651
- - Inspect with `claude-token-saver litellm-budget` (cached) or `litellm-budget --refresh` (query now).
653
+ - Inspect with `sprag litellm-budget` (cached) or `litellm-budget --refresh` (query now).
652
654
 
653
655
  One related non-bug: if your session model is already sonnet, a sonnet-delegation (T1) rule can never save anything, because there is no price gap to capture. That is correct, but `route-scan rules` displayed it identically to "no delegations yet", so it now says outright that the rule does not apply at the current default model.
654
656
 
@@ -667,7 +669,7 @@ Remediation commands are OS-aware (`~/.zshrc` for macOS/Linux/WSL, `setx` for Wi
667
669
 
668
670
  ## Real-world impact โ€” before/after report
669
671
 
670
- ![claude-token-saver โ€” harness + ratchet adoption impact](./docs/harness-impact.png)
672
+ ![sprag โ€” harness + ratchet adoption impact](./docs/harness-impact.png)
671
673
 
672
674
  harness 5/5 + ratchet applied to the author's own Claude Code work, normalized **per user message** (cutoff 2026-05-02, Opus 4.7 pricing):
673
675
 
@@ -684,7 +686,7 @@ Same request resolved in fewer round-trips โ†’ first-try success rate up โ€” the
684
686
  <summary>Measurement notes โ€” why cache hit rate isn't included ยท sample caveats</summary>
685
687
 
686
688
  - The author is on the Max plan (1-hour cache TTL) with hit rate already converged near ~98%, so little headroom there. **Pro-plan users (5-minute TTL)** likely see hit rate itself rise with the handoff-before-expiry workflow.
687
- - Handoff-before-expiry: watch the TTL countdown, run `claude-token-saver handoff` just before expiry to dump work state into a markdown brief, start a fresh cache cycle. Same flow handles the 1M warning and cap chips.
689
+ - Handoff-before-expiry: watch the TTL countdown, run `sprag handoff` just before expiry to dump work state into a markdown brief, start a fresh cache cycle. Same flow handles the 1M warning and cap chips.
688
690
  - โš ๏ธ POST window is only 2 days (157 msgs); statistical confidence is low, and week-to-week topic mix differs, so the tool effect isn't cleanly isolated.
689
691
  </details>
690
692
 
@@ -721,13 +723,13 @@ Node.js โ‰ฅ 18 ยท macOS / Linux / Windows / WSL ยท **zero dependencies**.
721
723
 
722
724
  **IntelliJ Claude Code plugin** โ€” the statusline widget fuses frames at the character level when emoji are present (`59:548` artifacts). v2.8.5+ detects `TERMINAL_EMULATOR=JetBrains-JediTerm` and falls back to text mode automatically.
723
725
 
724
- **If the countdown looks frozen:** ticking while idle requires Claude Code to re-run the statusline command on a timer, controlled by `statusLine.refreshInterval` (seconds, Claude Code v2.1.97+) in `~/.claude/settings.json`. Without it the line only redraws when the conversation updates. If behavior differs per terminal, check three things: โ‘  that machine's Claude Code is โ‰ฅ 2.1.97; โ‘ก no project `.claude/settings.json` / `settings.local.json` overrides `statusLine` without a refreshInterval; โ‘ข the statusline wrapper actually finds `claude-token-saver` on PATH instead of falling back to a multi-second `npx` run on every render (typical when nvm is not loaded in non-login shells). Re-running `claude-token-saver install` restores refreshInterval=5.
726
+ **If the countdown looks frozen:** ticking while idle requires Claude Code to re-run the statusline command on a timer, controlled by `statusLine.refreshInterval` (seconds, Claude Code v2.1.97+) in `~/.claude/settings.json`. Without it the line only redraws when the conversation updates. If behavior differs per terminal, check three things: โ‘  that machine's Claude Code is โ‰ฅ 2.1.97; โ‘ก no project `.claude/settings.json` / `settings.local.json` overrides `statusLine` without a refreshInterval; โ‘ข the statusline wrapper actually finds `sprag` on PATH instead of falling back to a multi-second `npx` run on every render (typical when nvm is not loaded in non-login shells). Re-running `sprag install` restores refreshInterval=5.
725
727
 
726
728
  **Migration from claude-cache-monitor:**
727
729
  ```bash
728
- npm uninstall -g claude-cache-monitor && npm i -g claude-token-saver
730
+ npm uninstall -g claude-cache-monitor && npm i -g sprag-cli
729
731
  ```
730
- Also update `statusLine.command` in `~/.claude/settings.json` to `claude-token-saver โ€ฆ`.
732
+ Also update `statusLine.command` in `~/.claude/settings.json` to `sprag โ€ฆ`.
731
733
 
732
734
  **Background:** [GitHub Issue #46829](https://github.com/anthropics/claude-code/issues/46829) (cache TTL regression) ยท [HN discussion](https://news.ycombinator.com/item?id=47736476)
733
735
  </details>
@@ -749,12 +751,12 @@ Found a bug, or want a feature? Open an issue: https://github.com/rootstudioyaml
749
751
  No browser or GitHub login handy (corporate network, mid-session)? Submit straight from the terminal โ€” or ask Claude to do it for you:
750
752
 
751
753
  ```bash
752
- claude-token-saver feedback "the 5m TTL chip never clears on Bedrock"
754
+ sprag feedback "the 5m TTL chip never clears on Bedrock"
753
755
  ```
754
756
 
755
757
  It files a GitHub issue via the `gh` CLI when one is authenticated; otherwise it submits anonymously (no login, works where github.com is blocked). Pass `--anonymous` to skip the `gh` path. Version and OS metadata are attached automatically.
756
758
 
757
- When reporting a bug, please include the tool version (`claude-token-saver --version`), your OS, and โ€” if it is a statusline or warning issue โ€” the statusline output or the `claude-token-saver last` result.
759
+ When reporting a bug, please include the tool version (`sprag --version`), your OS, and โ€” if it is a statusline or warning issue โ€” the statusline output or the `sprag last` result.
758
760
 
759
761
  ## License
760
762
 
package/bin/cli.js CHANGED
@@ -1,27 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * claude-token-saver CLI (formerly claude-cache-monitor)
4
+ * sprag CLI (formerly claude-token-saver / claude-cache-monitor)
5
5
  *
6
6
  * Usage:
7
- * npx claude-token-saver # default report (last 30 days)
8
- * npx claude-token-saver --days 7 # last 7 days
9
- * npx claude-token-saver --format json # JSON output
10
- * npx claude-token-saver --format csv # CSV output
11
- * npx claude-token-saver --project myproj # filter by project
7
+ * npx sprag # default report (last 30 days)
8
+ * npx sprag --days 7 # last 7 days
9
+ * npx sprag --format json # JSON output
10
+ * npx sprag --format csv # CSV output
11
+ * npx sprag --project myproj # filter by project
12
12
  * npx sprag route-scan # detect recurring easy work โ†’ haiku-delegation candidates
13
13
  * npx sprag install # set up skill/hooks/statusline; asks about harness + Korean guidance
14
14
  * npx sprag install --yes # take the defaults without asking (same as --no-input)
15
- * npx claude-token-saver --install-hook # install PostToolUse hook
16
- * npx claude-token-saver --uninstall-hook # remove hook
15
+ * npx sprag --install-hook # install PostToolUse hook
16
+ * npx sprag --uninstall-hook # remove hook
17
17
  * npx claude-token-saver --hook-run # internal: called by hook
18
- * npx claude-token-saver --statusline # one-line output for Claude Code statusline API
19
- * npx claude-token-saver --statusline --verbose # longer labels
20
- * npx claude-token-saver --statusline --no-color # strip ANSI colors
21
- * npx claude-token-saver --statusline --icon # use ๐Ÿง  โณ ๐Ÿ’ฐ icons
22
- * npx claude-token-saver --statusline --no-timer # hide the TTL countdown
23
- * npx claude-token-saver --statusline --single-line # legacy 1-line layout (no routing-totals headline)
24
- * npx claude-token-saver --statusline --exclude-session <path>
18
+ * npx sprag --statusline # one-line output for Claude Code statusline API
19
+ * npx sprag --statusline --verbose # longer labels
20
+ * npx sprag --statusline --no-color # strip ANSI colors
21
+ * npx sprag --statusline --icon # use ๐Ÿง  โณ ๐Ÿ’ฐ icons
22
+ * npx sprag --statusline --no-timer # hide the TTL countdown
23
+ * npx sprag --statusline --single-line # legacy 1-line layout (no routing-totals headline)
24
+ * npx sprag --statusline --exclude-session <path>
25
25
  * # exclude a JSONL path from lastActivity
26
26
  * # (or set CACHE_MONITOR_EXCLUDE_SESSION env var)
27
27
  */
@@ -90,32 +90,32 @@ const KNOWN_SUBCOMMANDS = new Set([
90
90
  'seed', 'litellm-budget', 'feedback',
91
91
  ]);
92
92
 
93
- const USAGE = `claude-token-saver โ€” Claude Code token usage, cache health, and model routing
93
+ const USAGE = `sprag โ€” Claude Code token usage, cache health, and model routing
94
94
 
95
95
  Usage:
96
- claude-token-saver default report (last 30 days)
97
- claude-token-saver --days 7 last 7 days
98
- claude-token-saver --format json JSON output
99
- claude-token-saver --format csv CSV output
100
- claude-token-saver --project myproj filter by project
96
+ sprag default report (last 30 days)
97
+ sprag --days 7 last 7 days
98
+ sprag --format json JSON output
99
+ sprag --format csv CSV output
100
+ sprag --project myproj filter by project
101
101
  sprag route-scan detect recurring easy work โ†’ delegation candidates
102
102
  sprag install set up skill/hooks/statusline
103
103
  sprag install --yes take the defaults without asking
104
- claude-token-saver uninstall remove everything install added
104
+ sprag uninstall remove everything install added
105
105
  sprag harness check score the harness setup in CLAUDE.md
106
106
  sprag harness analyze run the harness transcript analysis manually
107
- claude-token-saver last most recent warning + how to handle it
108
- claude-token-saver history recent warning transitions
109
- claude-token-saver handoff write a session handoff file
107
+ sprag last most recent warning + how to handle it
108
+ sprag history recent warning transitions
109
+ sprag handoff write a session handoff file
110
110
  sprag feedback "<msg>" file a bug report / feature request (no browser needed)
111
- claude-token-saver upgrade install the latest release
112
- claude-token-saver --install-hook install cache-monitor PostToolUse hook
113
- claude-token-saver --uninstall-hook remove that hook
114
- claude-token-saver --statusline one-line output for Claude Code statusline
111
+ sprag upgrade install the latest release
112
+ sprag --install-hook install cache-monitor PostToolUse hook
113
+ sprag --uninstall-hook remove that hook
114
+ sprag --statusline one-line output for Claude Code statusline
115
115
  --verbose / --no-color / --icon / --no-timer / --single-line
116
116
 
117
117
  Run any subcommand with --help for its own options where available.
118
- Bug reports & feature requests: https://github.com/rootstudioyaml/claude-token-saver/issues
118
+ Bug reports & feature requests: https://github.com/rootstudioyaml/sprag/issues
119
119
  `;
120
120
 
121
121
  async function main() {
@@ -140,8 +140,8 @@ async function main() {
140
140
  // Designed for the auto-trigger skill so the user immediately sees
141
141
  // "what just fired and how to fix it" without having to read the whole
142
142
  // history file.
143
- // claude-token-saver last # search last 1 day
144
- // claude-token-saver last --days 7 # widen the lookback
143
+ // sprag last # search last 1 day
144
+ // sprag last --days 7 # widen the lookback
145
145
  if (args[0] === 'last') {
146
146
  return (await import('../src/commands/last.js')).run({ numArg });
147
147
  }
@@ -149,9 +149,9 @@ async function main() {
149
149
  // Subcommand: history โ€” print recent warning transitions captured by the
150
150
  // statusline. One markdown file per day, persisted under the platform-
151
151
  // specific user-data dir.
152
- // claude-token-saver history # last 7 days
153
- // claude-token-saver history --days 30 # custom window
154
- // claude-token-saver history --list # just list available dates
152
+ // sprag history # last 7 days
153
+ // sprag history --days 30 # custom window
154
+ // sprag history --list # just list available dates
155
155
  if (args[0] === 'history') {
156
156
  return (await import('../src/commands/history.js')).run({ hasFlag, numArg });
157
157
  }
@@ -161,8 +161,8 @@ async function main() {
161
161
  // session can pick up where this one stopped. Pairs with the cap-warn chip:
162
162
  // when statusline shows ๐Ÿšจ 5H 90%+, run this to back up state before the cap
163
163
  // hits.
164
- // claude-token-saver handoff # write to cwd
165
- // claude-token-saver handoff --cwd PATH # custom directory
164
+ // sprag handoff # write to cwd
165
+ // sprag handoff --cwd PATH # custom directory
166
166
  // Subcommand: feedback โ€” file a bug report / feature request without a
167
167
  // browser. Tries gh CLI, then an anonymous form POST, then a local save
168
168
  // with a prefilled GitHub issue URL. See src/commands/feedback.js.
@@ -194,9 +194,9 @@ async function main() {
194
194
 
195
195
  // Subcommand: mode โ€” persist statusline preferences so future runs pick
196
196
  // them up without flags or wrapper edits.
197
- // claude-token-saver mode # show current config
198
- // claude-token-saver mode icon verbose # set icon + verbose
199
- // claude-token-saver mode reset # clear back to defaults
197
+ // sprag mode # show current config
198
+ // sprag mode icon verbose # set icon + verbose
199
+ // sprag mode reset # clear back to defaults
200
200
  if (args[0] === 'mode') {
201
201
  return (await import('../src/commands/mode.js')).run({ args });
202
202
  }
@@ -244,7 +244,7 @@ async function main() {
244
244
 
245
245
  // Subcommand: seed โ€” register the bundled starter rules (model-fitting
246
246
  // presets + curated ratchet rules), one answer at a time.
247
- // claude-token-saver seed | seed accept <id> --global|--project | seed skip <id>
247
+ // sprag seed | seed accept <id> --global|--project | seed skip <id>
248
248
  if (args[0] === 'seed') {
249
249
  return (await import('../src/commands/seed.js')).run({ args, hasFlag });
250
250
  }
@@ -263,10 +263,10 @@ async function main() {
263
263
  // Subcommand: compact-window โ€” audit / pin Claude Code's autoCompactWindow.
264
264
  // On a 1M-context model, compaction only fires near 800k unless the window is
265
265
  // capped; 200k sessions are exempt.
266
- // claude-token-saver compact-window # status
267
- // claude-token-saver compact-window set --global # pin 200k (~/.claude/settings.json)
268
- // claude-token-saver compact-window set --project # pin 200k (<root>/.claude/settings.json)
269
- // claude-token-saver compact-window off | on # toggle the statusline warning
266
+ // sprag compact-window # status
267
+ // sprag compact-window set --global # pin 200k (~/.claude/settings.json)
268
+ // sprag compact-window set --project # pin 200k (<root>/.claude/settings.json)
269
+ // sprag compact-window off | on # toggle the statusline warning
270
270
  if (args[0] === 'compact-window') {
271
271
  return (await import('../src/commands/compact-window.js')).run({ args, hasFlag });
272
272
  }
@@ -292,8 +292,8 @@ async function main() {
292
292
  }
293
293
 
294
294
  // Subcommand: litellm-budget ยท LiteLLM ๊ฒŒ์ดํŠธ์›จ์ด ํ‚ค์˜ max_budget/spend ์กฐํšŒ.
295
- // claude-token-saver litellm-budget # ์บ์‹œ๋œ ์˜ˆ์‚ฐ ์ƒํƒœ ์ถœ๋ ฅ
296
- // claude-token-saver litellm-budget --refresh # ์ง€๊ธˆ ํ”„๋ก์‹œ์— ๋ฌผ์–ด๋ด„ (detached ์ž์‹์ด ์‚ฌ์šฉ)
295
+ // sprag litellm-budget # ์บ์‹œ๋œ ์˜ˆ์‚ฐ ์ƒํƒœ ์ถœ๋ ฅ
296
+ // sprag litellm-budget --refresh # ์ง€๊ธˆ ํ”„๋ก์‹œ์— ๋ฌผ์–ด๋ด„ (detached ์ž์‹์ด ์‚ฌ์šฉ)
297
297
  if (args[0] === 'litellm-budget') {
298
298
  const { gatewayEnv, readBudgetState, refreshBudgetState } = await import('../src/litellm-budget.js');
299
299
  const quiet = hasFlag('--quiet');
@@ -319,8 +319,8 @@ async function main() {
319
319
 
320
320
  // Subcommand: upgrade โ€” run the install command that matches how this copy
321
321
  // got here, then confirm the new version.
322
- // claude-token-saver upgrade # install the latest release
323
- // claude-token-saver upgrade --print # just show the command, run nothing
322
+ // sprag upgrade # install the latest release
323
+ // sprag upgrade --print # just show the command, run nothing
324
324
  if (args[0] === 'upgrade') {
325
325
  return (await import('../src/commands/upgrade.js')).run({
326
326
  hasFlag,
@@ -356,7 +356,7 @@ async function main() {
356
356
  // every scenario based on wall clock so a screen recorder picks them up.
357
357
  const demoArg = getArg('--demo');
358
358
 
359
- // `claude-token-saver --demo table` (no --statusline) โ€” full table view
359
+ // `sprag --demo table` (no --statusline) โ€” full table view
360
360
  // with all six issue drill-downs at once, for marketing screencasts.
361
361
  if (!isStatusline && demoArg === 'table') {
362
362
  const { buildTableDemoData } = await import('../src/demo.js');
@@ -592,7 +592,7 @@ async function main() {
592
592
  }
593
593
  }
594
594
  // Persist transitions to ~/.config/claude-token-saver/history/YYYY-MM-DD.md
595
- // so `claude-token-saver history` and the auto-skill can replay them.
595
+ // so `sprag history` and the auto-skill can replay them.
596
596
  try {
597
597
  const { recordChip, recordCapTransition } = await import('../src/history.js');
598
598
  recordChip(spikeChip, { detail: chipDetail });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-token-saver",
3
- "version": "3.42.0",
3
+ "version": "3.42.2",
4
4
  "description": "Legacy name of sprag-cli (Sprag) - same tool, kept publishing so existing installs stay current. Prefer: npm i -g sprag-cli",
5
5
  "type": "module",
6
6
  "bin": {
package/src/advice.js CHANGED
@@ -467,7 +467,7 @@ export const ISSUE_MESSAGES = {
467
467
  * and how do I fix it" without re-running the tool.
468
468
  *
469
469
  * The full multi-step advice still lives in `ISSUE_MESSAGES[code].actions()`;
470
- * `claude-token-saver last` prints that long form on demand.
470
+ * `sprag last` prints that long form on demand.
471
471
  */
472
472
  export const ISSUE_TIPS = {
473
473
  LARGE_INPUT_PER_REQUEST: {
@@ -536,8 +536,8 @@ export const CHIP_TO_CODES = {
536
536
  * because once the cap blocks you, you need a fresh session to continue.
537
537
  */
538
538
  export const CAP_TIPS = {
539
- en: 'Run `claude-token-saver handoff` to back up state before the cap blocks you',
540
- ko: '`claude-token-saver handoff` ์‹คํ–‰ํ•ด์„œ ์บก ๋„๋‹ฌ ์ „์— ์ƒํƒœ ๋ฐฑ์—…',
539
+ en: 'Run `sprag handoff` to back up state before the cap blocks you',
540
+ ko: '`sprag handoff` ์‹คํ–‰ํ•ด์„œ ์บก ๋„๋‹ฌ ์ „์— ์ƒํƒœ ๋ฐฑ์—…',
541
541
  };
542
542
 
543
543
  /**
package/src/brief.js CHANGED
@@ -246,7 +246,7 @@ export async function runBrief({ sessionId, transcriptPath, now = Date.now() })
246
246
  briefed.add(sig);
247
247
  s.briefed = [...briefed];
248
248
  const now = st.window ? `ํ˜„์žฌ ${fmtK(st.window)}` : 'ํ˜„์žฌ ๋ฏธ์„ค์ •';
249
- items.push(`1M ์ปจํ…์ŠคํŠธ ๋ชจ๋ธ(${st.model})์ธ๋ฐ autoCompactWindow๊ฐ€ ${now}์ž…๋‹ˆ๋‹ค โ€” ์ž๋™ ์••์ถ•์ด 80๋งŒ ํ† ํฐ ๊ทผ์ฒ˜์—์„œ์•ผ ๊ฑธ๋ ค ๊ทธ์ „๊นŒ์ง€ ๋ชจ๋“  ์š”์ฒญ์ด ์ „์ฒด ์ปจํ…์ŠคํŠธ๋ฅผ ์žฌ๊ณผ๊ธˆํ•ฉ๋‹ˆ๋‹ค. 1M์€ ๋„ˆ๋ฌด ํฌ๋‹ˆ ${fmtK(st.recommendedMin)}~${fmtK(st.recommendedMax)} ๋ฒ”์œ„๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค(๊ทธ ๋ฒ”์œ„ ์•ˆ์ด๋ฉด ๊ฒฝ๊ณ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค). 1M ์ฐฝ ์ž์ฒด๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ์••์ถ• ์‹œ์ ๋งŒ ์•ž๋‹น๊น๋‹ˆ๋‹ค. ๋“ฑ๋ก: claude-token-saver compact-window set --global|--project [--value ${fmtK(st.recommendedMax)}] (๊ธฐ๋ณธ ${fmtK(st.recommended)}, ์ ์šฉ ๋ฒ”์œ„๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ํ™•์ธ) / ๋„๊ธฐ: compact-window off`);
249
+ items.push(`1M ์ปจํ…์ŠคํŠธ ๋ชจ๋ธ(${st.model})์ธ๋ฐ autoCompactWindow๊ฐ€ ${now}์ž…๋‹ˆ๋‹ค โ€” ์ž๋™ ์••์ถ•์ด 80๋งŒ ํ† ํฐ ๊ทผ์ฒ˜์—์„œ์•ผ ๊ฑธ๋ ค ๊ทธ์ „๊นŒ์ง€ ๋ชจ๋“  ์š”์ฒญ์ด ์ „์ฒด ์ปจํ…์ŠคํŠธ๋ฅผ ์žฌ๊ณผ๊ธˆํ•ฉ๋‹ˆ๋‹ค. 1M์€ ๋„ˆ๋ฌด ํฌ๋‹ˆ ${fmtK(st.recommendedMin)}~${fmtK(st.recommendedMax)} ๋ฒ”์œ„๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค(๊ทธ ๋ฒ”์œ„ ์•ˆ์ด๋ฉด ๊ฒฝ๊ณ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค). 1M ์ฐฝ ์ž์ฒด๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ์••์ถ• ์‹œ์ ๋งŒ ์•ž๋‹น๊น๋‹ˆ๋‹ค. ๋“ฑ๋ก: sprag compact-window set --global|--project [--value ${fmtK(st.recommendedMax)}] (๊ธฐ๋ณธ ${fmtK(st.recommended)}, ์ ์šฉ ๋ฒ”์œ„๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ํ™•์ธ) / ๋„๊ธฐ: compact-window off`);
250
250
  }
251
251
  }
252
252
  } catch { /* settings unreadable โ€” other briefings above still apply */ }
@@ -257,7 +257,7 @@ export async function runBrief({ sessionId, transcriptPath, now = Date.now() })
257
257
 
258
258
  if (items.length === 0) return null;
259
259
  const lines = [
260
- '[claude-token-saver ๋ธŒ๋ฆฌํ•‘] ์•„๋ž˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ ค์ฃผ์„ธ์š”. ์ง„ํ–‰ ์ค‘์ธ ๋‹ต๋ณ€ ํ๋ฆ„์„ ๋Š์ง€ ๋ง๊ณ , ๋‹ต๋ณ€ ๋ง๋ฏธ์— `โ€ป [sprag]` ๋ผ๋ฒจ์„ ๋‹ฌ์•„ ๊ฐ ํ•ญ๋ชฉ์„ 1~2์ค„๋กœ ์š”์•ฝํ•ด ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค (์ด ๋ธŒ๋ฆฌํ•‘์€ ํ•ญ๋ชฉ๋‹น ํ•œ ๋ฒˆ๋งŒ ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค):',
260
+ '[sprag ๋ธŒ๋ฆฌํ•‘] ์•„๋ž˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ ค์ฃผ์„ธ์š”. ์ง„ํ–‰ ์ค‘์ธ ๋‹ต๋ณ€ ํ๋ฆ„์„ ๋Š์ง€ ๋ง๊ณ , ๋‹ต๋ณ€ ๋ง๋ฏธ์— `โ€ป [sprag]` ๋ผ๋ฒจ์„ ๋‹ฌ์•„ ๊ฐ ํ•ญ๋ชฉ์„ 1~2์ค„๋กœ ์š”์•ฝํ•ด ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค (์ด ๋ธŒ๋ฆฌํ•‘์€ ํ•ญ๋ชฉ๋‹น ํ•œ ๋ฒˆ๋งŒ ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค):',
261
261
  ];
262
262
  for (const it of items) lines.push(`- ${it}`);
263
263
  return lines.join('\n');