@workweave/router 0.2.3 → 0.2.5
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/cc-statusline.sh +48 -33
- package/install.sh +134 -112
- package/opencode-weave/README.md +58 -39
- package/opencode-weave/src/index.ts +315 -98
- package/package.json +1 -1
- package/uninstall.sh +14 -12
package/opencode-weave/README.md
CHANGED
|
@@ -1,59 +1,78 @@
|
|
|
1
|
-
# opencode Weave
|
|
1
|
+
# opencode Weave subscription plugin
|
|
2
2
|
|
|
3
|
-
Lets a caller's own **
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Lets a caller's own **AI subscriptions** pay for their **opencode** turns, routed
|
|
4
|
+
through the Weave Router. A subscription is a **credential scoped to the model
|
|
5
|
+
family it can pay for**, not a provider you pick: you connect your ChatGPT
|
|
6
|
+
(Codex) and/or Claude (Pro/Max) plan once, the router routes every turn to the
|
|
7
|
+
best model, and bills the plan that matches the model it served — ChatGPT pays
|
|
8
|
+
for GPT/Codex turns, Claude pays for Claude turns, your Weave key pays for
|
|
9
|
+
everything else.
|
|
10
|
+
|
|
11
|
+
Bundled into `@workweave/router`; the installer (`--codex` / `--opencode`) drops
|
|
12
|
+
`src/index.ts` into the user's opencode plugins dir and writes a single
|
|
13
|
+
Responses-format `weave` provider (plus a login-only `weave-claude` provider)
|
|
14
|
+
into `opencode.json`.
|
|
8
15
|
|
|
9
16
|
## Why a plugin (config alone can't do it)
|
|
10
17
|
|
|
11
18
|
opencode removed built-in subscription auth in 1.3.0 and binds OAuth to its own
|
|
12
|
-
first-party providers
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`Authorization`, which expires hourly — a static `options.headers` string can't
|
|
16
|
-
refresh it.
|
|
17
|
-
|
|
18
|
-
This plugin re-implements the same ChatGPT OAuth + refresh against a **custom**
|
|
19
|
-
provider id (`weave-codex`) and, crucially, **leaves the request URL on the
|
|
20
|
-
Weave Router** instead of rewriting it to `chatgpt.com`.
|
|
19
|
+
first-party providers, so a custom router provider can't reuse it. And
|
|
20
|
+
subscription tokens expire hourly — a static `options.headers` string can't
|
|
21
|
+
refresh them, nor carry two subscriptions whose tokens rotate independently.
|
|
21
22
|
|
|
22
23
|
## Wire shape it produces
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
opencode talks to one Responses-format `weave` provider; the plugin's loader
|
|
26
|
+
attaches whichever subscriptions are connected to **every** request via the
|
|
27
|
+
router's dedicated headers:
|
|
25
28
|
|
|
26
29
|
| | |
|
|
27
30
|
|---|---|
|
|
28
31
|
| `POST {router}/v1/responses` | Responses wire format (opencode's default for an `@ai-sdk/openai` provider) |
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `X-Weave-
|
|
32
|
-
| `
|
|
32
|
+
| `X-Weave-OpenAI-Subscription: <ChatGPT JWT>` | pays GPT/Codex turns, refreshed on expiry |
|
|
33
|
+
| `X-Weave-OpenAI-Account-ID: <id>` | paired account id (required by the Codex backend) |
|
|
34
|
+
| `X-Weave-Anthropic-Subscription: <sk-ant-oat token>` | pays Claude turns, refreshed on expiry |
|
|
35
|
+
| `X-Weave-Router-Key: rk_…` | from `opencode.json` `options.headers` — the router authenticates off this |
|
|
36
|
+
|
|
37
|
+
The router routes the turn across every model the caller's subs + key can pay
|
|
38
|
+
for and resolves the subscription matching the chosen provider, so a sub is
|
|
39
|
+
never billed for a turn outside its family.
|
|
40
|
+
|
|
41
|
+
## Two storage slots, one request provider
|
|
42
|
+
|
|
43
|
+
opencode stores one credential per provider id and the loader's `getAuth()` is
|
|
44
|
+
scoped to its own provider, so the two logins live in two slots:
|
|
45
|
+
|
|
46
|
+
- **`weave`** — the request provider. Owns the **ChatGPT** login and the loader
|
|
47
|
+
that attaches both subscriptions. Connecting ChatGPT activates sub-routing.
|
|
48
|
+
- **`weave-claude`** — login-only (no models, serves no requests). Owns the
|
|
49
|
+
**Claude** login. Its token is read from opencode's on-disk auth store by the
|
|
50
|
+
`weave` loader (the SDK exposes no get-by-id).
|
|
33
51
|
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
With neither connected, `weave` is a plain router provider (your Weave key pays)
|
|
53
|
+
— the loader simply doesn't run. Connecting ChatGPT is what turns on
|
|
54
|
+
subscription routing; the Claude sub then rides along when present.
|
|
36
55
|
|
|
37
|
-
##
|
|
56
|
+
## Login
|
|
38
57
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
credential (the `Authorization` bearer + `ChatGPT-Account-Id`) via the auth
|
|
43
|
-
`loader`, and the login flow via auth `methods` (browser PKCE + headless
|
|
44
|
-
device code). Tokens are stored in opencode's own auth store under the
|
|
45
|
-
`weave-codex` provider id.
|
|
58
|
+
`opencode auth login` → **Weave Router** → *ChatGPT Pro/Plus* (browser or
|
|
59
|
+
headless device code) and/or **Weave Router — Claude plan** → *Claude Pro/Max*
|
|
60
|
+
(browser; paste the `code#state` shown after authorizing).
|
|
46
61
|
|
|
47
|
-
## Env overrides
|
|
62
|
+
## Env overrides (self-host + tests)
|
|
48
63
|
|
|
49
|
-
- `WEAVE_CODEX_OAUTH_ISSUER` —
|
|
50
|
-
|
|
64
|
+
- `WEAVE_CODEX_OAUTH_ISSUER` — OpenAI auth issuer.
|
|
65
|
+
- `WEAVE_ANTHROPIC_OAUTH_AUTHORIZE` / `WEAVE_ANTHROPIC_OAUTH_TOKEN` — Anthropic
|
|
66
|
+
OAuth authorize host / token endpoint.
|
|
67
|
+
- `WEAVE_OPENCODE_AUTH_FILE` — path to opencode's `auth.json` (the `weave`
|
|
68
|
+
loader reads the `weave-claude` slot from here; defaults to
|
|
69
|
+
`$XDG_DATA_HOME/opencode/auth.json`).
|
|
51
70
|
|
|
52
71
|
## Verification
|
|
53
72
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
and
|
|
59
|
-
`@opencode-ai/plugin`.
|
|
73
|
+
`bun test test/` (run under bun, opencode's own runtime) covers: dual-sub
|
|
74
|
+
injection via the dedicated headers with the router key preserved and
|
|
75
|
+
`Authorization` left clean; ChatGPT-only graceful degradation; expired Claude
|
|
76
|
+
token refresh + persist + rotated injection; the loader staying inert without
|
|
77
|
+
oauth; and the Claude login hook's canonical OAuth flow + `code#state` exchange.
|
|
78
|
+
Typechecks under `strict` against `@opencode-ai/plugin`.
|