@llblab/pi-kit 0.24.0 → 0.25.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 (112) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +6 -5
  4. package/node_modules/@llblab/pi-claude-usage/AGENTS.md +20 -0
  5. package/node_modules/@llblab/pi-claude-usage/BACKLOG.md +3 -0
  6. package/node_modules/@llblab/pi-claude-usage/CHANGELOG.md +13 -0
  7. package/node_modules/@llblab/pi-claude-usage/LICENSE +22 -0
  8. package/node_modules/@llblab/pi-claude-usage/README.md +110 -0
  9. package/node_modules/@llblab/pi-claude-usage/banner.jpg +0 -0
  10. package/node_modules/@llblab/pi-claude-usage/index.ts +1159 -0
  11. package/node_modules/@llblab/pi-claude-usage/package.json +60 -0
  12. package/node_modules/@llblab/pi-state-flow/AGENTS.md +42 -56
  13. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +16 -3
  14. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +19 -0
  15. package/node_modules/@llblab/pi-state-flow/README.md +15 -12
  16. package/node_modules/@llblab/pi-state-flow/dist/index.d.ts +2 -2
  17. package/node_modules/@llblab/pi-state-flow/dist/index.js +2 -2
  18. package/node_modules/@llblab/pi-state-flow/dist/lib/config.d.ts +7 -3
  19. package/node_modules/@llblab/pi-state-flow/dist/lib/config.js +16 -7
  20. package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +9 -9
  21. package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +5 -4
  22. package/node_modules/@llblab/pi-state-flow/dist/lib/continuation.js +2 -2
  23. package/node_modules/@llblab/pi-state-flow/dist/lib/durable.d.ts +1 -1
  24. package/node_modules/@llblab/pi-state-flow/dist/lib/durable.js +7 -4
  25. package/node_modules/@llblab/pi-state-flow/dist/lib/episode.d.ts +3 -3
  26. package/node_modules/@llblab/pi-state-flow/dist/lib/episode.js +5 -5
  27. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.d.ts +3 -5
  28. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +275 -199
  29. package/node_modules/@llblab/pi-state-flow/dist/lib/history.d.ts +11 -4
  30. package/node_modules/@llblab/pi-state-flow/dist/lib/history.js +6 -7
  31. package/node_modules/@llblab/pi-state-flow/dist/lib/logging.d.ts +4 -1
  32. package/node_modules/@llblab/pi-state-flow/dist/lib/logging.js +1 -0
  33. package/node_modules/@llblab/pi-state-flow/dist/lib/query.d.ts +4 -5
  34. package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +13 -13
  35. package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +7 -6
  36. package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.js +9 -9
  37. package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +3 -2
  38. package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +17 -12
  39. package/node_modules/@llblab/pi-state-flow/dist/lib/session.d.ts +4 -1
  40. package/node_modules/@llblab/pi-state-flow/dist/lib/session.js +2 -1
  41. package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +17 -8
  42. package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +49 -20
  43. package/node_modules/@llblab/pi-state-flow/dist/lib/state.d.ts +22 -3
  44. package/node_modules/@llblab/pi-state-flow/dist/lib/state.js +30 -10
  45. package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +5 -3
  46. package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +19 -28
  47. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +17 -15
  48. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +52 -52
  49. package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +8 -4
  50. package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +34 -18
  51. package/node_modules/@llblab/pi-state-flow/dist/lib/transition.d.ts +5 -5
  52. package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +13 -19
  53. package/node_modules/@llblab/pi-state-flow/dist/package.json +3 -3
  54. package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +2 -2
  55. package/node_modules/@llblab/pi-state-flow/docs/README.md +2 -1
  56. package/node_modules/@llblab/pi-state-flow/docs/agent-contract-relocation.md +72 -0
  57. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +36 -32
  58. package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +12 -4
  59. package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +5 -5
  60. package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +6 -6
  61. package/node_modules/@llblab/pi-state-flow/docs/performance.md +1 -1
  62. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +13 -12
  63. package/node_modules/@llblab/pi-state-flow/docs/usage.md +32 -29
  64. package/node_modules/@llblab/pi-state-flow/index.ts +3 -2
  65. package/node_modules/@llblab/pi-state-flow/lib/config.ts +20 -10
  66. package/node_modules/@llblab/pi-state-flow/lib/context.ts +15 -14
  67. package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +1 -1
  68. package/node_modules/@llblab/pi-state-flow/lib/durable.ts +8 -6
  69. package/node_modules/@llblab/pi-state-flow/lib/episode.ts +6 -6
  70. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +274 -197
  71. package/node_modules/@llblab/pi-state-flow/lib/history.ts +16 -11
  72. package/node_modules/@llblab/pi-state-flow/lib/logging.ts +5 -1
  73. package/node_modules/@llblab/pi-state-flow/lib/query.ts +16 -16
  74. package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +11 -11
  75. package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +19 -13
  76. package/node_modules/@llblab/pi-state-flow/lib/session.ts +6 -3
  77. package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +55 -22
  78. package/node_modules/@llblab/pi-state-flow/lib/state.ts +46 -13
  79. package/node_modules/@llblab/pi-state-flow/lib/status.ts +23 -32
  80. package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +66 -65
  81. package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +39 -19
  82. package/node_modules/@llblab/pi-state-flow/lib/transition.ts +19 -27
  83. package/node_modules/@llblab/pi-state-flow/package.json +3 -3
  84. package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +2 -2
  85. package/node_modules/@llblab/pi-telegram/AGENTS.md +1 -1
  86. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +5 -0
  87. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +2 -0
  88. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +55 -2
  89. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +21 -0
  90. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +144 -1
  91. package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +9 -0
  92. package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +19 -0
  93. package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +13 -0
  94. package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +29 -6
  95. package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +16 -0
  96. package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +5 -1
  97. package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +6 -2
  98. package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +7 -0
  99. package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +13 -5
  100. package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
  101. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +2 -2
  102. package/node_modules/@llblab/pi-telegram/docs/public-api.md +1 -1
  103. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +79 -1
  104. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +197 -0
  105. package/node_modules/@llblab/pi-telegram/lib/bus.ts +33 -0
  106. package/node_modules/@llblab/pi-telegram/lib/commands.ts +38 -6
  107. package/node_modules/@llblab/pi-telegram/lib/extension.ts +15 -0
  108. package/node_modules/@llblab/pi-telegram/lib/locks.ts +6 -1
  109. package/node_modules/@llblab/pi-telegram/lib/polling.ts +10 -2
  110. package/node_modules/@llblab/pi-telegram/lib/threads.ts +19 -5
  111. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  112. package/package.json +7 -3
