@wrongstack/cli 1.0.1 → 1.0.3
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/data/providers.json +21 -21
- package/dist/{acp-3LARESEO.js → acp-JK4ZQO3R.js} +4 -3
- package/dist/{auth-ZUMCDNE5.js → auth-XD3GN5RJ.js} +78 -54
- package/dist/auth-menu/index.d.ts +1 -0
- package/dist/auth-menu/oauth-menu.d.ts +3 -1
- package/dist/auth-menu/panel-service.d.ts +2 -0
- package/dist/auth-menu/provider-auth-login.d.ts +12 -0
- package/dist/auth-menu/types.d.ts +3 -0
- package/dist/auto-discover-providers-DXR25GTG.js +7 -0
- package/dist/boot/dispatch-webui.d.ts +1 -0
- package/dist/boot/system-prompt-builder.d.ts +7 -0
- package/dist/boot/system-prompt.d.ts +2 -1
- package/dist/chimera-reviewer-policy.d.ts +1 -1
- package/dist/{chunk-KHWDTNBZ.js → chunk-4NHD5OXJ.js} +2 -2
- package/dist/chunk-D5GB5MHA.js +87 -0
- package/dist/chunk-DAKVBMD4.js +36 -0
- package/dist/{chunk-ZSZ3EYWH.js → chunk-GMY45LO6.js} +9 -5
- package/dist/{chunk-D2VCUN7M.js → chunk-IUEKNHPT.js} +10 -10
- package/dist/{chunk-MNQQ4ZNF.js → chunk-ONOT5OJ2.js} +290 -687
- package/dist/chunk-SIGUWXAA.js +43 -0
- package/dist/{chunk-TEBMCYZN.js → chunk-SIS37L3W.js} +58 -2
- package/dist/{chunk-5IA5337I.js → chunk-U6KCWRMC.js} +4 -2
- package/dist/{cli-context-7X3M6U73.js → cli-context-Q6QP534K.js} +18 -7
- package/dist/{cli-main-53KG6HAV.js → cli-main-JQXCDZEA.js} +2909 -2277
- package/dist/execute-deps.d.ts +1 -0
- package/dist/{execution-MIBWBYB6.js → execution-KH7WJNAX.js} +11 -4
- package/dist/index.js +3 -3
- package/dist/live-settings-input.d.ts +2 -0
- package/dist/{mailbox-serve-VUCWZ2SJ.js → mailbox-serve-X3CR6VFW.js} +4 -3
- package/dist/{modeldiag-FMJT37SN.js → modeldiag-46CMWUNM.js} +31 -24
- package/dist/{plugin-usage-HFBI3TFT.js → plugin-usage-M6KET4OZ.js} +2 -2
- package/dist/{plugins-PZ2VZL7V.js → plugins-U7KGQAUG.js} +3 -3
- package/dist/{providers-models-YVMVYWRS.js → providers-models-6MOGAOVK.js} +2 -2
- package/dist/{short-circuit-flags-UREFSYBL.js → short-circuit-flags-ZNZX44MC.js} +2 -2
- package/dist/slash-commands/codebase-map.d.ts +11 -0
- package/dist/slash-commands/command-context.d.ts +7 -0
- package/dist/slash-commands/context.d.ts +10 -0
- package/dist/slash-commands/openai-quota.d.ts +31 -0
- package/dist/{subcommands-WJLBHVKC.js → subcommands-CUTGBDKP.js} +2 -2
- package/dist/{webui-server-5R35BHWZ.js → webui-server-QWBUT7BO.js} +19 -2
- package/dist/webui-server-options.d.ts +1 -0
- package/dist/wiring/atlas-prompt-contributor.d.ts +54 -0
- package/dist/wiring/cli-execute-builder.d.ts +1 -0
- package/dist/wiring/codebase-embeddings.d.ts +31 -0
- package/dist/wiring/command-host-state.d.ts +2 -0
- package/dist/wiring/concept-summarizer.d.ts +32 -0
- package/dist/wiring/external-plugins.d.ts +1 -0
- package/dist/wiring/lifecycle-plugins.d.ts +2 -1
- package/dist/wiring/plugins.d.ts +2 -1
- package/dist/wiring/provider.d.ts +2 -1
- package/package.json +29 -29
- package/dist/auto-discover-providers-VQU3IZMR.js +0 -7
- package/dist/chunk-52C7PD2H.js +0 -61
- package/dist/chunk-TNK6237M.js +0 -262
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { ProviderRegistry } from '@wrongstack/core/registry';
|
|
1
|
+
import { ProviderAuthRegistry, ProviderRegistry } from '@wrongstack/core/registry';
|
|
2
2
|
import type { ResolvedProvider } from '@wrongstack/core/types';
|
|
3
3
|
import { type Config, type Logger, type ModelsRegistry } from '@wrongstack/core/types';
|
|
4
4
|
interface ProviderSetupResult {
|
|
5
5
|
resolvedProvider: ResolvedProvider | undefined;
|
|
6
6
|
provider: ReturnType<ProviderRegistry['create']>;
|
|
7
7
|
providerRegistry: ProviderRegistry;
|
|
8
|
+
providerAuthRegistry: ProviderAuthRegistry;
|
|
8
9
|
}
|
|
9
10
|
export declare function setupProvider(params: {
|
|
10
11
|
config: Config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack CLI — terminal AI coding agent with provider catalog from models.dev. Provides `wrongstack` and `wstack` binaries.",
|
|
6
6
|
"keywords": [
|
|
@@ -41,36 +41,36 @@
|
|
|
41
41
|
"data"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@wrongstack/acp": "1.0.
|
|
45
|
-
"@wrongstack/bench": "1.0.
|
|
46
|
-
"@wrongstack/core": "1.0.
|
|
47
|
-
"@wrongstack/primitives": "1.0.
|
|
48
|
-
"@wrongstack/kanban": "1.0.
|
|
49
|
-
"@wrongstack/mcp": "1.0.
|
|
50
|
-
"@wrongstack/persistence": "1.0.
|
|
51
|
-
"@wrongstack/plug-lsp": "1.0.
|
|
52
|
-
"@wrongstack/plugins": "1.0.
|
|
53
|
-
"@wrongstack/providers": "1.0.
|
|
54
|
-
"@wrongstack/requirement-intake": "1.0.
|
|
55
|
-
"@wrongstack/runtime": "1.0.
|
|
56
|
-
"@wrongstack/sage": "1.0.
|
|
57
|
-
"@wrongstack/sdd": "1.0.
|
|
58
|
-
"@wrongstack/security-scanner": "1.0.
|
|
59
|
-
"@wrongstack/simpleui": "1.0.
|
|
60
|
-
"@wrongstack/techstack": "1.0.
|
|
61
|
-
"@wrongstack/telegram": "1.0.
|
|
62
|
-
"@wrongstack/tools": "1.0.
|
|
63
|
-
"@wrongstack/tui": "1.0.
|
|
64
|
-
"@wrongstack/vector-memory": "1.0.
|
|
65
|
-
"@wrongstack/webui": "1.0.
|
|
66
|
-
"@wrongstack/webui-hq": "1.0.
|
|
67
|
-
"@wrongstack/webui-protocol": "1.0.
|
|
68
|
-
"@wrongstack/wrongtrace": "1.0.
|
|
69
|
-
"@wrongstack/webui-server": "1.0.
|
|
44
|
+
"@wrongstack/acp": "1.0.3",
|
|
45
|
+
"@wrongstack/bench": "1.0.3",
|
|
46
|
+
"@wrongstack/core": "1.0.3",
|
|
47
|
+
"@wrongstack/primitives": "1.0.3",
|
|
48
|
+
"@wrongstack/kanban": "1.0.3",
|
|
49
|
+
"@wrongstack/mcp": "1.0.3",
|
|
50
|
+
"@wrongstack/persistence": "1.0.3",
|
|
51
|
+
"@wrongstack/plug-lsp": "1.0.3",
|
|
52
|
+
"@wrongstack/plugins": "1.0.3",
|
|
53
|
+
"@wrongstack/providers": "1.0.3",
|
|
54
|
+
"@wrongstack/requirement-intake": "1.0.3",
|
|
55
|
+
"@wrongstack/runtime": "1.0.3",
|
|
56
|
+
"@wrongstack/sage": "1.0.3",
|
|
57
|
+
"@wrongstack/sdd": "1.0.3",
|
|
58
|
+
"@wrongstack/security-scanner": "1.0.3",
|
|
59
|
+
"@wrongstack/simpleui": "1.0.3",
|
|
60
|
+
"@wrongstack/techstack": "1.0.3",
|
|
61
|
+
"@wrongstack/telegram": "1.0.3",
|
|
62
|
+
"@wrongstack/tools": "1.0.3",
|
|
63
|
+
"@wrongstack/tui": "1.0.3",
|
|
64
|
+
"@wrongstack/vector-memory": "1.0.3",
|
|
65
|
+
"@wrongstack/webui": "1.0.3",
|
|
66
|
+
"@wrongstack/webui-hq": "1.0.3",
|
|
67
|
+
"@wrongstack/webui-protocol": "1.0.3",
|
|
68
|
+
"@wrongstack/wrongtrace": "1.0.3",
|
|
69
|
+
"@wrongstack/webui-server": "1.0.3",
|
|
70
70
|
"ws": "^8.21.3"
|
|
71
71
|
},
|
|
72
72
|
"optionalDependencies": {
|
|
73
|
-
"@wrongstack/desktop": "1.0.
|
|
73
|
+
"@wrongstack/desktop": "1.0.3"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@types/node": "^26.2.0",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
"scripts": {
|
|
85
85
|
"build": "node ../../scripts/build-package.mjs",
|
|
86
|
-
"typecheck": "pnpm --filter @wrongstack/tools run build && pnpm --filter @wrongstack/tui run build && tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
86
|
+
"typecheck": "pnpm --filter @wrongstack/tools run build && pnpm --filter @wrongstack/tui run build && pnpm --filter @wrongstack/webui-server run build && tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
87
87
|
"test": "vitest run",
|
|
88
88
|
"test:hqdash": "vitest run --config vitest.hqdash.config.ts",
|
|
89
89
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|
package/dist/chunk-52C7PD2H.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// src/boot/auto-discover-providers.ts
|
|
3
|
-
import * as fs from "node:fs/promises";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import { discoverOpenAICompatibleModels, resolveDiscoveryTargets } from "@wrongstack/providers";
|
|
6
|
-
async function readCache(file) {
|
|
7
|
-
try {
|
|
8
|
-
return JSON.parse(await fs.readFile(file, "utf8"));
|
|
9
|
-
} catch {
|
|
10
|
-
return {};
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
async function discoverAndMergeProviders(opts) {
|
|
14
|
-
const targets = resolveDiscoveryTargets(opts.config);
|
|
15
|
-
if (targets.length === 0) return;
|
|
16
|
-
const cacheFile = path.join(opts.cacheDir, "discovered-models-cache.json");
|
|
17
|
-
const cache = await readCache(cacheFile);
|
|
18
|
-
let cacheDirty = false;
|
|
19
|
-
await Promise.all(
|
|
20
|
-
targets.map(async ({ id, cfg, baseUrl, apiKey, cacheKey }) => {
|
|
21
|
-
const provider = await discoverOpenAICompatibleModels(id, {
|
|
22
|
-
baseUrl,
|
|
23
|
-
apiKey,
|
|
24
|
-
headers: cfg.headers,
|
|
25
|
-
providerName: id,
|
|
26
|
-
fetchImpl: opts.fetchImpl
|
|
27
|
-
});
|
|
28
|
-
if (provider) {
|
|
29
|
-
cache[cacheKey] = { fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), provider };
|
|
30
|
-
cacheDirty = true;
|
|
31
|
-
opts.registry.mergeOverlay({ [id]: provider });
|
|
32
|
-
opts.logger?.info(
|
|
33
|
-
`auto-discovered ${Object.keys(provider.models).length} models for "${id}" from ${baseUrl}`
|
|
34
|
-
);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const cached = cache[cacheKey];
|
|
38
|
-
if (cached) {
|
|
39
|
-
opts.registry.mergeOverlay({ [id]: cached.provider });
|
|
40
|
-
opts.logger?.warn(
|
|
41
|
-
`auto-discovery for "${id}" failed; using ${Object.keys(cached.provider.models).length} cached models from ${cached.fetchedAt}`
|
|
42
|
-
);
|
|
43
|
-
} else {
|
|
44
|
-
opts.logger?.warn(
|
|
45
|
-
`auto-discovery for "${id}" failed and no cache available (server at ${baseUrl} unreachable?)`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
);
|
|
50
|
-
if (cacheDirty) {
|
|
51
|
-
try {
|
|
52
|
-
await fs.writeFile(cacheFile, JSON.stringify(cache), "utf8");
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export {
|
|
59
|
-
discoverAndMergeProviders
|
|
60
|
-
};
|
|
61
|
-
//# sourceMappingURL=chunk-52C7PD2H.js.map
|
package/dist/chunk-TNK6237M.js
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
mutateConfigProviders,
|
|
3
|
-
normalizeKeys,
|
|
4
|
-
nowIso,
|
|
5
|
-
writeKeysBack
|
|
6
|
-
} from "./chunk-DR2OXU46.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
|
-
var URL_METACHAR_REGEX = /[&|;<>(){}^"'`%\n\r\0]/;
|
|
36
|
-
function isSafeBrowserUrl(url) {
|
|
37
|
-
if (URL_METACHAR_REGEX.test(url)) return false;
|
|
38
|
-
try {
|
|
39
|
-
const parsed = new URL(url);
|
|
40
|
-
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
41
|
-
} catch {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function openBrowser(url) {
|
|
46
|
-
if (!isSafeBrowserUrl(url)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
const platform = process.platform;
|
|
51
|
-
const { command, args } = platform === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
52
|
-
const child = spawn(command, args, { stdio: "ignore", windowsHide: true });
|
|
53
|
-
child.on("error", () => {
|
|
54
|
-
});
|
|
55
|
-
child.unref();
|
|
56
|
-
} catch {
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function startLoopbackServer(expectedState, ports, signal, callbackPath = "/auth/callback", redirectHost = "127.0.0.1") {
|
|
60
|
-
const [primary = 1455, ...fallbackPorts] = ports;
|
|
61
|
-
return startSharedLoopbackServer({
|
|
62
|
-
port: primary,
|
|
63
|
-
fallbackPorts: [...fallbackPorts],
|
|
64
|
-
host: redirectHost,
|
|
65
|
-
path: callbackPath,
|
|
66
|
-
expectedState,
|
|
67
|
-
...signal ? { signal } : {}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// src/auth-menu/openai-codex-oauth.ts
|
|
72
|
-
import {
|
|
73
|
-
CODEX_BASE_URL as CODEX_BASE_URL2,
|
|
74
|
-
CODEX_CATALOG_FAMILIES,
|
|
75
|
-
CODEX_PROVIDER_ID as CODEX_PROVIDER_ID2,
|
|
76
|
-
extractAccountId as extractAccountId2,
|
|
77
|
-
FALLBACK_CODEX_MODELS,
|
|
78
|
-
fallbackCodexModelIds,
|
|
79
|
-
fallbackCodexProviderModels,
|
|
80
|
-
fetchCodexModels,
|
|
81
|
-
filterCurrentCodexModelIds,
|
|
82
|
-
generatePkce as generatePkce2,
|
|
83
|
-
isCodexCatalogModel,
|
|
84
|
-
parseAuthorizationInput as parseAuthorizationInput2,
|
|
85
|
-
resolveCodexModels as resolveCodexModels2
|
|
86
|
-
} from "@wrongstack/providers/oauth";
|
|
87
|
-
var buildAuthorizeUrl = buildCodexAuthorizeUrl;
|
|
88
|
-
var exchangeAuthorizationCode = exchangeCodexAuthorizationCode;
|
|
89
|
-
function startLoopbackServer2(expectedState, signal) {
|
|
90
|
-
return startLoopbackServer(
|
|
91
|
-
expectedState,
|
|
92
|
-
[CODEX_REDIRECT_PORT, CODEX_FALLBACK_REDIRECT_PORT],
|
|
93
|
-
signal,
|
|
94
|
-
CODEX_REDIRECT_PATH,
|
|
95
|
-
CODEX_REDIRECT_HOST
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
var redirectUri = codexRedirectUri;
|
|
99
|
-
async function runCodexOAuthLogin(deps, opts = {}) {
|
|
100
|
-
const providerId = opts.providerId ?? CODEX_PROVIDER_ID;
|
|
101
|
-
const pkce = generatePkce();
|
|
102
|
-
const state = createState();
|
|
103
|
-
const ac = new AbortController();
|
|
104
|
-
let sigintCount = 0;
|
|
105
|
-
const onSig = () => {
|
|
106
|
-
sigintCount += 1;
|
|
107
|
-
if (sigintCount === 1) {
|
|
108
|
-
deps.renderer.write(
|
|
109
|
-
color.dim("\n Cancelling sign-in\u2026 (press Ctrl+C again to force-quit)\n")
|
|
110
|
-
);
|
|
111
|
-
ac.abort();
|
|
112
|
-
} else {
|
|
113
|
-
process.exit(130);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const external = opts.signal;
|
|
117
|
-
const onExternalAbort = () => ac.abort();
|
|
118
|
-
if (external) {
|
|
119
|
-
if (external.aborted) ac.abort();
|
|
120
|
-
else external.addEventListener("abort", onExternalAbort, { once: true });
|
|
121
|
-
} else {
|
|
122
|
-
process.on("SIGINT", onSig);
|
|
123
|
-
}
|
|
124
|
-
const server = await startLoopbackServer2(state, ac.signal);
|
|
125
|
-
const authorizeUrl = buildAuthorizeUrl(pkce.challenge, state, server.port);
|
|
126
|
-
const osc8 = (url) => `\x1B]8;;${url}\x1B\\${url}\x1B]8;;\x1B\\`;
|
|
127
|
-
deps.renderer.write(
|
|
128
|
-
color.bold(`
|
|
129
|
-
Sign in with ChatGPT \u2014 ${color.cyan(providerId)}
|
|
130
|
-
`) + 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)}
|
|
131
|
-
`) + color.bold(" Open this URL in your browser to sign in:\n") + color.cyan(` ${osc8(authorizeUrl)}
|
|
132
|
-
`) + color.bold(` ${"\u2500".repeat(56)}
|
|
133
|
-
|
|
134
|
-
`)
|
|
135
|
-
);
|
|
136
|
-
if (server.bound) {
|
|
137
|
-
openBrowser(authorizeUrl);
|
|
138
|
-
deps.renderer.write(
|
|
139
|
-
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.)
|
|
140
|
-
`)
|
|
141
|
-
);
|
|
142
|
-
} else {
|
|
143
|
-
deps.renderer.write(
|
|
144
|
-
color.amber(
|
|
145
|
-
" \u26A0 Could not start the local callback listener (ports 1455 and 1457 in use).\n"
|
|
146
|
-
) + color.dim(" After signing in, copy the full redirect URL from your browser\n") + color.dim(
|
|
147
|
-
" (it starts with http://localhost:1455/auth/callback or :1457) and paste it below.\n"
|
|
148
|
-
)
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
let code;
|
|
152
|
-
try {
|
|
153
|
-
if (server.bound) {
|
|
154
|
-
const callback = await server.waitForCode();
|
|
155
|
-
if (ac.signal.aborted) {
|
|
156
|
-
deps.renderer.write(color.dim(" Cancelled.\n"));
|
|
157
|
-
return 1;
|
|
158
|
-
}
|
|
159
|
-
if (callback) code = callback.code;
|
|
160
|
-
}
|
|
161
|
-
if (!code) {
|
|
162
|
-
const input = (await deps.reader.readLine(
|
|
163
|
-
`
|
|
164
|
-
${color.amber("?")} Paste the redirect URL or code ${color.dim("(or q to cancel)")}: `
|
|
165
|
-
)).trim();
|
|
166
|
-
if (input.toLowerCase() === "q" || input === "") {
|
|
167
|
-
deps.renderer.write(color.dim(" Cancelled.\n"));
|
|
168
|
-
return 1;
|
|
169
|
-
}
|
|
170
|
-
const parsed = parseAuthorizationInput(input);
|
|
171
|
-
if (parsed.state && parsed.state !== state) {
|
|
172
|
-
deps.renderer.writeError(" State mismatch \u2014 please restart the login flow.");
|
|
173
|
-
return 1;
|
|
174
|
-
}
|
|
175
|
-
code = parsed.code;
|
|
176
|
-
}
|
|
177
|
-
if (!code) {
|
|
178
|
-
deps.renderer.writeError(" No authorization code received.");
|
|
179
|
-
return 1;
|
|
180
|
-
}
|
|
181
|
-
deps.renderer.write(color.dim("\n Exchanging authorization code for tokens...\n"));
|
|
182
|
-
const tokens = await exchangeAuthorizationCode(code, pkce.verifier, ac.signal, server.port);
|
|
183
|
-
const accountId = extractAccountId(tokens.access) ?? (tokens.idToken ? extractAccountId(tokens.idToken) : null);
|
|
184
|
-
if (!accountId) {
|
|
185
|
-
deps.renderer.writeError(
|
|
186
|
-
" Signed in, but the token has no ChatGPT account id.\n This account may not have Codex/ChatGPT subscription access."
|
|
187
|
-
);
|
|
188
|
-
return 1;
|
|
189
|
-
}
|
|
190
|
-
deps.renderer.write(color.dim(" Fetching available models...\n"));
|
|
191
|
-
const models = await resolveCodexModels(
|
|
192
|
-
deps.modelsRegistry,
|
|
193
|
-
tokens.access,
|
|
194
|
-
CODEX_BASE_URL,
|
|
195
|
-
ac.signal
|
|
196
|
-
);
|
|
197
|
-
const saved = await saveCodexTokens(deps, providerId, tokens, accountId, models);
|
|
198
|
-
if (!saved) return 1;
|
|
199
|
-
const modelHint = models[0] ?? "gpt-5.5";
|
|
200
|
-
deps.renderer.write(color.green("\n \u2713 Signed in with ChatGPT!\n"));
|
|
201
|
-
deps.renderer.writeInfo(
|
|
202
|
-
` Saved as provider ${color.bold(providerId)}${models.length > 0 ? ` (${models.length} models)` : ""}.
|
|
203
|
-
Use: ${color.bold(`wstack --provider ${providerId} --model ${modelHint}`)} "<task>"
|
|
204
|
-
` + color.dim(" Tokens refresh automatically before they expire.\n")
|
|
205
|
-
);
|
|
206
|
-
return 0;
|
|
207
|
-
} catch (err) {
|
|
208
|
-
const msg = err instanceof DOMException && err.name === "AbortError" ? "Login cancelled." : err.message;
|
|
209
|
-
deps.renderer.writeError(` Login failed: ${msg}`);
|
|
210
|
-
return 1;
|
|
211
|
-
} finally {
|
|
212
|
-
server.close();
|
|
213
|
-
if (external) external.removeEventListener("abort", onExternalAbort);
|
|
214
|
-
else process.off("SIGINT", onSig);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
async function saveCodexTokens(deps, providerId, tokens, accountId, models) {
|
|
218
|
-
const entry = {
|
|
219
|
-
label: "oauth-default",
|
|
220
|
-
apiKey: tokens.access,
|
|
221
|
-
createdAt: nowIso(),
|
|
222
|
-
authMethod: "oauth",
|
|
223
|
-
expiresAt: new Date(tokens.expires).toISOString(),
|
|
224
|
-
refreshToken: tokens.refresh,
|
|
225
|
-
tokenType: "bearer",
|
|
226
|
-
scope: CODEX_SCOPE,
|
|
227
|
-
accountId
|
|
228
|
-
};
|
|
229
|
-
try {
|
|
230
|
-
await mutateConfigProviders(
|
|
231
|
-
deps.profileConfigPath,
|
|
232
|
-
deps.vault,
|
|
233
|
-
(all) => {
|
|
234
|
-
const existing = all[providerId];
|
|
235
|
-
const p = existing ? { ...existing } : { type: providerId };
|
|
236
|
-
p.family = "openai-codex";
|
|
237
|
-
if (!p.baseUrl) p.baseUrl = CODEX_BASE_URL;
|
|
238
|
-
p.models = [...models];
|
|
239
|
-
const keys = normalizeKeys(p).filter((k) => k.label !== entry.label);
|
|
240
|
-
keys.push(entry);
|
|
241
|
-
writeKeysBack(p, keys);
|
|
242
|
-
p.activeKey = entry.label;
|
|
243
|
-
all[providerId] = p;
|
|
244
|
-
},
|
|
245
|
-
deps.profileConfigPath
|
|
246
|
-
);
|
|
247
|
-
return true;
|
|
248
|
-
} catch (err) {
|
|
249
|
-
deps.renderer.writeError(` Failed to save tokens: ${err.message}`);
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export {
|
|
255
|
-
openBrowser,
|
|
256
|
-
startLoopbackServer,
|
|
257
|
-
runCodexOAuthLogin,
|
|
258
|
-
fallbackCodexProviderModels,
|
|
259
|
-
filterCurrentCodexModelIds,
|
|
260
|
-
isCodexCatalogModel
|
|
261
|
-
};
|
|
262
|
-
//# sourceMappingURL=chunk-TNK6237M.js.map
|