@wrongstack/cli 0.299.0 → 0.300.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.
- package/dist/{acp-S4LZQB66.js → acp-IDNS2YVE.js} +3 -3
- package/dist/{auth-G5YKKSRH.js → auth-6T6ZOT2R.js} +5 -5
- package/dist/auth-menu/loopback-server.d.ts +41 -55
- package/dist/auth-menu/openai-codex-oauth.d.ts +36 -123
- package/dist/auto-discover-providers-DRW4OZHG.js +8 -0
- package/dist/boot/dispatch-webui.d.ts +3 -0
- package/dist/{chunk-PEKUKUCH.js → chunk-3MWUZMOL.js} +19 -12
- package/dist/{chunk-TGDHN4LM.js → chunk-4GVH7V3S.js} +4 -24
- package/dist/{chunk-4U3DMA2Y.js → chunk-4WJKVQJY.js} +15 -20
- package/dist/{chunk-2SLSUDYS.js → chunk-GYDQABMA.js} +269 -180
- package/dist/{chunk-4HH3YGG4.js → chunk-MRLYDHQ7.js} +8 -5
- package/dist/{chunk-66T43Q4Y.js → chunk-N7ULWBO5.js} +4 -3
- package/dist/{chunk-ZNZJ34RF.js → chunk-PEMN4T5O.js} +2 -2
- package/dist/chunk-PYTFS4MC.js +238 -0
- package/dist/{chunk-L5CE52XW.js → chunk-V76R7DC5.js} +25 -19
- package/dist/{cli-main-3MQDFSYK.js → cli-main-7B3G2YSG.js} +528 -156
- package/dist/{execution-ANOYMWPO.js → execution-SHGM7BVC.js} +50 -5
- package/dist/fleet/budget-source.d.ts +18 -0
- package/dist/fleet/host-status.d.ts +31 -0
- package/dist/fleet/host-types.d.ts +8 -0
- package/dist/fleet/host.d.ts +5 -0
- package/dist/{hq-BDO56CX6.js → hq-DVDD4XPV.js} +22 -3
- package/dist/hq-server/auth-state.d.ts +29 -1
- package/dist/hq-server/auth.d.ts +16 -0
- package/dist/hq-server/client-address.d.ts +56 -0
- package/dist/hq-server/login-attempt-store.d.ts +30 -10
- package/dist/hq-server/routes/auth-handlers.d.ts +66 -26
- package/dist/hq-server/routes.d.ts +13 -0
- package/dist/hq-server/types.d.ts +10 -0
- package/dist/{hq-server-RJLJJZU7.js → hq-server-DQHLNHDL.js} +2 -2
- package/dist/hq-server.d.ts +19 -0
- package/dist/index.js +20 -20
- package/dist/{modeldiag-HENYJ4N7.js → modeldiag-YOQZHBQV.js} +2 -2
- package/dist/{plugin-usage-VTL7ZTVC.js → plugin-usage-EOG4ET4S.js} +2 -2
- package/dist/{plugins-ETY6W3DC.js → plugins-56CMWMPR.js} +3 -3
- package/dist/{providers-models-GDELBHZK.js → providers-models-K6RT7ABI.js} +34 -9
- package/dist/slash-commands/command-context.d.ts +19 -0
- package/dist/webui-server/setup-events.d.ts +17 -0
- package/dist/webui-server/terminal-log-view.d.ts +29 -12
- package/dist/{webui-server-PCLSXX6L.js → webui-server-G3EKFXLL.js} +109 -38
- package/dist/webui-server-options.d.ts +16 -0
- package/dist/wiring/brain-and-orchestration.d.ts +3 -0
- package/dist/wiring/director-setup.d.ts +4 -0
- package/dist/wiring/fallback-gate.d.ts +31 -0
- package/dist/wiring/fleet-command-handlers.d.ts +1 -1
- package/dist/wiring/plugins.d.ts +2 -8
- package/dist/wiring/provider-utility-tools.d.ts +26 -1
- package/package.json +23 -23
- package/dist/chunk-GO3TJICK.js +0 -489
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
fallbackCodexProviderModels,
|
|
3
3
|
filterCurrentCodexModelIds,
|
|
4
4
|
isCodexCatalogModel
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PYTFS4MC.js";
|
|
6
6
|
|
|
7
7
|
// src/acp-registry-cache.ts
|
|
8
8
|
import {
|
|
@@ -92,6 +92,7 @@ import { ConfigError } from "@wrongstack/core/types";
|
|
|
92
92
|
import { ProviderRegistry } from "@wrongstack/core/registry";
|
|
93
93
|
import {
|
|
94
94
|
buildProviderFactoriesFromRegistry,
|
|
95
|
+
createAiGatewayProviderFactory,
|
|
95
96
|
installCatalogModelOutputLimits,
|
|
96
97
|
makeProviderFromConfig,
|
|
97
98
|
withCatalogCapabilities
|
|
@@ -157,6 +158,7 @@ async function setupProvider(params) {
|
|
|
157
158
|
});
|
|
158
159
|
}
|
|
159
160
|
const providerRegistry = new ProviderRegistry();
|
|
161
|
+
providerRegistry.register(createAiGatewayProviderFactory());
|
|
160
162
|
if (config.features.modelsRegistry) {
|
|
161
163
|
try {
|
|
162
164
|
const factories = await buildProviderFactoriesFromRegistry({
|
|
@@ -181,11 +183,12 @@ Try \`wstack models refresh\` once you have network access, or run with --no-fea
|
|
|
181
183
|
};
|
|
182
184
|
let provider;
|
|
183
185
|
try {
|
|
186
|
+
const factoryType = providerConfig.type ?? config.provider;
|
|
184
187
|
const cfgWithType = { ...providerConfig, type: config.provider };
|
|
185
|
-
if (
|
|
186
|
-
provider = providerRegistry.create(cfgWithType);
|
|
188
|
+
if (providerRegistry.has(factoryType)) {
|
|
189
|
+
provider = providerRegistry.create(cfgWithType, factoryType);
|
|
187
190
|
} else {
|
|
188
|
-
provider = makeProviderFromConfig(config.provider, cfgWithType);
|
|
191
|
+
provider = makeProviderFromConfig(config.provider, { ...cfgWithType, type: factoryType });
|
|
189
192
|
}
|
|
190
193
|
} catch (err) {
|
|
191
194
|
throw new ConfigError({
|
|
@@ -213,4 +216,4 @@ export {
|
|
|
213
216
|
setupProvider,
|
|
214
217
|
createGracefulShutdown
|
|
215
218
|
};
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
219
|
+
//# sourceMappingURL=chunk-MRLYDHQ7.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
// src/provider-helpers.ts
|
|
3
|
+
import { catalogProviderIdFor } from "@wrongstack/providers";
|
|
3
4
|
function uniqueModelIds(primary, fallback) {
|
|
4
5
|
const seen = /* @__PURE__ */ new Set();
|
|
5
6
|
const out = [];
|
|
@@ -65,8 +66,8 @@ async function buildPickableProviders(modelsRegistry, config) {
|
|
|
65
66
|
for (const [id, cfg] of Object.entries(overlay)) {
|
|
66
67
|
if (!isSelectable(id)) continue;
|
|
67
68
|
seen.add(id);
|
|
68
|
-
const catalogType =
|
|
69
|
-
const inherited = catalogById.get(catalogType);
|
|
69
|
+
const catalogType = catalogProviderIdFor(id, cfg.type);
|
|
70
|
+
const inherited = catalogById.get(catalogType) ?? catalogById.get(cfg.type ?? id);
|
|
70
71
|
const family = cfg.family ?? inherited?.family ?? "unsupported";
|
|
71
72
|
if (family === "unsupported") continue;
|
|
72
73
|
const models = visibleModelIds(id, config, (inherited?.models ?? []).map((m) => m.id), cfg);
|
|
@@ -87,4 +88,4 @@ export {
|
|
|
87
88
|
hasApiKey,
|
|
88
89
|
buildPickableProviders
|
|
89
90
|
};
|
|
90
|
-
//# sourceMappingURL=chunk-
|
|
91
|
+
//# sourceMappingURL=chunk-N7ULWBO5.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
hasApiKey,
|
|
3
3
|
isKeylessLocalProvider,
|
|
4
4
|
visibleModelIds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-N7ULWBO5.js";
|
|
6
6
|
import {
|
|
7
7
|
appendHistory,
|
|
8
8
|
backupCurrent
|
|
@@ -1020,4 +1020,4 @@ export {
|
|
|
1020
1020
|
runLiveProviderPicker,
|
|
1021
1021
|
runPicker
|
|
1022
1022
|
};
|
|
1023
|
-
//# sourceMappingURL=chunk-
|
|
1023
|
+
//# sourceMappingURL=chunk-PEMN4T5O.js.map
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mutateConfigProviders,
|
|
3
|
+
normalizeKeys,
|
|
4
|
+
nowIso,
|
|
5
|
+
writeKeysBack
|
|
6
|
+
} from "./chunk-PJHET45A.js";
|
|
7
|
+
|
|
8
|
+
// src/auth-menu/openai-codex-oauth.ts
|
|
9
|
+
import { color } from "@wrongstack/core/utils";
|
|
10
|
+
import {
|
|
11
|
+
buildCodexAuthorizeUrl,
|
|
12
|
+
CODEX_BASE_URL,
|
|
13
|
+
CODEX_FALLBACK_REDIRECT_PORT,
|
|
14
|
+
CODEX_PROVIDER_ID,
|
|
15
|
+
CODEX_REDIRECT_HOST,
|
|
16
|
+
CODEX_REDIRECT_PATH,
|
|
17
|
+
CODEX_REDIRECT_PORT,
|
|
18
|
+
CODEX_SCOPE,
|
|
19
|
+
codexRedirectUri,
|
|
20
|
+
createState,
|
|
21
|
+
exchangeCodexAuthorizationCode,
|
|
22
|
+
extractAccountId,
|
|
23
|
+
generatePkce,
|
|
24
|
+
parseAuthorizationInput,
|
|
25
|
+
refreshCodexTokens,
|
|
26
|
+
resolveCodexModels
|
|
27
|
+
} from "@wrongstack/providers/oauth";
|
|
28
|
+
|
|
29
|
+
// src/auth-menu/loopback-server.ts
|
|
30
|
+
import { spawn } from "node:child_process";
|
|
31
|
+
import {
|
|
32
|
+
startLoopbackServer as startSharedLoopbackServer
|
|
33
|
+
} from "@wrongstack/providers/oauth";
|
|
34
|
+
import { callbackHtml } from "@wrongstack/providers/oauth";
|
|
35
|
+
function openBrowser(url) {
|
|
36
|
+
try {
|
|
37
|
+
const platform = process.platform;
|
|
38
|
+
const { command, args } = platform === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
39
|
+
const child = spawn(command, args, { stdio: "ignore", windowsHide: true });
|
|
40
|
+
child.on("error", () => {
|
|
41
|
+
});
|
|
42
|
+
child.unref();
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function startLoopbackServer(expectedState, ports, signal, callbackPath = "/auth/callback", redirectHost = "127.0.0.1") {
|
|
47
|
+
const [primary = 1455, ...fallbackPorts] = ports;
|
|
48
|
+
return startSharedLoopbackServer({
|
|
49
|
+
port: primary,
|
|
50
|
+
fallbackPorts: [...fallbackPorts],
|
|
51
|
+
host: redirectHost,
|
|
52
|
+
path: callbackPath,
|
|
53
|
+
expectedState,
|
|
54
|
+
...signal ? { signal } : {}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/auth-menu/openai-codex-oauth.ts
|
|
59
|
+
import {
|
|
60
|
+
CODEX_BASE_URL as CODEX_BASE_URL2,
|
|
61
|
+
CODEX_CATALOG_FAMILIES,
|
|
62
|
+
CODEX_PROVIDER_ID as CODEX_PROVIDER_ID2,
|
|
63
|
+
extractAccountId as extractAccountId2,
|
|
64
|
+
FALLBACK_CODEX_MODELS,
|
|
65
|
+
fallbackCodexModelIds,
|
|
66
|
+
fallbackCodexProviderModels,
|
|
67
|
+
fetchCodexModels,
|
|
68
|
+
filterCurrentCodexModelIds,
|
|
69
|
+
generatePkce as generatePkce2,
|
|
70
|
+
isCodexCatalogModel,
|
|
71
|
+
parseAuthorizationInput as parseAuthorizationInput2,
|
|
72
|
+
resolveCodexModels as resolveCodexModels2
|
|
73
|
+
} from "@wrongstack/providers/oauth";
|
|
74
|
+
var buildAuthorizeUrl = buildCodexAuthorizeUrl;
|
|
75
|
+
var exchangeAuthorizationCode = exchangeCodexAuthorizationCode;
|
|
76
|
+
function startLoopbackServer2(expectedState, signal) {
|
|
77
|
+
return startLoopbackServer(
|
|
78
|
+
expectedState,
|
|
79
|
+
[CODEX_REDIRECT_PORT, CODEX_FALLBACK_REDIRECT_PORT],
|
|
80
|
+
signal,
|
|
81
|
+
CODEX_REDIRECT_PATH,
|
|
82
|
+
CODEX_REDIRECT_HOST
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
var redirectUri = codexRedirectUri;
|
|
86
|
+
async function runCodexOAuthLogin(deps, opts = {}) {
|
|
87
|
+
const providerId = opts.providerId ?? CODEX_PROVIDER_ID;
|
|
88
|
+
const pkce = generatePkce();
|
|
89
|
+
const state = createState();
|
|
90
|
+
const ac = new AbortController();
|
|
91
|
+
let sigintCount = 0;
|
|
92
|
+
const onSig = () => {
|
|
93
|
+
sigintCount += 1;
|
|
94
|
+
if (sigintCount === 1) {
|
|
95
|
+
deps.renderer.write(color.dim("\n Cancelling sign-in\u2026 (press Ctrl+C again to force-quit)\n"));
|
|
96
|
+
ac.abort();
|
|
97
|
+
} else {
|
|
98
|
+
process.exit(130);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const external = opts.signal;
|
|
102
|
+
const onExternalAbort = () => ac.abort();
|
|
103
|
+
if (external) {
|
|
104
|
+
if (external.aborted) ac.abort();
|
|
105
|
+
else external.addEventListener("abort", onExternalAbort, { once: true });
|
|
106
|
+
} else {
|
|
107
|
+
process.on("SIGINT", onSig);
|
|
108
|
+
}
|
|
109
|
+
const server = await startLoopbackServer2(state, ac.signal);
|
|
110
|
+
const authorizeUrl = buildAuthorizeUrl(pkce.challenge, state, server.port);
|
|
111
|
+
const osc8 = (url) => `\x1B]8;;${url}\x1B\\${url}\x1B]8;;\x1B\\`;
|
|
112
|
+
deps.renderer.write(
|
|
113
|
+
color.bold(`
|
|
114
|
+
Sign in with ChatGPT \u2014 ${color.cyan(providerId)}
|
|
115
|
+
`) + color.dim(" Uses your ChatGPT Plus/Pro/Team subscription (not an API key).\n") + color.amber(" \u26A0 Using a subscription outside the official Codex client may violate\n") + color.amber(" OpenAI\u2019s Terms \u2014 your account could be rate-limited or banned.\n") + color.dim(" Sanctioned programmatic use = an API key: ") + color.bold("wstack auth openai") + color.dim("\n\n") + color.bold(` ${"\u2500".repeat(56)}
|
|
116
|
+
`) + color.bold(" Open this URL in your browser to sign in:\n") + color.cyan(` ${osc8(authorizeUrl)}
|
|
117
|
+
`) + color.bold(` ${"\u2500".repeat(56)}
|
|
118
|
+
|
|
119
|
+
`)
|
|
120
|
+
);
|
|
121
|
+
if (server.bound) {
|
|
122
|
+
openBrowser(authorizeUrl);
|
|
123
|
+
deps.renderer.write(
|
|
124
|
+
color.dim(" A browser window should open. Waiting for you to finish signing in...\n") + color.dim(` (Listening on ${redirectUri(server.port)} \u2014 press Ctrl+C to cancel.)
|
|
125
|
+
`)
|
|
126
|
+
);
|
|
127
|
+
} else {
|
|
128
|
+
deps.renderer.write(
|
|
129
|
+
color.amber(" \u26A0 Could not start the local callback listener (ports 1455 and 1457 in use).\n") + color.dim(" After signing in, copy the full redirect URL from your browser\n") + color.dim(" (it starts with http://localhost:1455/auth/callback or :1457) and paste it below.\n")
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
let code;
|
|
133
|
+
try {
|
|
134
|
+
if (server.bound) {
|
|
135
|
+
const callback = await server.waitForCode();
|
|
136
|
+
if (ac.signal.aborted) {
|
|
137
|
+
deps.renderer.write(color.dim(" Cancelled.\n"));
|
|
138
|
+
return 1;
|
|
139
|
+
}
|
|
140
|
+
if (callback) code = callback.code;
|
|
141
|
+
}
|
|
142
|
+
if (!code) {
|
|
143
|
+
const input = (await deps.reader.readLine(
|
|
144
|
+
`
|
|
145
|
+
${color.amber("?")} Paste the redirect URL or code ${color.dim("(or q to cancel)")}: `
|
|
146
|
+
)).trim();
|
|
147
|
+
if (input.toLowerCase() === "q" || input === "") {
|
|
148
|
+
deps.renderer.write(color.dim(" Cancelled.\n"));
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
const parsed = parseAuthorizationInput(input);
|
|
152
|
+
if (parsed.state && parsed.state !== state) {
|
|
153
|
+
deps.renderer.writeError(" State mismatch \u2014 please restart the login flow.");
|
|
154
|
+
return 1;
|
|
155
|
+
}
|
|
156
|
+
code = parsed.code;
|
|
157
|
+
}
|
|
158
|
+
if (!code) {
|
|
159
|
+
deps.renderer.writeError(" No authorization code received.");
|
|
160
|
+
return 1;
|
|
161
|
+
}
|
|
162
|
+
deps.renderer.write(color.dim("\n Exchanging authorization code for tokens...\n"));
|
|
163
|
+
const tokens = await exchangeAuthorizationCode(code, pkce.verifier, ac.signal, server.port);
|
|
164
|
+
const accountId = extractAccountId(tokens.access) ?? (tokens.idToken ? extractAccountId(tokens.idToken) : null);
|
|
165
|
+
if (!accountId) {
|
|
166
|
+
deps.renderer.writeError(
|
|
167
|
+
" Signed in, but the token has no ChatGPT account id.\n This account may not have Codex/ChatGPT subscription access."
|
|
168
|
+
);
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
deps.renderer.write(color.dim(" Fetching available models...\n"));
|
|
172
|
+
const models = await resolveCodexModels(
|
|
173
|
+
deps.modelsRegistry,
|
|
174
|
+
tokens.access,
|
|
175
|
+
CODEX_BASE_URL,
|
|
176
|
+
ac.signal
|
|
177
|
+
);
|
|
178
|
+
const saved = await saveCodexTokens(deps, providerId, tokens, accountId, models);
|
|
179
|
+
if (!saved) return 1;
|
|
180
|
+
const modelHint = models[0] ?? "gpt-5.5";
|
|
181
|
+
deps.renderer.write(color.green("\n \u2713 Signed in with ChatGPT!\n"));
|
|
182
|
+
deps.renderer.writeInfo(
|
|
183
|
+
` Saved as provider ${color.bold(providerId)}${models.length > 0 ? ` (${models.length} models)` : ""}.
|
|
184
|
+
Use: ${color.bold(`wstack --provider ${providerId} --model ${modelHint}`)} "<task>"
|
|
185
|
+
` + color.dim(" Tokens refresh automatically before they expire.\n")
|
|
186
|
+
);
|
|
187
|
+
return 0;
|
|
188
|
+
} catch (err) {
|
|
189
|
+
const msg = err instanceof DOMException && err.name === "AbortError" ? "Login cancelled." : err.message;
|
|
190
|
+
deps.renderer.writeError(` Login failed: ${msg}`);
|
|
191
|
+
return 1;
|
|
192
|
+
} finally {
|
|
193
|
+
server.close();
|
|
194
|
+
if (external) external.removeEventListener("abort", onExternalAbort);
|
|
195
|
+
else process.off("SIGINT", onSig);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async function saveCodexTokens(deps, providerId, tokens, accountId, models) {
|
|
199
|
+
const entry = {
|
|
200
|
+
label: "oauth-default",
|
|
201
|
+
apiKey: tokens.access,
|
|
202
|
+
createdAt: nowIso(),
|
|
203
|
+
authMethod: "oauth",
|
|
204
|
+
expiresAt: new Date(tokens.expires).toISOString(),
|
|
205
|
+
refreshToken: tokens.refresh,
|
|
206
|
+
tokenType: "bearer",
|
|
207
|
+
scope: CODEX_SCOPE,
|
|
208
|
+
accountId
|
|
209
|
+
};
|
|
210
|
+
try {
|
|
211
|
+
await mutateConfigProviders(deps.profileConfigPath, deps.vault, (all) => {
|
|
212
|
+
const existing = all[providerId];
|
|
213
|
+
const p = existing ? { ...existing } : { type: providerId };
|
|
214
|
+
p.family = "openai-codex";
|
|
215
|
+
if (!p.baseUrl) p.baseUrl = CODEX_BASE_URL;
|
|
216
|
+
p.models = [...models];
|
|
217
|
+
const keys = normalizeKeys(p).filter((k) => k.label !== entry.label);
|
|
218
|
+
keys.push(entry);
|
|
219
|
+
writeKeysBack(p, keys);
|
|
220
|
+
p.activeKey = entry.label;
|
|
221
|
+
all[providerId] = p;
|
|
222
|
+
}, deps.profileConfigPath);
|
|
223
|
+
return true;
|
|
224
|
+
} catch (err) {
|
|
225
|
+
deps.renderer.writeError(` Failed to save tokens: ${err.message}`);
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export {
|
|
231
|
+
openBrowser,
|
|
232
|
+
startLoopbackServer,
|
|
233
|
+
runCodexOAuthLogin,
|
|
234
|
+
fallbackCodexProviderModels,
|
|
235
|
+
filterCurrentCodexModelIds,
|
|
236
|
+
isCodexCatalogModel
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=chunk-PYTFS4MC.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LOCAL_LLM_PRESETS,
|
|
3
3
|
runLiveProviderPicker
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PEMN4T5O.js";
|
|
5
5
|
import {
|
|
6
6
|
openBrowser,
|
|
7
7
|
runCodexOAuthLogin,
|
|
8
8
|
startLoopbackServer
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PYTFS4MC.js";
|
|
10
10
|
import {
|
|
11
11
|
activeLabel,
|
|
12
12
|
loadConfigProviders,
|
|
@@ -146,9 +146,10 @@ async function runClaudeOAuthLogin(deps, opts = {}) {
|
|
|
146
146
|
const ac = new AbortController();
|
|
147
147
|
const onSig = () => ac.abort();
|
|
148
148
|
const external = opts.signal;
|
|
149
|
+
const onExternalAbort = () => ac.abort();
|
|
149
150
|
if (external) {
|
|
150
151
|
if (external.aborted) ac.abort();
|
|
151
|
-
else external.addEventListener("abort",
|
|
152
|
+
else external.addEventListener("abort", onExternalAbort, { once: true });
|
|
152
153
|
} else {
|
|
153
154
|
process.on("SIGINT", onSig);
|
|
154
155
|
}
|
|
@@ -222,7 +223,8 @@ async function runClaudeOAuthLogin(deps, opts = {}) {
|
|
|
222
223
|
return 1;
|
|
223
224
|
} finally {
|
|
224
225
|
server.close();
|
|
225
|
-
if (
|
|
226
|
+
if (external) external.removeEventListener("abort", onExternalAbort);
|
|
227
|
+
else process.off("SIGINT", onSig);
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
async function saveClaudeTokens(deps, providerId, tokens, models) {
|
|
@@ -257,7 +259,6 @@ async function saveClaudeTokens(deps, providerId, tokens, models) {
|
|
|
257
259
|
}
|
|
258
260
|
|
|
259
261
|
// src/auth-menu/github-copilot-oauth.ts
|
|
260
|
-
import { spawn } from "node:child_process";
|
|
261
262
|
import { color as color2 } from "@wrongstack/core/utils";
|
|
262
263
|
import { FetchError as FetchError2, ParseError as ParseError2 } from "@wrongstack/core/types";
|
|
263
264
|
import { copilotBaseUrlFromToken, refreshCopilotToken } from "@wrongstack/providers";
|
|
@@ -272,17 +273,6 @@ var COPILOT_HEADERS = {
|
|
|
272
273
|
};
|
|
273
274
|
var COPILOT_API_VERSION = "2026-06-01";
|
|
274
275
|
var COPILOT_PROVIDER_ID = "github-copilot";
|
|
275
|
-
function openBrowser2(url) {
|
|
276
|
-
try {
|
|
277
|
-
const platform = process.platform;
|
|
278
|
-
const { command, args } = platform === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
279
|
-
const child = spawn(command, args, { stdio: "ignore", windowsHide: true });
|
|
280
|
-
child.on("error", () => {
|
|
281
|
-
});
|
|
282
|
-
child.unref();
|
|
283
|
-
} catch {
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
276
|
function sleep(ms, signal) {
|
|
287
277
|
return new Promise((resolve, reject) => {
|
|
288
278
|
if (signal.aborted) return reject(new DOMException("Aborted", "AbortError"));
|
|
@@ -430,7 +420,7 @@ async function runCopilotOAuthLogin(deps, opts = {}) {
|
|
|
430
420
|
|
|
431
421
|
`)
|
|
432
422
|
);
|
|
433
|
-
|
|
423
|
+
openBrowser(device.verification_uri);
|
|
434
424
|
deps.renderer.write(color2.dim(" Waiting for you to authorize in the browser...\n"));
|
|
435
425
|
const githubToken = await pollForGitHubToken(device, ac.signal);
|
|
436
426
|
deps.renderer.write(color2.dim(" Authorized. Fetching your Copilot token...\n"));
|
|
@@ -715,6 +705,7 @@ function validateFamily(raw) {
|
|
|
715
705
|
|
|
716
706
|
// src/auth-menu/add-provider.ts
|
|
717
707
|
import { atomicWrite, color as color5 } from "@wrongstack/core/utils";
|
|
708
|
+
import { catalogProviderIdFor, PROVIDER_DEFINITIONS } from "@wrongstack/providers";
|
|
718
709
|
import * as fs from "node:fs/promises";
|
|
719
710
|
|
|
720
711
|
// src/provider-id.ts
|
|
@@ -726,6 +717,20 @@ function nextCustomProviderId(existing) {
|
|
|
726
717
|
}
|
|
727
718
|
|
|
728
719
|
// src/auth-menu/add-provider.ts
|
|
720
|
+
function ownDefinitionsAsCatalog(known) {
|
|
721
|
+
return Object.values(PROVIDER_DEFINITIONS).filter((d) => !known.has(d.id) && d.family !== "unsupported" && d.usage !== "local").map((d) => ({
|
|
722
|
+
id: d.id,
|
|
723
|
+
name: d.name,
|
|
724
|
+
family: d.family,
|
|
725
|
+
envVars: [...d.envVars],
|
|
726
|
+
models: [],
|
|
727
|
+
// `discoveryOnlyBaseUrl` definitions keep their model-list URL out of the
|
|
728
|
+
// Base URL prompt: offering it as a default persists it as the provider's
|
|
729
|
+
// wire base, which is a different endpoint (see the AI Gateway entry).
|
|
730
|
+
...d.baseUrl && !d.discoveryOnlyBaseUrl ? { apiBase: d.baseUrl } : {},
|
|
731
|
+
...d.docsUrl ? { doc: d.docsUrl } : {}
|
|
732
|
+
}));
|
|
733
|
+
}
|
|
729
734
|
async function addFromCatalog(deps) {
|
|
730
735
|
let catalog = [];
|
|
731
736
|
try {
|
|
@@ -736,6 +741,7 @@ async function addFromCatalog(deps) {
|
|
|
736
741
|
if (catalog.length === 0) {
|
|
737
742
|
return addManualEntry(deps);
|
|
738
743
|
}
|
|
744
|
+
catalog = [...catalog, ...ownDefinitionsAsCatalog(new Set(catalog.map((p) => p.id)))];
|
|
739
745
|
const saved = new Set(Object.keys(await loadProviders(deps)));
|
|
740
746
|
deps.renderer.write(
|
|
741
747
|
color5.dim(
|
|
@@ -937,7 +943,7 @@ async function addKeyForProvider(providerId, deps, template) {
|
|
|
937
943
|
}
|
|
938
944
|
async function resolveDefaultModelId(deps, providerId, template) {
|
|
939
945
|
if (template.models && template.models.length > 0) return template.models[0];
|
|
940
|
-
const catalogId =
|
|
946
|
+
const catalogId = catalogProviderIdFor(providerId, template.type);
|
|
941
947
|
const provider = await deps.modelsRegistry.getProvider(catalogId).catch(() => void 0);
|
|
942
948
|
return provider?.models?.[0]?.id;
|
|
943
949
|
}
|
|
@@ -1327,4 +1333,4 @@ export {
|
|
|
1327
1333
|
addKeyForProvider,
|
|
1328
1334
|
runAuthLocal
|
|
1329
1335
|
};
|
|
1330
|
-
//# sourceMappingURL=chunk-
|
|
1336
|
+
//# sourceMappingURL=chunk-V76R7DC5.js.map
|