package/AGENTS.md CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  - Start work from `BACKLOG.md` and inspect the included package manifests before changing pins or resource paths.
22
22
  - Keep `dependencies`, `bundledDependencies`, Pi resource paths, README inventory, tests, and lockfile synchronized.
23
- - Bundle every included Pi package so npm installation is self-contained under this package's module root.
23
+ - Bundle every included Pi package so npm installation is self-contained under this package's module root. Keep repository-local `legacy-peer-deps=true` so host-provided Pi peers are not resolved into the kit's lockfile; Pi supplies them at runtime.
24
24
  - Expose only resources declared by each included package. Prefer published distribution entrypoints over source entrypoints when both exist.
25
25
  - Do not copy extension source, Skills, or documentation into this repository.
26
26
  - Preserve package independence: a kit release may advance any subset of included extensions without forcing lockstep extension releases.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to `@llblab/pi-kit` are documented here.
4
4
 
5
+ ## 0.25.0 - 2026-10-02
6
+
7
+ - `State Flow Modes`: Advances the exact State Flow pin from `0.21.0` to `0.23.0`. Adds sparse-state handling and session-owned modes; new sessions now default to Off while retained choices and explicit global policy survive. Telegram adds mode radios and scope explanations, with opt-in barrier diagnostics. No State Flow memory is erased by switching modes.
8
+ - `Claude Subscription Usage`: Adds the independently released `@llblab/pi-claude-usage@0.1.1` as an eighth bundled member and seventh extension entrypoint. It shows Claude Pro/Max quota windows using Pi Anthropic OAuth, with shared cross-instance refresh and optional Telegram status. Existing Codex Usage stays at `0.10.0`.
9
+ - `Host Peer Isolation`: Repository-local npm peer settings keep Pi-provided packages out of the kit lockfile and validation audit; Pi continues to supply them at runtime. The six unchanged member pins, existing resource order, Skill ownership and Pi minimum remain unchanged; the new Claude entrypoint is inserted explicitly.
10
+
11
+ ## 0.24.1 - 2026-09-26
12
+
13
+ - `Follower Thread Hotfix`: Advances the exact Telegram pin to `0.51.5`. Telegram `/new` in a follower Thread now replaces that follower's session while the leader durably authorizes the Thread binding handoff; automatic follower restore reports why it could not reconnect. Package membership, load order, and other pins remain unchanged.
14
+
5
15
  ## 0.24.0 - 2026-09-25
