@wrongstack/cli 1.0.17 → 1.0.24
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-INCNOH42.js → acp-AJWSKWE5.js} +18 -7
- package/dist/arg-parser.d.ts +1 -0
- package/dist/{auth-YXK3EDUL.js → auth-GRBZ7Y3D.js} +61 -15
- package/dist/auth-menu/direct.d.ts +1 -0
- package/dist/auth-menu/local.d.ts +2 -0
- package/dist/auth-menu/oauth-menu.d.ts +3 -1
- package/dist/auth-menu/panel-service.d.ts +20 -0
- package/dist/{bench-YBU6BVQP.js → bench-N5K7Z5O3.js} +2 -2
- package/dist/boot/config-backup-recovery.d.ts +2 -1
- package/dist/boot/dispatch-webui.d.ts +11 -0
- package/dist/boot/short-circuit-desktop.d.ts +1 -0
- package/dist/boot/tui-project-picker-callback.d.ts +1 -1
- package/dist/boot/tui-settings-adapter.d.ts +15 -2
- package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
- package/dist/{chunk-6WRKAACA.js → chunk-2BKFWIER.js} +4 -2
- package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
- package/dist/chunk-3OCUS3VN.js +46 -0
- package/dist/chunk-424ORSE7.js +56 -0
- package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
- package/dist/chunk-BBHWW6LR.js +549 -0
- package/dist/{chunk-CJTBLTS4.js → chunk-BLD5DSVA.js} +4 -3
- package/dist/{chunk-K5PAL6KR.js → chunk-DRM7PSW7.js} +75 -29
- package/dist/{chunk-XJ7K67PP.js → chunk-JF2MULWF.js} +17 -10
- package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
- package/dist/{chunk-RDHFXOJM.js → chunk-LFMVHT3R.js} +106 -57
- package/dist/chunk-LUMETJFO.js +171 -0
- package/dist/{chunk-C3Z4N6A6.js → chunk-MHEBWVXL.js} +6 -2
- package/dist/{chunk-VGER3HYZ.js → chunk-PGKJ2OQP.js} +5 -5
- package/dist/{chunk-672UXYL3.js → chunk-QBBF7GIK.js} +2 -2
- package/dist/{chunk-DE7BZDNK.js → chunk-QFPQXKCG.js} +11 -3
- package/dist/chunk-R4QGL6GB.js +10 -0
- package/dist/chunk-S4FFHDJG.js +93 -0
- package/dist/chunk-SFBFYIOW.js +271 -0
- package/dist/{chunk-JX6KL7OF.js → chunk-SKPDE62W.js} +4 -3
- package/dist/{chunk-RMQNCHGO.js → chunk-U46QR4WR.js} +5 -9
- package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
- package/dist/chunk-YBUCXXYZ.js +36 -0
- package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
- package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
- package/dist/{chunk-YLQEGYV4.js → chunk-ZZRSG7VK.js} +14 -4
- package/dist/{cli-context-4PTWEK52.js → cli-context-34Q5IJRA.js} +121 -89
- package/dist/cli-entry-point.d.ts +2 -0
- package/dist/{cli-main-DQ2GBY7M.js → cli-main-AELJDBGU.js} +1471 -1293
- package/dist/config-doctor.d.ts +10 -2
- package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
- package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-WIFJH3XH.js} +2 -2
- package/dist/execute-deps.d.ts +2 -1
- package/dist/{execution-A6WJLSOC.js → execution-PYC5FCS4.js} +303 -256
- package/dist/{hq-NU75W3SE.js → hq-JTUTFI4L.js} +274 -258
- package/dist/hq-command-controller.d.ts +1 -1
- package/dist/hq-server/project-root.d.ts +35 -1
- package/dist/{hq-server-M2JWVW4D.js → hq-server-PC7GZMPT.js} +2 -2
- package/dist/{hq-service-L5INQFM4.js → hq-service-NW56MUP2.js} +11 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -12
- package/dist/kanban-supervisor-67ECABTD.js +7 -0
- package/dist/live-settings-input.d.ts +7 -0
- package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-WDOCH6KR.js} +3 -3
- package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
- package/dist/modeldiag-36OGAL5C.js +828 -0
- package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-XE77MTGJ.js} +3 -3
- package/dist/permission-prompt-mirror.d.ts +1 -1
- package/dist/permission-prompt.d.ts +2 -2
- package/dist/plugin-config.d.ts +12 -0
- package/dist/plugin-management-types.d.ts +31 -0
- package/dist/plugin-management.d.ts +2 -30
- package/dist/plugin-package-install.d.ts +3 -0
- package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-S5LVGMBW.js} +6 -5
- package/dist/{plugins-WJLW6ULV.js → plugins-RHBIVLI7.js} +4 -3
- package/dist/provider-config-utils.d.ts +1 -6
- package/dist/{providers-models-LFNZ5WI7.js → providers-models-2CFG46RD.js} +41 -31
- package/dist/release-asset-download.d.ts +3 -0
- package/dist/services/dispatch-classifier.d.ts +39 -5
- package/dist/{sessions-config-UL45XKX7.js → sessions-config-IQUH2GXT.js} +13 -5
- package/dist/settings-menu.d.ts +2 -0
- package/dist/short-circuit-flags-SDT53OML.js +10 -0
- package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
- package/dist/skill-suggest-L2EVWB6R.js +290 -0
- package/dist/slash-commands/effort.d.ts +1 -1
- package/dist/slash-commands/fallback.d.ts +1 -1
- package/dist/slash-commands/gitid.d.ts +1 -1
- package/dist/slash-commands/jev.d.ts +4 -0
- package/dist/slash-commands/openai-quota.d.ts +15 -0
- package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
- package/dist/slash-commands/settings-keys.d.ts +2 -0
- package/dist/slash-commands/settings-reset.d.ts +6 -0
- package/dist/standalone-update-MW47J3AK.js +164 -0
- package/dist/standalone-update.d.ts +19 -0
- package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
- package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
- package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
- package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
- package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
- package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
- package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
- package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
- package/dist/subcommands/handlers/typesafe.d.ts +23 -0
- package/dist/{subcommands-ERDDIJ3L.js → subcommands-ZTSIN7LG.js} +2 -2
- package/dist/typesafe-HVEVPA6R.js +316 -0
- package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
- package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
- package/dist/typesafe-topic-replay-4W73BOLV.js +218 -0
- package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
- package/dist/{update-5DPB4YD4.js → update-7XIOEXTD.js} +4 -3
- package/dist/{update-check-BS3DHTSI.js → update-check-2POMBHFB.js} +3 -2
- package/dist/update-check.d.ts +1 -1
- package/dist/version-help-WZ623NWM.js +10 -0
- package/dist/version.d.ts +3 -2
- package/dist/webui-client-observability.d.ts +7 -0
- package/dist/{webui-server-MRPGTTKL.js → webui-server-L2SICPTB.js} +158 -94
- package/dist/webui-server-options.d.ts +11 -0
- package/dist/webui-server.d.ts +15 -1
- package/dist/wiring/domain-glossary.d.ts +5 -4
- package/dist/wiring/plugins.d.ts +1 -1
- package/dist/wiring/provider-persisters.d.ts +24 -0
- package/dist/wiring/provider-runtime.d.ts +9 -1
- package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
- package/package.json +28 -28
- package/dist/chunk-DR2OXU46.js +0 -174
- package/dist/chunk-JACOMTIH.js +0 -275
- package/dist/chunk-M4W3QLQW.js +0 -54
- package/dist/chunk-XJXDOF63.js +0 -28
- package/dist/modeldiag-CJSFHZ3J.js +0 -1356
- package/dist/short-circuit-flags-SJQBJ33I.js +0 -10
- package/dist/version-help-WXI42PZ3.js +0 -10
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
appendHistory,
|
|
3
|
-
backupCurrent
|
|
4
|
-
} from "./chunk-B4JLSXZB.js";
|
|
5
1
|
import {
|
|
6
2
|
hasApiKey,
|
|
7
3
|
isKeylessLocalProvider,
|
|
8
4
|
visibleModelIds
|
|
9
5
|
} from "./chunk-3VXYY5JC.js";
|
|
6
|
+
import {
|
|
7
|
+
appendHistory,
|
|
8
|
+
backupCurrent
|
|
9
|
+
} from "./chunk-WSTVGC2C.js";
|
|
10
10
|
import {
|
|
11
11
|
openBrowser
|
|
12
12
|
} from "./chunk-DAKVBMD4.js";
|
|
@@ -17,8 +17,9 @@ import {
|
|
|
17
17
|
mutateConfigProviders,
|
|
18
18
|
normalizeKeys,
|
|
19
19
|
nowIso,
|
|
20
|
+
resolveActiveApiKey,
|
|
20
21
|
writeKeysBack
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-LUMETJFO.js";
|
|
22
23
|
|
|
23
24
|
// src/auth-menu/auth-menu-audit.ts
|
|
24
25
|
import { appendFileSync } from "node:fs";
|
|
@@ -260,10 +261,12 @@ async function runProviderAuthLogin(deps, strategyId, opts = {}) {
|
|
|
260
261
|
deps.renderer.write(color.dim(" Sign-in cancelled or timed out.\n"));
|
|
261
262
|
return 1;
|
|
262
263
|
}
|
|
264
|
+
controller.signal.throwIfAborted();
|
|
263
265
|
await mutateConfigProviders(
|
|
264
266
|
deps.profileConfigPath,
|
|
265
267
|
deps.vault,
|
|
266
268
|
(providers) => {
|
|
269
|
+
controller.signal.throwIfAborted();
|
|
267
270
|
applyProviderAuthOutcome(providers, outcome, { targetProviderId: opts.providerId });
|
|
268
271
|
},
|
|
269
272
|
deps.profileConfigPath
|
|
@@ -287,6 +290,7 @@ async function runProviderAuthLogin(deps, strategyId, opts = {}) {
|
|
|
287
290
|
// src/auth-menu/local.ts
|
|
288
291
|
import { DefaultSecretScrubber as DefaultSecretScrubber2 } from "@wrongstack/core/security";
|
|
289
292
|
import { color as color3 } from "@wrongstack/core/utils";
|
|
293
|
+
import { authProfileAliasError } from "@wrongstack/providers";
|
|
290
294
|
import { probeLocalLlm } from "@wrongstack/runtime/probe";
|
|
291
295
|
|
|
292
296
|
// src/auth-menu/helpers.ts
|
|
@@ -479,10 +483,27 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
479
483
|
if (!chosen) {
|
|
480
484
|
return 0;
|
|
481
485
|
}
|
|
482
|
-
const
|
|
486
|
+
const profileId = opts.alias?.trim() || chosen.id;
|
|
487
|
+
const aliasError = authProfileAliasError(
|
|
488
|
+
opts.alias !== void 0 ? opts.alias.trim() : profileId
|
|
489
|
+
);
|
|
490
|
+
if (aliasError) {
|
|
491
|
+
deps.renderer.writeError(aliasError);
|
|
492
|
+
return 1;
|
|
493
|
+
}
|
|
494
|
+
const aliasedProfile = opts.alias !== void 0 ? (await loadProviders(deps))[profileId] : void 0;
|
|
495
|
+
if (aliasedProfile && !opts.probeOnly) {
|
|
496
|
+
deps.renderer.writeError(
|
|
497
|
+
`Auth profile "${profileId}" already exists. Choose another alias or manage its keys explicitly.`
|
|
498
|
+
);
|
|
499
|
+
return 1;
|
|
500
|
+
}
|
|
501
|
+
const baseUrl = opts.baseUrl?.trim() || (opts.probeOnly ? aliasedProfile?.baseUrl : void 0) || chosen.defaultBaseUrl;
|
|
483
502
|
let apiKey;
|
|
484
503
|
if (opts.apiKey !== void 0) {
|
|
485
504
|
apiKey = opts.apiKey.trim() || void 0;
|
|
505
|
+
} else if (opts.probeOnly && aliasedProfile) {
|
|
506
|
+
apiKey = resolveActiveApiKey(aliasedProfile);
|
|
486
507
|
} else if (chosen.noAuth) {
|
|
487
508
|
apiKey = void 0;
|
|
488
509
|
} else if (opts.skipKey) {
|
|
@@ -528,7 +549,7 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
528
549
|
const resolvedModels = resolveModelList(opts.models, probe, scrubber);
|
|
529
550
|
const label = opts.label?.trim() || "default";
|
|
530
551
|
const providers = await loadProviders(deps);
|
|
531
|
-
const existing = providers[
|
|
552
|
+
const existing = providers[profileId];
|
|
532
553
|
const previousModels = existing?.models ? [...existing.models] : existing?.models === void 0 ? void 0 : [...existing.models];
|
|
533
554
|
const usedLabels = new Set(existing ? normalizeKeys(existing).map((k) => k.label) : []);
|
|
534
555
|
let finalLabel = label;
|
|
@@ -543,7 +564,9 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
543
564
|
deps.profileConfigPath,
|
|
544
565
|
deps.vault,
|
|
545
566
|
(all) => {
|
|
546
|
-
|
|
567
|
+
if (opts.alias !== void 0 && all[profileId])
|
|
568
|
+
throw new Error(`Auth profile "${profileId}" already exists.`);
|
|
569
|
+
const p = all[profileId] ?? { type: chosen.id };
|
|
547
570
|
if (!p.type) p.type = chosen.id;
|
|
548
571
|
if (!p.family) p.family = "openai-compatible";
|
|
549
572
|
if (!p.baseUrl) p.baseUrl = baseUrl;
|
|
@@ -557,16 +580,16 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
557
580
|
writeKeysBack(p, list);
|
|
558
581
|
if (!p.activeKey) p.activeKey = finalLabel;
|
|
559
582
|
}
|
|
560
|
-
all[
|
|
583
|
+
all[profileId] = p;
|
|
561
584
|
},
|
|
562
585
|
deps.profileConfigPath
|
|
563
586
|
);
|
|
564
587
|
} catch (err) {
|
|
565
|
-
deps.renderer.writeError(`Failed to save ${
|
|
588
|
+
deps.renderer.writeError(`Failed to save ${profileId}: ${err.message}`);
|
|
566
589
|
return 1;
|
|
567
590
|
}
|
|
568
591
|
const events = decideAuthLocalEvents({
|
|
569
|
-
providerId:
|
|
592
|
+
providerId: profileId,
|
|
570
593
|
baseUrl,
|
|
571
594
|
previousModels,
|
|
572
595
|
newModels: resolvedModels,
|
|
@@ -581,19 +604,19 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
581
604
|
}
|
|
582
605
|
if (apiKey) {
|
|
583
606
|
deps.renderer.write(
|
|
584
|
-
` ${color3.green("\u2713")} Saved ${color3.bold(
|
|
607
|
+
` ${color3.green("\u2713")} Saved ${color3.bold(profileId)}/${color3.bold(finalLabel)} \u2192 ${color3.cyan(baseUrl)}
|
|
585
608
|
`
|
|
586
609
|
);
|
|
587
610
|
} else {
|
|
588
611
|
deps.renderer.write(
|
|
589
|
-
` ${color3.green("\u2713")} Saved ${color3.bold(
|
|
612
|
+
` ${color3.green("\u2713")} Saved ${color3.bold(profileId)} (no key) \u2192 ${color3.cyan(baseUrl)}
|
|
590
613
|
`
|
|
591
614
|
);
|
|
592
615
|
}
|
|
593
616
|
const firstModel = resolvedModels && resolvedModels.length > 0 ? resolvedModels[0] : null;
|
|
594
617
|
const modelHint = firstModel ? color3.cyan(firstModel) : color3.dim("<model-id>");
|
|
595
618
|
deps.renderer.write(
|
|
596
|
-
color3.dim(` Launch: wstack --provider ${
|
|
619
|
+
color3.dim(` Launch: wstack --provider ${profileId} --model ${modelHint} "<task>"
|
|
597
620
|
`)
|
|
598
621
|
);
|
|
599
622
|
return 0;
|
|
@@ -746,11 +769,19 @@ function resolveOAuthKind(choice, opts = {}) {
|
|
|
746
769
|
async function runOAuthLoginChoice(deps, choice, opts = {}) {
|
|
747
770
|
const kind = resolveOAuthKind(choice, { ...opts, deps });
|
|
748
771
|
if (!kind) return false;
|
|
749
|
-
|
|
772
|
+
const sourceId = providerAuthRegistryFor(deps).get(kind)?.providerId ?? kind;
|
|
773
|
+
const profiles = await loadProviders(deps);
|
|
774
|
+
let suggestedAlias = sourceId;
|
|
775
|
+
for (let n = 2; profiles[suggestedAlias]; n++) suggestedAlias = `${sourceId}-${n}`;
|
|
776
|
+
const alias = (await deps.reader.readLine(
|
|
777
|
+
` Auth profile alias [${suggestedAlias}] (existing alias re-authenticates; q cancels): `
|
|
778
|
+
)).trim();
|
|
779
|
+
if (alias.toLowerCase() !== "q")
|
|
780
|
+
await runOAuthLoginKind(deps, kind, { providerId: alias || suggestedAlias });
|
|
750
781
|
return true;
|
|
751
782
|
}
|
|
752
|
-
async function runOAuthLoginKind(deps, kind) {
|
|
753
|
-
return runProviderAuthLogin(deps, kind);
|
|
783
|
+
async function runOAuthLoginKind(deps, kind, opts) {
|
|
784
|
+
return opts ? runProviderAuthLogin(deps, kind, opts) : runProviderAuthLogin(deps, kind);
|
|
754
785
|
}
|
|
755
786
|
async function runOAuthLoginMenu(deps) {
|
|
756
787
|
const entries = providerAuthRegistryFor(deps).list();
|
|
@@ -777,6 +808,7 @@ import {
|
|
|
777
808
|
setRawMode as setRawMode2,
|
|
778
809
|
stripAnsi as stripAnsi2,
|
|
779
810
|
toErrorMessage,
|
|
811
|
+
withFileLock,
|
|
780
812
|
writeOut as writeOut2
|
|
781
813
|
} from "@wrongstack/core/utils";
|
|
782
814
|
|
|
@@ -1053,6 +1085,7 @@ var PROVIDER_FAMILY_PREFERRED_ORDER = [
|
|
|
1053
1085
|
"openai-codex",
|
|
1054
1086
|
"github-copilot",
|
|
1055
1087
|
"google",
|
|
1088
|
+
"google-antigravity",
|
|
1056
1089
|
"openai-compatible"
|
|
1057
1090
|
];
|
|
1058
1091
|
function orderProvidersForDisplay(filtered) {
|
|
@@ -1129,41 +1162,44 @@ function renderLiveProviderList(query, filtered, selectedIdx, savedSet) {
|
|
|
1129
1162
|
}
|
|
1130
1163
|
async function saveToGlobalConfig(configPath, provider, model, homeFn = () => process.env.HOME ?? os.homedir()) {
|
|
1131
1164
|
try {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
await
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1165
|
+
return await withFileLock(configPath, async () => {
|
|
1166
|
+
const { atomicWrite } = await import("@wrongstack/core/utils");
|
|
1167
|
+
const fs = await import("node:fs/promises");
|
|
1168
|
+
let existing = {};
|
|
1169
|
+
try {
|
|
1170
|
+
const raw = await fs.readFile(configPath, "utf8");
|
|
1171
|
+
existing = JSON.parse(raw);
|
|
1172
|
+
} catch (err) {
|
|
1173
|
+
if (err.code !== "ENOENT") throw err;
|
|
1174
|
+
}
|
|
1175
|
+
const oldCfg = { ...existing };
|
|
1176
|
+
existing.provider = provider;
|
|
1177
|
+
existing.model = model;
|
|
1178
|
+
try {
|
|
1179
|
+
await backupCurrent(homeFn, configPath);
|
|
1180
|
+
} catch (err) {
|
|
1181
|
+
console.warn(
|
|
1182
|
+
JSON.stringify({
|
|
1183
|
+
level: "warn",
|
|
1184
|
+
event: "picker.backup_failed",
|
|
1185
|
+
message: toErrorMessage(err),
|
|
1186
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1187
|
+
})
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
1191
|
+
try {
|
|
1192
|
+
await appendHistory(
|
|
1193
|
+
oldCfg,
|
|
1194
|
+
existing,
|
|
1195
|
+
`Provider/model changed: ${oldCfg.provider ?? "(none)"} \u2192 ${provider}, ${oldCfg.model ?? "(none)"} \u2192 ${model}`,
|
|
1196
|
+
homeFn,
|
|
1197
|
+
configPath
|
|
1198
|
+
);
|
|
1199
|
+
} catch {
|
|
1200
|
+
}
|
|
1201
|
+
return true;
|
|
1202
|
+
});
|
|
1167
1203
|
} catch (err) {
|
|
1168
1204
|
console.warn(
|
|
1169
1205
|
JSON.stringify({
|
|
@@ -1357,6 +1393,7 @@ ${theme.accent(color7.bold("\u258C WrongStack"))} ${color7.dim("Provider & Mode
|
|
|
1357
1393
|
"openai-codex",
|
|
1358
1394
|
"github-copilot",
|
|
1359
1395
|
"google",
|
|
1396
|
+
"google-antigravity",
|
|
1360
1397
|
"openai-compatible"
|
|
1361
1398
|
];
|
|
1362
1399
|
const familyOrder = [
|
|
@@ -1585,7 +1622,11 @@ async function resolveModelSelection(answer, models, provider, _registry, render
|
|
|
1585
1622
|
|
|
1586
1623
|
// src/auth-menu/add-provider.ts
|
|
1587
1624
|
import { color as color8 } from "@wrongstack/core/utils";
|
|
1588
|
-
import {
|
|
1625
|
+
import {
|
|
1626
|
+
authProfileAliasError as authProfileAliasError2,
|
|
1627
|
+
catalogProviderIdFor,
|
|
1628
|
+
PROVIDER_DEFINITIONS
|
|
1629
|
+
} from "@wrongstack/providers";
|
|
1589
1630
|
|
|
1590
1631
|
// src/provider-id.ts
|
|
1591
1632
|
function nextCustomProviderId(existing) {
|
|
@@ -1640,9 +1681,7 @@ async function addFromCatalog(deps) {
|
|
|
1640
1681
|
${color8.dim("OAuth login options: enter a registered strategy name, or q to quit.")}
|
|
1641
1682
|
`
|
|
1642
1683
|
);
|
|
1643
|
-
const answer = (await deps.reader.readLine(
|
|
1644
|
-
` ${color8.amber("?")} OAuth strategy ${color8.dim("(or q)")}: `
|
|
1645
|
-
)).trim();
|
|
1684
|
+
const answer = (await deps.reader.readLine(` ${color8.amber("?")} OAuth strategy ${color8.dim("(or q)")}: `)).trim();
|
|
1646
1685
|
if (answer && await runOAuthLoginChoice(deps, answer, { allowNumeric: false })) {
|
|
1647
1686
|
return true;
|
|
1648
1687
|
}
|
|
@@ -1678,6 +1717,7 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1678
1717
|
const baseUrl = baseRaw || chosen.apiBase;
|
|
1679
1718
|
const providersNow = await loadProviders(deps);
|
|
1680
1719
|
let suggestedAlias = chosen.id;
|
|
1720
|
+
for (let n = 2; providersNow[suggestedAlias]; n++) suggestedAlias = `${chosen.id}-${n}`;
|
|
1681
1721
|
if (family !== chosen.family) {
|
|
1682
1722
|
let candidate = `${chosen.id}-${family}`;
|
|
1683
1723
|
let n = 2;
|
|
@@ -1691,6 +1731,11 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1691
1731
|
` ${color8.amber("?")} Save as alias ${color8.dim(`[${suggestedAlias}]`)} ${color8.dim("(used with --provider <alias>)")}: `
|
|
1692
1732
|
)).trim();
|
|
1693
1733
|
const alias = aliasRaw || suggestedAlias;
|
|
1734
|
+
const aliasError = authProfileAliasError2(alias);
|
|
1735
|
+
if (aliasError) {
|
|
1736
|
+
deps.renderer.writeError(aliasError);
|
|
1737
|
+
return false;
|
|
1738
|
+
}
|
|
1694
1739
|
const existing = providersNow[alias];
|
|
1695
1740
|
if (existing) {
|
|
1696
1741
|
const sameFamily = (existing.family ?? chosen.family) === family;
|
|
@@ -1704,6 +1749,10 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1704
1749
|
);
|
|
1705
1750
|
return false;
|
|
1706
1751
|
}
|
|
1752
|
+
deps.renderer.writeError(
|
|
1753
|
+
`Auth profile "${alias}" already exists. Choose another alias or manage its keys explicitly.`
|
|
1754
|
+
);
|
|
1755
|
+
return false;
|
|
1707
1756
|
}
|
|
1708
1757
|
return addKeyForProvider(alias, deps, {
|
|
1709
1758
|
type: chosen.id,
|
|
@@ -1897,4 +1946,4 @@ export {
|
|
|
1897
1946
|
addCustomProvider,
|
|
1898
1947
|
addKeyForProvider
|
|
1899
1948
|
};
|
|
1900
|
-
//# sourceMappingURL=chunk-
|
|
1949
|
+
//# sourceMappingURL=chunk-LFMVHT3R.js.map
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
|
|
2
|
+
// src/provider-config-utils.ts
|
|
3
|
+
import { FsError } from "@wrongstack/core/types";
|
|
4
|
+
import { expectDefined } from "@wrongstack/core/utils";
|
|
5
|
+
import * as fs from "node:fs/promises";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import {
|
|
8
|
+
decryptConfigSecrets,
|
|
9
|
+
decryptConfigSecretsForRewrite,
|
|
10
|
+
encryptConfigSecrets
|
|
11
|
+
} from "@wrongstack/core/security";
|
|
12
|
+
import { atomicWrite, backupConfigFile, color, withFileLock } from "@wrongstack/core/utils";
|
|
13
|
+
import {
|
|
14
|
+
clearStaleProviderDefaults,
|
|
15
|
+
removeProviderFallbackReferences,
|
|
16
|
+
validateProviderConfigShape
|
|
17
|
+
} from "@wrongstack/providers";
|
|
18
|
+
import { clearStaleProviderDefaults as clearStaleProviderDefaults2 } from "@wrongstack/providers";
|
|
19
|
+
import { nowIso } from "@wrongstack/primitives";
|
|
20
|
+
function normalizeKeys(cfg) {
|
|
21
|
+
if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {
|
|
22
|
+
return cfg.apiKeys.map((k) => ({ ...k }));
|
|
23
|
+
}
|
|
24
|
+
if (typeof cfg.apiKey === "string" && cfg.apiKey.length > 0) {
|
|
25
|
+
return [{ label: "default", apiKey: cfg.apiKey, createdAt: "" }];
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
function writeKeysBack(cfg, keys) {
|
|
30
|
+
if (keys.length === 0) {
|
|
31
|
+
delete cfg.apiKeys;
|
|
32
|
+
delete cfg.apiKey;
|
|
33
|
+
delete cfg.activeKey;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
cfg.apiKeys = keys;
|
|
37
|
+
const active = keys.find((k) => k.label === cfg.activeKey) ?? expectDefined(keys[0]);
|
|
38
|
+
delete cfg.apiKey;
|
|
39
|
+
if (!cfg.activeKey || !keys.some((k) => k.label === cfg.activeKey)) {
|
|
40
|
+
cfg.activeKey = active.label;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function resolveActiveApiKey(cfg) {
|
|
44
|
+
if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {
|
|
45
|
+
const active = cfg.activeKey ? cfg.apiKeys.find((k) => k.label === cfg.activeKey) : void 0;
|
|
46
|
+
return (active ?? cfg.apiKeys[0])?.apiKey;
|
|
47
|
+
}
|
|
48
|
+
return cfg.apiKey && cfg.apiKey.length > 0 ? cfg.apiKey : void 0;
|
|
49
|
+
}
|
|
50
|
+
function activeLabel(cfg, keys) {
|
|
51
|
+
if (cfg.activeKey && keys.some((k) => k.label === cfg.activeKey)) return cfg.activeKey;
|
|
52
|
+
return keys[0]?.label;
|
|
53
|
+
}
|
|
54
|
+
function maskedKey(key) {
|
|
55
|
+
if (!key) return color.dim("\u2014");
|
|
56
|
+
if (key.length <= 8) return color.dim("\u2022".repeat(key.length));
|
|
57
|
+
const head = key.slice(0, 4);
|
|
58
|
+
const tail = key.slice(-4);
|
|
59
|
+
return `${color.dim(head + "\u2026")}${tail}`;
|
|
60
|
+
}
|
|
61
|
+
async function loadConfigProviders(configPath, vault, opts) {
|
|
62
|
+
const warn = opts?.warn;
|
|
63
|
+
const targetPath = opts?.profileConfigPath ?? configPath;
|
|
64
|
+
let raw;
|
|
65
|
+
try {
|
|
66
|
+
raw = await fs.readFile(targetPath, "utf8");
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (err.code !== "ENOENT") {
|
|
69
|
+
warn?.(`Could not read ${targetPath}: ${err.message}. Treating as empty.`);
|
|
70
|
+
}
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
let parsed;
|
|
74
|
+
try {
|
|
75
|
+
parsed = JSON.parse(raw);
|
|
76
|
+
validateProviderConfigShape(parsed);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
warn?.(`Config at ${targetPath} is not valid JSON: ${err.message}`);
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
const decrypted = decryptConfigSecrets(parsed, vault);
|
|
82
|
+
return decrypted.providers ?? {};
|
|
83
|
+
}
|
|
84
|
+
var configMutationChain = Promise.resolve();
|
|
85
|
+
function globalRootForConfigPath(configPath) {
|
|
86
|
+
const configDir = path.dirname(configPath);
|
|
87
|
+
const profilesDir = path.dirname(configDir);
|
|
88
|
+
return path.basename(profilesDir) === "profiles" ? path.dirname(profilesDir) : configDir;
|
|
89
|
+
}
|
|
90
|
+
function queueConfigMutation(mutate) {
|
|
91
|
+
const run = configMutationChain.then(mutate, mutate);
|
|
92
|
+
configMutationChain = run.then(
|
|
93
|
+
() => void 0,
|
|
94
|
+
() => void 0
|
|
95
|
+
);
|
|
96
|
+
return run;
|
|
97
|
+
}
|
|
98
|
+
async function mutateConfigProviders(configPath, vault, mutator, profileConfigPath) {
|
|
99
|
+
await queueConfigMutation(
|
|
100
|
+
() => withFileLock(profileConfigPath ?? configPath, async () => {
|
|
101
|
+
const targetPath = profileConfigPath ?? configPath;
|
|
102
|
+
let raw;
|
|
103
|
+
let fileExists = true;
|
|
104
|
+
try {
|
|
105
|
+
raw = await fs.readFile(targetPath, "utf8");
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (err.code !== "ENOENT") {
|
|
108
|
+
throw new FsError({
|
|
109
|
+
message: `Refusing to mutate ${configPath}: ${err.message}`,
|
|
110
|
+
code: "FS_READ_FAILED",
|
|
111
|
+
path: targetPath,
|
|
112
|
+
context: { operation: "mutateConfigProviders", phase: "read" },
|
|
113
|
+
cause: err
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
fileExists = false;
|
|
117
|
+
raw = "{}";
|
|
118
|
+
}
|
|
119
|
+
let parsed;
|
|
120
|
+
try {
|
|
121
|
+
parsed = JSON.parse(raw);
|
|
122
|
+
validateProviderConfigShape(parsed);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
if (fileExists) {
|
|
125
|
+
throw new FsError({
|
|
126
|
+
message: `Refusing to overwrite corrupt config at ${targetPath} (${err.message}). Fix or move the file aside before retrying.`,
|
|
127
|
+
code: "FS_READ_FAILED",
|
|
128
|
+
path: targetPath,
|
|
129
|
+
context: { operation: "mutateConfigProviders", phase: "parse" },
|
|
130
|
+
cause: err
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
parsed = {};
|
|
134
|
+
}
|
|
135
|
+
const decrypted = decryptConfigSecretsForRewrite(parsed, vault);
|
|
136
|
+
const providers = decrypted.providers ?? {};
|
|
137
|
+
const previousProviderIds = Object.keys(providers);
|
|
138
|
+
const primaryBefore = JSON.stringify([
|
|
139
|
+
decrypted["provider"],
|
|
140
|
+
decrypted["model"],
|
|
141
|
+
typeof decrypted["provider"] === "string" ? providers[decrypted["provider"]] : void 0
|
|
142
|
+
]);
|
|
143
|
+
mutator(providers, decrypted);
|
|
144
|
+
for (const id of previousProviderIds) {
|
|
145
|
+
if (!Object.hasOwn(providers, id)) removeProviderFallbackReferences(decrypted, id);
|
|
146
|
+
}
|
|
147
|
+
decrypted.providers = providers;
|
|
148
|
+
const primaryAfter = JSON.stringify([
|
|
149
|
+
decrypted["provider"],
|
|
150
|
+
decrypted["model"],
|
|
151
|
+
typeof decrypted["provider"] === "string" ? providers[decrypted["provider"]] : void 0
|
|
152
|
+
]);
|
|
153
|
+
clearStaleProviderDefaults(decrypted, { preservePrimary: primaryBefore === primaryAfter });
|
|
154
|
+
const encrypted = encryptConfigSecrets(decrypted, vault);
|
|
155
|
+
await backupConfigFile(targetPath, { globalRoot: globalRootForConfigPath(targetPath) });
|
|
156
|
+
await atomicWrite(targetPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
157
|
+
})
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export {
|
|
162
|
+
normalizeKeys,
|
|
163
|
+
writeKeysBack,
|
|
164
|
+
resolveActiveApiKey,
|
|
165
|
+
activeLabel,
|
|
166
|
+
maskedKey,
|
|
167
|
+
loadConfigProviders,
|
|
168
|
+
mutateConfigProviders,
|
|
169
|
+
nowIso
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=chunk-LUMETJFO.js.map
|
|
@@ -185,7 +185,11 @@ function parseAuthFlags(args) {
|
|
|
185
185
|
key = a.slice(0, eq);
|
|
186
186
|
inlineVal = a.slice(eq + 1);
|
|
187
187
|
}
|
|
188
|
-
if (key === "--
|
|
188
|
+
if (key === "--alias") {
|
|
189
|
+
const next = args[i + 1];
|
|
190
|
+
const v = inlineVal !== void 0 ? inlineVal : next !== void 0 && !next.startsWith("-") ? args[++i] : "";
|
|
191
|
+
out.alias = v ?? "";
|
|
192
|
+
} else if (key === "--label") {
|
|
189
193
|
const v = inlineVal !== void 0 ? inlineVal : args[++i];
|
|
190
194
|
if (v) out.label = v;
|
|
191
195
|
} else if (key === "--family") {
|
|
@@ -258,4 +262,4 @@ export {
|
|
|
258
262
|
parseAuthFlags,
|
|
259
263
|
parseSpawnFlags
|
|
260
264
|
};
|
|
261
|
-
//# sourceMappingURL=chunk-
|
|
265
|
+
//# sourceMappingURL=chunk-MHEBWVXL.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
helpCmd,
|
|
3
3
|
versionCmd
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2BKFWIER.js";
|
|
5
5
|
import {
|
|
6
6
|
parseArgs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-MHEBWVXL.js";
|
|
8
8
|
|
|
9
9
|
// src/boot/short-circuit-flags.ts
|
|
10
10
|
async function handleHelpVersionShortCircuit(argv) {
|
|
@@ -22,11 +22,11 @@ async function handleHelpVersionShortCircuit(argv) {
|
|
|
22
22
|
}
|
|
23
23
|
if (earlyFlags["help"] === true) {
|
|
24
24
|
if (positional.length > 0) {
|
|
25
|
-
const { subcommandNames } = await import("./subcommands-
|
|
25
|
+
const { subcommandNames } = await import("./subcommands-ZTSIN7LG.js");
|
|
26
26
|
if (subcommandNames.includes(positional[0])) {
|
|
27
27
|
const first = positional[0];
|
|
28
28
|
const deep = positional[1];
|
|
29
|
-
const { renderDeepHelp, renderFocusedHelp } = await import("./per-subcommand-help-
|
|
29
|
+
const { renderDeepHelp, renderFocusedHelp } = await import("./per-subcommand-help-XE77MTGJ.js");
|
|
30
30
|
if (deep && renderDeepHelp(`${first}:${deep}`, stubRenderer)) {
|
|
31
31
|
return 0;
|
|
32
32
|
}
|
|
@@ -43,4 +43,4 @@ async function handleHelpVersionShortCircuit(argv) {
|
|
|
43
43
|
export {
|
|
44
44
|
handleHelpVersionShortCircuit
|
|
45
45
|
};
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-PGKJ2OQP.js.map
|
|
@@ -14,7 +14,7 @@ async function printUpdateNotice(initialUpdateInfo) {
|
|
|
14
14
|
const ac = new AbortController();
|
|
15
15
|
const timer = setTimeout(() => ac.abort(), 2e3);
|
|
16
16
|
try {
|
|
17
|
-
const { checkForUpdate } = await import("./update-check-
|
|
17
|
+
const { checkForUpdate } = await import("./update-check-2POMBHFB.js");
|
|
18
18
|
info = await checkForUpdate(ac.signal);
|
|
19
19
|
} catch {
|
|
20
20
|
} finally {
|
|
@@ -62,4 +62,4 @@ export {
|
|
|
62
62
|
applySessionShellDefault,
|
|
63
63
|
runPreflight
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-QBBF7GIK.js.map
|
|
@@ -3,12 +3,13 @@ import {
|
|
|
3
3
|
} from "./chunk-U3SS4NRH.js";
|
|
4
4
|
import {
|
|
5
5
|
checkForUpdate
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZZRSG7VK.js";
|
|
7
7
|
|
|
8
8
|
// src/subcommands/handlers/update.ts
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
10
10
|
import { existsSync, realpathSync } from "node:fs";
|
|
11
11
|
import * as path from "node:path";
|
|
12
|
+
import { isStandaloneBinary } from "@wrongstack/core/utils";
|
|
12
13
|
var MAX_UPDATE_OUTPUT_CHARS = 256 * 1024;
|
|
13
14
|
async function runUpdateCommand(args, deps) {
|
|
14
15
|
const cwd = deps.cwd;
|
|
@@ -55,7 +56,7 @@ async function runUpdateCommand(args, deps) {
|
|
|
55
56
|
});
|
|
56
57
|
if (info.checkFailed) {
|
|
57
58
|
deps.renderer.write(
|
|
58
|
-
`Update check failed for ${packageName}. Check your internet connection and try again.
|
|
59
|
+
`Update check failed for ${isStandaloneBinary() ? "the GitHub releases" : packageName}. Check your internet connection and try again.
|
|
59
60
|
`
|
|
60
61
|
);
|
|
61
62
|
return 1;
|
|
@@ -75,6 +76,13 @@ async function runUpdateCommand(args, deps) {
|
|
|
75
76
|
`);
|
|
76
77
|
return 0;
|
|
77
78
|
}
|
|
79
|
+
if (isStandaloneBinary()) {
|
|
80
|
+
const { updateStandaloneBinary } = await import("./standalone-update-MW47J3AK.js");
|
|
81
|
+
return updateStandaloneBinary({
|
|
82
|
+
current: info.current,
|
|
83
|
+
renderer: deps.renderer
|
|
84
|
+
});
|
|
85
|
+
}
|
|
78
86
|
const packageManager = parsed.packageManager ?? detectUpdatePackageManager();
|
|
79
87
|
let updateCommand;
|
|
80
88
|
try {
|
|
@@ -383,4 +391,4 @@ export {
|
|
|
383
391
|
detectUpdatePackageManager,
|
|
384
392
|
detectUpdatePackageName
|
|
385
393
|
};
|
|
386
|
-
//# sourceMappingURL=chunk-
|
|
394
|
+
//# sourceMappingURL=chunk-QFPQXKCG.js.map
|