@wrongstack/cli 1.1.2 → 1.1.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/dist/{acp-HCGUTFNE.js → acp-NKUEYJDZ.js} +14 -5
- package/dist/acp-leader/acp-leader-confirm.d.ts +20 -0
- package/dist/acp-leader/acp-leader-context.d.ts +29 -0
- package/dist/acp-leader/acp-leader-fleet.d.ts +26 -0
- package/dist/acp-leader/acp-leader-host-binding.d.ts +17 -0
- package/dist/acp-leader/acp-leader-host.d.ts +82 -0
- package/dist/acp-leader/acp-leader-picker.d.ts +24 -0
- package/dist/acp-leader/acp-leader-provider.d.ts +85 -0
- package/dist/acp-leader/acp-leader-resume.d.ts +10 -0
- package/dist/acp-leader/acp-leader-stream.d.ts +83 -0
- package/dist/{auth-ANOVZVHE.js → auth-2ZG5DBHS.js} +62 -66
- package/dist/auth-menu/index.d.ts +1 -2
- package/dist/boot/dispatch-webui.d.ts +16 -0
- package/dist/boot/launch-menu-arrow.d.ts +20 -0
- package/dist/boot/launch-menu-types.d.ts +36 -0
- package/dist/boot/launch-menu.d.ts +1 -57
- package/dist/boot/tui-session-resume-rollback.d.ts +31 -0
- package/dist/{boot-auto-thin-7D4OVEWA.js → boot-auto-thin-N2CIGTXE.js} +3 -3
- package/dist/{chunk-TZPKOS5G.js → chunk-2XQ6SRKG.js} +2 -2
- package/dist/chunk-3LEIFO5D.js +65 -0
- package/dist/chunk-5SGMUDP5.js +752 -0
- package/dist/{chunk-3EXRPTAU.js → chunk-5TQ65PXQ.js} +17 -17
- package/dist/{chunk-GRAGMA4B.js → chunk-7BM4LGKQ.js} +18 -18
- package/dist/{chunk-VAQXOZKP.js → chunk-AJM4EFCM.js} +139 -136
- package/dist/{chunk-C2BBH4S4.js → chunk-E3MJFAFR.js} +2 -2
- package/dist/{chunk-5TRZZHMN.js → chunk-JCZ2D3VV.js} +4 -65
- package/dist/{chunk-AWRZWPJ3.js → chunk-JFYQGMMM.js} +99 -75
- package/dist/{chunk-BIGSVBPI.js → chunk-KNYIEQAY.js} +64 -61
- package/dist/chunk-LUEO5HLZ.js +50 -0
- package/dist/chunk-LYWOV4OX.js +252 -0
- package/dist/chunk-M7FNHCE3.js +2070 -0
- package/dist/{chunk-75OLD563.js → chunk-M7PSENGF.js} +3 -1
- package/dist/{chunk-NMXQFQ26.js → chunk-MEBXWI7U.js} +5 -5
- package/dist/{chunk-RAWHRRUJ.js → chunk-MKMM5RIW.js} +209 -201
- package/dist/{chunk-3R3OADC5.js → chunk-P7MEEUGT.js} +281 -252
- package/dist/chunk-QLYPIJ7X.js +258 -0
- package/dist/chunk-RN5CFAVQ.js +292 -0
- package/dist/{chunk-WDXNBYGD.js → chunk-TDP7CZGE.js} +6 -1
- package/dist/{chunk-6VPWQ4TG.js → chunk-UROB7MK5.js} +2 -1
- package/dist/chunk-VEESMPTX.js +254 -0
- package/dist/{chunk-IJLIAPCW.js → chunk-VPSAKGLK.js} +47 -47
- package/dist/{cli-context-YIT4FEDM.js → cli-context-CQYGIWOU.js} +254 -237
- package/dist/{cli-main-JIADJ5OL.js → cli-main-VRUJNUBX.js} +2081 -1594
- package/dist/cli-main-boot.d.ts +1 -1
- package/dist/config-doctor-known-keys.d.ts +33 -0
- package/dist/config-doctor.d.ts +2 -47
- package/dist/config-history-support.d.ts +36 -0
- package/dist/config-history.d.ts +1 -1
- package/dist/{config-transfer-Y7XJMJRN.js → config-transfer-B4GOZTFC.js} +2 -2
- package/dist/{execution-BAP566QC.js → execution-IV72RUSM.js} +5354 -5258
- package/dist/execution-tui.d.ts +30 -0
- package/dist/fleet/acp-live-steer.d.ts +28 -0
- package/dist/fleet/acp-permission-bridge.d.ts +49 -0
- package/dist/fleet/acp-quota-hold.d.ts +3 -0
- package/dist/fleet/acp-quota-reading.d.ts +3 -0
- package/dist/fleet/acp-turn-reminders.d.ts +15 -0
- package/dist/fleet/acp-wrongstack-bridge.d.ts +50 -0
- package/dist/fleet/host-acp.d.ts +23 -2
- package/dist/fleet/wrongforge-client.d.ts +116 -0
- package/dist/fleet/wrongforge-gateway.d.ts +20 -0
- package/dist/fleet/wrongforge-info.d.ts +32 -0
- package/dist/fleet/wrongforge-quota.d.ts +10 -0
- package/dist/fleet/wrongforge-runner.d.ts +37 -0
- package/dist/fleet/wrongforge-runtime.d.ts +10 -0
- package/dist/{hq-JD5AZVMG.js → hq-54PQYR5O.js} +311 -307
- package/dist/hq-server/sweeps.d.ts +28 -0
- package/dist/{hq-server-BI23EPM7.js → hq-server-YK7FBLL6.js} +3 -3
- package/dist/index.js +8 -5
- package/dist/mcp-22CFBX4H.js +236 -0
- package/dist/mcp-serve-project.d.ts +18 -0
- package/dist/mcp-serve.d.ts +0 -63
- package/dist/{modeldiag-HDIKG37X.js → modeldiag-5PBB777J.js} +4 -4
- package/dist/{per-subcommand-help-D6J4ZXW2.js → per-subcommand-help-MQGERD4E.js} +2 -2
- package/dist/plugin-llm-command.d.ts +9 -0
- package/dist/{plugin-usage-TYF5HY4K.js → plugin-usage-UWKYMNQU.js} +3 -3
- package/dist/{plugins-XGAXDLPT.js → plugins-VP7JQH47.js} +4 -4
- package/dist/{sdd-runtime-6MFUXWJK.js → sdd-runtime-HIJ4Z5TF.js} +2 -2
- package/dist/services/sdd/state.d.ts +2 -0
- package/dist/session-event-wiring-types.d.ts +62 -0
- package/dist/session-event-wiring.d.ts +2 -52
- package/dist/{sessions-config-SJVQXCIE.js → sessions-config-7MK742OW.js} +2 -2
- package/dist/short-circuit-flags-AGHURHMQ.js +11 -0
- package/dist/slash-commands/command-context-fleet.d.ts +187 -0
- package/dist/slash-commands/command-context-sdd-goal.d.ts +102 -0
- package/dist/slash-commands/command-context.d.ts +3 -282
- package/dist/slash-commands/project-switch-interactive.d.ts +11 -0
- package/dist/slash-commands/setmodel-helpers.d.ts +36 -0
- package/dist/subcommands/handlers/hq-token.d.ts +3 -0
- package/dist/subcommands/handlers/hq.d.ts +0 -21
- package/dist/subcommands/handlers/per-subcommand-help-operations.d.ts +8 -0
- package/dist/subcommands/handlers/tools-cli-args.d.ts +57 -0
- package/dist/subcommands/handlers/tools-cli.d.ts +5 -0
- package/dist/subcommands/handlers/tools-serve.d.ts +4 -0
- package/dist/{subcommands-VTMIZQBP.js → subcommands-OCJNO57E.js} +2 -2
- package/dist/tool-gateway-http.d.ts +30 -0
- package/dist/tool-gateway.d.ts +185 -0
- package/dist/tools-cli-44MLIUQO.js +509 -0
- package/dist/tools-serve-TRCET2M7.js +102 -0
- package/dist/{tools-skills-55QVTMSK.js → tools-skills-WDTMCE46.js} +7 -2
- package/dist/tuneup-runtime-checks.d.ts +7 -0
- package/dist/tuneup-types.d.ts +118 -0
- package/dist/tuneup.d.ts +3 -122
- package/dist/{typesafe-YBEADNAH.js → typesafe-QLSMFU7J.js} +1 -1
- package/dist/{version-help-RBZC5GZZ.js → version-help-X6CC4CFY.js} +2 -2
- package/dist/{webui-server-HIUY3RHD.js → webui-server-V2R5WQUK.js} +79 -3
- package/dist/wiring/provider-runtime-setup.d.ts +3 -1
- package/dist/wiring/session-runtime.d.ts +1 -1
- package/dist/wrongforge-gateway-UOFBK56J.js +92 -0
- package/dist/wrongforge-leader/wrongforge-leader-gateway.d.ts +9 -0
- package/dist/wrongforge-leader/wrongforge-leader-picker.d.ts +12 -0
- package/dist/wrongforge-leader/wrongforge-leader-provider.d.ts +49 -0
- package/package.json +34 -30
- package/dist/auth-menu/anthropic-oauth.d.ts +0 -43
- package/dist/chunk-XT3NAHRX.js +0 -337
- package/dist/chunk-ZNNFEKDZ.js +0 -319
- package/dist/mcp-2XWBJEQN.js +0 -464
- package/dist/short-circuit-flags-CPCT5MWB.js +0 -11
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
appendHistory,
|
|
18
18
|
backupCurrent
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-KNYIEQAY.js";
|
|
20
20
|
import {
|
|
21
21
|
openBrowser
|
|
22
22
|
} from "./chunk-BCKVNORU.js";
|
|
@@ -171,12 +171,11 @@ function decideAuthLocalEvents(opts) {
|
|
|
171
171
|
return events;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
// src/auth-menu/
|
|
175
|
-
import {
|
|
176
|
-
import {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
} from "@wrongstack/providers/oauth";
|
|
174
|
+
// src/auth-menu/local.ts
|
|
175
|
+
import { DefaultSecretScrubber as DefaultSecretScrubber2 } from "@wrongstack/core/security";
|
|
176
|
+
import { color as color2 } from "@wrongstack/core/utils";
|
|
177
|
+
import { authProfileAliasError } from "@wrongstack/providers";
|
|
178
|
+
import { probeLocalLlm } from "@wrongstack/runtime/probe";
|
|
180
179
|
|
|
181
180
|
// src/auth-menu/helpers.ts
|
|
182
181
|
async function loadProviders(deps) {
|
|
@@ -186,125 +185,6 @@ async function loadProviders(deps) {
|
|
|
186
185
|
});
|
|
187
186
|
}
|
|
188
187
|
|
|
189
|
-
// src/auth-menu/provider-auth-login.ts
|
|
190
|
-
var defaultRegistry;
|
|
191
|
-
function providerAuthRegistryFor(deps) {
|
|
192
|
-
if (deps.providerAuthRegistry) return deps.providerAuthRegistry;
|
|
193
|
-
defaultRegistry ??= createBuiltinProviderAuthRegistry();
|
|
194
|
-
return defaultRegistry;
|
|
195
|
-
}
|
|
196
|
-
function providerAuthStrategiesFor(deps) {
|
|
197
|
-
return providerAuthRegistryFor(deps).list();
|
|
198
|
-
}
|
|
199
|
-
function hyperlink(url) {
|
|
200
|
-
return `\x1B]8;;${url}\x1B\\${url}\x1B]8;;\x1B\\`;
|
|
201
|
-
}
|
|
202
|
-
async function runProviderAuthLogin(deps, strategyId, opts = {}) {
|
|
203
|
-
const registry = providerAuthRegistryFor(deps);
|
|
204
|
-
const strategy = registry.get(strategyId);
|
|
205
|
-
if (!strategy) {
|
|
206
|
-
deps.renderer.writeError(`Unknown OAuth login "${strategyId}".`);
|
|
207
|
-
return 1;
|
|
208
|
-
}
|
|
209
|
-
const controller = new AbortController();
|
|
210
|
-
let sigintCount = 0;
|
|
211
|
-
const onSigint = () => {
|
|
212
|
-
sigintCount += 1;
|
|
213
|
-
if (sigintCount === 1) {
|
|
214
|
-
deps.renderer.write(
|
|
215
|
-
color.dim("\n Cancelling sign-in\u2026 (press Ctrl+C again to force-quit)\n")
|
|
216
|
-
);
|
|
217
|
-
controller.abort();
|
|
218
|
-
} else {
|
|
219
|
-
process.exit(130);
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
const onExternalAbort = () => controller.abort();
|
|
223
|
-
if (opts.signal) {
|
|
224
|
-
if (opts.signal.aborted) controller.abort();
|
|
225
|
-
else opts.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
226
|
-
} else {
|
|
227
|
-
process.on("SIGINT", onSigint);
|
|
228
|
-
}
|
|
229
|
-
let session;
|
|
230
|
-
try {
|
|
231
|
-
deps.renderer.write(
|
|
232
|
-
color.bold(`
|
|
233
|
-
Sign in with ${strategy.label}`) + color.dim(` \u2192 ${opts.providerId ?? strategy.providerId}
|
|
234
|
-
`)
|
|
235
|
-
);
|
|
236
|
-
const saved = strategy.id === "chatgpt-api" ? (await loadProviders(deps))[opts.providerId ?? strategy.providerId] : void 0;
|
|
237
|
-
const credential = saved?.apiKeys?.find((key) => key.label === saved.activeKey) ?? saved?.apiKeys?.[0];
|
|
238
|
-
session = await registry.begin(
|
|
239
|
-
strategy.id,
|
|
240
|
-
{ modelsRegistry: deps.modelsRegistry, ...credential ? { credential } : {} },
|
|
241
|
-
controller.signal
|
|
242
|
-
);
|
|
243
|
-
let outcome;
|
|
244
|
-
if (session.interaction.type === "device_code") {
|
|
245
|
-
const { verificationUri, userCode } = session.interaction;
|
|
246
|
-
deps.renderer.write(
|
|
247
|
-
color.bold("\n Open this URL and enter the code:\n") + color.cyan(` ${hyperlink(verificationUri)}
|
|
248
|
-
`) + color.bold(` Code: ${userCode}
|
|
249
|
-
`) + color.dim(" Waiting for authorization\u2026\n")
|
|
250
|
-
);
|
|
251
|
-
openBrowser(verificationUri);
|
|
252
|
-
outcome = await session.waitForCompletion(controller.signal);
|
|
253
|
-
} else {
|
|
254
|
-
const { authorizeUrl, bound } = session.interaction;
|
|
255
|
-
deps.renderer.write(
|
|
256
|
-
color.bold("\n Open this URL in your browser to sign in:\n") + color.cyan(` ${hyperlink(authorizeUrl)}
|
|
257
|
-
`)
|
|
258
|
-
);
|
|
259
|
-
if (bound) {
|
|
260
|
-
openBrowser(authorizeUrl);
|
|
261
|
-
deps.renderer.write(color.dim(" Waiting for browser authorization\u2026\n"));
|
|
262
|
-
outcome = await session.waitForCompletion(controller.signal);
|
|
263
|
-
} else {
|
|
264
|
-
const input = (await deps.reader.readLine(
|
|
265
|
-
`
|
|
266
|
-
${color.amber("?")} Paste the redirect URL or code ${color.dim("(or q to cancel)")}: `
|
|
267
|
-
)).trim();
|
|
268
|
-
if (!input || input.toLowerCase() === "q") return 1;
|
|
269
|
-
outcome = await session.completeWithCode(input, controller.signal);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
if (!outcome) {
|
|
273
|
-
deps.renderer.write(color.dim(" Sign-in cancelled or timed out.\n"));
|
|
274
|
-
return 1;
|
|
275
|
-
}
|
|
276
|
-
controller.signal.throwIfAborted();
|
|
277
|
-
await mutateConfigProviders(
|
|
278
|
-
deps.profileConfigPath,
|
|
279
|
-
deps.vault,
|
|
280
|
-
(providers) => {
|
|
281
|
-
controller.signal.throwIfAborted();
|
|
282
|
-
applyProviderAuthOutcome(providers, outcome, { targetProviderId: opts.providerId });
|
|
283
|
-
},
|
|
284
|
-
deps.profileConfigPath
|
|
285
|
-
);
|
|
286
|
-
const savedId = opts.providerId ?? outcome.providerId;
|
|
287
|
-
deps.renderer.write(color.green(`
|
|
288
|
-
\u2713 Signed in \u2014 saved as ${savedId}.
|
|
289
|
-
`));
|
|
290
|
-
return 0;
|
|
291
|
-
} catch (error) {
|
|
292
|
-
const message = error instanceof DOMException && error.name === "AbortError" ? "Login cancelled." : toErrorMessage(error);
|
|
293
|
-
deps.renderer.writeError(` Login failed: ${message}`);
|
|
294
|
-
return 1;
|
|
295
|
-
} finally {
|
|
296
|
-
session?.close();
|
|
297
|
-
if (opts.signal) opts.signal.removeEventListener("abort", onExternalAbort);
|
|
298
|
-
else process.off("SIGINT", onSigint);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// src/auth-menu/local.ts
|
|
303
|
-
import { DefaultSecretScrubber as DefaultSecretScrubber2 } from "@wrongstack/core/security";
|
|
304
|
-
import { color as color3 } from "@wrongstack/core/utils";
|
|
305
|
-
import { authProfileAliasError } from "@wrongstack/providers";
|
|
306
|
-
import { probeLocalLlm } from "@wrongstack/runtime/probe";
|
|
307
|
-
|
|
308
188
|
// src/auth-menu/local-presets.ts
|
|
309
189
|
import { projectLocalProviderPresets } from "@wrongstack/providers/definitions";
|
|
310
190
|
var LOCAL_LLM_PRESETS = projectLocalProviderPresets();
|
|
@@ -318,24 +198,24 @@ function parseAuthMenuIndex(raw) {
|
|
|
318
198
|
}
|
|
319
199
|
|
|
320
200
|
// src/auth-menu/shared.ts
|
|
321
|
-
import { color
|
|
201
|
+
import { color } from "@wrongstack/core/utils";
|
|
322
202
|
function renderProviderLine(renderer, id, cfg, idx) {
|
|
323
203
|
const keys = normalizeKeys(cfg);
|
|
324
204
|
const active = activeLabel(cfg, keys);
|
|
325
205
|
const firstKey = keys[0];
|
|
326
206
|
let summary;
|
|
327
207
|
if (keys.length === 0) {
|
|
328
|
-
summary =
|
|
208
|
+
summary = color.dim("(no keys)");
|
|
329
209
|
} else if (keys.length === 1) {
|
|
330
210
|
summary = maskedKey(firstKey?.apiKey ?? "");
|
|
331
211
|
} else {
|
|
332
212
|
const activeKeyObj = active != null ? keys.find((k) => k.label === active) : void 0;
|
|
333
|
-
summary = `${
|
|
213
|
+
summary = `${color.dim(`${keys.length} keys`)} ${color.dim("active:")} ${color.bold(active ?? "?")} ` + maskedKey(activeKeyObj?.apiKey ?? firstKey?.apiKey ?? "");
|
|
334
214
|
}
|
|
335
|
-
const fam = cfg.family ?
|
|
336
|
-
const aliasHint = cfg.type && cfg.type !== id ?
|
|
215
|
+
const fam = cfg.family ? color.dim(`[${cfg.family}]`) : "";
|
|
216
|
+
const aliasHint = cfg.type && cfg.type !== id ? color.dim(`\u2192 ${cfg.type}`) : "";
|
|
337
217
|
renderer.write(
|
|
338
|
-
` ${
|
|
218
|
+
` ${color.dim(`${idx}.`.padStart(4))} ${id.padEnd(22)} ${fam} ${aliasHint} ${summary}
|
|
339
219
|
`
|
|
340
220
|
);
|
|
341
221
|
}
|
|
@@ -344,23 +224,23 @@ function renderProviderHeader(renderer, providerId, cfg) {
|
|
|
344
224
|
const active = activeLabel(cfg, keys);
|
|
345
225
|
renderer.write(
|
|
346
226
|
`
|
|
347
|
-
${
|
|
227
|
+
${color.bold(providerId)} ${cfg.family ? color.dim(`[${cfg.family}]`) : color.amber("[no family]")}
|
|
348
228
|
`
|
|
349
229
|
);
|
|
350
230
|
const details = [
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
231
|
+
color.dim(` type: ${cfg.type ?? providerId}`),
|
|
232
|
+
color.dim(` family: ${cfg.family ?? "(unset \u2192 resolved from models.dev when type matches)"}`),
|
|
233
|
+
color.dim(` baseUrl: ${cfg.baseUrl ?? "(unset \u2192 catalog default)"}`)
|
|
354
234
|
];
|
|
355
235
|
if (cfg.envVars && cfg.envVars.length > 0) {
|
|
356
|
-
details.push(
|
|
236
|
+
details.push(color.dim(` envVars: ${cfg.envVars.join(", ")}`));
|
|
357
237
|
}
|
|
358
238
|
if (cfg.models && cfg.models.length > 0) {
|
|
359
|
-
details.push(
|
|
239
|
+
details.push(color.dim(` models: ${cfg.models.join(", ")}`));
|
|
360
240
|
}
|
|
361
241
|
renderer.write(details.join("\n") + "\n");
|
|
362
242
|
if (keys.length === 0) {
|
|
363
|
-
renderer.write(
|
|
243
|
+
renderer.write(color.dim(" (no keys saved)\n"));
|
|
364
244
|
} else {
|
|
365
245
|
for (let i = 0; i < keys.length; i++) {
|
|
366
246
|
const key = keys[i];
|
|
@@ -369,56 +249,56 @@ ${color2.bold(providerId)} ${cfg.family ? color2.dim(`[${cfg.family}]`) : color2
|
|
|
369
249
|
}
|
|
370
250
|
}
|
|
371
251
|
function renderKeyLine(renderer, key, idx, active) {
|
|
372
|
-
const marker = key.label === active ?
|
|
252
|
+
const marker = key.label === active ? color.green("\u25CF") : color.dim("\u25CB");
|
|
373
253
|
renderer.write(
|
|
374
|
-
` ${
|
|
254
|
+
` ${color.dim(`${idx}.`.padStart(4))} ${marker} ${key.label.padEnd(20)} ${maskedKey(key.apiKey)} ${color.dim(key.createdAt)}
|
|
375
255
|
`
|
|
376
256
|
);
|
|
377
257
|
}
|
|
378
258
|
function renderActions(renderer, keysLength) {
|
|
379
259
|
renderer.write(`
|
|
380
|
-
${
|
|
260
|
+
${color.dim("Actions:")}
|
|
381
261
|
`);
|
|
382
|
-
renderer.write(` ${
|
|
262
|
+
renderer.write(` ${color.bold("a")} Add another key
|
|
383
263
|
`);
|
|
384
264
|
if (keysLength > 0) {
|
|
385
|
-
renderer.write(` ${
|
|
265
|
+
renderer.write(` ${color.bold("u")} <n> Update key <n>
|
|
386
266
|
`);
|
|
387
|
-
renderer.write(` ${
|
|
267
|
+
renderer.write(` ${color.bold("d")} <n> Delete key <n>
|
|
388
268
|
`);
|
|
389
|
-
renderer.write(` ${
|
|
269
|
+
renderer.write(` ${color.bold("s")} <n> Set key <n> as active
|
|
390
270
|
`);
|
|
391
271
|
}
|
|
392
|
-
renderer.write(` ${
|
|
272
|
+
renderer.write(` ${color.bold("f")} Edit family
|
|
393
273
|
`);
|
|
394
274
|
renderer.write(
|
|
395
|
-
` ${
|
|
275
|
+
` ${color.bold("B")} Edit baseUrl ${color.dim("(capital B \u2014 b is Back)")}
|
|
396
276
|
`
|
|
397
277
|
);
|
|
398
|
-
renderer.write(` ${
|
|
278
|
+
renderer.write(` ${color.bold("m")} Edit visible model list
|
|
399
279
|
`);
|
|
400
|
-
renderer.write(` ${
|
|
280
|
+
renderer.write(` ${color.bold("x")} Remove this provider entirely
|
|
401
281
|
`);
|
|
402
|
-
renderer.write(` ${
|
|
282
|
+
renderer.write(` ${color.bold("b")} Back
|
|
403
283
|
`);
|
|
404
|
-
renderer.write(` ${
|
|
284
|
+
renderer.write(` ${color.bold("q")} Quit
|
|
405
285
|
`);
|
|
406
286
|
}
|
|
407
287
|
function renderTopMenu(renderer, providers) {
|
|
408
288
|
renderer.write(`
|
|
409
|
-
${
|
|
289
|
+
${color.bold("WrongStack")} ${color.dim("\u2014 API key manager")}
|
|
410
290
|
|
|
411
291
|
`);
|
|
412
292
|
const ids = Object.keys(providers).sort();
|
|
413
293
|
if (ids.length === 0) {
|
|
414
|
-
renderer.write(
|
|
294
|
+
renderer.write(color.dim(" No providers configured yet.\n"));
|
|
415
295
|
renderer.write(
|
|
416
|
-
|
|
296
|
+
color.dim(
|
|
417
297
|
" Use (a) to add one from the models.dev catalog, (l) for a local server, or (c) for a custom provider.\n"
|
|
418
298
|
)
|
|
419
299
|
);
|
|
420
300
|
} else {
|
|
421
|
-
renderer.write(` ${
|
|
301
|
+
renderer.write(` ${color.dim("Saved providers:")}
|
|
422
302
|
`);
|
|
423
303
|
let idx = 1;
|
|
424
304
|
for (const id of ids) {
|
|
@@ -429,30 +309,30 @@ ${color2.bold("WrongStack")} ${color2.dim("\u2014 API key manager")}
|
|
|
429
309
|
}
|
|
430
310
|
}
|
|
431
311
|
renderer.write(`
|
|
432
|
-
${
|
|
312
|
+
${color.dim("Actions:")}
|
|
433
313
|
`);
|
|
434
|
-
renderer.write(` ${
|
|
314
|
+
renderer.write(` ${color.bold("a")} Add a provider (from catalog)
|
|
435
315
|
`);
|
|
436
316
|
renderer.write(
|
|
437
|
-
` ${
|
|
317
|
+
` ${color.bold("l")} Add a local server ${color.dim("(OmniRoute / Ollama / vLLM / LM Studio)")}
|
|
438
318
|
`
|
|
439
319
|
);
|
|
440
|
-
renderer.write(` ${
|
|
320
|
+
renderer.write(` ${color.bold("c")} Add a custom provider
|
|
441
321
|
`);
|
|
442
|
-
renderer.write(` ${
|
|
322
|
+
renderer.write(` ${color.bold("s")} Login with provider OAuth
|
|
443
323
|
`);
|
|
444
324
|
if (ids.length > 0) {
|
|
445
325
|
renderer.write(
|
|
446
|
-
` ${
|
|
326
|
+
` ${color.dim("1-")}${color.dim(String(ids.length))} ${color.bold("Manage a provider")}
|
|
447
327
|
`
|
|
448
328
|
);
|
|
449
329
|
}
|
|
450
|
-
renderer.write(` ${
|
|
330
|
+
renderer.write(` ${color.bold("q")} Quit
|
|
451
331
|
`);
|
|
452
332
|
}
|
|
453
333
|
async function readKeyInput(deps, intent) {
|
|
454
334
|
const key = (await deps.reader.readSecret(
|
|
455
|
-
` ${
|
|
335
|
+
` ${color.amber("?")} ${intent} ${color.dim("(hidden, paste OK)")}: `
|
|
456
336
|
)).trim();
|
|
457
337
|
if (!key) {
|
|
458
338
|
deps.renderer.writeError("No key entered.");
|
|
@@ -461,7 +341,7 @@ async function readKeyInput(deps, intent) {
|
|
|
461
341
|
return key;
|
|
462
342
|
}
|
|
463
343
|
async function confirm(deps, question) {
|
|
464
|
-
const answer = (await deps.reader.readLine(` ${
|
|
344
|
+
const answer = (await deps.reader.readLine(` ${color.amber("?")} ${question} ${color.dim("[y/N/q]")} `)).trim().toLowerCase();
|
|
465
345
|
if (answer === "q" || answer === "quit") return null;
|
|
466
346
|
return answer === "y" || answer === "yes";
|
|
467
347
|
}
|
|
@@ -540,7 +420,7 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
540
420
|
if (!probe.ok) {
|
|
541
421
|
if (chosen.noAuth) {
|
|
542
422
|
deps.renderer.write(
|
|
543
|
-
|
|
423
|
+
color2.dim(
|
|
544
424
|
` Saving ${chosen.label} anyway \u2014 keyless local gateway needs no key and discovers models when it comes up.
|
|
545
425
|
`
|
|
546
426
|
)
|
|
@@ -549,7 +429,7 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
549
429
|
} else {
|
|
550
430
|
const saveAnyway = await promptSaveAnyway(deps);
|
|
551
431
|
if (!saveAnyway) {
|
|
552
|
-
deps.renderer.write(
|
|
432
|
+
deps.renderer.write(color2.dim(" Cancelled. Nothing saved.\n"));
|
|
553
433
|
return 0;
|
|
554
434
|
}
|
|
555
435
|
probeFailedAndSaved = true;
|
|
@@ -614,19 +494,19 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
614
494
|
}
|
|
615
495
|
if (apiKey) {
|
|
616
496
|
deps.renderer.write(
|
|
617
|
-
` ${
|
|
497
|
+
` ${color2.green("\u2713")} Saved ${color2.bold(profileId)}/${color2.bold(finalLabel)} \u2192 ${color2.cyan(baseUrl)}
|
|
618
498
|
`
|
|
619
499
|
);
|
|
620
500
|
} else {
|
|
621
501
|
deps.renderer.write(
|
|
622
|
-
` ${
|
|
502
|
+
` ${color2.green("\u2713")} Saved ${color2.bold(profileId)} (no key) \u2192 ${color2.cyan(baseUrl)}
|
|
623
503
|
`
|
|
624
504
|
);
|
|
625
505
|
}
|
|
626
506
|
const firstModel = resolvedModels && resolvedModels.length > 0 ? resolvedModels[0] : null;
|
|
627
|
-
const modelHint = firstModel ?
|
|
507
|
+
const modelHint = firstModel ? color2.cyan(firstModel) : color2.dim("<model-id>");
|
|
628
508
|
deps.renderer.write(
|
|
629
|
-
|
|
509
|
+
color2.dim(` Launch: wstack --provider ${profileId} --model ${modelHint} "<task>"
|
|
630
510
|
`)
|
|
631
511
|
);
|
|
632
512
|
return 0;
|
|
@@ -658,47 +538,47 @@ function resolveModelList(models, probe, scrubber) {
|
|
|
658
538
|
return out;
|
|
659
539
|
}
|
|
660
540
|
function renderProbeResult(deps, probe, opts = {}) {
|
|
661
|
-
const label = opts.presetLabel ? ` ${
|
|
662
|
-
const elapsed = probe.elapsedMs !== void 0 ? ` ${
|
|
541
|
+
const label = opts.presetLabel ? ` ${color2.bold(opts.presetLabel)}` : "";
|
|
542
|
+
const elapsed = probe.elapsedMs !== void 0 ? ` ${color2.dim(`(${probe.elapsedMs}ms)`)}` : "";
|
|
663
543
|
switch (probe.status) {
|
|
664
544
|
case "ok": {
|
|
665
|
-
const models = probe.modelCount !== void 0 ?
|
|
666
|
-
deps.renderer.write(` ${
|
|
545
|
+
const models = probe.modelCount !== void 0 ? color2.dim(`, ${probe.modelCount} model${probe.modelCount === 1 ? "" : "s"}`) : "";
|
|
546
|
+
deps.renderer.write(` ${color2.green("\u25CF")} ${label} health probe ok${models}${elapsed}
|
|
667
547
|
`);
|
|
668
548
|
break;
|
|
669
549
|
}
|
|
670
550
|
case "timeout": {
|
|
671
551
|
deps.renderer.write(
|
|
672
|
-
` ${
|
|
673
|
-
${
|
|
674
|
-
${
|
|
552
|
+
` ${color2.red("\u25CF")} ${label} health probe timed out${elapsed}
|
|
553
|
+
${color2.dim("The server did not respond within the timeout.")}
|
|
554
|
+
${color2.dim("Is the local server running? Check the port and try again.")}
|
|
675
555
|
`
|
|
676
556
|
);
|
|
677
557
|
break;
|
|
678
558
|
}
|
|
679
559
|
case "unreachable": {
|
|
680
|
-
const detail = probe.detail ? ` ${
|
|
560
|
+
const detail = probe.detail ? ` ${color2.dim(`(${probe.detail})`)}` : "";
|
|
681
561
|
deps.renderer.write(
|
|
682
|
-
` ${
|
|
683
|
-
${
|
|
684
|
-
${
|
|
685
|
-
${
|
|
686
|
-
${
|
|
562
|
+
` ${color2.red("\u25CF")} ${label} server unreachable${detail}
|
|
563
|
+
${color2.dim("Could not connect. Common causes:")}
|
|
564
|
+
${color2.dim(" - The local server is not running")}
|
|
565
|
+
${color2.dim(" - The port is blocked by a firewall")}
|
|
566
|
+
${color2.dim(" - The base URL is wrong")}
|
|
687
567
|
`
|
|
688
568
|
);
|
|
689
569
|
break;
|
|
690
570
|
}
|
|
691
571
|
case "http_error": {
|
|
692
572
|
const status = probe.httpStatus !== void 0 ? ` HTTP ${probe.httpStatus}` : "";
|
|
693
|
-
const detail = probe.detail ? ` ${
|
|
694
|
-
deps.renderer.write(` ${
|
|
573
|
+
const detail = probe.detail ? ` ${color2.dim(`\u2014 ${probe.detail}`)}` : "";
|
|
574
|
+
deps.renderer.write(` ${color2.yellow("\u25CF")} ${label} health probe got${status}${detail}
|
|
695
575
|
`);
|
|
696
576
|
break;
|
|
697
577
|
}
|
|
698
578
|
case "invalid_response": {
|
|
699
579
|
deps.renderer.write(
|
|
700
|
-
` ${
|
|
701
|
-
` + (probe.detail ? ` ${
|
|
580
|
+
` ${color2.yellow("\u25CF")} ${label} health probe returned an unexpected shape
|
|
581
|
+
` + (probe.detail ? ` ${color2.dim(probe.detail)}
|
|
702
582
|
` : "")
|
|
703
583
|
);
|
|
704
584
|
break;
|
|
@@ -711,31 +591,31 @@ function renderProbeResult(deps, probe, opts = {}) {
|
|
|
711
591
|
async function promptSaveAnyway(deps) {
|
|
712
592
|
const answer = (await deps.reader.readLine(
|
|
713
593
|
`
|
|
714
|
-
${
|
|
594
|
+
${color2.amber("?")} ${color2.bold("Save anyway?")} ${color2.dim("[y/N]")}: `
|
|
715
595
|
)).trim().toLowerCase();
|
|
716
596
|
return answer === "y" || answer === "yes";
|
|
717
597
|
}
|
|
718
598
|
async function pickLocalPreset(deps) {
|
|
719
599
|
deps.renderer.write(
|
|
720
600
|
`
|
|
721
|
-
${
|
|
601
|
+
${color2.bold("Local LLM servers")} ${color2.dim("\u2014 pick one to pre-fill the base URL")}
|
|
722
602
|
|
|
723
603
|
`
|
|
724
604
|
);
|
|
725
605
|
let idx = 1;
|
|
726
606
|
for (const entry of LOCAL_LLM_PRESETS) {
|
|
727
|
-
const auth = entry.noAuth ?
|
|
607
|
+
const auth = entry.noAuth ? color2.dim("(no auth)") : color2.dim("(optional auth)");
|
|
728
608
|
deps.renderer.write(
|
|
729
|
-
` ${
|
|
609
|
+
` ${color2.dim(`${idx}.`.padStart(4))} ${color2.bold(entry.label.padEnd(12))} ${color2.cyan(entry.defaultBaseUrl.padEnd(34))} ${auth}
|
|
730
610
|
`
|
|
731
611
|
);
|
|
732
|
-
deps.renderer.write(` ${
|
|
612
|
+
deps.renderer.write(` ${color2.dim(entry.hint)}
|
|
733
613
|
`);
|
|
734
614
|
idx++;
|
|
735
615
|
}
|
|
736
616
|
const answer = (await deps.reader.readLine(
|
|
737
617
|
`
|
|
738
|
-
${
|
|
618
|
+
${color2.amber("?")} Pick ${color2.dim(`(1-${LOCAL_LLM_PRESETS.length}, q to quit)`)}: `
|
|
739
619
|
)).trim().toLowerCase();
|
|
740
620
|
if (!answer || answer === "q" || answer === "quit") return void 0;
|
|
741
621
|
const num = parseAuthMenuIndex(answer);
|
|
@@ -749,12 +629,133 @@ ${color3.amber("?")} Pick ${color3.dim(`(1-${LOCAL_LLM_PRESETS.length}, q to qui
|
|
|
749
629
|
}
|
|
750
630
|
async function promptOptionalKey(deps, preset) {
|
|
751
631
|
const answer = (await deps.reader.readSecret(
|
|
752
|
-
` ${
|
|
632
|
+
` ${color2.amber("?")} ${color2.bold(preset.label)} API key ${color2.dim("(hidden \u2014 Enter to skip if auth is disabled on the server)")}: `
|
|
753
633
|
)).trim();
|
|
754
634
|
if (!answer) return void 0;
|
|
755
635
|
return answer;
|
|
756
636
|
}
|
|
757
637
|
|
|
638
|
+
// src/auth-menu/provider-auth-login.ts
|
|
639
|
+
import { color as color3, toErrorMessage } from "@wrongstack/core/utils";
|
|
640
|
+
import {
|
|
641
|
+
applyProviderAuthOutcome,
|
|
642
|
+
createBuiltinProviderAuthRegistry,
|
|
643
|
+
retiredProviderAuthLoginHint
|
|
644
|
+
} from "@wrongstack/providers/oauth";
|
|
645
|
+
var defaultRegistry;
|
|
646
|
+
function providerAuthRegistryFor(deps) {
|
|
647
|
+
if (deps.providerAuthRegistry) return deps.providerAuthRegistry;
|
|
648
|
+
defaultRegistry ??= createBuiltinProviderAuthRegistry();
|
|
649
|
+
return defaultRegistry;
|
|
650
|
+
}
|
|
651
|
+
function providerAuthStrategiesFor(deps) {
|
|
652
|
+
return providerAuthRegistryFor(deps).list();
|
|
653
|
+
}
|
|
654
|
+
function hyperlink(url) {
|
|
655
|
+
return `\x1B]8;;${url}\x1B\\${url}\x1B]8;;\x1B\\`;
|
|
656
|
+
}
|
|
657
|
+
async function runProviderAuthLogin(deps, strategyId, opts = {}) {
|
|
658
|
+
const registry = providerAuthRegistryFor(deps);
|
|
659
|
+
const strategy = registry.get(strategyId);
|
|
660
|
+
if (!strategy) {
|
|
661
|
+
deps.renderer.writeError(
|
|
662
|
+
retiredProviderAuthLoginHint(strategyId) ?? `Unknown OAuth login "${strategyId}".`
|
|
663
|
+
);
|
|
664
|
+
return 1;
|
|
665
|
+
}
|
|
666
|
+
const controller = new AbortController();
|
|
667
|
+
let sigintCount = 0;
|
|
668
|
+
const onSigint = () => {
|
|
669
|
+
sigintCount += 1;
|
|
670
|
+
if (sigintCount === 1) {
|
|
671
|
+
deps.renderer.write(
|
|
672
|
+
color3.dim("\n Cancelling sign-in\u2026 (press Ctrl+C again to force-quit)\n")
|
|
673
|
+
);
|
|
674
|
+
controller.abort();
|
|
675
|
+
} else {
|
|
676
|
+
process.exit(130);
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
const onExternalAbort = () => controller.abort();
|
|
680
|
+
if (opts.signal) {
|
|
681
|
+
if (opts.signal.aborted) controller.abort();
|
|
682
|
+
else opts.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
683
|
+
} else {
|
|
684
|
+
process.on("SIGINT", onSigint);
|
|
685
|
+
}
|
|
686
|
+
let session;
|
|
687
|
+
try {
|
|
688
|
+
deps.renderer.write(
|
|
689
|
+
color3.bold(`
|
|
690
|
+
Sign in with ${strategy.label}`) + color3.dim(` \u2192 ${opts.providerId ?? strategy.providerId}
|
|
691
|
+
`)
|
|
692
|
+
);
|
|
693
|
+
const saved = strategy.id === "chatgpt-api" ? (await loadProviders(deps))[opts.providerId ?? strategy.providerId] : void 0;
|
|
694
|
+
const credential = saved?.apiKeys?.find((key) => key.label === saved.activeKey) ?? saved?.apiKeys?.[0];
|
|
695
|
+
session = await registry.begin(
|
|
696
|
+
strategy.id,
|
|
697
|
+
{ modelsRegistry: deps.modelsRegistry, ...credential ? { credential } : {} },
|
|
698
|
+
controller.signal
|
|
699
|
+
);
|
|
700
|
+
let outcome;
|
|
701
|
+
if (session.interaction.type === "device_code") {
|
|
702
|
+
const { verificationUri, userCode } = session.interaction;
|
|
703
|
+
deps.renderer.write(
|
|
704
|
+
color3.bold("\n Open this URL and enter the code:\n") + color3.cyan(` ${hyperlink(verificationUri)}
|
|
705
|
+
`) + color3.bold(` Code: ${userCode}
|
|
706
|
+
`) + color3.dim(" Waiting for authorization\u2026\n")
|
|
707
|
+
);
|
|
708
|
+
openBrowser(verificationUri);
|
|
709
|
+
outcome = await session.waitForCompletion(controller.signal);
|
|
710
|
+
} else {
|
|
711
|
+
const { authorizeUrl, bound } = session.interaction;
|
|
712
|
+
deps.renderer.write(
|
|
713
|
+
color3.bold("\n Open this URL in your browser to sign in:\n") + color3.cyan(` ${hyperlink(authorizeUrl)}
|
|
714
|
+
`)
|
|
715
|
+
);
|
|
716
|
+
if (bound) {
|
|
717
|
+
openBrowser(authorizeUrl);
|
|
718
|
+
deps.renderer.write(color3.dim(" Waiting for browser authorization\u2026\n"));
|
|
719
|
+
outcome = await session.waitForCompletion(controller.signal);
|
|
720
|
+
} else {
|
|
721
|
+
const input = (await deps.reader.readLine(
|
|
722
|
+
`
|
|
723
|
+
${color3.amber("?")} Paste the redirect URL or code ${color3.dim("(or q to cancel)")}: `
|
|
724
|
+
)).trim();
|
|
725
|
+
if (!input || input.toLowerCase() === "q") return 1;
|
|
726
|
+
outcome = await session.completeWithCode(input, controller.signal);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
if (!outcome) {
|
|
730
|
+
deps.renderer.write(color3.dim(" Sign-in cancelled or timed out.\n"));
|
|
731
|
+
return 1;
|
|
732
|
+
}
|
|
733
|
+
controller.signal.throwIfAborted();
|
|
734
|
+
await mutateConfigProviders(
|
|
735
|
+
deps.profileConfigPath,
|
|
736
|
+
deps.vault,
|
|
737
|
+
(providers) => {
|
|
738
|
+
controller.signal.throwIfAborted();
|
|
739
|
+
applyProviderAuthOutcome(providers, outcome, { targetProviderId: opts.providerId });
|
|
740
|
+
},
|
|
741
|
+
deps.profileConfigPath
|
|
742
|
+
);
|
|
743
|
+
const savedId = opts.providerId ?? outcome.providerId;
|
|
744
|
+
deps.renderer.write(color3.green(`
|
|
745
|
+
\u2713 Signed in \u2014 saved as ${savedId}.
|
|
746
|
+
`));
|
|
747
|
+
return 0;
|
|
748
|
+
} catch (error) {
|
|
749
|
+
const message = error instanceof DOMException && error.name === "AbortError" ? "Login cancelled." : toErrorMessage(error);
|
|
750
|
+
deps.renderer.writeError(` Login failed: ${message}`);
|
|
751
|
+
return 1;
|
|
752
|
+
} finally {
|
|
753
|
+
session?.close();
|
|
754
|
+
if (opts.signal) opts.signal.removeEventListener("abort", onExternalAbort);
|
|
755
|
+
else process.off("SIGINT", onSigint);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
758
759
|
// src/auth-menu/oauth-menu.ts
|
|
759
760
|
import { color as color4 } from "@wrongstack/core/utils";
|
|
760
761
|
function renderOAuthLoginOptions(deps, indent = " ") {
|
|
@@ -1853,9 +1854,16 @@ ${color9.bold("Custom provider")} ${color9.dim("\u2014 for local models or proxi
|
|
|
1853
1854
|
type = nextCustomProviderId(Object.keys(providersNow));
|
|
1854
1855
|
deps.renderer.write(` ${color9.dim("Using generated id:")} ${color9.bold(type)}
|
|
1855
1856
|
`);
|
|
1856
|
-
} else
|
|
1857
|
-
|
|
1858
|
-
|
|
1857
|
+
} else {
|
|
1858
|
+
const idError = authProfileAliasError2(type);
|
|
1859
|
+
if (idError) {
|
|
1860
|
+
deps.renderer.writeError(idError);
|
|
1861
|
+
return false;
|
|
1862
|
+
}
|
|
1863
|
+
if (providersNow[type]) {
|
|
1864
|
+
deps.renderer.writeWarning(`"${type}" already exists. Pick it from the main menu to edit.`);
|
|
1865
|
+
return false;
|
|
1866
|
+
}
|
|
1859
1867
|
}
|
|
1860
1868
|
const familyRaw = (await deps.reader.readLine(
|
|
1861
1869
|
` ${color9.amber("?")} Wire family ${color9.dim("(anthropic | openai | openai-compatible | google)")} ${color9.dim("(q to quit)")}: `
|
|
@@ -2001,11 +2009,11 @@ export {
|
|
|
2001
2009
|
readKeyInput,
|
|
2002
2010
|
confirm,
|
|
2003
2011
|
validateFamily,
|
|
2004
|
-
providerAuthStrategiesFor,
|
|
2005
|
-
runProviderAuthLogin,
|
|
2006
2012
|
LOCAL_LLM_PRESETS,
|
|
2007
2013
|
parseAuthMenuIndex,
|
|
2008
2014
|
runAuthLocal,
|
|
2015
|
+
providerAuthStrategiesFor,
|
|
2016
|
+
runProviderAuthLogin,
|
|
2009
2017
|
resolveOAuthKind,
|
|
2010
2018
|
runOAuthLoginKind,
|
|
2011
2019
|
runOAuthLoginMenu,
|
|
@@ -2024,4 +2032,4 @@ export {
|
|
|
2024
2032
|
addCustomProvider,
|
|
2025
2033
|
addKeyForProvider
|
|
2026
2034
|
};
|
|
2027
|
-
//# sourceMappingURL=chunk-
|
|
2035
|
+
//# sourceMappingURL=chunk-MKMM5RIW.js.map
|