@llblab/pi-codex-usage 0.11.0 → 0.12.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/AGENTS.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # Agent Notes
2
2
 
3
- - `Statusline-first scope`: Keep this extension zero-configuration and focused on compact status surfaces.
4
- - Trigger: Considering commands, menus, persisted settings, or notification output.
5
- - Action: Prefer deleting the surface unless it is required for the optimistic TUI status widget or the optional `pi-telegram` `/start` status-line mirror.
3
+ - `Registry dependency`: Use published `@llblab/pi-command-fast@^0.1.0` with aligned registry lock metadata. Local folder links are only for explicitly requested development tests; rebuild the library's `dist/` after source edits and restore registry dependency/locks before consumer publication.
4
+ - `Pi baseline`: Every declared `@earendil-works/*` peer requires ≥1.0.0. Keep Pi peer lock identities aligned and validate against that host generation.
5
+ - `Domain DAG`: `index.ts` only re-exports the extension and public contracts; `lib/extension.ts` composes the Pi extension. `lib/usage-store.ts` owns persistence/leadership, `lib/query.ts` owns quota I/O, `lib/usage.ts` owns normalized reports, `lib/status.ts` and `lib/status-format.ts` own local UI orchestration and formatting, `lib/telegram.ts` owns optional registration, and `lib/fast.ts` owns Codex Fast semantics/request adaptation. `@llblab/pi-command-fast` owns command arbitration and generic JSONC override editing. Keep dependency direction acyclic; do not import `index.ts` from `lib/` or mix Fast persistence into quota coordination. Place domain tests in `tests/<domain>.test.ts` (or a domain-prefixed focused integration test); use independent names such as `invariants.test.ts` only for cross-domain invariants.
6
+ - `Statusline-first scope`: Own usage state + usage mode: keep quota reporting zero-configuration and the optional Fast toggle focused on the existing terminal status.
7
+ - Trigger: Considering new commands, menus, persisted settings, or notification output.
8
+ - Action: Prefer deleting the surface unless it is required for the optimistic TUI status widget, the optional `pi-telegram` `/start` status-line mirror, or the existing argument-free `/fast` command. Register the `openai-codex` provider handler through `registerFastProvider` on session_start and release on session_shutdown; never register `/fast` directly or filter Fast by model ID/auth. Fast persists solely as `serviceTier: "priority"` in the current model override; OFF deletes only that property. Preserve JSONC/unrelated settings, existing wire tiers, and usage refresh/Telegram. Apply lowercase ` fast` through the final terminal boundary; toggle redraws without quota fetch or success notification. The library owns session WeakMap/reload arbitration, not Fast state. A Fast config read failure must not block usage status.
6
9
  - `Optimistic refresh`: Preserve the last good statusline bar during refresh and transient failures.
7
10
  - Trigger: Updating quota polling or error handling.
8
11
  - Action: Do not collapse the bar while a request is in flight; only show `n/a` or `error` after repeated failures or no usable quota.
@@ -14,4 +17,4 @@
14
17
  - Action: Treat the secondary window as weekly in dual-window responses and the sole window as weekly in single-window responses. Keep `d` labels rounded upward in 144-minute day-tenth steps above 24h, show 24h..1h labels in upward-rounded 6-minute hour-tenth steps, keep `m`/`s` labels floored, and hold `0s` until a successful quota refresh reports the next window.
15
18
  - `Shared refresh`: Instances must not poll independently.
16
19
  - Trigger: Changing refresh cadence, retries, locking, or adding fetch paths.
17
- - Action: Keep the single shared-state protocol in the `Shared Refresh` section of `index.ts` (one shared `~/.pi/agent/tmp/pi-codex-usage/usage.json` for all Codex models; leader refreshes every minute, takeover after 90 seconds by claiming leadership before fetching, a non-waiting OS-backed SQLite mutex around claiming and fenced publication, atomic writes, shared failure backoff). Always re-read the file for request authorization (`owner` + `claimId` + lease) and publication; do not use an in-memory ownership fallback. Lock failures and failed claim writes must deny requests. `mutex.sqlite` stores no quota or leadership data: never unlink/replace it while instances run or evict a paused holder; close or process death releases the mutex. Keep network calls outside critical sections. Instances otherwise only read the file. Ignore additional quota buckets; do not restore model-specific labels, source priority, or cache directories. Keep the coordination behavior in sync with `pi-claude-usage`, which has its own independent state directory.
20
+ - Action: Keep the single shared-state protocol in `lib/usage-store.ts` (one shared `~/.pi/agent/tmp/pi-codex-usage/usage.json` for all Codex models; leader refreshes every minute, takeover after 90 seconds by claiming leadership before fetching, a non-waiting OS-backed SQLite mutex around claiming and fenced publication, atomic writes, shared failure backoff). Always re-read the file for request authorization (`owner` + `claimId` + lease) and publication; do not use an in-memory ownership fallback. Lock failures and failed claim writes must deny requests. `mutex.sqlite` stores no quota or leadership data: never unlink/replace it while instances run or evict a paused holder; close or process death releases the mutex. Keep network calls outside critical sections. Instances otherwise only read the file. Ignore additional quota buckets; do not restore model-specific labels, source priority, or cache directories. Keep the coordination behavior in sync with `pi-claude-usage`, which has its own independent state directory.
package/BACKLOG.md CHANGED
@@ -1,3 +1,4 @@
1
1
  # Backlog
