sprag-cli 3.41.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/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
12
- * npx claude-token-saver route-scan # detect recurring easy work → haiku-delegation candidates
13
- * npx claude-token-saver install # set up skill/hooks/statusline; asks about harness + Korean guidance
14
- * npx claude-token-saver 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
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
+ * npx sprag route-scan # detect recurring easy work → haiku-delegation candidates
13
+ * npx sprag install # set up skill/hooks/statusline; asks about harness + Korean guidance
14
+ * npx sprag install --yes # take the defaults without asking (same as --no-input)
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
101
- claude-token-saver route-scan detect recurring easy work → delegation candidates
102
- claude-token-saver install set up skill/hooks/statusline
103
- claude-token-saver install --yes take the defaults without asking
104
- claude-token-saver uninstall remove everything install added
105
- claude-token-saver harness check score the harness setup in CLAUDE.md
106
- claude-token-saver 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
110
- claude-token-saver 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
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
+ sprag route-scan detect recurring easy work → delegation candidates
102
+ sprag install set up skill/hooks/statusline
103
+ sprag install --yes take the defaults without asking
104
+ sprag uninstall remove everything install added
105
+ sprag harness check score the harness setup in CLAUDE.md
106
+ sprag harness analyze run the harness transcript analysis manually
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
+ sprag feedback "<msg>" file a bug report / feature request (no browser needed)
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.
@@ -179,8 +179,8 @@ async function main() {
179
179
  // user can just mention chip wording and Claude responds. v2.6.0 dropped
180
180
  // the redundant /token-monitor slash command in favor of the skill alone;
181
181
  // a legacy command file is removed automatically. Cross-platform.
182
- // claude-token-saver install # install/update the skill
183
- // claude-token-saver install --force # overwrite existing skill file
182
+ // sprag install # install/update the skill
183
+ // sprag install --force # overwrite existing skill file
184
184
  if (args[0] === 'install') {
185
185
  return (await import('../src/commands/install.js')).run({ hasFlag });
186
186
  }
@@ -194,22 +194,22 @@ 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
  }
203
203
 
204
204
  // Subcommand: route-scan — detect recurring easy work on expensive models
205
205
  // and propose model-delegation ratchet rules. Zero token cost, fully local.
206
- // claude-token-saver route-scan # scan (24h cache) + print candidates
207
- // claude-token-saver route-scan --refresh # force rescan
208
- // claude-token-saver route-scan --days 30 # wider lookback
209
- // claude-token-saver route-scan --hook # SessionStart hook mode (context injection)
210
- // claude-token-saver route-scan dismiss <N> # mute candidate R<N>
206
+ // sprag route-scan # scan (24h cache) + print candidates
207
+ // sprag route-scan --refresh # force rescan
208
+ // sprag route-scan --days 30 # wider lookback
209
+ // sprag route-scan --hook # SessionStart hook mode (context injection)
210
+ // sprag route-scan dismiss <N> # mute candidate R<N>
211
211
  // Promote a candidate to a ratchet rule (scope is always explicit):
212
- // claude-token-saver harness promote R<N> --project|--global
212
+ // sprag harness promote R<N> --project|--global
213
213
  // brief --hook — UserPromptSubmit hook mode: per-session, change-triggered
214
214
  // briefing of state the statusline can only chip (ctx tier crossings,
215
215
  // mid-session route/rule-health changes). Silent when nothing changed.
