@vacbo/opencode-anthropic-fix 0.1.8 → 0.1.9
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 +88 -88
- package/dist/opencode-anthropic-auth-cli.mjs +804 -507
- package/dist/opencode-anthropic-auth-plugin.js +4751 -4109
- package/package.json +67 -67
- package/src/__tests__/billing-edge-cases.test.ts +59 -59
- package/src/__tests__/bun-proxy.parallel.test.ts +388 -382
- package/src/__tests__/cc-comparison.test.ts +87 -87
- package/src/__tests__/cc-credentials.test.ts +254 -250
- package/src/__tests__/cch-drift-checker.test.ts +51 -51
- package/src/__tests__/cch-native-style.test.ts +56 -56
- package/src/__tests__/debug-gating.test.ts +42 -42
- package/src/__tests__/decomposition-smoke.test.ts +68 -68
- package/src/__tests__/fingerprint-regression.test.ts +575 -566
- package/src/__tests__/helpers/conversation-history.smoke.test.ts +271 -271
- package/src/__tests__/helpers/conversation-history.ts +119 -119
- package/src/__tests__/helpers/deferred.smoke.test.ts +103 -103
- package/src/__tests__/helpers/deferred.ts +69 -69
- package/src/__tests__/helpers/in-memory-storage.smoke.test.ts +155 -155
- package/src/__tests__/helpers/in-memory-storage.ts +88 -88
- package/src/__tests__/helpers/mock-bun-proxy.smoke.test.ts +68 -68
- package/src/__tests__/helpers/mock-bun-proxy.ts +189 -189
- package/src/__tests__/helpers/plugin-fetch-harness.smoke.test.ts +273 -273
- package/src/__tests__/helpers/plugin-fetch-harness.ts +288 -288
- package/src/__tests__/helpers/sse.smoke.test.ts +236 -236
- package/src/__tests__/helpers/sse.ts +209 -209
- package/src/__tests__/index.parallel.test.ts +605 -595
- package/src/__tests__/sanitization-regex.test.ts +112 -112
- package/src/__tests__/state-bounds.test.ts +90 -90
- package/src/account-identity.test.ts +197 -192
- package/src/account-identity.ts +69 -67
- package/src/account-state.test.ts +86 -86
- package/src/account-state.ts +25 -25
- package/src/accounts/matching.test.ts +335 -0
- package/src/accounts/matching.ts +167 -0
- package/src/accounts/persistence.test.ts +345 -0
- package/src/accounts/persistence.ts +432 -0
- package/src/accounts/repair.test.ts +276 -0
- package/src/accounts/repair.ts +407 -0
- package/src/accounts.dedup.test.ts +621 -621
- package/src/accounts.test.ts +933 -929
- package/src/accounts.ts +633 -989
- package/src/backoff.test.ts +345 -345
- package/src/backoff.ts +219 -219
- package/src/betas.ts +124 -124
- package/src/bun-fetch.test.ts +345 -342
- package/src/bun-fetch.ts +424 -424
- package/src/bun-proxy.test.ts +25 -25
- package/src/bun-proxy.ts +209 -209
- package/src/cc-credentials.ts +111 -111
- package/src/circuit-breaker.test.ts +184 -184
- package/src/circuit-breaker.ts +169 -169
- package/src/cli/commands/auth.ts +963 -0
- package/src/cli/commands/config.ts +547 -0
- package/src/cli/formatting.test.ts +406 -0
- package/src/cli/formatting.ts +219 -0
- package/src/cli.ts +255 -2022
- package/src/commands/handlers/betas.ts +100 -0
- package/src/commands/handlers/config.ts +99 -0
- package/src/commands/handlers/files.ts +375 -0
- package/src/commands/oauth-flow.ts +181 -166
- package/src/commands/prompts.ts +61 -61
- package/src/commands/router.test.ts +421 -0
- package/src/commands/router.ts +143 -635
- package/src/config.test.ts +482 -482
- package/src/config.ts +412 -404
- package/src/constants.ts +48 -48
- package/src/drift/cch-constants.ts +95 -95
- package/src/env.ts +111 -105
- package/src/headers/billing.ts +33 -33
- package/src/headers/builder.ts +130 -130
- package/src/headers/cch.ts +75 -75
- package/src/headers/stainless.ts +25 -25
- package/src/headers/user-agent.ts +23 -23
- package/src/index.ts +436 -828
- package/src/models.ts +27 -27
- package/src/oauth.test.ts +102 -102
- package/src/oauth.ts +178 -178
- package/src/parent-pid-watcher.test.ts +148 -148
- package/src/parent-pid-watcher.ts +69 -69
- package/src/plugin-helpers.ts +82 -82
- package/src/refresh-helpers.ts +145 -139
- package/src/refresh-lock.test.ts +94 -94
- package/src/refresh-lock.ts +93 -93
- package/src/request/body.history.test.ts +579 -571
- package/src/request/body.ts +255 -255
- package/src/request/metadata.ts +65 -65
- package/src/request/retry.test.ts +156 -156
- package/src/request/retry.ts +67 -67
- package/src/request/url.ts +21 -21
- package/src/request-orchestration-helpers.ts +648 -0
- package/src/response/index.ts +5 -5
- package/src/response/mcp.ts +58 -58
- package/src/response/streaming.test.ts +313 -311
- package/src/response/streaming.ts +412 -410
- package/src/rotation.test.ts +304 -301
- package/src/rotation.ts +205 -205
- package/src/storage.test.ts +547 -547
- package/src/storage.ts +315 -291
- package/src/system-prompt/builder.ts +38 -38
- package/src/system-prompt/index.ts +5 -5
- package/src/system-prompt/normalize.ts +60 -60
- package/src/system-prompt/sanitize.ts +30 -30
- package/src/thinking.ts +21 -20
- package/src/token-refresh.test.ts +265 -265
- package/src/token-refresh.ts +219 -214
- package/src/types.ts +30 -30
|
@@ -8,222 +8,222 @@ type ForwardFetchInput = string | URL | Request;
|
|
|
8
8
|
type ForwardFetch = (input: ForwardFetchInput, init?: RequestInit) => Promise<Response>;
|
|
9
9
|
|
|
10
10
|
type MockChildProcess = EventEmitter &
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
Omit<
|
|
12
|
+
ChildProcess,
|
|
13
|
+
"pid" | "killed" | "exitCode" | "signalCode" | "stdout" | "stderr" | "spawnfile" | "spawnargs" | "kill"
|
|
14
|
+
> & {
|
|
15
|
+
killSignals: NodeJS.Signals[];
|
|
16
|
+
pid: number;
|
|
17
|
+
killed: boolean;
|
|
18
|
+
exitCode: number | null;
|
|
19
|
+
signalCode: NodeJS.Signals | null;
|
|
20
|
+
stdout: PassThrough;
|
|
21
|
+
stderr: PassThrough;
|
|
22
|
+
spawnfile: string;
|
|
23
|
+
spawnargs: string[];
|
|
24
|
+
kill: (signal?: number | NodeJS.Signals | null) => boolean;
|
|
25
|
+
forwardFetch: ForwardFetch;
|
|
26
|
+
};
|
|
27
27
|
|
|
28
28
|
export interface MockProxyOptions {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
bannerDelay?: number;
|
|
30
|
+
spawnError?: Error;
|
|
31
|
+
forwardToMockFetch?: ForwardFetch;
|
|
32
|
+
parentDeathSimulation?: boolean;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface MockBunProxy {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
mockSpawn: Mock;
|
|
37
|
+
child: MockChildProcess;
|
|
38
|
+
simulateExit(code?: number | null, signal?: NodeJS.Signals | null): void;
|
|
39
|
+
simulateStdoutBanner(port?: number): void;
|
|
40
|
+
simulateCrash(message?: string): void;
|
|
41
|
+
getInFlightCount(): number;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
let nextPid = 48_372;
|
|
45
45
|
|
|
46
46
|
function normalizeSignal(signal?: number | NodeJS.Signals | null): NodeJS.Signals {
|
|
47
|
-
|
|
47
|
+
return typeof signal === "string" ? signal : "SIGTERM";
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function inferSpawnPort(args: string[]): number {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const numericArg = [...args].reverse().find((arg) => /^\d+$/.test(arg));
|
|
52
|
+
return numericArg ? Number.parseInt(numericArg, 10) : 48_372;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
async function normalizeForwardedRequest(
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
input: ForwardFetchInput,
|
|
57
|
+
init?: RequestInit,
|
|
58
58
|
): Promise<{
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
targetUrl: string;
|
|
60
|
+
forwardedInit: RequestInit;
|
|
61
61
|
}> {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
62
|
+
const request =
|
|
63
|
+
input instanceof Request
|
|
64
|
+
? new Request(input, init)
|
|
65
|
+
: new Request(input instanceof URL ? input.toString() : input, init);
|
|
66
|
+
const headers = new Headers(request.headers);
|
|
67
|
+
const targetUrl = headers.get("x-proxy-url") ?? request.url;
|
|
68
|
+
|
|
69
|
+
headers.delete("x-proxy-url");
|
|
70
|
+
headers.delete("host");
|
|
71
|
+
headers.delete("connection");
|
|
72
|
+
|
|
73
|
+
const method = request.method || "GET";
|
|
74
|
+
let body: RequestInit["body"] | undefined;
|
|
75
|
+
|
|
76
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
77
|
+
if (init?.body !== undefined) {
|
|
78
|
+
body = init.body;
|
|
79
|
+
} else {
|
|
80
|
+
const textBody = await request.clone().text();
|
|
81
|
+
body = textBody.length > 0 ? textBody : undefined;
|
|
82
|
+
}
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
};
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
targetUrl,
|
|
87
|
+
forwardedInit: {
|
|
88
|
+
method,
|
|
89
|
+
headers,
|
|
90
|
+
body,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
export function createMockBunProxy(options: MockProxyOptions = {}): MockBunProxy {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
96
|
+
let inFlightCount = 0;
|
|
97
|
+
let exited = false;
|
|
98
|
+
let lastSpawnArgs: string[] = [];
|
|
99
|
+
const pendingTimers = new Set<NodeJS.Timeout>();
|
|
100
|
+
const forwardToMockFetch: ForwardFetch =
|
|
101
|
+
options.forwardToMockFetch ?? (async () => new Response(null, { status: 204 }));
|
|
102
|
+
|
|
103
|
+
const stdout = new PassThrough();
|
|
104
|
+
const stderr = new PassThrough();
|
|
105
|
+
const child = new EventEmitter() as MockChildProcess;
|
|
106
|
+
|
|
107
|
+
child.pid = nextPid++;
|
|
108
|
+
child.killed = false;
|
|
109
|
+
child.exitCode = null;
|
|
110
|
+
child.signalCode = null;
|
|
111
|
+
child.stdout = stdout;
|
|
112
|
+
child.stderr = stderr;
|
|
113
|
+
child.killSignals = [];
|
|
114
|
+
child.spawnfile = "";
|
|
115
|
+
child.spawnargs = [];
|
|
116
|
+
child.kill = (signal?: number | NodeJS.Signals | null) => {
|
|
117
|
+
const normalizedSignal = normalizeSignal(signal);
|
|
118
|
+
child.killSignals.push(normalizedSignal);
|
|
119
|
+
child.killed = true;
|
|
120
|
+
|
|
121
|
+
if (options.parentDeathSimulation) {
|
|
122
|
+
queueMicrotask(() => {
|
|
123
|
+
emitExit(null, normalizedSignal);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return true;
|
|
128
|
+
};
|
|
129
|
+
child.forwardFetch = async (input: ForwardFetchInput, init?: RequestInit): Promise<Response> => {
|
|
130
|
+
inFlightCount += 1;
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const { targetUrl, forwardedInit } = await normalizeForwardedRequest(input, init);
|
|
134
|
+
return await forwardToMockFetch(targetUrl, forwardedInit);
|
|
135
|
+
} finally {
|
|
136
|
+
inFlightCount -= 1;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
const clearPendingTimers = (): void => {
|
|
141
|
+
for (const timer of pendingTimers) {
|
|
142
|
+
clearTimeout(timer);
|
|
143
|
+
}
|
|
144
|
+
pendingTimers.clear();
|
|
145
|
+
};
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
const emitExit = (code: number | null = 0, signal: NodeJS.Signals | null = null): void => {
|
|
148
|
+
if (exited) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
child.emit("exit", code, signal);
|
|
158
|
-
child.emit("close", code, signal);
|
|
159
|
-
stdout.end();
|
|
160
|
-
stderr.end();
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const mockSpawn = vi.fn(
|
|
164
|
-
(
|
|
165
|
-
command: string,
|
|
166
|
-
argsOrOptions?: readonly string[] | SpawnOptions,
|
|
167
|
-
maybeOptions?: SpawnOptions,
|
|
168
|
-
): MockChildProcess => {
|
|
169
|
-
if (options.spawnError) {
|
|
170
|
-
throw options.spawnError;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const args = Array.isArray(argsOrOptions) ? [...argsOrOptions] : [];
|
|
174
|
-
const spawnOptions = Array.isArray(argsOrOptions) ? maybeOptions : argsOrOptions;
|
|
175
|
-
|
|
176
|
-
lastSpawnArgs = args;
|
|
177
|
-
child.spawnfile = command;
|
|
178
|
-
child.spawnargs = [command, ...args];
|
|
179
|
-
void spawnOptions;
|
|
180
|
-
|
|
181
|
-
return child;
|
|
182
|
-
},
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
const simulateStdoutBanner = (port = inferSpawnPort(lastSpawnArgs)): void => {
|
|
186
|
-
if (exited) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
152
|
+
exited = true;
|
|
153
|
+
clearPendingTimers();
|
|
154
|
+
child.exitCode = code;
|
|
155
|
+
child.signalCode = signal;
|
|
189
156
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
stdout.
|
|
193
|
-
|
|
157
|
+
child.emit("exit", code, signal);
|
|
158
|
+
child.emit("close", code, signal);
|
|
159
|
+
stdout.end();
|
|
160
|
+
stderr.end();
|
|
194
161
|
};
|
|
195
162
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
163
|
+
const mockSpawn = vi.fn(
|
|
164
|
+
(
|
|
165
|
+
command: string,
|
|
166
|
+
argsOrOptions?: readonly string[] | SpawnOptions,
|
|
167
|
+
maybeOptions?: SpawnOptions,
|
|
168
|
+
): MockChildProcess => {
|
|
169
|
+
if (options.spawnError) {
|
|
170
|
+
throw options.spawnError;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const args = Array.isArray(argsOrOptions) ? [...argsOrOptions] : [];
|
|
174
|
+
const spawnOptions = Array.isArray(argsOrOptions) ? maybeOptions : argsOrOptions;
|
|
175
|
+
|
|
176
|
+
lastSpawnArgs = args;
|
|
177
|
+
child.spawnfile = command;
|
|
178
|
+
child.spawnargs = [command, ...args];
|
|
179
|
+
void spawnOptions;
|
|
180
|
+
|
|
181
|
+
return child;
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
const simulateStdoutBanner = (port = inferSpawnPort(lastSpawnArgs)): void => {
|
|
186
|
+
if (exited) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const writeBanner = (): void => {
|
|
191
|
+
if (!exited) {
|
|
192
|
+
stdout.write(`BUN_PROXY_PORT=${port}\n`);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
if (!options.bannerDelay || options.bannerDelay <= 0) {
|
|
197
|
+
writeBanner();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const timer = setTimeout(() => {
|
|
202
|
+
pendingTimers.delete(timer);
|
|
203
|
+
writeBanner();
|
|
204
|
+
}, options.bannerDelay);
|
|
205
|
+
|
|
206
|
+
timer.unref?.();
|
|
207
|
+
pendingTimers.add(timer);
|
|
208
|
+
};
|
|
200
209
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
stderr.write(`${message}\n`);
|
|
223
|
-
emitExit(1, null);
|
|
224
|
-
},
|
|
225
|
-
getInFlightCount(): number {
|
|
226
|
-
return inFlightCount;
|
|
227
|
-
},
|
|
228
|
-
};
|
|
210
|
+
return {
|
|
211
|
+
mockSpawn,
|
|
212
|
+
child,
|
|
213
|
+
simulateExit(code = 0, signal = null): void {
|
|
214
|
+
emitExit(code, signal);
|
|
215
|
+
},
|
|
216
|
+
simulateStdoutBanner,
|
|
217
|
+
simulateCrash(message = "mock bun proxy crashed"): void {
|
|
218
|
+
if (exited) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
stderr.write(`${message}\n`);
|
|
223
|
+
emitExit(1, null);
|
|
224
|
+
},
|
|
225
|
+
getInFlightCount(): number {
|
|
226
|
+
return inFlightCount;
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
229
|
}
|