2
2
 
3
- No open items.
3
+ - Operator-owned terminal/optional Telegram visual smoke remains separate from the packed offline Pi SDK smoke. No operator session reload was performed.
4
+ - Further paid live investigation needs fresh authorization: the earlier six-generation sample sent priority but the backend reported `response.service_tier: "default"`. Stored intent/terminal suffix are not service confirmation.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.0: Shared Fast Mode and Pi 1.0 Baseline
4
+
5
+ - Requires Pi ≥1.0.0 across the coding-agent, AI and agent-core peers; previous hosts are outside this release's compatibility contract.
6
+ - Added argument-free, persistent per-model `/fast` for the `openai-codex` provider with no model-ID allowlist or Fast-specific auth gate. `@llblab/pi-command-fast@^0.1.0` coordinates one command alongside Claude Usage across duplicate library copies, separate sessions and reloads; generic JSONC editing moved to that normal library. Enabled stores only `serviceTier: "priority"`; OFF removes the property.
7
+ - Enabled Fast adds `service_tier: "priority"` to eligible Codex requests only when no tier is already present, and appends `fast` to the existing terminal status in the same dim theme color as its reset countdown, with immediate redraw and no success notification. State follows model selection and survives restart; the loading renderer tracks the newly selected model so an old timer cannot restore its previous suffix. Quota coordination and the Telegram status row are unchanged.
8
+ - Split the monolithic entrypoint into an explicit domain DAG under `lib/`. `index.ts` only re-exports the composition root in `lib/extension.ts` and previous public contracts. The quota store, provider transport, normalized report, status lifecycle/format, Telegram adapter, and Fast override have separate owners; tests now live in `tests/` with domain-matched names.
9
+
3
10
  ## 0.11.0: Shared Quota Refresh
4
11
 
5
12
  - Coordinated polling across Pi instances through one `~/.pi/agent/tmp/pi-codex-usage/usage.json`: the leader refreshes every 60 seconds, followers normally read every 30 seconds, and leadership becomes eligible for takeover after 90 seconds without a touch. Failure backoff is shared, the last successful report stays visible for up to an hour, and provisional full-availability confirmation runs only in the refreshing instance.
package/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # pi-codex-usage
2
2
 
3
- > Minimal zero-configuration Pi extension for showing primary ChatGPT Codex usage limits in the statusline
3
+ > Pi extension for ChatGPT Codex usage limits and a local Fast toggle
4
4
 
5
5
  ![Codex Usage](./banner.jpg)
6
6
 
