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.
- package/LICENSE +202 -21
- package/NOTICE +35 -0
- package/README.ko.md +150 -48
- package/README.md +205 -192
- package/bin/cli.js +108 -39
- package/docs/CODEX.ko.md +184 -0
- package/docs/CODEX.md +497 -0
- package/examples/statusline-command.ps1 +11 -5
- package/examples/statusline-command.sh +9 -4
- package/package.json +20 -6
- package/presets/delegation/bounds.md +29 -0
- package/presets/model-rules.json +50 -9
- package/presets/ratchet-rules.json +4 -1
- package/src/agent.js +33 -0
- package/src/caps-cache.js +6 -2
- package/src/changelog.js +70 -0
- package/src/cli-name.js +25 -0
- package/src/codex-brief.js +89 -0
- package/src/codex-budget.js +73 -0
- package/src/codex-cache-policy.js +203 -0
- package/src/codex-cache.js +46 -0
- package/src/codex-delegation.js +154 -0
- package/src/codex-doc2md-ledger.js +45 -0
- package/src/codex-doc2md.js +99 -0
- package/src/codex-doctor.js +53 -0
- package/src/codex-harness.js +200 -0
- package/src/codex-hooks.js +138 -0
- package/src/codex-installer.js +79 -0
- package/src/codex-ledger.js +143 -0
- package/src/codex-panel-launcher.js +48 -0
- package/src/codex-panel-runner.js +74 -0
- package/src/codex-panel-session.js +35 -0
- package/src/codex-panel-setup.js +98 -0
- package/src/codex-panel-shell.js +51 -0
- package/src/codex-panel-state.js +40 -0
- package/src/codex-panel.js +448 -0
- package/src/codex-parser.js +397 -0
- package/src/codex-route-scan.js +171 -0
- package/src/commands/brief.js +24 -1
- package/src/commands/codex-delegate.js +59 -0
- package/src/commands/codex.js +579 -0
- package/src/commands/delegate.js +133 -0
- package/src/commands/harness.js +16 -3
- package/src/commands/install.js +109 -12
- package/src/commands/korean.js +2 -2
- package/src/commands/mode.js +22 -2
- package/src/commands/profile-map.js +164 -0
- package/src/commands/route-scan.js +74 -7
- package/src/commands/seed.js +16 -12
- package/src/commands/uninstall.js +28 -4
- package/src/commands/upgrade.js +13 -0
- package/src/compact-window.js +7 -1
- package/src/config.js +22 -3
- package/src/cost.js +34 -0
- package/src/delegation-guard.js +278 -0
- package/src/doc2md-ledger.cjs +3 -3
- package/src/doc2md.cjs +72 -28
- package/src/effort-palette.js +145 -0
- package/src/formatters/statusline.js +352 -123
- package/src/formatters/table.js +5 -4
- package/src/gateway-auth.js +86 -0
- package/src/glyphs.js +103 -0
- package/src/handoff.js +27 -7
- package/src/harness-analyzer.cjs +7 -2
- package/src/harness-templates.js +33 -1
- package/src/harness.js +51 -17
- package/src/hook-manager.js +42 -14
- package/src/hook.cjs +34 -2
- package/src/installer.js +300 -16
- package/src/litellm-budget.js +38 -67
- package/src/litellm-models.js +264 -0
- package/src/model-alias.js +170 -16
- package/src/model-rules.js +53 -17
- package/src/parser.js +89 -1
- package/src/preset-ratchet.js +133 -0
- package/src/route-inject.js +161 -0
- package/src/route-scan.js +68 -8
- package/src/seed-rules.js +117 -55
- package/src/session-paths.js +242 -0
- package/src/statusline-mode.js +106 -0
- package/src/stdin-payload.js +40 -0
- package/src/ultracode.js +202 -0
- package/src/update-check.js +217 -3
- 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
|
-
#
|
|
3
|
+
# sprag output as a second segment.
|
|
4
4
|
#
|
|
5
5
|
# Install:
|
|
6
|
-
# 1) npm install -g
|
|
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
|
-
|
|
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
|
-
&
|
|
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
|
|
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
|
|
3
|
+
# Prints "user@host:cwd" then appends sprag as a second segment.
|
|
4
4
|
#
|
|
5
5
|
# Install:
|
|
6
|
-
# 1) npm install -g
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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": "
|
|
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.
|