claude-token-saver 3.44.0 → 3.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +202 -21
  2. package/NOTICE +35 -0
  3. package/README.ko.md +150 -48
  4. package/README.md +205 -192
  5. package/bin/cli.js +108 -39
  6. package/docs/CODEX.ko.md +184 -0
  7. package/docs/CODEX.md +497 -0
  8. package/examples/statusline-command.ps1 +11 -5
  9. package/examples/statusline-command.sh +9 -4
  10. package/package.json +20 -6
  11. package/presets/delegation/bounds.md +29 -0
  12. package/presets/model-rules.json +50 -9
  13. package/presets/ratchet-rules.json +4 -1
  14. package/src/agent.js +33 -0
  15. package/src/caps-cache.js +6 -2
  16. package/src/changelog.js +70 -0
  17. package/src/cli-name.js +25 -0
  18. package/src/codex-brief.js +89 -0
  19. package/src/codex-budget.js +73 -0
  20. package/src/codex-cache-policy.js +203 -0
  21. package/src/codex-cache.js +46 -0
  22. package/src/codex-delegation.js +154 -0
  23. package/src/codex-doc2md-ledger.js +45 -0
  24. package/src/codex-doc2md.js +99 -0
  25. package/src/codex-doctor.js +53 -0
  26. package/src/codex-harness.js +200 -0
  27. package/src/codex-hooks.js +138 -0
  28. package/src/codex-installer.js +79 -0
  29. package/src/codex-ledger.js +143 -0
  30. package/src/codex-panel-launcher.js +48 -0
  31. package/src/codex-panel-runner.js +74 -0
  32. package/src/codex-panel-session.js +35 -0
  33. package/src/codex-panel-setup.js +98 -0
  34. package/src/codex-panel-shell.js +51 -0
  35. package/src/codex-panel-state.js +40 -0
  36. package/src/codex-panel.js +448 -0
  37. package/src/codex-parser.js +397 -0
  38. package/src/codex-route-scan.js +171 -0
  39. package/src/commands/brief.js +24 -1
  40. package/src/commands/codex-delegate.js +59 -0
  41. package/src/commands/codex.js +579 -0
  42. package/src/commands/delegate.js +133 -0
  43. package/src/commands/harness.js +16 -3
  44. package/src/commands/install.js +109 -12
  45. package/src/commands/korean.js +2 -2
  46. package/src/commands/mode.js +22 -2
  47. package/src/commands/profile-map.js +164 -0
  48. package/src/commands/route-scan.js +74 -7
  49. package/src/commands/seed.js +16 -12
  50. package/src/commands/uninstall.js +28 -4
  51. package/src/commands/upgrade.js +13 -0
  52. package/src/compact-window.js +7 -1
  53. package/src/config.js +22 -3
  54. package/src/cost.js +34 -0
  55. package/src/delegation-guard.js +278 -0
  56. package/src/doc2md-ledger.cjs +3 -3
  57. package/src/doc2md.cjs +72 -28
  58. package/src/effort-palette.js +145 -0
  59. package/src/formatters/statusline.js +352 -123
  60. package/src/formatters/table.js +5 -4
  61. package/src/gateway-auth.js +86 -0
  62. package/src/glyphs.js +103 -0
  63. package/src/handoff.js +27 -7
  64. package/src/harness-analyzer.cjs +7 -2
  65. package/src/harness-templates.js +33 -1
  66. package/src/harness.js +51 -17
  67. package/src/hook-manager.js +42 -14
  68. package/src/hook.cjs +34 -2
  69. package/src/installer.js +300 -16
  70. package/src/litellm-budget.js +38 -67
  71. package/src/litellm-models.js +264 -0
  72. package/src/model-alias.js +170 -16
  73. package/src/model-rules.js +53 -17
  74. package/src/parser.js +89 -1
  75. package/src/preset-ratchet.js +133 -0
  76. package/src/route-inject.js +161 -0
  77. package/src/route-scan.js +68 -8
  78. package/src/seed-rules.js +117 -55
  79. package/src/session-paths.js +242 -0
  80. package/src/statusline-mode.js +106 -0
  81. package/src/stdin-payload.js +40 -0
  82. package/src/ultracode.js +202 -0
  83. package/src/update-check.js +217 -3
  84. package/src/window-labels.js +19 -8