7
+ This extension owns **usage state + usage mode**: zero-configuration quota reporting, plus an optional per-model Fast preference. Shared command arbitration and JSONC editing belong to [`@llblab/pi-command-fast`](https://github.com/llblab/pi-command-fast), a normal dependency, not another Pi extension.
8
+
7
9
  This repository is a minimal fork of [`narumiruna/pi-extensions/extensions/pi-codex-usage`](https://github.com/narumiruna/pi-extensions/tree/main/extensions/pi-codex-usage). It keeps the auth and quota-fetching path, but intentionally narrows the interface to the Codex quota windows returned by OpenAI.
8
10
 
9
11
  ## Start Here
@@ -26,10 +28,12 @@ This repository is a minimal fork of [`narumiruna/pi-extensions/extensions/pi-co
26
28
  - Successful updates briefly redraw the bar only when a 5% segment changes
27
29
  - Network/provider failures keep the last good bar (up to an hour), then show `error`
28
30
  - Any number of Pi instances share one request stream, see [Shared Refresh](#shared-refresh)
29
- - No commands or configuration are required
31
+ - Quota display requires no configuration; `/fast` optionally toggles priority service for the active native Codex model
30
32
 
31
33
  ## Install
32
34
 
35
+ Requires Pi ≥1.0.0 and Node ≥22.19.0. Every declared Pi package peer follows the 1.0.0 minimum.
36
+
33
37
  From npm:
34
38
 
35
39
  ```bash
@@ -42,6 +46,47 @@ From git:
42
46
  pi install git:github.com/llblab/pi-codex-usage
43
47
  ```
44
48
 
49
+ ## Development
50
+
51
+ The shared `@llblab/pi-command-fast@^0.1.0` dependency now resolves from npm; no sibling library checkout is required.
52
+
53
+ ```bash
54
+ npm ci
55
+ npm run validate
56
+ ```
57
+
58
+ For explicitly local library experiments, a temporary folder link reads the library's built `dist/`, not TypeScript source directly. Rebuild after source edits and restore the registry dependency/lock before publishing; see [Backlog](./BACKLOG.md).
59
+
60
+ ## Fast mode
61
+
62
+ `/fast` takes no arguments and dispatches by the current **provider**, not model names or OAuth eligibility. For any `openai-codex` model, it stores only `serviceTier: "priority"` in Pi's canonical `models.json` (honoring `PI_CODING_AGENT_DIR`):
63
+
64
+ ```json
65
+ {
66
+ "providers": {
67
+ "openai-codex": {
68
+ "modelOverrides": {
69
+ "your-current-model": { "serviceTier": "priority" }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ OFF removes only `serviceTier`; it never writes `"default"`. JSONC comments and unrelated configuration survive. There is no separate Fast config or model allowlist. State follows provider/model selection and survives restart; manual edits are read on lifecycle refresh and each request.
77
+
78
+ When this and Claude Usage are loaded, their shared library registers **one** `/fast`, in either load order, even with separate physical dependency copies. A session-scoped WeakMap avoids cross-session dispatch; shutdown releases registrations for reload (Pi retains the session manager). Unrelated providers receive a concise unsupported-provider message. Invalid arguments show `Usage: /fast`; success is silent.
79
+
80
+ Enabled native requests receive `service_tier: "priority"` only when the payload matches the current model and has no existing tier. The existing **terminal** status redraws immediately without fetching quota, for example:
81
+
82
+ ```text
83
+ codex ██████▀▀▀▀ 6d fast
84
+ ```
85
+
86
+ The lowercase ` fast` suffix uses the existing dim/countdown theme role and is applied at the final terminal boundary, including loading, percentages/credits, `n/a`, and errors. Telegram values and quota polling/auth/leadership are unchanged.
87
+
88
+ Pi 1.0.0 accepts the extra override but does not propagate it to native request options, so a small `before_provider_request` adapter remains necessary; no replacement provider or transport is registered. Its public command API cannot hide/unregister commands by current model, so `/fast` stays listed and checks the provider at invocation. Backend capability and actual priority service are not guaranteed by a stored preference or suffix: an earlier authorized sample sent `priority` but received `default`. Priority service may have different provider pricing.
89
+
45
90
  ## Statusline
46
91
 
47
92
  Regular Codex usage:
@@ -90,7 +135,7 @@ codex error
90
135
 
91
136
  ## Shared Refresh
92
137
 
93
- The coordination code lives in the `Shared Refresh` section of [`index.ts`](./index.ts); the extension ships as a single TypeScript source file.
138
+ [`index.ts`](./index.ts) is a re-export-only Pi entrypoint; [`lib/extension.ts`](./lib/extension.ts) composes the live extension. [`lib/usage-store.ts`](./lib/usage-store.ts) owns cross-instance quota coordination, [`lib/query.ts`](./lib/query.ts) owns provider requests, [`lib/usage.ts`](./lib/usage.ts) owns quota normalization, [`lib/status.ts`](./lib/status.ts) and [`lib/status-format.ts`](./lib/status-format.ts) own lifecycle and terminal display, [`lib/telegram.ts`](./lib/telegram.ts) adapts the optional Telegram row, and [`lib/fast.ts`](./lib/fast.ts) owns Codex Fast semantics and the native payload bridge; the shared library owns JSONC and command arbitration. Domain tests live under [`tests/`](./tests/) with matching names; integration tests name the domain whose boundary they exercise.
94
139
 
95
140
  All Codex models and instances coordinate through `~/.pi/agent/tmp/pi-codex-usage/usage.json` (quota percentages and timestamps only, no tokens). The Claude extension uses its own independent file at `~/.pi/agent/tmp/pi-claude-usage/usage.json`.
96
141