@rikcodes/teamclaude 1.1.20-rik.8 → 1.1.22-rik.1

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 (49) hide show
  1. package/README.md +24 -12
  2. package/package.json +3 -2
  3. package/src/account-manager.js +1259 -73
  4. package/src/account-pairing.js +45 -0
  5. package/src/account-routing.js +608 -0
  6. package/src/backend-quota.js +2 -0
  7. package/src/brand.js +57 -0
  8. package/src/cache-control-sanitize.js +2 -2
  9. package/src/claude-env.js +89 -0
  10. package/src/client-usage.js +198 -5
  11. package/src/codex-auth.js +26 -8
  12. package/src/codex-quota.js +94 -0
  13. package/src/codex-reset-credits.js +836 -0
  14. package/src/codex-usage.js +51 -0
  15. package/src/config-ops.js +399 -0
  16. package/src/config.js +30 -5
  17. package/src/content-block-sanitize.js +105 -0
  18. package/src/conversation.js +260 -0
  19. package/src/crash-log.js +5 -1
  20. package/src/dashboard.js +558 -45
  21. package/src/early-log.js +60 -0
  22. package/src/forward-target.js +6 -2
  23. package/src/identity.js +35 -4
  24. package/src/index.js +873 -231
  25. package/src/mcp-tools.js +674 -0
  26. package/src/mcp.js +262 -0
  27. package/src/mitm.js +14 -2
  28. package/src/model.js +239 -1
  29. package/src/oauth.js +123 -14
  30. package/src/prober.js +11 -4
  31. package/src/provider.js +45 -0
  32. package/src/quota-projection.js +102 -9
  33. package/src/quota-summary.js +475 -0
  34. package/src/responses-usage.js +148 -0
  35. package/src/restart.js +205 -0
  36. package/src/server.js +1369 -106
  37. package/src/session-tracker.js +101 -17
  38. package/src/sidecar.js +266 -3
  39. package/src/status-renderer.js +193 -12
  40. package/src/sx.js +21 -3
  41. package/src/sync-accounts.js +95 -3
  42. package/src/terminal-title.js +22 -7
  43. package/src/tui-remote.js +102 -3
  44. package/src/tui.js +1763 -220
  45. package/src/update-watch.js +232 -0
  46. package/src/updater.js +30 -12
  47. package/src/upstream-fetch.js +45 -14
  48. package/src/upstream-proxy.js +2 -1
  49. package/src/warmer.js +10 -2
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # TeamClaude
2
2
 
3
3
  > **Fork notice (rikbrown).** This fork adds two features on top of
