sprag-cli 3.42.0 โ†’ 3.42.1

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
 
@@ -69,14 +69,14 @@ The two savings figures are never added together, because they answer different
69
69
 
70
70
  ```bash
71
71
  npm uninstall -g claude-cache-monitor # (previous-package users only)
72
- npm i -g claude-token-saver
72
+ npm i -g sprag-cli
73
73
  ```
74
74
 
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`.
75
+ 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
76
 
77
77
  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
78
 
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.
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 sprag-cli` to skip the harness entirely, and `sprag harness uninit --global` to undo it.
80
80
 
81
81
  > โš ๏ธ 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
82
 
@@ -86,7 +86,7 @@ Everything that costs nothing until it is needed is on after a plain install. Th
86
86
 
87
87
  | Feature | After install | How to turn it off |
88
88
  |---|---|---|
89
- | statusline (diagnostic chips, savings ledger) | on | `claude-token-saver uninstall` |
89
+ | statusline (diagnostic chips, savings ledger) | on | `sprag uninstall` |
90
90
  | `/claude-token-saver` Skill | on | same |
91
91
  | SessionStart hook (route-scan refresh) | on | same |
92
92
  | UserPromptSubmit hook (brief injection) | on | same |
@@ -117,7 +117,7 @@ Every delegated run is recorded like this:
117
117
  ```
118
118
 
119
119
  ```bash
120
- $ claude-token-saver route-scan savings # trace every dollar back to its rule
120
+ $ sprag route-scan savings # trace every dollar back to its rule
121
121
 
122
122
  ๐Ÿ”€ Routing saved, lifetime $2.09 (last 7d $1.40 ยท 30d $2.09)
123
123
 
@@ -164,10 +164,10 @@ Teams shipping routing products have turned the feature off for exactly this rea
164
164
  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
165
 
166
166
  ```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
167
+ npm i -g sprag-cli@latest
168
+ sprag route-scan # find delegation candidates in your own history (0 LLM calls)
169
+ sprag route-scan rules # list promoted rules ยท rm <N> to remove
170
+ sprag route-scan savings # audit every dollar the routing saved
171
171
  ```
172
172
 
173
173
  Thresholds come from **your own last-14-day distribution (p25/p75)**, not someone else's benchmark.