@@ -223,39 +223,39 @@ async function main() {
223
223
 
224
224
  // Subcommand: korean — Korean writing guidance injected at session start,
225
225
  // so the rules apply in every project without an output-style switch.
226
- // claude-token-saver korean on | off | status | show
226
+ // sprag korean on | off | status | show
227
227
  if (args[0] === 'korean') {
228
228
  return (await import('../src/commands/korean.js')).run({ args, hasFlag });
229
229
  }
230
230
 
231
231
  // Subcommand: cohesion — English sentence-connection guidance injected at
232
232
  // session start; the language-neutral half of the Korean supplement.
233
- // claude-token-saver cohesion on | off | status | show
233
+ // sprag cohesion on | off | status | show
234
234
  if (args[0] === 'cohesion') {
235
235
  return (await import('../src/commands/cohesion.js')).run({ args, hasFlag });
236
236
  }
237
237
 
238
238
  // Subcommand: doc2md — convert pptx/xlsx/pdf/docx to Markdown before the
239
239
  // model reads them, so an unreadable binary never enters the context window.
240
- // claude-token-saver doc2md on | off | <file> | --clean
240
+ // sprag doc2md on | off | <file> | --clean
241
241
  if (args[0] === 'doc2md') {
242
242
  return (await import('../src/commands/doc2md.js')).run({ args, hasFlag });
243
243
  }
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
  }
251
251
 
252
252
  // Subcommand: harness — manage the project's CLAUDE.md harness rules.
253
- // claude-token-saver harness init # write CLAUDE.md (5 sections) + ratchet.md
254
- // claude-token-saver harness uninit # remove harness block from CLAUDE.md (backup kept)
255
- // claude-token-saver harness check # show 🅷 N/5 + which sections are missing
256
- // claude-token-saver harness promote "<rule>" # append a rule to ratchet.md
257
- // claude-token-saver harness pull [--global|--project] # register the package's curated preset rules (default global)
258
- // claude-token-saver harness off | on # toggle the statusline 🅷 segment
253
+ // sprag harness init # write CLAUDE.md (5 sections) + ratchet.md
254
+ // sprag harness uninit # remove harness block from CLAUDE.md (backup kept)
255
+ // sprag harness check # show 🅷 N/5 + which sections are missing
256
+ // sprag harness promote "<rule>" # append a rule to ratchet.md
257
+ // sprag harness pull [--global|--project] # register the package's curated preset rules (default global)
258
+ // sprag harness off | on # toggle the statusline 🅷 segment
259
259
  if (args[0] === 'harness') {
260
260
  return (await import('../src/commands/harness.js')).run({ args, hasFlag });
261
261
  }
@@ -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
  }
@@ -281,9 +281,9 @@ async function main() {
281
281
 
282
282
  // Subcommand: update-check — the registry lookup behind the ⬆ statusline
283
283
  // chip and the session-start upgrade offer.
284
- // claude-token-saver update-check # print cached status
285
- // claude-token-saver update-check --refresh # hit the registry now (detached child uses this)
286
- // claude-token-saver update-check --dismiss # stop offering THIS version at session start
284
+ // sprag update-check # print cached status
285
+ // sprag update-check --refresh # hit the registry now (detached child uses this)
286
+ // sprag update-check --dismiss # stop offering THIS version at session start
287
287
  if (args[0] === 'update-check') {
288
288
  return (await import('../src/commands/update-check.js')).run({
289
289
  hasFlag,
@@ -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.41.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
@@ -226,8 +226,8 @@ export async function runBrief({ sessionId, transcriptPath, now = Date.now() })
226
226
  }
227
227
  for (const [kind, x] of fresh) {
228
228
  items.push(kind === 'route'
229
- ? `새 위임 후보가 감지되었습니다 — "${x.label}" 유형 ${x.count}회 반복(statusline의 route? R${x.id} 칩). 등록: claude-token-saver harness promote R${x.id} --project|--global (적용 범위는 사용자에게 확인) / 무시: route-scan dismiss ${x.id}`
230
- : `승인된 위임 룰의 최근 에러율이 기준(20%)을 넘었습니다 — "${x.label}" (${x.healthSource === 'delegated' ? `위임 실행 ${x.delegatedRuns}건 중 에러율 ${Math.round((x.delegatedErrRate || 0) * 100)}%` : `유사 에피소드 기준 에러율 ${Math.round((x.errRate || 0) * 100)}%`}, statusline의 rule-health 칩). 조건 좁히기/제거를 사용자와 상의하세요: claude-token-saver route-scan rules`);
229
+ ? `새 위임 후보가 감지되었습니다 — "${x.label}" 유형 ${x.count}회 반복(statusline의 route? R${x.id} 칩). 등록: sprag harness promote R${x.id} --project|--global (적용 범위는 사용자에게 확인) / 무시: route-scan dismiss ${x.id}`
230
+ : `승인된 위임 룰의 최근 에러율이 기준(20%)을 넘었습니다 — "${x.label}" (${x.healthSource === 'delegated' ? `위임 실행 ${x.delegatedRuns}건 중 에러율 ${Math.round((x.delegatedErrRate || 0) * 100)}%` : `유사 에피소드 기준 에러율 ${Math.round((x.errRate || 0) * 100)}%`}, statusline의 rule-health 칩). 조건 좁히기/제거를 사용자와 상의하세요: sprag route-scan rules`);
231
231
  }
232
232
  s.briefed = [...briefed];
233
233
  } catch { /* caches unreadable — ctx briefing above still applies */ }
@@ -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 브리핑] 아래 상태 변화를 사용자에게 알려주세요. 진행 중인 답변 흐름을 끊지 말고, 답변 말미에 `※ [claude-token-saver]` 라벨을 달아 각 항목을 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');
package/src/cohesion.js CHANGED
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * Off by default for the same reason the Korean guidance is opt-in: a
11
11
  * token-saving tool has no business silently billing ~0.5k tokens a session.
