@victor-software-house/pi-multicodex 2.0.0 → 2.0.2
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/README.md
CHANGED
|
@@ -1,233 +1,120 @@
|
|
|
1
1
|
# @victor-software-house/pi-multicodex
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
MultiCodex is a [pi](https://github.com/badlogic/pi-mono) extension that manages multiple ChatGPT Codex accounts and rotates between them automatically when you hit quota limits.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
You add your Codex accounts once. After that, MultiCodex transparently picks the account with the most remaining quota for every request. When one account runs dry mid-session, it switches to another and retries — no manual intervention needed.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- auto-imports pi's stored `openai-codex` auth when it is new or changed
|
|
11
|
-
- rotates accounts on quota and rate-limit failures
|
|
12
|
-
- prefers untouched accounts when usage data is available
|
|
13
|
-
- otherwise prefers the account whose weekly window resets first
|
|
14
|
-
- keeps the implementation focused on Codex account rotation
|
|
9
|
+
## Getting started
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
Install from npm:
|
|
17
12
|
|
|
18
13
|
```bash
|
|
19
14
|
pi install npm:@victor-software-house/pi-multicodex
|
|
20
15
|
```
|
|
21
16
|
|
|
22
|
-
Restart
|
|
17
|
+
Restart pi. That is all you need — MultiCodex takes over the normal `openai-codex` provider path and auto-imports any Codex auth you have already set up in pi.
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
This repo uses `mise` to pin tools and `pnpm` for dependency management.
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
mise install
|
|
30
|
-
pnpm install
|
|
31
|
-
pnpm check
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Equivalent mise tasks:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
mise run install
|
|
38
|
-
mise run check
|
|
39
|
-
mise run pack-dry
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Run the extension directly during local development:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
pi -e ./index.ts
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Command family
|
|
49
|
-
|
|
50
|
-
The extension now uses one command family:
|
|
51
|
-
|
|
52
|
-
- `/multicodex`
|
|
53
|
-
- open the main interactive UI
|
|
54
|
-
- `/multicodex show`
|
|
55
|
-
- show managed account status and cached usage
|
|
56
|
-
- `/multicodex use [identifier]`
|
|
57
|
-
- with an identifier, activate existing auth or trigger login
|
|
58
|
-
- with no identifier, open the account picker
|
|
59
|
-
- in the picker, `Backspace` removes the highlighted account after confirmation
|
|
60
|
-
- `/multicodex footer`
|
|
61
|
-
- open footer settings in interactive mode
|
|
62
|
-
- show footer settings summary in non-interactive mode
|
|
63
|
-
- `/multicodex rotation`
|
|
64
|
-
- show current hard-coded rotation policy
|
|
65
|
-
- `/multicodex verify`
|
|
66
|
-
- verify writable local paths and report runtime summary
|
|
67
|
-
- `/multicodex path`
|
|
68
|
-
- show storage and settings file paths
|
|
69
|
-
- `/multicodex reset [manual|quota|all]`
|
|
70
|
-
- reset manual override state, quota cooldown state, or both
|
|
71
|
-
- `/multicodex help`
|
|
72
|
-
- print compact usage text
|
|
19
|
+
To manage your accounts inside a session, type `/multicodex`.
|
|
73
20
|
|
|
74
|
-
|
|
21
|
+
## How it works
|
|
75
22
|
|
|
76
|
-
|
|
23
|
+
When you start a session, MultiCodex:
|
|
77
24
|
|
|
78
|
-
|
|
25
|
+
1. Imports your existing pi Codex auth automatically (if present).
|
|
26
|
+
2. Checks usage data across all managed accounts.
|
|
27
|
+
3. Picks the account with the most headroom — preferring untouched accounts first, then the one whose weekly reset window ends soonest.
|
|
79
28
|
|
|
80
|
-
|
|
81
|
-
- overrides the normal `openai-codex` provider path
|
|
82
|
-
- mirrors Codex models and installs the managed stream wrapper
|
|
83
|
-
- `stream-wrapper.ts`
|
|
84
|
-
- account selection, retry, and quota-rotation path during streaming
|
|
85
|
-
- `account-manager.ts`
|
|
86
|
-
- managed account storage, token refresh, usage cache, activation logic, and auth import sync
|
|
87
|
-
- `auth.ts`
|
|
88
|
-
- reads pi's `~/.pi/agent/auth.json` and extracts importable `openai-codex` OAuth state
|
|
89
|
-
- `status.ts`
|
|
90
|
-
- footer rendering, footer settings persistence, footer settings panel, and footer status refresh logic
|
|
91
|
-
- `commands.ts`
|
|
92
|
-
- `/multicodex` command-family routing, autocomplete, and account-selection flows
|
|
93
|
-
- `hooks.ts`
|
|
94
|
-
- session-start and session-switch refresh behavior
|
|
95
|
-
- `storage.ts`
|
|
96
|
-
- persisted account state in `~/.pi/agent/codex-accounts.json`
|
|
29
|
+
When a request hits a quota or rate limit **before** any output is streamed, MultiCodex marks that account exhausted, picks the next available one, and retries the request. This happens up to 5 times transparently. Once output has started streaming, the error is surfaced as-is.
|
|
97
30
|
|
|
98
|
-
##
|
|
31
|
+
## Commands
|
|
99
32
|
|
|
100
|
-
|
|
33
|
+
Everything lives under one command: `/multicodex`.
|
|
101
34
|
|
|
102
|
-
|
|
35
|
+
| Command | What it does |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `/multicodex` | Open the main interactive menu |
|
|
38
|
+
| `/multicodex show` | Print account status and cached usage |
|
|
39
|
+
| `/multicodex use [identifier]` | Activate an account, or open the picker if no identifier given |
|
|
40
|
+
| `/multicodex footer` | Configure the usage footer display |
|
|
41
|
+
| `/multicodex rotation` | Show the current rotation policy |
|
|
42
|
+
| `/multicodex verify` | Check that local storage paths are writable |
|
|
43
|
+
| `/multicodex path` | Print storage and settings file locations |
|
|
44
|
+
| `/multicodex reset [manual\|quota\|all]` | Clear manual override, quota cooldowns, or both |
|
|
45
|
+
| `/multicodex help` | Print a compact usage line |
|
|
103
46
|
|
|
104
|
-
|
|
105
|
-
- Codex-only scope
|
|
106
|
-
- local account state stored at `~/.pi/agent/codex-accounts.json`
|
|
107
|
-
- footer and future extension settings stored under `pi-multicodex` in `~/.pi/agent/settings.json`
|
|
108
|
-
- internal logic split into focused modules today, with a broader shared controller planned next
|
|
109
|
-
- current roadmap tracked in `ROADMAP.md`
|
|
47
|
+
All subcommands support dynamic autocomplete. `/multicodex use` also autocompletes from your managed account list.
|
|
110
48
|
|
|
111
|
-
|
|
49
|
+
Commands that do not need a UI panel (`show`, `verify`, `path`, `reset`, `help`) work in non-interactive mode too.
|
|
112
50
|
|
|
113
|
-
|
|
114
|
-
2. Add configurable rotation settings and document the rotation behavior contract.
|
|
115
|
-
3. Broaden the current footer controller into a shared MultiCodex controller.
|
|
116
|
-
4. Improve imported-account labels by deriving email identity safely when possible.
|
|
51
|
+
## Account picker
|
|
117
52
|
|
|
118
|
-
|
|
53
|
+
The `/multicodex use` picker lets you select, add, and remove accounts in one place.
|
|
119
54
|
|
|
120
|
-
|
|
55
|
+

|
|
121
56
|
|
|
122
|
-
|
|
57
|
+
- **Enter** activates the highlighted account.
|
|
58
|
+
- **Backspace** removes it (after confirmation).
|
|
123
59
|
|
|
124
|
-
|
|
125
|
-
2. Otherwise clear the stale manual override and select the best available managed account.
|
|
126
|
-
3. Best-account selection prefers:
|
|
127
|
-
- untouched accounts with usage data
|
|
128
|
-
- then the account whose weekly reset window ends first
|
|
129
|
-
- then a random available account as fallback
|
|
60
|
+
When you remove an active account, MultiCodex switches to the next available one automatically.
|
|
130
61
|
|
|
131
|
-
|
|
62
|
+

|
|
132
63
|
|
|
133
|
-
|
|
134
|
-
- When a request fails before any output is streamed, MultiCodex marks that account exhausted and retries on another account.
|
|
135
|
-
- Exhaustion lasts until the next known reset time.
|
|
136
|
-
- If usage data does not provide a reset time, exhaustion falls back to a 1 hour cooldown.
|
|
64
|
+
## Usage footer
|
|
137
65
|
|
|
138
|
-
|
|
66
|
+
MultiCodex adds a live footer to your session showing the active account, 5-hour and 7-day usage percentages, and reset countdowns. The footer updates after every turn and on account switches.
|
|
139
67
|
|
|
140
|
-
|
|
141
|
-
- Retries only happen for quota and rate-limit style failures that occur before output is forwarded.
|
|
142
|
-
- Once output has started streaming, the original error is surfaced instead of rotating.
|
|
68
|
+
You can customize which fields appear and their ordering with `/multicodex footer`.
|
|
143
69
|
|
|
144
|
-
|
|
70
|
+
## What it does under the hood
|
|
145
71
|
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
|
|
151
|
-
### Usage cache and refresh rules
|
|
152
|
-
|
|
153
|
-
- Usage is cached in memory for 5 minutes per account.
|
|
154
|
-
- Footer updates render cached usage immediately and refresh in the background when needed.
|
|
155
|
-
- Rapid `model_select` changes debounce background refresh work so non-Codex model switching clears the footer immediately.
|
|
156
|
-
|
|
157
|
-
### Error classification
|
|
72
|
+
- **Provider override.** MultiCodex registers itself as the `openai-codex` provider. You do not need to select a different provider or change your model — it works with whatever Codex model you already use.
|
|
73
|
+
- **Auth import.** When pi has stored Codex OAuth credentials, MultiCodex imports them automatically. You can also add accounts manually with `/multicodex use <email>`.
|
|
74
|
+
- **Token refresh.** OAuth tokens are refreshed before expiry so requests do not fail due to stale credentials.
|
|
75
|
+
- **Usage tracking.** Usage data is fetched from the Codex API and cached for 5 minutes per account. The footer renders cached data immediately and refreshes in the background.
|
|
76
|
+
- **Quota cooldown.** When an account is exhausted, it stays on cooldown until its next known reset time (or 1 hour if the reset time is unknown).
|
|
158
77
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
- HTTP `429`
|
|
162
|
-
- `quota`
|
|
163
|
-
- `usage limit`
|
|
164
|
-
- `rate limit`
|
|
165
|
-
- `too many requests`
|
|
166
|
-
- `limit reached`
|
|
167
|
-
|
|
168
|
-
## Release validation
|
|
78
|
+
## Local development
|
|
169
79
|
|
|
170
|
-
|
|
80
|
+
This repo uses `mise` for tool versions and `pnpm` for dependency management.
|
|
171
81
|
|
|
172
82
|
```bash
|
|
173
|
-
|
|
174
|
-
|
|
83
|
+
mise install # pin tool versions
|
|
84
|
+
pnpm install # install dependencies
|
|
85
|
+
pnpm check # lint + typecheck + test
|
|
86
|
+
npm pack --dry-run # verify package contents
|
|
175
87
|
```
|
|
176
88
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
This repository uses `semantic-release` with npm trusted publishing.
|
|
180
|
-
|
|
181
|
-
Maintainer flow:
|
|
182
|
-
|
|
183
|
-
1. Write Conventional Commits.
|
|
184
|
-
2. The local `commit-msg` hook validates commit messages with Lefthook + commitlint.
|
|
185
|
-
3. CI validates commit messages again and runs release checks.
|
|
186
|
-
4. Merge to `main`.
|
|
187
|
-
5. GitHub Actions runs `semantic-release` from `.github/workflows/publish.yml`.
|
|
188
|
-
6. `semantic-release` computes the next version, creates the git tag and GitHub release, updates `package.json` and `CHANGELOG.md`, and publishes to npm through trusted publishing.
|
|
189
|
-
|
|
190
|
-
Local verification:
|
|
89
|
+
Run the extension directly during development:
|
|
191
90
|
|
|
192
91
|
```bash
|
|
193
|
-
|
|
194
|
-
npm pack --dry-run
|
|
195
|
-
pnpm release:dry
|
|
92
|
+
pi -e ./index.ts
|
|
196
93
|
```
|
|
197
94
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
- `lefthook` runs `mise run pre-push`
|
|
201
|
-
- the `pre-push` mise task runs the same core validations as CI:
|
|
202
|
-
- `pnpm check`
|
|
203
|
-
- `npm pack --dry-run`
|
|
204
|
-
|
|
205
|
-
Do not use local `npm publish` for normal releases in this repo.
|
|
95
|
+
## Data storage
|
|
206
96
|
|
|
207
|
-
|
|
97
|
+
MultiCodex stores all data locally under `~/.pi/agent/`:
|
|
208
98
|
|
|
209
|
-
|
|
99
|
+
| File | Contents |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `codex-accounts.json` | Managed account credentials and state |
|
|
102
|
+
| `settings.json` (key `pi-multicodex`) | Footer display preferences |
|
|
210
103
|
|
|
211
|
-
|
|
104
|
+
No data is sent anywhere except to the Codex API endpoints for auth refresh and usage queries.
|
|
212
105
|
|
|
213
|
-
|
|
214
|
-
- repository: `victor-founder/pi-multicodex`
|
|
215
|
-
- workflow file: `.github/workflows/publish.yml`
|
|
106
|
+
## Release process
|
|
216
107
|
|
|
217
|
-
|
|
108
|
+
Releases are automated. Push a conventional commit to `main` and GitHub Actions handles versioning, changelog, npm publishing (via trusted publishing), and GitHub releases.
|
|
218
109
|
|
|
219
|
-
|
|
220
|
-
npm trust list @victor-software-house/pi-multicodex
|
|
221
|
-
script -q /dev/null bash -lc 'npm trust github @victor-software-house/pi-multicodex --repository victor-founder/pi-multicodex --file publish.yml --yes'
|
|
222
|
-
```
|
|
110
|
+
Local push protection via `lefthook` runs the same checks as CI before every push.
|
|
223
111
|
|
|
224
|
-
##
|
|
112
|
+
## Roadmap
|
|
225
113
|
|
|
226
|
-
|
|
227
|
-
- `AGENTS.md` for repository-specific agent guidance
|
|
114
|
+
See [ROADMAP.md](ROADMAP.md) for planned work including configurable rotation settings, a shared controller architecture, and immediate footer persistence.
|
|
228
115
|
|
|
229
116
|
## Acknowledgment
|
|
230
117
|
|
|
231
118
|
This project descends from earlier MultiCodex work. Thanks to the original creator for the starting point that made this package possible.
|
|
232
119
|
|
|
233
|
-
The
|
|
120
|
+
The usage footer draws on ideas from [calesennett/pi-codex-usage](https://github.com/calesennett/pi-codex-usage). Thanks to its author for the reference implementation and footer design.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|