@@ -212,7 +212,7 @@ Chips โ€” `๐Ÿšจ 5H/7D NN%` (cap imminent) ยท `โš  Ctx 500k+` (a single request a
212
212
 
213
213
  ### When a chip appears
214
214
 
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.
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 `sprag handoff` to back up your work state to markdown and continue in a fresh session.
216
216
 
217
217
  ## Commands
218
218
 
@@ -220,27 +220,27 @@ Run these in your shell (inside Claude Code, the `/claude-token-saver` Skill is
220
220
 
221
221
  | Command | What it does |
222
222
  |---|---|
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 |
223
+ | `sprag` | Last-1-day diagnostic report (`--days N` / `--hours N`) |
224
+ | `sprag last` | Most recent warning + remediation |
225
+ | `sprag history` | Last 7 days of warning transitions |
226
+ | `sprag handoff` | Back work up to `HANDOFF-*.md` before a cap blocks you |
227
+ | `sprag mode [keywords...]` | Output config (`icon`/`text`, `en`/`ko`, `1h`โ€“`30d` window, โ€ฆ) |
228
+ | `sprag harness ...` | ๐Ÿ…ท Harness management (below) |
229
+ | `sprag route-scan` | Detect recurring easy work on expensive models โ†’ propose haiku-delegation ratchet rules (below) |
230
+ | `sprag route-scan savings` | The routing-savings ledger โ€” per-model-change rollup + per-run log (the evidence behind the figure) |
231
+ | `sprag compact-window` | Warn when a 1M-context session has no auto-compact cap โ†’ pin 400k with `set` (below) |
232
+ | `sprag korean on\|off\|status` | Inject Korean writing guidance at session start and install the write-time check (below) |
233
+ | `sprag cohesion on\|off\|status\|show` | Inject English cohesion guidance (sentence-connection rules) at session start |
234
+ | `sprag korean lint block\|warn\|off` | How the write-time check handles findings |
235
+ | `sprag korean lint scope all\|prose` | Check every text file, or documents only |
236
+ | `sprag doc2md on\|off` | Convert attached documents to Markdown before the model reads them (below) |
237
+ | `sprag doc2md <file>` | Convert one file by hand. Diagnostic: it prints the refusal reason instead of swallowing it |
238
+ | `sprag mode ttl=5m\|1h\|auto` | Pin the cache TTL bucket. The default `auto` trusts the measured split, then falls back to gateway detection |
239
+ | `sprag --version` | Print the installed version |
240
+ | `sprag update-check` | Is a newer version out? (`--refresh` to ask now, `--dismiss` to mute this version's offer) |
241
+ | `sprag upgrade` | Install the latest release with the package manager that installed this copy (`--print` shows the command only) |
242
+ | `sprag install` | Manually register Skill + statusline |
243
+ | `sprag uninstall [--purge]` | Remove the hooks, statusline and skill it registered. Recorded savings are kept unless `--purge` is given |
244
244
 
245
245
  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
246
 
@@ -268,8 +268,8 @@ The output language is decided once, at install time: a terminal install propose
268
268
  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
269
 
270
270
  - **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.
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 `sprag upgrade`.
272
+ - **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
273
 
274
274
  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
275
 
@@ -278,15 +278,15 @@ The registry lookup runs at most once every 24h in a detached background process
278
278
  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
279
 
280
280
  ```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
281
+ sprag harness init # this project
282
+ sprag harness init --global # ~/.claude/CLAUDE.md โ€” every project
283
+ sprag harness check # current score (global fallback honored)
284
+ sprag harness analyze # run the transcript analysis manually (no hook needed); refreshes harness-state.json
285
+ sprag harness promote <N> --project|--global # warning #N โ†’ ratchet rule (scope required)
286
+ sprag harness promote "<rule text>" --project|--global # register your own hand-written rules the same way
287
+ sprag harness pull # register the package's curated ratchet rules into your global ratchet (opt-in, dedupes)
288
+ sprag harness list / rm <N> # view / delete rules (auto .bak)
289
+ sprag harness off | on # toggle the ๐Ÿ…ท chip
290
290
  ```
291
291
 
292
292
  - `promote` **requires** `--project`/`--global` in non-TTY contexts (scripts, LLM calls) โ€” a scope choice is never silently made for the caller.
@@ -316,11 +316,11 @@ Claude Code compacts when usage approaches `min(autoCompactWindow, model max con
316
316
  **200k sessions are never warned** โ€” their window is already at or below 200k, so the setting cannot change anything.
317
317
 
318
318
  ```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
319
+ sprag compact-window # status (model, window, value, source)
320
+ sprag compact-window set --global # pin 500k (mid-band) in ~/.claude/settings.json
321
+ sprag compact-window set --project # pin it in <root>/.claude/settings.json
322
+ sprag compact-window set --global --value 600k # explicit value (100kโ€“1M)
323
+ sprag compact-window off | on # toggle the warning
324
324
  ```
325
325
 
326
326
  - 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 +342,11 @@ Three design pillars:
342
342
  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
343
 
344
344
  ```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
345
+ sprag route-scan # scan (24h cache) + tiered candidates
346
+ sprag harness promote R1 --project # promote candidate R1 to a model-fitting rule
347
+ sprag route-scan dismiss 1 # not interested โ€” won't resurface
348
+ sprag route-scan rules # list model-fitting rules (rm <N> to remove)
349
+ sprag route-scan savings # the savings ledger โ€” which rule moved work off which model, onto which
350
350
  ```
351
351
 
352
352
  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 +387,11 @@ The model-fitting ratchet (`ratchet-model.md`) **starts empty.** A rule exists o
387
387
  **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
388
 
389
389
  ```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
390
+ sprag seed # pending presets + recorded answers
391
+ sprag seed accept <id> --global|--project # register one (scope required)
392
+ sprag seed accept all --global # when the user says "register them all"
393
+ sprag seed skip <id> # decline โ€” never offered again
394
+ sprag seed reset # clear the answers and offer everything again
395
395
  ```
396
396
 
397
397
  - **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 +404,10 @@ claude-token-saver seed reset # clear the answers a
404
404
  Injects guidance that corrects how Claude writes Korean (dropped sentence parts, noun-stopped sentences, translationese, em-dash overuse) **once per session.**
405
405
 
406
406
  ```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
407
+ sprag korean on # on, for every project
408
+ sprag korean status # state, cost, provenance
409
+ sprag korean show # print the guidance itself
410
+ sprag korean off # off
411
411
  ```
412
412
 
413
413
  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 +442,7 @@ It adds three layers:
442
442
  - **AI-writing tics**: automatic intensifiers ("๋‹ค์–‘ํ•œ", "ํ•ต์‹ฌ์ ์ธ"), signpost sentences, rhetorical question-then-answer, unconditionally upbeat endings.
443
443
  - **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
444
 
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.
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 `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
446
 
447
447
  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
448
 
@@ -453,14 +453,14 @@ Injecting the guidance once at session start turned out to be half the job. The
453
453
  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
454
 
455
455
  ```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
456
+ sprag korean lint block # default: findings are handed back as blocking feedback
457
+ sprag korean lint warn # print findings, do not block
458
+ sprag korean lint off # disable the check
459
459
 
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
460
+ sprag korean lint scope all # default: every text file the session writes
461
+ sprag korean lint scope prose # documents only
462
462
 
463
- claude-token-saver korean lint docs/*.md # check files already on disk
463
+ sprag korean lint docs/*.md # check files already on disk
464
464
  ```
465
465
 
466
466
  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 +475,7 @@ Alongside the writing guidance, one more line is injected: **non-ASCII strings i
475
475
 
476
476
  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
477
 
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.
478
+ 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
479
 
480
480
  > **Evidence**
481
481
  > 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 +507,10 @@ Three situations, three different interception points:
507
507
  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
508
 
509
509
  ```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
510
+ sprag doc2md on # register the hooks (the converter installs itself)
511
+ sprag doc2md # check converter + hook registration
512
+ sprag doc2md report.pptx # convert by hand and see the result
513
+ sprag doc2md install-converter # only to get the install out of the way early
514
514
  ```
515
515
 
516
516
  **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 +623,7 @@ The model is told to ask for an unlocked copy. This tool never asks for or store
623
623
  - 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
624
  - The background install and every child process set `windowsHide`, so no console window appears in the middle of someone's prompt.
625
625
 
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.
626
+ `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
627
 
628
628
  ## ๐ŸŒ Behind a gateway (Bedrock / Vertex)
629
629
 
@@ -638,7 +638,7 @@ Since v3.26.0 the gateway is detected from the model ids in the transcript, whic
638
638
  - 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
639
  - 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
640
 
641
- If the detection is wrong, pin it with `claude-token-saver mode ttl=5m` (or `ttl=1h`). An explicit value outranks the measurement.
641
+ If the detection is wrong, pin it with `sprag mode ttl=5m` (or `ttl=1h`). An explicit value outranks the measurement.
642
642
 
643
643
  ### LiteLLM: your key budget stands in for the missing 5h/7d caps (v3.35.0)
644
644
 
@@ -648,7 +648,7 @@ Behind a LiteLLM proxy (Bedrock and friends), Claude Code's stdin never carries
648
648
  - 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
649
  - 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
650
  - 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).
651
+ - Inspect with `sprag litellm-budget` (cached) or `litellm-budget --refresh` (query now).
652
652
 
653
653
  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
654
 
@@ -667,7 +667,7 @@ Remediation commands are OS-aware (`~/.zshrc` for macOS/Linux/WSL, `setx` for Wi
667
667
 
668
668
  ## Real-world impact โ€” before/after report
669
669
 
670
- ![claude-token-saver โ€” harness + ratchet adoption impact](./docs/harness-impact.png)
670
+ ![sprag โ€” harness + ratchet adoption impact](./docs/harness-impact.png)
671
671
 
672
672
  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
673
 
@@ -684,7 +684,7 @@ Same request resolved in fewer round-trips โ†’ first-try success rate up โ€” the
684
684
  <summary>Measurement notes โ€” why cache hit rate isn't included ยท sample caveats</summary>
685
685
 
686
686
  - 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.
687
+ - 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
688
  - โš ๏ธ 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
689
  </details>
690
690
 
@@ -721,13 +721,13 @@ Node.js โ‰ฅ 18 ยท macOS / Linux / Windows / WSL ยท **zero dependencies**.
721
721
 
722
722
  **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
723
 
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.
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 `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
725
 
726
726
  **Migration from claude-cache-monitor:**
727
727
  ```bash
728
- npm uninstall -g claude-cache-monitor && npm i -g claude-token-saver
728
+ npm uninstall -g claude-cache-monitor && npm i -g sprag-cli
729
729
  ```
730
- Also update `statusLine.command` in `~/.claude/settings.json` to `claude-token-saver โ€ฆ`.
730
+ Also update `statusLine.command` in `~/.claude/settings.json` to `sprag โ€ฆ`.
731
731
 
732
732
  **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
733
  </details>
@@ -749,12 +749,12 @@ Found a bug, or want a feature? Open an issue: https://github.com/rootstudioyaml
749
749
  No browser or GitHub login handy (corporate network, mid-session)? Submit straight from the terminal โ€” or ask Claude to do it for you:
750
750
 
751
751
  ```bash
752
- claude-token-saver feedback "the 5m TTL chip never clears on Bedrock"
752
+ sprag feedback "the 5m TTL chip never clears on Bedrock"
753
753
  ```
754
754
 
755
755
  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
756
 
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.
757
+ 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
758
 
759
759
  ## License
760
760
 
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": "sprag-cli",
3
- "version": "3.42.0",
3
+ "version": "3.42.1",
4
4
  "description": "Sprag - a quality ratchet harness for AI coding agents: model-fitting delegation, ratchet rules, doc2md, Korean style gate. Same tool as claude-token-saver, under its new name.",
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');