4
- > [KarpelesLab/teamclaude](https://github.com/KarpelesLab/teamclaude), currently based on upstream 1.1.20:
4
+ > [KarpelesLab/teamclaude](https://github.com/KarpelesLab/teamclaude), currently based on upstream 1.1.22:
5
5
  >
6
6
  > - **[OpenAI models via a Codex sidecar](docs/openai.md)** (`sidecars` + `customModels`, opt-in):
7
7
  > route `gpt-*` requests through a supervised local translating proxy to a ChatGPT subscription,
@@ -22,7 +22,7 @@
22
22
  > ```
23
23
  >
24
24
  > Already have upstream installed globally? Run `npm uninstall -g @karpeleslab/teamclaude` first —
25
- > both packages provide the `teamclaude` command.
25
+ > both packages provide the `teamclaude` and `teamrouter` commands.
26
26
  >
27
27
  > Branch: `rik/main`. Everything else matches upstream.
28
28
 
@@ -59,12 +59,16 @@ Already logged into Claude Code? `teamclaude import` takes its credentials inste
59
59
  - Tells a spent quota bucket apart from a per-minute rate limit and only rotates on the first one. Rotating on a rate limit would just move the burst to the next account and drop the warm cache, so it paces the same account instead.
60
60
  - Paces requests onto a freshly switched account, so a herd of agents failing over at the same instant doesn't throttle it and cascade down the fleet.
61
61
  - TUI with quota bars, reset countdowns, activity log, and settings you can change while it runs, including adding and removing accounts.
62
+ - Opt-in MCP endpoint that hands the same control plane to Claude Code as tools, so an agent can read the fleet's quota or switch accounts from inside a session.
62
63
  - Catches hardcoded `api.anthropic.com` endpoints (the Claude Design MCP, for one) through a local MITM forward proxy, not only what `ANTHROPIC_BASE_URL` covers.
63
64
  - Holds the request open until quota resets instead of returning 429 when every account is spent, so an unattended run finishes on its own (`holdSeconds`, off by default).
65
+ - Optionally leans on accounts with Anthropic's paid extra usage once every account is out of free quota, instead of returning 429 (`allowExtraUsage`, off by default — it bills real money). Quota between the switch threshold and 100% is used first, on any account; billing starts only when none is left, and stops as soon as a window resets.
64
66
  - Refreshes OAuth tokens before they expire and writes them back to config. Client refreshes pass through untouched.
65
67
  - Pools OpenAI Codex subscriptions alongside Claude accounts (experimental): the Codex CLI is routed through the same proxy, by config or transparently through the MITM proxy, and rotates on its own quota.
66
68
  - Takes any Anthropic-compatible API (DeepSeek, GLM) as a low-priority fallback for when the Claude accounts are done.
69
+ - Sends one account's traffic through its own HTTP or SOCKS proxy (`login --routing "socks5h://user:pass@host:1080"`), sign-in and token refresh included, and leaves every other account alone. If that proxy goes down, the request fails over to the next account.
67
70
  - Serves OpenAI models next to Claude ones — a supervised local sidecar translates `gpt-*` requests onto a ChatGPT subscription, with real model names in `/model` and GPT subagents dispatchable from a Claude parent (`sidecars` + `customModels`, this fork).
71
+ - Ships those subagents as a Claude Code plugin: one named agent per model **and effort level**, which the Agent tool's `model` parameter cannot express (`/plugin install rikclaude-agents@rikclaude`, this fork).
68
72
  - No dependencies. Node built-ins only.
69
73
 
70
74
  ## Everyday commands
@@ -107,10 +111,12 @@ A Claude Code session can use OpenAI models alongside the Claude accounts. They
107
111
  **1. Install the sidecar and log it into your ChatGPT account** (one time):
108
112
 
109
113
  ```bash
110
- brew install raine/claude-code-proxy/claude-code-proxy
114
+ curl -fsSL https://raw.githubusercontent.com/rikbrown/claude-code-proxy/rik/main/scripts/install.sh | bash
111
115
  claude-code-proxy codex auth login
112
116
  ```
113
117
 
118
+ This installs [rikbrown/claude-code-proxy](https://github.com/rikbrown/claude-code-proxy), a fork of the reference sidecar. Take the fork rather than upstream's Homebrew build: it forwards Codex's quota headers, without which every bar on the account reads `unknown`, and it lets you raise the 60-second header timeout that otherwise kills a long reasoning turn. See [Timeouts](docs/openai.md#timeouts).
119
+
114
120
  **2. Connect it** — add four pieces to `~/.config/teamclaude.json`:
115
121
 
116
122
  ```json
@@ -150,10 +156,10 @@ At launch, `teamclaude run` — and the `claude` alias, which passes through `ru
150
156
  | Row field | Where it ends up |
151
157
  | --- | --- |
152
158
  | `model`, `label`, `description` | A `/model` picker row under the **real** model id (`--settings`), so `/model gpt-5.6-sol` works picked or typed |
153
- | `model` | A dispatchable subagent named after the model (`--agents`), so "dispatch a `gpt-5.6-terra` subagent" works from a Claude parent. Set `"customModelAgents": false` to skip these if you define your own agents in `~/.claude/agents/` |
159
+ | `model` | Nothing by default. Set `"customModelAgents": true` and each row also becomes a plain subagent named after the model (`--agents`), so "dispatch a `gpt-5.6-terra` subagent" works from a Claude parent. Off because those agents pin no effort and outrank every agent file on disk — prefer the effort-pinned [plugin agents](docs/agents.md) |
154
160
  | `contextTokens` | `CLAUDE_CODE_MAX_CONTEXT_TOKENS`, set to the largest value across rows, so Claude Code compacts at the real window instead of assuming 200k |
155
161
 
156
- For tools that spawn `claude` themselves, `teamclaude env` can set only environment variables. It carries the window and `ANTHROPIC_CUSTOM_MODEL_OPTION` for the **first** row. For GPT subagents under `env`, create `~/.claude/agents/<name>.md` with `model: gpt-5.6-terra` in its frontmatter.
162
+ For tools that spawn `claude` themselves, `teamclaude env` can set only environment variables. It carries the window and `ANTHROPIC_CUSTOM_MODEL_OPTION` for the **first** row. Agents do not depend on either mode: they are read from disk, whether they come from the [`rikclaude-agents` plugin](docs/agents.md) or from a `~/.claude/agents/<name>.md` you write with `model: gpt-5.6-terra` in its frontmatter.
157
163
 
158
164
  Each request is routed by the model name in its body, so one session can freely mix models: use `claude --model gpt-5.6-sol` for a whole session, `/model gpt-5.6-sol` during a session, or a Claude parent that dispatches a GPT subagent.
159
165
 
@@ -161,11 +167,11 @@ Each request is routed by the model name in its body, so one session can freely
161
167
 
162
168
  1. Check that your sidecar build lists it: `curl -s http://127.0.0.1:18765/v1/models`. The sidecar has its own allow-list and rejects any id that it does not know, regardless of the TeamClaude configuration. Upgrade the sidecar if the id is missing.
163
169
  2. Add a `customModels` row. Codex publishes the window for each model as `context_window` in `~/.codex/models_cache.json`; copy it to `contextTokens`.
164
- 3. Start a new `teamclaude run` session. The rows are read at launch, so you do not need to restart the server. If you upgraded the sidecar binary, restart the server — or send `SIGTERM` to the sidecar process and let the supervisor restart it with the new binary.
170
+ 3. Start a new `teamclaude run` session. The rows are read at launch, so you do not need to restart the server. If you upgraded the sidecar binary, restart the server — or send `SIGTERM` to the sidecar process and let the supervisor restart it with the new binary. The first `SIGTERM` only starts a graceful shutdown, which a request in flight holds open; send it a second time to force the exit.
165
171
 
166
- Claude Code prints one `[claude-code:unrecognized_model]` line to stderr for each custom model. This is expected; suppressing it would lose the correct context window. The quota bars for the sidecar account show `unknown` unless the sidecar forwards Codex's rate-limit headers — see [Quota](docs/openai.md#quota). Keep the sidecar on loopback.
172
+ Claude Code prints one `[claude-code:unrecognized_model]` line to stderr for each custom model. This is expected; suppressing it would lose the correct context window. The quota bars for the sidecar account show `unknown` unless the sidecar forwards Codex's rate-limit headers, which the fork build in step 1 does and upstream's does not — see [Quota](docs/openai.md#quota). Keep the sidecar on loopback.
167
173
 
168
- The sidecar appears under the account table as a `⚙` line rather than a row because it holds no subscription, is the only account its route can use, and never rotates. The line also shows its supervised process state (`up pid 98018`, or `down (code 1) 3 restarts`).
174
+ The sidecar appears under the account table as a `⚙` line rather than a row because it holds no subscription, is the only account its route can use, and never rotates. The line also shows its supervised process state (`up pid 98018`, or `down (code 1) 3 restarts`), followed by what the sidecar reports about itself while it is up (`2 active 3 errors`, read from its own `/monitor` endpoint; each is omitted at zero, and both are omitted if that endpoint does not answer).
169
175
 
170
176
  #### Several ChatGPT accounts
171
177
 
@@ -221,7 +227,7 @@ Three details matter:
221
227
  - **`CCP_CODEX_TRANSPORT=http` is required.** A WebSocket upgrade is relayed with the caller's own headers and draws no account, so the WebSocket transport cannot be pooled.
222
228
  - **Do not reuse a name across providers.** Routes address accounts by name, so a shared name admits both — including the Claude account that cannot serve `gpt-*`, which outranks the sidecar on priority and wins. TeamClaude warns at startup when it sees one.
223
229
 
224
- Two things differ from the single-account setup: each turn appears **twice** in the activity list, once per hop, and tokens are booked against the sidecar account, so a ChatGPT account reads `N req · 0 tok`. Its quota bars are unaffected because they come from the `x-codex-*` headers on the second hop, where the subscription is.
230
+ One thing differs from the single-account setup: each turn appears **twice** in the activity list, once per hop. Tokens and quota bars both come from the second hop, where the subscription is, so they are booked against the ChatGPT account that served. The sidecar account holds a stub login and spends nothing of its own, so it reads `N req · 0 tok` — booking it as well would double every figure.
225
231
 
226
232
  Full details, including what happens to quota on each hop: [Several ChatGPT accounts behind one sidecar](docs/openai.md#several-chatgpt-accounts-behind-one-sidecar).
227
233
 
@@ -233,15 +239,21 @@ This feature is on by default. Each account row shows which window binds first:
233
239
 
234
240
  | Page | Contents |
235
241
  | --- | --- |
236
- | [Accounts](docs/accounts.md) | OAuth login, import, API keys, multiple orgs, Codex accounts, third-party backends |
237
- | [Usage](docs/usage.md) | Server and TUI, running Claude Code, shell alias, command reference, logging |
242
+ | [Accounts](docs/accounts.md) | OAuth login, import, API keys, multiple orgs, per-account proxy routing, Codex accounts, third-party backends |
243
+ | [Usage](docs/usage.md) | Server and TUI, running Claude Code, shell alias, command reference, browser dashboard, MCP endpoint, logging |
238
244
  | [Routing](docs/routing.md) | Rotation, the two kinds of 429, storm control, model routes, session spreading, pinning, prompt cache |
239
245
  | [Quota](docs/quota.md) | Quota probe, keep-warm, holding on exhaustion |
240
246
  | [OpenAI models](docs/openai.md) | Codex sidecar setup, custom model registration, GPT subagents, limitations |
247
+ | [Subagents](docs/agents.md) | The `rikclaude-agents` plugin: effort-pinned agents per model, installing it, seeding it for a team |
241
248
  | [Configuration](docs/configuration.md) | Config format, every field, environment variables, network tuning |
242
- | [Proxy modes](docs/proxy-modes.md) | MITM forward proxy, sx.org residential egress |
249
+ | [Proxy modes](docs/proxy-modes.md) | MITM forward proxy, upstream proxy, per-account routing, sx.org residential egress |
250
+ | [Remote host](docs/remote.md) | Running the fleet on an always-on box: reaching it, moving the accounts, service supervision, pointing clients at it |
243
251
  | [Compliance](docs/compliance.md) | Terms of service notes |
244
252
 
253
+ ## Renaming to TeamRouter
254
+
255
+ TeamClaude is becoming **TeamRouter** — it pools Codex and third-party accounts as well as Claude ones, and the name should say so. The rename is spread over several releases so that nothing installed, scripted or configured breaks; the plan and its progress are in [issue #72](https://github.com/KarpelesLab/teamclaude/issues/72). As of this release the new name is *accepted* everywhere while the old one stays canonical: `teamrouter` runs the same CLI as `teamclaude`, every `TEAMCLAUDE_*` variable is also read as `TEAMROUTER_*`, every `/teamclaude/…` control route also answers at `/teamrouter/…`, and a `~/.config/teamrouter.json` is used when it exists. Nothing on an existing install needs to change, now or when the default flips.
256
+
245
257
  ## Releasing this fork
246
258
 
247
259
  Versions are `<upstream base>-rik.<n>`, e.g. `1.1.19-rik.1`. The self-updater orders that tail and installs only that shape (`x.y.z` or `x.y.z-rik.N`), so every publish reaches existing installs within a day.
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@rikcodes/teamclaude",
3
- "version": "1.1.20-rik.8",
3
+ "version": "1.1.22-rik.1",
4
4
  "description": "Multi-account proxy for Claude Code and Codex: pools Claude Max, ChatGPT/Codex, API-key and third-party backend accounts, and rotates on quota",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
7
  "bin": {
8
- "teamclaude": "src/index.js"
8
+ "teamclaude": "src/index.js",
9
+ "teamrouter": "src/index.js"
9
10
  },
10
11
  "files": [
11
12
  "src/"