6
16
 
7
17
  - `Minimal State Flow Reconciliation`: Advances the exact State Flow pin to `0.21.0`. Frozen context heads retain cache-stable prefixes while predictable accepted writes omit redundant semantic tails. Shared drift, changed hints and unknown fallback still reconcile; lazy bodies and provenance remain hidden. Artifact prediction cannot reject an already accepted patch. Canonical storage, other package pins, resources and load order are unchanged.
package/README.md CHANGED
@@ -13,18 +13,19 @@ Package links lead to the owning repositories for usage, documentation, issues,
13
13
  | Package | Version | Purpose |
14
14
  | --- | ---: | --- |
15
15
  | [`@llblab/pi-actors`](https://github.com/llblab/pi-actors) | `0.53.2` | Inspectable local Runs, reusable Recipes, persistent tools, and delegation Skills |
16
+ | [`@llblab/pi-claude-usage`](https://github.com/llblab/pi-claude-usage) | `0.1.1` | Claude Pro/Max subscription quota status using Pi's Anthropic OAuth login |
16
17
  | [`@llblab/pi-clean-room`](https://github.com/llblab/pi-clean-room) | `0.2.0` | Isolated nested Pi TUI with named npm extensions and compatible model selection |
17
18
  | [`@llblab/pi-codex-usage`](https://github.com/llblab/pi-codex-usage) | `0.10.0` | Compact Codex/Spark subscription-limit and Business credit-usage status |
18
19
  | [`@llblab/pi-grow-loop`](https://github.com/llblab/pi-grow-loop) | `0.8.2` | Visible continuation scheduling and bounded worker Skills through compiled, manifest-owned resources |
19
- | [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.21.0` | Incremental scoped context/memory compiler with cache-stable heads, sparse acceptance reconciliation, lazy isolation, private fork memory, and optional Git backup |
20
- | [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.51.4` | Telegram companion with resolver-owned filterable Skills, compiled distribution, self-healing follower registration, in-flight model switching, files, voice, and controls |
20
+ | [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.23.0` | Scoped context/memory compiler; new sessions default to Off with opt-in Passive/Active and Telegram mode controls |
21
+ | [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.51.5` | Telegram companion with follower Thread `/new`, restore diagnostics, filterable Skills, files, voice, and controls |
21
22
  | [`@llblab/skills`](https://github.com/llblab/skills) | `1.15.0` | Portable workflows for engineering, review, design, context maintenance, and other focused tasks |
22
23
 
23
24
  Versions are exact by design. An upstream release does not change an installed kit until this repository explicitly advances the dependency and publishes a new kit version. Runtime defects and package-specific feature requests belong in the linked repository; package selection and kit installation issues belong here.
24
25
 
25
26
  ## Install
26
27
 
27
- Requires **Pi 0.87.0+** and **Node.js 22.19.0+**. State Flow requires its canonical checkpoint/tail storage format and does not convert unsupported stores in place. Preserve existing stores and consult the [owning package's storage guidance](https://github.com/llblab/pi-state-flow/blob/v0.19.0/docs/usage.md#moving-a-store-and-the-017-format-boundary) before changing installations.
28
+ Requires **Pi 0.87.0+** and **Node.js 22.19.0+**. State Flow requires its canonical checkpoint/tail storage format and does not convert unsupported stores in place. Preserve existing stores and consult the [owning package's storage guidance](https://github.com/llblab/pi-state-flow/blob/v0.23.0/docs/usage.md#moving-a-store-and-the-017-format-boundary) before changing installations.
28
29
 
29
30
  From npm:
30
31
 
@@ -38,7 +39,7 @@ From GitHub:
38
39
  pi install git:github.com/llblab/pi-kit
39
40
  ```
40
41
 
41
- Pi loads the six extension entrypoints and the Skill resources explicitly declared by the kit. The kit adds no runtime behavior and does not copy the packages' source or instructions into a new owner. State Flow remains opt-in; bundling it does not enable its state handoff mode.
42
+ Pi loads the seven extension entrypoints and the Skill resources explicitly declared by the kit. The kit adds no runtime behavior and does not copy the packages' source or instructions into a new owner. State Flow remains opt-in; bundling it does not enable its state handoff mode.
42
43
 
43
44
  Prefer the kit instead of separately loading the same packages. If you already use individual installations or local Skill copies, use `pi config` to disable duplicate resources. Installing the kit does not remove or rewrite those installations.
44
45
 
@@ -49,7 +50,7 @@ npm install
49
50
  npm run validate
50
51
  ```
51
52
 
52
- To advance an included package, update its exact version in `dependencies`, run `npm install`, synchronize bundled dependencies, declared resource paths, tests, the table above, and the changelog, then validate the packed artifact. Expose only resources declared by the published owning package; do not use version ranges or unpublished local paths.
53
+ The repository-local `.npmrc` keeps Pi-provided peer packages out of the kit's lockfile; Pi supplies those peers at runtime. To advance an included package, update its exact version in `dependencies`, run `npm install`, synchronize bundled dependencies, declared resource paths, tests, the table above, and the changelog, then validate the packed artifact. Expose only resources declared by the published owning package; do not use version ranges or unpublished local paths.
53
54
 
54
55
  ## Security
55
56
 
@@ -0,0 +1,20 @@
1
+ # Agent Notes
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.
6
+ - `Optimistic refresh`: Preserve the last good statusline bar during refresh and transient failures.
7
+ - Trigger: Updating quota polling or error handling.
8
+ - 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.
9
+ - `Adaptive compact status`: Match the status representation to the server-provided quota windows.
10
+ - Trigger: Changing statusline formatting.
11
+ - Action: When both windows exist, keep the classic dual bar with 20 top steps for the 5-hour window and 20 bottom steps for the weekly window. When only one weekly window exists, show its rounded remaining percentage directly instead of using a bar.
12
+ - `Weekly reset countdown`: Append the weekly reset countdown whenever the available weekly window exposes a reset time.
13
+ - Trigger: Changing reset-time normalization or statusline refresh cadence.
14
+ - Action: Map `five_hour` to the primary window and `seven_day` to the secondary (weekly) window; treat a sole window as weekly. 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
+ - `Pi auth only`: Usage is read from `https://api.anthropic.com/api/oauth/usage` with the Pi `anthropic` provider OAuth token (`sk-ant-oat…`) and the `anthropic-beta: oauth-2025-04-20` header.
16
+ - Trigger: Touching auth or adding usage sources.
17
+ - Action: Do not add fallbacks, CLI probes, or API-key paths; API keys have no subscription quota, so report `n/a`. `utilization` is a used percent.
18
+ - `Rate-limit discipline`: Quota polling must be shared across instances; HTTP 429 triggers shared backoff.
19
+ - Trigger: Changing refresh cadence, retries, locking, or adding fetch paths.
20
+ - Action: Keep the single shared-state protocol in the `Shared Refresh` section of `index.ts` (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; never add per-instance polling or probing requests.
@@ -0,0 +1,3 @@
1
+ # Backlog
2
+
3
+ No open implementation items.
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ ## 0.1.1: Trusted CI Publication
4
+
5
+ - Releases use the configured npm Trusted Publisher for GitHub Actions, with provenance and workflow-owned GitHub Release creation. Public-package verification now allows approximately 30 minutes for npm processing, with a 35-minute step limit, while retaining exact commit and package-inventory checks.
6
+ - Quota polling, OAuth authentication, shared-state coordination, and statusline behavior are unchanged from 0.1.0.
7
+
8
+ ## 0.1.0: Claude Subscription Usage
9
+
10
+ - Initial standalone release, adapted from [pi-codex-usage](https://github.com/llblab/pi-codex-usage), for Claude Pro/Max subscriptions. Reads the 5-hour and 7-day quota windows using Pi's Anthropic OAuth login; API-key-only auth reports `n/a`.
11
+ - Shows remaining quota in a compact dual bar, with reset countdowns, animated loading, exhausted-quota highlighting, and optimistic display during refreshes or transient failures. A single available window uses a remaining percentage. Optionally mirrors the same value in the `pi-telegram` status menu.
12
+ - Coordinates all local Pi instances through one shared `usage.json`: the leader refreshes every minute, followers normally read every 30 seconds, and takeover becomes eligible after 90 seconds. Shared failure backoff, including HTTP 429, prevents independent polling.
13
+ - Uses an OS-backed SQLite mutex, atomic JSON writes, and on-disk claim generation/lease checks to deny requests when coordination fails and discard superseded results. Requires Node ≥22.19.0 and a local filesystem. **Upgrade from development versions:** close all old Pi sessions before starting this version; never delete or replace `mutex.sqlite` while sessions run.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 narumiruna
4
+ Copyright (c) 2026 llblab
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,110 @@
1
+ # pi-claude-usage
2
+
3
+ > Minimal zero-configuration Pi extension for showing Anthropic Claude subscription usage limits in the statusline
4
+
5
+ ![Claude Usage](./banner.jpg)
6
+
7
+ This repository is an adaptation of [`pi-codex-usage`](https://github.com/llblab/pi-codex-usage) for Anthropic Claude Pro/Max subscriptions. It keeps the statusline design, but reads quota from the Anthropic OAuth usage endpoint using Pi's own Anthropic login.
8
+
9
+ ## Start Here
10
+
11
+ - [Agent Notes](./AGENTS.md)
12
+ - [Backlog](./BACKLOG.md)
13
+ - [Changelog](./CHANGELOG.md)
14
+
15
+ ## Features
16
+
17
+ - Shows two counter-moving half-height markers in the statusline bar while quota is loading, then keeps the bar fresh (the countdown ticks locally)
18
+ - Keeps the last usable bar visible during ordinary refreshes instead of replacing known quota with a loading state
19
+ - Dual bar: the top half shows the 5-hour session window and the bottom half shows the 7-day window, 20 steps (5% each) per window
20
+ - If only one window is returned, shows its remaining percentage and reset countdown instead of a bar
21
+ - Shown only while the active model uses the Pi `anthropic` provider
22
+ - When `pi-telegram` is available, the same compact value appears as `claude: <value>` in the `/start` menu status text
23
+ - Missing OAuth auth, API-key-only auth, or missing quota windows are shown as `n/a`, not as an error
24
+ - Network/provider failures keep the last good bar, then show `error` after repeated failures
25
+ - Any number of Pi instances share one request stream, see [Shared Refresh](#shared-refresh)
26
+ - No commands or configuration are required
27
+
28
+ ## Install
29
+
30
+ From npm:
31
+
32
+ ```bash
33
+ pi install npm:@llblab/pi-claude-usage
34
+ ```
35
+
36
+ From git:
37
+
38
+ ```bash
39
+ pi install git:github.com/llblab/pi-claude-usage
40
+ ```
41
+
42
+ ## Statusline
43
+
44
+ ```text
45
+ claude ██████▀▀▀▀ 6d
46
+ ```
47
+
48
+ The ten-character bar encodes two twenty-step limits at once: the top quadrants show the remaining 5-hour limit and the bottom quadrants show the remaining weekly limit. If either window is exhausted, the bar keeps its shape but switches to the error background color.
49
+
50
+ When the weekly reset time is available, it follows the bar. More than a day remains is shown in 144-minute day-tenth steps such as `7d`, `6.9d`, `1.1d`, rounded upward. At 24 hours and below it switches to upward-rounded hour-tenths such as `24h`, `23.7h`, `1.1h`, `1h`. Under an hour it shows floored minutes, then seconds. After the reset passes, `0s` is held until the next successful refresh.
51
+
52
+ When the 5-hour window is exhausted and exposes its reset time, the statusline adds it before the weekly reset:
53
+
54
+ ```text
55
+ claude ▄▄▄▄▄⠀⠀⠀⠀⠀ 5h/7d
56
+ ```
57
+
58
+ If only one window is returned, the exact remaining percentage is shown:
59
+
60
+ ```text
61
+ claude 67% 7d
62
+ ```
63
+
64
+ Unavailable (no Anthropic subscription auth):
65
+
66
+ ```text
67
+ claude n/a
68
+ ```
69
+
70
+ Runtime failure, such as a network or provider error (including rate limiting of the usage endpoint):
71
+
72
+ ```text
73
+ claude error
74
+ ```
75
+
76
+ ## Shared Refresh
77
+
78
+ The coordination code lives in the `Shared Refresh` section of [`index.ts`](./index.ts); the extension ships as a single TypeScript source file.
79
+
80
+ To avoid independent polling, instances coordinate through `~/.pi/agent/tmp/pi-claude-usage/usage.json` (percentages and timestamps only, no tokens):
81
+
82
+ - The instance that last updated the file is the leader and refreshes it every minute
83
+ - Every other instance only reads the file (re-checking every ≤30s) and redraws when it changes
84
+ - Leadership is never cached in memory: before each usage request, the instance re-reads the file and checks its `owner`, unique `claimId`, and 90s lease. Publication rechecks that claim under the lock; a superseded success or failure is discarded. Failed locks or unwritten claims never authorize a request
85
+ - If the file is 90 seconds old (leader is closed, busy, or asleep), the first follower that obtains the mutex takes over: it re-reads the JSON, writes itself as the leader with a fresh timestamp, releases the mutex, then fetches from the server and publishes under the mutex after rechecking its claim. Its next refresh is one minute later; JSON writes remain atomic renames
86
+ - Claiming and publication use a non-waiting transaction in `mutex.sqlite`, through Node's built-in `node:sqlite` (Node ≥22.19.0, the existing package minimum). It stores no quota or leadership records and needs no extra package or service. The OS releases the lock when the connection closes or the process dies; there is no timeout-based lock stealing
87
+ - Failures are written to the file with an exponential backoff (1 to 5 minutes; 5 to 30 minutes for HTTP 429) that applies to all instances
88
+ - The last report stays visible for up to an hour; after that `error` is shown
89
+
90
+ Coordination assumes a local filesystem and cooperating instances on the same machine. Never delete or replace `mutex.sqlite` while instances are running. Network requests do not hold the mutex; a process paused inside a short critical section keeps it until it resumes or exits, so other writers retry later without blocking the TUI. This preserves exclusion instead of stealing a live lock.
91
+
92
+ **Upgrade:** Close all old instances before starting updated ones. The legacy `lock` files are ignored; old and new locking protocols must not run together. Cached `usage.json` data needs no migration.
93
+
94
+ ## Telegram Status Menu
95
+
96
+ If `@llblab/pi-telegram` is loaded with the public status-line provider API, this extension registers an optional `/start` menu status row while the active model uses the Anthropic provider:
97
+
98
+ ```text
99
+ claude: ██████▀▀▀▀ 6d
100
+ ```
101
+
102
+ If `pi-telegram` is absent or older, or the active model is not Anthropic, no Telegram row is added.
103
+
104
+ ## Auth
105
+
106
+ The extension uses the OAuth token of Pi's `anthropic` provider (`/login` → Anthropic Claude Pro/Max) and calls `GET https://api.anthropic.com/api/oauth/usage` with the `anthropic-beta: oauth-2025-04-20` header. Pi refreshes the token as needed. Anthropic API keys are not subscription auth and do not expose these quotas.
107
+
108
+ ## License
109
+
110
+ MIT. See [`LICENSE`](./LICENSE).