12
- * Enable with `claude-token-saver cohesion on`.
12
+ * Enable with `sprag cohesion on`.
13
13
  *
14
14
  * When the Korean guidance is enabled, this block is NOT injected even if
15
15
  * enabled: the Korean supplement already carries the cohesion rules, and
@@ -62,7 +62,7 @@ export async function cohesionInjection({ cfg = loadConfig() } = {}) {
62
62
  const text = cohesionText();
63
63
  if (!text) return null;
64
64
  return [
65
- '[claude-token-saver cohesion] Follow this guidance for English prose in this session.',
65
+ '[sprag cohesion] Follow this guidance for English prose in this session.',
66
66
  'The user enabled it in claude-token-saver.',
67
67
  '',
68
68
  text,
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Subcommand: route-scan — detect recurring easy work on expensive models
3
3
  * and propose model-delegation ratchet rules. Zero token cost, fully local.
4
- * claude-token-saver route-scan # scan (24h cache) + print candidates
5
- * claude-token-saver route-scan --refresh # force rescan
6
- * claude-token-saver route-scan --days 30 # wider lookback
7
- * claude-token-saver route-scan --hook # SessionStart hook mode (context injection)
8
- * claude-token-saver route-scan dismiss <N> # mute candidate R<N>
4
+ * sprag route-scan # scan (24h cache) + print candidates
5
+ * sprag route-scan --refresh # force rescan
6
+ * sprag route-scan --days 30 # wider lookback
7
+ * sprag route-scan --hook # SessionStart hook mode (context injection)
8
+ * sprag route-scan dismiss <N> # mute candidate R<N>
9
9
  * Promote a candidate to a ratchet rule (scope is always explicit):
10
- * claude-token-saver harness promote R<N> --project|--global
10
+ * sprag harness promote R<N> --project|--global
11
11
  * brief --hook — UserPromptSubmit hook mode: per-session, change-triggered
12
12
  * briefing of state the statusline can only chip (ctx tier crossings,
13
13
  * mid-session route/rule-health changes). Silent when nothing changed.
@@ -18,7 +18,7 @@ import { debug } from '../debug.js';
18
18
 
19
19
  export async function run({ hasFlag }) {
20
20
  if (!hasFlag('--hook')) {
21
- console.error('Usage: claude-token-saver brief --hook (UserPromptSubmit hook mode)');
21
+ console.error('Usage: sprag brief --hook (UserPromptSubmit hook mode)');
22
22
  process.exit(1);
23
23
  }
24
24
  const ctx = readStdinJson() || {};
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Subcommand: cohesion — English sentence-connection guidance for every session.
3
- * claude-token-saver cohesion on # inject at session start, all projects
4
- * claude-token-saver cohesion off # stop injecting
5
- * claude-token-saver cohesion status # current state and cost
6
- * claude-token-saver cohesion show # print the guidance itself
3
+ * sprag cohesion on # inject at session start, all projects
4
+ * sprag cohesion off # stop injecting
5
+ * sprag cohesion status # current state and cost
6
+ * sprag cohesion show # print the guidance itself
7
7
  *
8
8
  * The English sibling of `korean on`, carrying only the language-neutral
9
9
  * cohesion rules (given-before-new, one referent per pronoun, subject
@@ -51,9 +51,9 @@ export async function run({ args }) {
51
51
  const suppressed = enabled && koreanStyleEnabled();
52
52
  if (lang === 'ko') {
53
53
  console.log(`cohesion: ${enabled ? 'on' : 'off'}${suppressed ? ' (korean 지침이 켜져 있어 주입은 생략됨)' : ''}`);
54
- console.log('영어 산문의 문장 연결 지침을 세션 시작에 주입합니다. 켜기: claude-token-saver cohesion on');
54
+ console.log('영어 산문의 문장 연결 지침을 세션 시작에 주입합니다. 켜기: sprag cohesion on');
55
55
  } else {
56
56
  console.log(`cohesion: ${enabled ? 'on' : 'off'}${suppressed ? ' (suppressed while the Korean guidance is on — it already carries these rules)' : ''}`);
57
- console.log('Injects English cohesion guidance at session start. Enable with: claude-token-saver cohesion on');
57
+ console.log('Injects English cohesion guidance at session start. Enable with: sprag cohesion on');
58
58
  }
59
59
  }
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Subcommand: compact-window — audit / pin Claude Code's `autoCompactWindow`.
3
- * claude-token-saver compact-window # status
4
- * claude-token-saver compact-window set --global # pin 500k in ~/.claude/settings.json
5
- * claude-token-saver compact-window set --project # pin 500k in <root>/.claude/settings.json
6
- * claude-token-saver compact-window set --global --value 600k
7
- * claude-token-saver compact-window off | on # toggle the statusline warning
3
+ * sprag compact-window # status
4
+ * sprag compact-window set --global # pin 500k in ~/.claude/settings.json
5
+ * sprag compact-window set --project # pin 500k in <root>/.claude/settings.json
6
+ * sprag compact-window set --global --value 600k
7
+ * sprag compact-window off | on # toggle the statusline warning
8
8
  *
9
9
  * Scope is deliberately explicit for `set`: writing a global settings.json is
10
10
  * not something to guess at, and the non-TTY hook environment cannot prompt.
@@ -80,14 +80,14 @@ export async function run({ args, hasFlag }) {
80
80
  console.log(ko
81
81
  ? ` 그 전까지 모든 요청이 전체 컨텍스트를 재과금합니다. 1M은 너무 크니 ${fmt(s.recommendedMin)}~${fmt(s.recommendedMax)} 범위를 권장합니다 (기본값 ${fmt(s.recommended)}, --value로 조절). 1M 창 자체는 그대로 두고 압축 시점만 앞당깁니다.`
82
82
  : ` Until then every request re-bills the whole context. 1M is too large — pick something in ${fmt(s.recommendedMin)}–${fmt(s.recommendedMax)} (default ${fmt(s.recommended)}, override with --value). The 1M window itself stays.`);
83
- console.log(`\n claude-token-saver compact-window set --global (~/.claude/settings.json, ${fmt(s.recommended)})`);
84
- console.log(` claude-token-saver compact-window set --project (<root>/.claude/settings.json, ${fmt(s.recommended)})`);
85
- console.log(` claude-token-saver compact-window set --global --value ${fmt(s.recommendedMax)}`);
83
+ console.log(`\n sprag compact-window set --global (~/.claude/settings.json, ${fmt(s.recommended)})`);
84
+ console.log(` sprag compact-window set --project (<root>/.claude/settings.json, ${fmt(s.recommended)})`);
85
+ console.log(` sprag compact-window set --global --value ${fmt(s.recommendedMax)}`);
86
86
  console.log(ko ? ' (적용 범위는 사용자에게 먼저 확인할 것)' : ' (confirm the scope with the user first)');
87
87
  return;
88
88
  }
89
89
 
90
90
  console.error(`Unknown compact-window subcommand: ${sub}`);
91
- console.error('Usage: claude-token-saver compact-window [status|set --global|--project [--value 500k]|off|on]');
91
+ console.error('Usage: sprag compact-window [status|set --global|--project [--value 500k]|off|on]');
92
92
  process.exit(1);
93
93
  }
@@ -2,11 +2,11 @@
2
2
  * Subcommand: doc2md — convert attached documents to Markdown before the
3
3
  * model reads them.
4
4
  *
5
- * claude-token-saver doc2md # status
6
- * claude-token-saver doc2md on|off # register / remove the Read hook
7
- * claude-token-saver doc2md <file> # convert one file by hand
8
- * claude-token-saver doc2md --clean # drop every cached conversion
9
- * claude-token-saver doc2md --hook # PreToolUse entry point
5
+ * sprag doc2md # status
6
+ * sprag doc2md on|off # register / remove the Read hook
7
+ * sprag doc2md <file> # convert one file by hand
8
+ * sprag doc2md --clean # drop every cached conversion
9
+ * sprag doc2md --hook # PreToolUse entry point
10
10
  */
11
11
 
12
12
  import { createRequire } from 'node:module';
@@ -162,5 +162,5 @@ export async function run({ args, hasFlag }) {
162
162
  console.log(` hook: ${hookRegistered() ? 'registered on Read' : 'not registered'}`);
163
163
  console.log('');
164
164
  if (!python) console.log(`Install the converter: ${doc2md.INSTALL_HINT}`);
165
- console.log('Enable with: claude-token-saver doc2md on');
165
+ console.log('Enable with: sprag doc2md on');
166
166
  }
@@ -2,8 +2,8 @@
2
2
  * Subcommand: feedback — submit a bug report or feature request from the
3
3
  * terminal (or from a Claude Code session) without opening a browser.
4
4
  *
5
- * claude-token-saver feedback "statusline이 IntelliJ에서 깨져요"
6
- * claude-token-saver feedback --title "cache chip" "5m TTL 칩이 안 사라짐"
5
+ * sprag feedback "statusline이 IntelliJ에서 깨져요"
6
+ * sprag feedback --title "cache chip" "5m TTL 칩이 안 사라짐"
7
7
  *
8
8
  * Why this exists: GitHub issues require a logged-in browser session, and
9
9
  * corporate networks often block github.com entirely. This command tries
@@ -25,13 +25,13 @@ import { join } from 'node:path';
25
25
  import os from 'node:os';
26
26
  import { debug } from '../debug.js';
27
27
 
28
- const REPO = 'rootstudioyaml/claude-token-saver';
28
+ const REPO = 'rootstudioyaml/sprag';
29
29
  const ISSUES_URL = `https://github.com/${REPO}/issues`;
30
30
 
31
31
  // Anonymous submission endpoint (Google Form). A Google Form's formResponse
32
32
  // URL accepts unauthenticated POSTs, which is exactly the property a
33
33
  // login-free, GitHub-blocked-network path needs. Responses land in the
34
- // maintainer's "claude-token-saver 피드백 (Feedback)" form (published
34
+ // maintainer's "sprag 피드백 (Feedback)" form (published
35
35
  // 2026-09-13, responder access: anyone with the link).
36
36
  // id — the /d/e/<id>/ segment of the form URL
37
37
  // message — entry.NNNN field id of the message question
@@ -102,7 +102,7 @@ export async function run({ args, getArg, version, dataDir }) {
102
102
  const explicitTitle = getArg('--title');
103
103
 
104
104
  if (!message) {
105
- console.log('usage: claude-token-saver feedback [--title "<제목>"] "<내용>"');
105
+ console.log('usage: sprag feedback [--title "<제목>"] "<내용>"');
106
106
  console.log(` (GitHub에서 직접 제보: ${ISSUES_URL})`);
107
107
  process.exitCode = 1;
108
108
  return;