package/docs/CODEX.md ADDED
@@ -0,0 +1,497 @@
1
+ # Codex Integration
2
+
3
+ [← README](../README.md) · [한국어](./CODEX.ko.md)
4
+
5
+ Sprag supports Codex through its native `AGENTS.md` and `hooks.json` interfaces.
6
+ The default agent remains Claude Code. Pass `--agent codex` before or after the
7
+ subcommand to select Codex explicitly; this does not change a global default.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm i -g sprag-cli
13
+ ```
14
+
15
+ The package install sets up Codex on its own when Codex is present, together
16
+ with the Claude Code integration and the bundled presets; nothing is asked
17
+ (`sprag install --manual` asks at each step). For a Codex-only installation that
18
+ leaves Claude Code settings alone, skip the postinstall and run the Codex
19
+ install directly:
20
+
21
+ ```sh
22
+ npm i -g sprag-cli --ignore-scripts
23
+ sprag install --agent codex
24
+ ```
25
+
26
+ Both integrations can coexist. Codex installation uses `$CODEX_HOME` when set,
27
+ otherwise `~/.codex`. It adds the integration hooks to `hooks.json` and a marked harness
28
+ block to the global `AGENTS.md`. A non-empty `AGENTS.override.md` takes precedence,
29
+ so the block is added there instead when present. Existing instructions and
30
+ other hooks are preserved; changed files are backed up. `config.toml`, hook
31
+ trust settings, and Claude Code settings are never changed by this command.
32
+
33
+ Open **`/hooks` in Codex**, review the Sprag commands, and trust them. New or
34
+ changed hooks do not run until trusted. Use a Codex release that supports the
35
+ events documented below. Admin policies or `features.hooks = false` may disable
36
+ hooks. The `sprag` executable and Node.js must be on Codex's PATH.
37
+
38
+ On macOS with zsh, installation also makes sure tmux is present: it installs
39
+ tmux with Homebrew when missing (skip this with `CTS_NO_TMUX=1`) and adds the
40
+ zsh integration so typing `codex` shows the panel inline in the same terminal.
41
+ The separate-window hook is then not registered. When tmux cannot be
42
+ installed, the login shell is not zsh, or an existing `codex` alias or
43
+ function is already present, installation falls back to the separate window
44
+ instead. `sprag panel shell remove --agent codex` is remembered across
45
+ reinstalls and upgrades, and `--no-panel` skips both.
46
+ An explicit `panel auto off` preference survives reinstall. Installation
47
+ reports registration, not successful activation. After approval and restarting
48
+ Codex, run `sprag panel doctor --agent codex` to check the last hook execution,
49
+ any launch failure, and recent rendered frames. These diagnostics are local;
50
+ they do not read or change Codex's trust database.
51
+
52
+ `CTS_NO_HARNESS=1` skips the global harness. Korean guidance is opt-in, using the
53
+ existing shared Sprag preference:
54
+
55
+ ```sh
56
+ sprag korean on --agent codex
57
+ sprag korean lint warn --agent codex
58
+ sprag doc2md install-converter --agent codex
59
+ ```
60
+
61
+ `korean on`, `cohesion on`, `brief on`, `doc2md on`, and `delegate on`
62
+ register Codex hooks before saving the enabled preference. If hook registration
63
+ fails, the preference stays unchanged. Review new or changed definitions in
64
+ `/hooks`; registration does not grant trust. Turning a feature off keeps the
65
+ shared hooks needed by other features.
66
+
67
+ ## Supported Workflows
68
+
69
+ | Feature | Codex behavior |
70
+ |---|---|
71
+ | Harness | Five principles in global or project `AGENTS.md`, with override-file support |
72
+ | Ratchet rules | Separate Codex files; global and project rules injected at SessionStart, including resume and compaction |
73
+ | Korean guidance / English cohesion | SessionStart injection using shared Sprag preferences |
74
+ | Korean write-time lint | PostToolUse feedback for `apply_patch` and recognized shell write targets; block, warn, and off modes |
75
+ | Documents | Shared converter, prompt paths, supported file reads, and recognized document/cache write guards; `sprag doc2md <file> --agent codex` also works manually |
76
+ | Token report | Table, JSON, or CSV from local Codex rollout logs, with time and project filters |
77
+ | Statusline | `--statusline` or `--format statusline` renders the compact panel once, with wrapping and label/color preferences |
78
+ | Briefing | UserPromptSubmit reports fresh context/limit threshold crossings once per session and threshold cycle |
79
+ | Warning history | `last` and `history` read Codex-only, per-session warning records |
80
+ | Handoff | Git state, session/model, recorded context/tokens/limits, and fillable remaining-work sections |
81
+ | Subagents | Opt-in native spawn model routing, scoped category rules, and SubagentStart guidance |
82
+ | Cache timer | Resolved provider retention policy after recorded cache usage; exact expiry is unknown |
83
+ | Route discovery | Repeated simple turns grouped by project, provider, and parent model; no automatic registration |
84
+ | Ratchet detection | Recent repeated command/patch failures produce `ratchet?` candidates |
85
+ | Seed presets | Compatible ratchet rules, separate decisions, explicit registration scope |
86
+ | Routing saved | Sprag-attributed child tokens priced with matching LiteLLM rates; an estimate, not billed savings |
87
+ | Diagnostics | `doctor` checks user config, hook registration, harness, logs, panel activity, and preferences |
88
+ | Capability matrix | `capabilities` lists supported, partial, native, and unsupported areas without invoking a model |
89
+
90
+ The document converter is shared with Claude Code and requires its optional
91
+ converter dependencies. Disable automatic Codex conversion and write guards with
92
+ `sprag doc2md off --agent codex` or `CTS_NO_DOC2MD=1`. PreToolUse handles supported
93
+ file-read calls and literal single-file `cat`, `head`, and `tail` reads. Successful
94
+ conversion blocks the original read with the Markdown path for a retry. Conversion
95
+ failures are reported; unsafe archives are denied. Patches and recognized shell
96
+ text writes cannot overwrite binary documents or conversion caches. Arbitrary
97
+ extraction scripts and compound shell reads are not intercepted; use the manual
98
+ command. Text extraction never verifies charts, images, or layout.
99
+
100
+ Conversion hooks have a 600-second outer timeout to accommodate interpreter
101
+ probes and multiple conversions; each converter invocation retains its own
102
+ 120-second limit. An unavailable Codex cache view is reported as
103
+ `cache-unavailable` without suppressing other document results or the context
104
+ briefing. Both byte-clipped output and converter-reported truncation are marked
105
+ as incomplete in read and prompt feedback.
106
+
107
+ Codex keeps document accounting separate from Claude. `Doc2md N docs (Codex total)`
108
+ counts distinct source paths successfully prepared through Codex, including reuse
109
+ of an existing conversion. Reusing or reconverting a source does not increment its
110
+ count. The total is scoped to Codex home, not the current session. Old shared
111
+ history is not imported. Counts are sorted by frequency, then extension, with no
112
+ Claude pricing involved. Codex reads a neutral Markdown view without the shared
113
+ cache's Claude-based savings banner; the shared cache remains unchanged.
114
+
115
+ ## Diagnostics And Continuity
116
+
117
+ ```sh
118
+ sprag doctor --agent codex
119
+ sprag doctor --agent codex --format json
120
+ sprag capabilities --agent codex
121
+ sprag brief --agent codex
122
+ sprag brief on --agent codex
123
+ sprag last --agent codex
124
+ sprag history --agent codex --days 7 --format json
125
+ sprag history --agent codex --session SESSION_ID
126
+ sprag handoff --agent codex --cwd /path/to/repo
127
+ sprag delegate on --agent codex
128
+ ```
129
+
130
+ The doctor is read-only. It reports missing/outdated hook definitions, including
131
+ insufficient timeouts or asynchronous handlers, disabled
132
+ hooks in user config, and unavailable logs without treating registration as
133
+ proof of trust. Its config report excludes provider credentials and is not an
134
+ effective-config resolver: active profiles, project config, managed policy,
135
+ and invocation overrides can differ. Check Codex `/hooks` for approval.
136
+
137
+ Briefing is enabled by default after installing and trusting the prompt hook.
138
+ It reads at most the latest 256 KiB of the current transcript and warns when
139
+ recorded input reaches 80% or 95% of the recorded context window, or a reported
140
+ rate-limit window reaches 90%. Missing measurements, measurements older than
141
+ five minutes, and expired limits do not generate new warnings. Lower fresh
142
+ context measurements re-arm the warning after compaction. `brief off` disables
143
+ automatic briefing without disabling document conversion; bare `brief` shows
144
+ current warnings without recording or consuming the automatic notification.
145
+
146
+ History records automatic warning entries, not every tool call or a complete
147
+ audit log. Files are separated by Codex home and session beneath Sprag's state
148
+ directory; each keeps up to 200 warning entries. `--project` filters history by
149
+ substring and `--session` by exact ID. The history remains separate from Claude
150
+ warning records. A handoff file is never overwritten and identifies quota
151
+ values as recorded snapshots, not live responses. Fill in its remaining-work
152
+ sections before using it to continue in another session.
153
+
154
+ Delegation is independently opt-in via `delegate on`. PreToolUse rewrites native
155
+ `spawn_agent` arguments using Codex's `message`, `model`, and `reasoning_effort`
156
+ fields. It preserves explicit model choices and custom roles, including custom
157
+ overrides of built-in roles. SubagentStart injects scoped ratchets and enabled
158
+ writing guidance. Bounds are instructions, not an enforced tool-call budget.
159
+ Normal Codex sandbox and approval rules still apply. Review new hooks in `/hooks`.
160
+
161
+ ```sh
162
+ sprag delegate on --agent codex
163
+ sprag delegate model gpt-6-luna --effort high --agent codex
164
+ sprag delegate model off --agent codex
165
+ sprag delegate rules add explore --from gpt-6-astra --model gpt-6-luna --project --agent codex
166
+ sprag delegate rules --agent codex
167
+ sprag delegate rules rm 1 --agent codex
168
+ ```
169
+
170
+ Use model IDs available from your provider. A default target applies to built-in
171
+ spawns without an explicit model. Category rules (`paste`, `translate`, `explore`,
172
+ `read`, `check`, `run`) reuse Sprag's classifier and escalation gates, require an
173
+ exact parent model, and prefer project rules over global rules. Matching prompts
174
+ request native delegation; unavailable subagent tools leave work on the main
175
+ agent. Claude tier presets and history are not imported.
176
+
177
+ ## Harness Commands
178
+
179
+ ```sh
180
+ sprag harness init --agent codex # current project
181
+ sprag harness check --agent codex # project, or global fallback
182
+ sprag harness init --agent codex --global
183
+ sprag harness promote --agent codex --project "Run the changed module's tests before reporting completion."
184
+ sprag harness list --agent codex --project
185
+ sprag harness rm 1 --agent codex --project
186
+ sprag harness prune --agent codex --global --older-than 6 --dry-run
187
+ sprag harness uninit --agent codex --project
188
+ ```
189
+
190
+ Rules live in `<project>/.codex/ratchet.md` or `$CODEX_HOME/ratchet.md`.
191
+ The harness also instructs Codex to retrieve both files, since Claude's `@file`
192
+ import syntax is not used. Promotion always requires an explicit scope.
193
+ `rm` and `prune` preserve backups; `uninit` removes only the managed block.
194
+
195
+ The panel detects repeated command or patch failures in the recent rollout tail
196
+ (up to 2 MiB, 30 tool-bearing turns, 30 minutes). Lookup misses and ordinary
197
+ `grep`/`diff` exit-1 results are excluded. A `ratchet? #1 x2` chip identifies a
198
+ candidate in that session. Inspect it before promoting:
199
+
200
+ ```sh
201
+ sprag harness promote 1 --session SESSION_ID --project --agent codex
202
+ ```
203
+
204
+ This appends an editable TODO for the cause and prevention, not a diagnosed fix.
205
+ Prefer promoting a complete condition/action rule after confirming its cause.
206
+ Candidate IDs are session-local and temporary; Claude candidate IDs are not imported.
207
+
208
+ ## Route Discovery And Presets
209
+
210
+ ```sh
211
+ sprag route-scan --refresh --days 14 --agent codex
212
+ sprag delegate rules add R1 --project --agent codex
213
+ sprag route-scan dismiss R1 --agent codex
214
+ sprag seed --agent codex
215
+ sprag seed accept all --project --agent codex
216
+ sprag seed skip all --agent codex
217
+ sprag seed reset --agent codex
218
+ ```
219
+
220
+ Route candidates need at least three completed simple turns with the same
221
+ category, provider, parent model, and project. Aborted, already delegated,
222
+ high-error, complex, and mid-turn steering requests are excluded. Archived
223
+ copies of one session do not count twice. Modern turn usage takes precedence;
224
+ older cumulative `token_count` records are supported without double-counting.
225
+
226
+ Targets need a lower price at the observed token mix and evidence that the model
227
+ is usable: a recorded run, an existing provider-scoped rule, or the configured
228
+ default target. Without matching prices, the candidate remains available but
229
+ approval requires `--model <id>`. Availability still depends on the active provider.
230
+ SessionStart reads cached candidates and schedules an eligible refresh outside
231
+ the hook. Small log changes refresh at most daily; a 5 MiB increase can refresh
232
+ after an hour. `--refresh` bypasses that schedule.
233
+
234
+ `seed` offers only compatible ratchet presets, not Claude model-tier presets.
235
+ Accept and skip decisions are separate from Claude. Both seed acceptance and
236
+ route approval require the user's choice of global or project scope. A project
237
+ route is saved for the project where it was observed. Enable delegation with
238
+ `sprag delegate on --agent codex` and trust the hooks before expecting rules to run.
239
+
240
+ ## Reports
241
+
242
+ ### One-Shot Statusline
243
+
244
+ ```sh
245
+ sprag --statusline --agent codex
246
+ sprag --statusline --agent codex --text --no-color --columns 80
247
+ sprag --format statusline --agent codex --session SESSION_ID
248
+ sprag --statusline --agent codex --single-line
249
+ ```
250
+
251
+ This is terminal output, not a shell command installed into Codex's native
252
+ footer. It reads local logs, does not fetch gateway budgets, and exits after
253
+ one frame. Chips wrap to terminal width (100 columns when piped), with an
254
+ explicit `--columns` override. `--single-line` produces one unwrapped line for
255
+ external terminal integrations. It shares `mode text|narrow|icon`, timer, and color
256
+ preferences with the panel; explicit `--text`, `--narrow`, and `--no-color`
257
+ flags are supported, along with `--timer` and `--no-timer`.
258
+ Claude's TTL buckets and routing options do not apply.
259
+
260
+ ### Cache Timer And Display Order
261
+
262
+ Both panel layouts and the one-shot statusline use a Codex-specific order:
263
+ warnings, usage limits/budget, context, cache timer, model/effort, session
264
+ cache/token totals, Codex lifetime document counts, then harness/preferences and
265
+ version. Session measurements stay together before lifetime totals. Claude's
266
+ statusline order is unchanged.
267
+
268
+ The cache clock starts from a new recorded cache read or write, not the latest
269
+ tool event, prompt, or repeated quota snapshot. Each session has its own clock;
270
+ changing models invalidates the old model's clock until new cache usage arrives.
271
+ `Cache 29:59 (Bedrock 30m)` uses the documented minimum retention for a resolved
272
+ supported model, not a server expiration timestamp or a promise of a cache hit.
273
+ For LiteLLM, Sprag queries the configured `/model/info` endpoint and checks the
274
+ actual deployment/base model. All deployments behind an alias must agree.
275
+ Only sanitized policy and price fields are persisted; policy freshness is five minutes. Secrets
276
+ and raw deployment records are not stored. The live panel refreshes policies;
277
+ one-shot statuslines remain offline. Unresolved, earlier, or unknown models show
278
+ cache age with `TTL unknown`; no observed cache activity shows `Cache timer n/a`.
279
+ The tilde and old unverified-policy labels are removed. After the window passes, the display
280
+ says `window elapsed` and `expiry unknown`, never `EXPIRED`.
281
+
282
+ ```sh
283
+ sprag cache status --agent codex
284
+ sprag cache status --refresh --agent codex
285
+ sprag cache 30m --agent codex
286
+ sprag cache auto --agent codex
287
+ sprag cache off --agent codex
288
+ sprag --statusline --agent codex --no-timer
289
+ ```
290
+
291
+ A configured duration (1 minute through 24 hours) changes only Sprag's display
292
+ estimate, not the request or provider retention. It is stored separately from
293
+ Claude's `mode ttl=5m|1h|auto`. The shared `mode no-timer` also hides the Codex
294
+ clock; `--timer` overrides that preference, but not `cache off`.
295
+
296
+ ### Routing Saved
297
+
298
+ ```sh
299
+ sprag route-scan savings --refresh --agent codex
300
+ sprag route-scan savings --format json --agent codex
301
+ ```
302
+
303
+ The separate Codex ledger joins a route ID recorded by Sprag at spawn time to
304
+ the child's own rollout. An explicit model choice or an unrelated cheaper
305
+ subagent earns no credit. The estimate holds the child's measured tokens
306
+ constant and prices them at the parent and child rates. Negative differences
307
+ remain negative; this is not a comparison of actual billed totals.
308
+
309
+ Rates come from the configured LiteLLM `/model/info` endpoint, with agreement
310
+ required across deployments behind an alias. Price snapshots last seven days.
311
+ Providers are kept separate; direct OpenAI/subscription pricing is not inferred.
312
+ Missing rates or usage produce unpriced entries, never invented zeroes. A priced
313
+ entry keeps its rate snapshot across later outages. Pending route records are
314
+ matched for seven days; saved ledger entries remain afterward. Run `--refresh`
315
+ after delegation to update the ledger without waiting for the next route scan.
316
+
317
+ Claude's ledger is never imported. Document conversion shows distinct document
318
+ counts rather than a Codex dollar saving or billing measurement.
319
+
320
+ ### Live Companion Panel
321
+
322
+ Codex 0.157.1 was observed to defer SessionStart until the first submitted prompt,
323
+ even after hook trust is granted. Installation now adds this shell integration by
324
+ default on macOS zsh; to install or remove it manually:
325
+
326
+ ```sh
327
+ sprag panel shell install --agent codex
328
+ ```
329
+
330
+ Install tmux first (`brew install tmux` on macOS), then open a new terminal.
331
+ This adds a backed-up, marked function to `$ZDOTDIR/.zshrc` (or `~/.zshrc`).
332
+ Interactive Codex runs above a compact Sprag panel in the SAME terminal.
333
+ An isolated tmux server leaves existing tmux sessions and configuration alone.
334
+ Each inline launch has its own session binding. The runner adds `--no-daemon`
335
+ so the trusted SessionStart hook receives that launch's environment instead of
336
+ a shared app-server's environment. The hook supplies the exact session ID and
337
+ transcript path; another active session in the same project cannot take over
338
+ the panel. Before the hook runs, the panel shows **Waiting for session binding**,
339
+ not another session's usage. On versions that defer SessionStart, submit the
340
+ first prompt to bind the panel. Install and trust the Sprag SessionStart hook
341
+ to enable binding; disabling hooks leaves the panel waiting.
342
+ Resume, clear, and compaction hooks refresh the binding. Each compact frame
343
+ identifies its session by the last eight ID characters. Inline remote-server
344
+ invocations are rejected because their hook environment and logs are not local;
345
+ use standalone Codex and an explicitly pinned panel with accessible local logs.
346
+ Codex arguments and exit status are preserved. The inline runner prepends
347
+ `-c 'tui.status_line=[]'` so Codex's model/effort/directory row does not duplicate
348
+ the Sprag panel. This is an invocation-only override: it does not edit
349
+ `config.toml`, change the model or effort, or affect standalone Codex runs.
350
+ Codex's startup banner, shortcut hints, approval prompts, and other notices
351
+ remain visible. To keep the native row, run
352
+ `sprag panel run --agent codex --keep-native-statusline --` followed by Codex
353
+ arguments. An explicit later Codex `-c 'tui.status_line=["current-dir"]'` also
354
+ overrides Sprag's default. Restart the inline session to apply a runner update.
355
+ Exiting Codex closes the panel;
356
+ detaching also ends this temporary session. For explicit launch without shell
357
+ integration, run `sprag panel run --agent codex --` followed by Codex arguments.
358
+ An existing codex alias/function is not overwritten. It does not bypass hook
359
+ trust: it starts the local display independently. The panel-start hook skips
360
+ opening a separate window inside this layout. Remove the shell function with
361
+ `sprag panel shell remove --agent codex` and open a new terminal.
362
+ The shell integration currently targets common plain, prompt, and resume
363
+ invocations; use the explicit panel command for unusual global-option/subcommand
364
+ combinations. Non-TTY invocations and recognized utility commands do not open windows.
365
+
366
+ On macOS, enable automatic opening when Codex starts or resumes:
367
+
368
+ ```sh
369
+ sprag panel auto on --agent codex
370
+ sprag panel --open --agent codex
371
+ ```
372
+
373
+ The first command registers a separate `panel-start` SessionStart hook. Review
374
+ and trust that new hook in Codex `/hooks`, then restart or resume Codex. It opens
375
+ a macOS Terminal window pinned to the hook's session ID; only a panel for that
376
+ same session and Codex home is reused. Concurrent sessions get separate windows.
377
+ Reused windows are unminimized, their panel tab is selected, and Terminal is
378
+ brought forward so a background panel does not look like a failed launch.
379
+ Clear and compaction events do not open windows. macOS may request Terminal
380
+ automation permission. Codex's native footer is unchanged. Disable automatic
381
+ opening with `sprag panel auto off --agent codex`; check registration with
382
+ `sprag panel auto status --agent codex`. Reinstall preserves this preference.
383
+ `--open --session SESSION_ID` opens or reuses a pinned window immediately.
384
+ Without `--session`, `--open` creates a project-following window. Other platforms use a manual
385
+ terminal or tmux split as below. Hook trust is never bypassed by Sprag.
386
+
387
+ Run this in a separate terminal window or a tmux split alongside Codex:
388
+
389
+ ```sh
390
+ sprag panel --agent codex
391
+ sprag panel --agent codex --project /path/to/repo
392
+ sprag panel --agent codex --session SESSION_ID --interval 2
393
+ sprag panel --agent codex --once --no-color
394
+ ```
395
+
396
+ The manually launched panel refreshes every two seconds and follows the latest main session in
397
+ the current project (including subdirectories and filesystem path aliases).
398
+ Subagent rollouts do not replace the main display. `--session` pins an exact
399
+ session ID, including a child when explicitly selected. Pinned and bound sessions
400
+ are looked up even when their logs are older than seven days or have been archived.
401
+ `--days` controls project-following discovery (default seven days). `--project` is a directory
402
+ path in panel mode, not the report's substring filter. Press `r` to refresh and
403
+ `q` or Ctrl-C to exit. The terminal's screen and cursor are restored on exit.
404
+ Piped output requires `--once` so scripts cannot accidentally start an endless loop.
405
+ Use `sprag panel doctor --agent codex --session SESSION_ID` to inspect rendering
406
+ for one session; without an ID, diagnostics show the last project-wide activity.
407
+
408
+ The display shows model/effort, recorded working/idle/interrupted state when
409
+ available, latest recorded input context, cache hit rate,
410
+ session token totals, recorded rate-limit gauges/reset times, harness score,
411
+ ratchet counts, hook registration, and Korean/cohesion/doc2md/brief/delegate
412
+ preferences. Preference labels do not claim
413
+ that hooks are trusted. Logs older than five minutes are marked stale. Reset
414
+ times that have elapsed are marked as awaiting a new usage event, not zero usage.
415
+ Unreported limits, session cost, exact cache expiry, and unpriced routing estimates remain unknown.
416
+ Non-ASCII dynamic labels are replaced with `?` to maintain terminal cell widths.
417
+
418
+ The inline compact panel reuses Claude's icon/narrow/text preferences and
419
+ segmented gauges. Chips wrap as units instead of losing their trailing values;
420
+ the pane grows with the content while keeping at least ten rows for Codex.
421
+ If the terminal is too small, a remaining-row count marks hidden content.
422
+ Cache reuse is shown in tokens, not an inferred dollar saving. Document counts
423
+ and format breakdowns come from Codex's own document records and are labelled
424
+ `Codex total`; Claude-based dollar estimates are not attributed to Codex.
425
+ Unavailable cost and limit placeholders are hidden in compact mode. Cache timer
426
+ availability and unpriced routing accounting remain explicit.
427
+
428
+ The panel is a separate terminal UI, not an injection into Codex's native footer.
429
+ It consumes local rollout logs without invoking a model or modifying Codex config.
430
+ For a configured LiteLLM provider, the existing budget reader also queries that
431
+ provider's budget and model-info endpoints, using its configured environment key or auth helper.
432
+ Both full and compact views show a returned budget, with its source and freshness,
433
+ separately from unavailable per-session cost. Document counts cover Codex history
434
+ in both views; Claude dollar-saving estimates are excluded.
435
+ Unchanged files are cached for the panel's lifetime; changed logs are reparsed.
436
+
437
+ ```sh
438
+ sprag --agent codex --days 7
439
+ sprag --agent codex --hours 6 --format json
440
+ sprag --agent codex --project my-project --format csv
441
+ sprag --agent codex --session SESSION_ID --format json
442
+ ```
443
+
444
+ Sprag reads `.jsonl` files under `$CODEX_HOME/sessions` and
445
+ `$CODEX_HOME/archived_sessions`, not `history.jsonl`. The project filter matches
446
+ the session metadata's working directory. Usage is filtered within each session,
447
+ not just by file modification time. A session without token-count records does
448
+ not appear in the report.
449
+
450
+ Cumulative token-count deltas prevent repeated usage events from being counted
451
+ twice. Cached input is included in total input, and reasoning is included in
452
+ output; neither subset is added twice. Usage updates are **not an exact API call
453
+ count**. JSON retains the existing summary field `apiCalls` for compatibility,
454
+ but its Codex value counts usage updates. Context size comes from recorded
455
+ `last_token_usage`, not Claude's 200k/1M heuristic.
456
+ The top-level JSON field `usageUpdates` names that count explicitly.
457
+
458
+ Rollout JSONL is not a stable public Codex interface. Missing or malformed records
459
+ are skipped, and incomplete/copied/reset logs can only give best-effort totals.
460
+ Reports show **cost and exact cache TTL as unavailable** (`null` in JSON). They do not
461
+ apply Anthropic prices, infer subscription charges, or claim Claude's cache TTL.
462
+ Document counts are not a measurement of Codex billing or avoided tokens.
463
+
464
+ ## Limits And Removal
465
+
466
+ Claude's cap/TTL heuristics, Haiku/Sonnet tier presets, and the Claude
467
+ `compact-window` command do not apply to Codex. Codex provides its own
468
+ `model_auto_compact_token_limit` setting; Sprag does not apply Claude's 1M
469
+ heuristic or change that setting. Codex's native `tui.status_line` accepts
470
+ item identifiers, not a Sprag shell command. Unsupported integration commands
471
+ fail explicitly rather than modifying Claude settings.
472
+
473
+ Use `sprag panel --agent codex` for the live display or
474
+ `sprag --statusline --agent codex` for one-shot terminal output.
475
+ Rate-limit gauges use Codex's recorded values only. Run
476
+ `sprag capabilities --agent codex` for the complete support matrix.
477
+
478
+ ```sh
479
+ sprag uninstall --agent codex
480
+ ```
481
+
482
+ Removal takes out Sprag's Codex hooks and global harness block. It keeps project
483
+ harnesses, ratchet rules, backups, other hooks, and shared Sprag state.
484
+ `--purge` is intentionally unsupported for Codex. Remove a project block with
485
+ `sprag harness uninit --agent codex --project` in that project.
486
+
487
+ Normal npm upgrades still run the package's Claude postinstall. Codex-only users
488
+ should keep using `npm i -g sprag-cli --ignore-scripts` followed by
489
+ `sprag install --agent codex` when upgrading.
490
+
491
+ ## Official References
492
+
493
+ - [Codex hooks, event schemas, and trust](https://developers.openai.com/codex/hooks/)
494
+ - [AGENTS.md discovery and overrides](https://developers.openai.com/codex/guides/agents-md/)
495
+ - [Codex configuration reference](https://developers.openai.com/codex/config-reference/)
496
+ - [Prompt cache lifetime](https://developers.openai.com/api/docs/guides/prompt-caching#cache-lifetime)
497
+ - [Codex subagent configuration](https://developers.openai.com/codex/subagents/)
@@ -1,9 +1,9 @@
1
1
  # Claude Code statusline (Windows PowerShell version)
2
2
  # Mirrors the POSIX sh script — prints "user@host:cwd" then appends
3
- # claude-token-saver output as a second segment.
3
+ # sprag output as a second segment.
4
4
  #
5
5
  # Install:
6
- # 1) npm install -g claude-token-saver
6
+ # 1) npm install -g sprag-cli
7
7
  # 2) Save this file as: %USERPROFILE%\.claude\statusline-command.ps1
8
8
  # 3) In %USERPROFILE%\.claude\settings.json add:
9
9
  # {
@@ -30,14 +30,20 @@ Write-Host -NoNewline "$esc[01;32m$env:USERNAME@$env:COMPUTERNAME$esc[00m`:$esc[
30
30
  # 2) cache monitor (appended). Separator " | ". Falls back silently.
31
31
  Write-Host -NoNewline " $esc[90m|$esc[00m "
32
32
 
33
- $cacheMonitor = Get-Command claude-token-saver -ErrorAction SilentlyContinue
33
+ # `claude-token-saver` is the older binary name, still installed by the current
34
+ # package; the npx fallback names `sprag-cli`, since the old package name is
35
+ # deprecated on npm and would fetch a version that stopped receiving releases.
36
+ $cacheMonitor = Get-Command sprag -ErrorAction SilentlyContinue
37
+ if (-not $cacheMonitor) {
38
+ $cacheMonitor = Get-Command claude-token-saver -ErrorAction SilentlyContinue
39
+ }
34
40
  if ($cacheMonitor) {
35
41
  try {
36
- & claude-token-saver --statusline --icon 2>$null
42
+ & $cacheMonitor.Name --statusline --icon 2>$null
37
43
  } catch { }
38
44
  } else {
39
45
  # fallback: npx (first run downloads the package; subsequent runs are warm)
40
46
  try {
41
- & npx --yes claude-token-saver@latest --statusline --icon 2>$null
47
+ & npx --yes sprag-cli@latest --statusline --icon 2>$null
42
48
  } catch { }
43
49
  }
@@ -1,9 +1,9 @@
1
1
  #!/bin/sh
2
2
  # Claude Code statusline (POSIX sh — works on macOS, Linux, and WSL)
3
- # Prints "user@host:cwd" then appends claude-token-saver as a second segment.
3
+ # Prints "user@host:cwd" then appends sprag as a second segment.
4
4
  #
5
5
  # Install:
6
- # 1) npm install -g claude-token-saver
6
+ # 1) npm install -g sprag-cli
7
7
  # 2) Save this file as: ~/.claude/statusline-command.sh
8
8
  # chmod +x ~/.claude/statusline-command.sh (optional)
9
9
  # 3) In ~/.claude/settings.json:
@@ -29,8 +29,13 @@ printf '\033[01;32m%s@%s\033[00m:\033[01;34m%s\033[00m' "$(whoami)" "$(hostname
29
29
 
30
30
  # 2) cache monitor (appended). Separator " | ". Falls back silently.
31
31
  printf ' \033[90m|\033[00m '
32
- if command -v claude-token-saver >/dev/null 2>&1; then
32
+ # `claude-token-saver` is the older binary name, still installed by the current
33
+ # package; the npx fallback names `sprag-cli`, since the old package name is
34
+ # deprecated on npm and would fetch a version that stopped receiving releases.
35
+ if command -v sprag >/dev/null 2>&1; then
36
+ sprag --statusline --icon 2>/dev/null || true
37
+ elif command -v claude-token-saver >/dev/null 2>&1; then
33
38
  claude-token-saver --statusline --icon 2>/dev/null || true
34
39
  else
35
- npx --yes claude-token-saver@latest --statusline --icon 2>/dev/null || true
40
+ npx --yes sprag-cli@latest --statusline --icon 2>/dev/null || true
36
41
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-token-saver",
3
- "version": "3.44.0",
3
+ "version": "3.55.0",
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": {
@@ -8,11 +8,14 @@
8
8
  "claude-token-saver": "bin/cli.js"
9
9
  },
10
10
  "scripts": {
11
- "test": "node --test",
11
+ "deploy": "node scripts/deploy.mjs",
12
12
  "docs:statusline": "node scripts/docs-statusline.mjs",
13
13
  "postinstall": "node bin/cli.js install || true",
14
14
  "publish:legacy": "node scripts/publish-legacy.mjs",
15
- "sync:ko": "node scripts/sync-readme-ko.mjs"
15
+ "release:notes": "node scripts/release-notes.mjs",
16
+ "site:docs": "node scripts/build-site-docs.mjs",
17
+ "test": "node --test",
18
+ "version": "node scripts/sync-site-version.mjs"
16
19
  },
17
20
  "files": [
18
21
  "bin/",
@@ -21,7 +24,10 @@
21
24
  "examples/",
22
25
  "README.md",
23
26
  "README.ko.md",
24
- "LICENSE"
27
+ "docs/CODEX.md",
28
+ "docs/CODEX.ko.md",
29
+ "LICENSE",
30
+ "NOTICE"
25
31
  ],
26
32
  "engines": {
27
33
  "node": ">=18"
@@ -33,6 +39,9 @@
33
39
  "ai-agent",
34
40
  "claude",
35
41
  "claude-code",
42
+ "codex",
43
+ "openai-codex",
44
+ "agents-md",
36
45
  "anthropic",
37
46
  "model-routing",
38
47
  "llm-router",
@@ -40,6 +49,8 @@
40
49
  "subagent",
41
50
  "haiku",
42
51
  "cost-savings",
52
+ "token-saver",
53
+ "reduce-tokens",
43
54
  "token-usage",
44
55
  "prompt-caching",
45
56
  "cache",
@@ -51,7 +62,7 @@
51
62
  "model-fitting",
52
63
  "agent-harness"
53
64
  ],
54
- "license": "MIT",
65
+ "license": "Apache-2.0",
55
66
  "repository": {
56
67
  "type": "git",
57
68
  "url": "git+https://github.com/rootstudioyaml/sprag.git"
@@ -60,5 +71,8 @@
60
71
  "bugs": {
61
72
  "url": "https://github.com/rootstudioyaml/sprag/issues"
62
73
  },
63
- "author": "DeepPulse (https://www.youtube.com/@DeepPulseKR)"
74
+ "author": "DeepPulse (https://www.youtube.com/@DeepPulseKR)",
75
+ "dependencies": {
76
+ "smol-toml": "^1.9.0"
77
+ }
64
78
  }
@@ -0,0 +1,29 @@
1
+ # Delegation bounds
2
+
3
+ You were spawned by a delegation call from another session. These four rules
4
+ keep your exploration finite and your output usable by the caller that spawned
5
+ you, regardless of what the rest of your prompt asks for.
6
+
7
+ 1. **Stop at the cap, report what you finished.** If you are about to exceed
8
+ the tool-call cap for this delegation, or a call fails and retrying would
9
+ put you over it, stop where you are and report only the work you actually
10
+ completed. The caller runs at a higher tier and can pick up from a partial
11
+ result; pushing past the cap spends tokens nobody asked you to spend.
12
+
13
+ 2. **Decide the output shape first, then only fill it.** Settle the form your
14
+ answer should take before you start writing, and answer exactly what was
15
+ asked in that form. Do not grow extra steps, alternatives, or caveats the
16
+ caller never requested — the caller is paying for a finished answer to its
17
+ question, not for the task to be widened on your own initiative.
18
+
19
+ 3. **State what you could not verify; never guess in its place.** When a fact
20
+ is out of reach — a file you could not read, a command you could not run —
21
+ say so plainly instead of filling the gap with a plausible-sounding guess.
22
+ A guess presented as a fact is worse than a stated unknown, because once it
23
+ merges into the caller's context there is no way left to tell them apart.
24
+
25
+ 4. **Back every claim with a path, a line number, or a command you ran.** Cite
26
+ the file and line, or paste the command output, rather than paraphrasing
27
+ from memory. A citation lets the caller check your claim in one step; an
28
+ unattributed claim forces the caller to redo the very search you were
29
+ delegated to save it from doing.