@wrongstack/cli 1.0.32 → 1.0.35
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 +322 -2
- package/dist/{acp-EDGUWU7N.js → acp-T77EAEDB.js} +469 -465
- package/dist/{auth-SUHKFFO4.js → auth-M6LXZTDA.js} +4 -4
- package/dist/auth-menu/openai-codex-oauth.d.ts +1 -1
- package/dist/auth-menu/panel-provider-edits.d.ts +15 -0
- package/dist/auth-menu/panel-service.d.ts +1 -1
- package/dist/auto-discover-providers-JX346GOM.js +7 -0
- package/dist/boot/governance-evidence-candidate.d.ts +1 -2
- package/dist/boot/system-prompt-builder.d.ts +1 -1
- package/dist/boot/tui-project-spawn.d.ts +0 -1
- package/dist/boot/tui-session-resume-contracts.d.ts +95 -0
- package/dist/boot/tui-session-resume.d.ts +2 -88
- package/dist/boot/tui-settings-read.d.ts +3 -0
- package/dist/{boot-auto-thin-K2DHHYIW.js → boot-auto-thin-YMAZI3QL.js} +2 -2
- package/dist/boot-launch-choices.d.ts +22 -0
- package/dist/boot-provider-gate.d.ts +28 -0
- package/dist/boot-subcommand-dispatch.d.ts +24 -0
- package/dist/boot.d.ts +1 -1
- package/dist/chimera-cascade-evidence.d.ts +1 -1
- package/dist/{chunk-TI7KLHYX.js → chunk-2CMMWRQH.js} +81 -80
- package/dist/{chunk-3LEFXLAW.js → chunk-6SIUTX75.js} +36 -36
- package/dist/{chunk-RQ4UBKYH.js → chunk-6Z6C6ZHH.js} +3 -3
- package/dist/{chunk-5EA6OTLJ.js → chunk-AFOH6CHO.js} +2 -2
- package/dist/{chunk-WHEYHDIE.js → chunk-AKESWZH5.js} +2 -1
- package/dist/{chunk-JHUJUIOH.js → chunk-AT2A7RJZ.js} +4 -16
- package/dist/{chunk-U3SS4NRH.js → chunk-BHXAKTBE.js} +1 -1
- package/dist/{chunk-MPQCHBDJ.js → chunk-CJSHS2K7.js} +5 -1
- package/dist/{chunk-P3GRLV47.js → chunk-GZSKLXYG.js} +208 -141
- package/dist/{chunk-4MDRHMX4.js → chunk-KMU7GF7X.js} +3 -26
- package/dist/{chunk-WXJH4F6K.js → chunk-LDV4ERNV.js} +4 -4
- package/dist/{chunk-LIZXJHZQ.js → chunk-LDXXMPMS.js} +13 -13
- package/dist/{chunk-UQUYBDMG.js → chunk-M4G5FO7F.js} +1 -1
- package/dist/{chunk-CFHWIFXL.js → chunk-PA4VBCXS.js} +25 -33
- package/dist/{chunk-5UZBUV2H.js → chunk-RKU66D2O.js} +6 -4
- package/dist/{chunk-PGNERAZL.js → chunk-RWNI5OWT.js} +2 -2
- package/dist/chunk-TGSPCFBT.js +1 -0
- package/dist/{cli-context-ITHGP2CE.js → cli-context-II57EHD2.js} +1555 -1451
- package/dist/cli-initial-tools.d.ts +54 -0
- package/dist/{cli-main-TQGLKB6D.js → cli-main-YR2WJCPL.js} +38062 -37035
- package/dist/cli-main-boot.d.ts +133 -0
- package/dist/cli-main-orchestration.d.ts +170 -0
- package/dist/cli-main-state.d.ts +19 -0
- package/dist/config-doctor.d.ts +1 -1
- package/dist/{config-transfer-UE37X4B5.js → config-transfer-VOIFY7U4.js} +2 -2
- package/dist/{execution-C2IECWF7.js → execution-IBAZ2EIU.js} +138 -124
- package/dist/fleet/host-director-setup.d.ts +41 -0
- package/dist/fleet/host-spawn-types.d.ts +17 -0
- package/dist/fleet/host.d.ts +2 -1
- package/dist/goal-host-prompts.d.ts +5 -0
- package/dist/goal-host-types.d.ts +94 -0
- package/dist/goal-host.d.ts +2 -91
- package/dist/{hq-KBFDKTDD.js → hq-5OIEKB4V.js} +5 -6
- package/dist/hq-server/handle-types.d.ts +1 -1
- package/dist/hq-server/routes/auth-handlers.d.ts +1 -1
- package/dist/hq-server/routes.d.ts +1 -13
- package/dist/hq-server/utils.d.ts +1 -1
- package/dist/{hq-server-AVNKZ2PV.js → hq-server-DU3ZH3X7.js} +3 -3
- package/dist/{hq-service-FGB7BY2D.js → hq-service-LYZV7EK7.js} +3 -3
- package/dist/index.js +4 -4
- package/dist/live-settings-input.d.ts +2 -0
- package/dist/mailbox-bridge-bootstrap.d.ts +1 -4
- package/dist/{modeldiag-PQILD7TN.js → modeldiag-NEPTLFZW.js} +2 -2
- package/dist/picker-effort.d.ts +32 -0
- package/dist/picker-model-picker.d.ts +13 -2
- package/dist/picker-provider-list.d.ts +66 -0
- package/dist/picker.d.ts +12 -12
- package/dist/{providers-models-W57I3QOA.js → providers-models-37DUV2GW.js} +297 -253
- package/dist/repl-suggestions.d.ts +0 -5
- package/dist/{sdd-runtime-PTOSPYI4.js → sdd-runtime-PF72WHLO.js} +3 -20
- package/dist/services/sdd/task-manager.d.ts +1 -12
- package/dist/services/sdd-runtime.d.ts +3 -4
- package/dist/services/statusline-config.d.ts +0 -2
- package/dist/settings-behavior-sections.d.ts +0 -1
- package/dist/short-circuit-flags-EXJBJ5GT.js +10 -0
- package/dist/{skill-suggest-L2EVWB6R.js → skill-suggest-THANK3LV.js} +1 -1
- package/dist/slash-commands/command-context.d.ts +2 -0
- package/dist/slash-commands/fallback-chain-view.d.ts +3 -0
- package/dist/slash-commands/fallback-ref-validation.d.ts +34 -0
- package/dist/slash-commands/goal-refiner.d.ts +10 -2
- package/dist/slash-commands/goals.d.ts +6 -0
- package/dist/slash-commands/kanban-task-completion.d.ts +17 -0
- package/dist/slash-commands/mcp.d.ts +0 -1
- package/dist/slash-commands/memory-purge-domain-terms.d.ts +5 -0
- package/dist/slash-commands/nextsteps-mode.d.ts +13 -0
- package/dist/slash-commands/session-live-status.d.ts +21 -0
- package/dist/slash-commands/session.d.ts +1 -1
- package/dist/slash-commands/settings-feature-ui-mutations.d.ts +8 -0
- package/dist/slash-commands/settings-hq-autonomy-mutations.d.ts +8 -0
- package/dist/slash-commands/settings-persist-deps.d.ts +10 -0
- package/dist/slash-commands/settings-runtime-mutations.d.ts +12 -0
- package/dist/slash-commands/shadow.d.ts +0 -1
- package/dist/slash-commands/tool-auto-thin-commands.d.ts +15 -0
- package/dist/subcommands/handlers/acp-agents.d.ts +9 -0
- package/dist/subcommands/handlers/acp-server.d.ts +7 -0
- package/dist/subcommands/handlers/hq.d.ts +0 -1
- package/dist/subcommands/handlers/providers-models-custom.d.ts +33 -0
- package/dist/subcommands/handlers/providers-models-visibility.d.ts +29 -0
- package/dist/subcommands/handlers/skill-suggest.d.ts +0 -2
- package/dist/{subcommands-QO7VYTSS.js → subcommands-DTKBXLPU.js} +2 -2
- package/dist/{update-J5WHAFPE.js → update-6OEPAEUV.js} +3 -3
- package/dist/utils/win32-cmd.d.ts +1 -1
- package/dist/{version-help-ATOKGMTK.js → version-help-JQGRPDJW.js} +2 -2
- package/dist/webui-server/host-settings.d.ts +17 -0
- package/dist/webui-server/http-bridge.d.ts +32 -0
- package/dist/webui-server/instance-registration.d.ts +19 -0
- package/dist/webui-server/kanban-services.d.ts +9 -0
- package/dist/webui-server/message-router.d.ts +14 -0
- package/dist/webui-server/prefs-seeding.d.ts +1 -2
- package/dist/webui-server/provider-config.d.ts +0 -1
- package/dist/webui-server/provider-plane.d.ts +14 -0
- package/dist/webui-server/session-agents.d.ts +18 -0
- package/dist/webui-server/session-start-live.d.ts +11 -0
- package/dist/webui-server/stream-coalescer.d.ts +1 -1
- package/dist/webui-server/transport.d.ts +12 -0
- package/dist/{webui-server-GQOVLQS3.js → webui-server-6IC3SLZG.js} +1600 -1435
- package/dist/webui-session-maintenance.d.ts +16 -0
- package/dist/wiring/brain-and-orchestration.d.ts +1 -1
- package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
- package/dist/wiring/command-host-state.d.ts +11 -2
- package/dist/wiring/dep-watcher-bridge.d.ts +8 -1
- package/dist/wiring/session-command-handlers.d.ts +2 -1
- package/dist/worktree-command-host.d.ts +31 -0
- package/package.json +30 -30
- package/dist/auto-discover-providers-QIL34K3U.js +0 -7
- package/dist/chunk-WHOIR577.js +0 -1
- package/dist/short-circuit-flags-6LB3EGF7.js +0 -10
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
hasApiKey,
|
|
3
3
|
isKeylessLocalProvider,
|
|
4
4
|
visibleModelIds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RKU66D2O.js";
|
|
6
6
|
import {
|
|
7
7
|
activeLabel,
|
|
8
8
|
loadConfigProviders,
|
|
@@ -809,17 +809,51 @@ async function runOAuthLoginMenu(deps) {
|
|
|
809
809
|
await runOAuthLoginChoice(deps, pick);
|
|
810
810
|
}
|
|
811
811
|
|
|
812
|
+
// src/picker-effort.ts
|
|
813
|
+
import {
|
|
814
|
+
REASONING_EFFORT_LEVELS
|
|
815
|
+
} from "@wrongstack/core/types";
|
|
816
|
+
var EFFORT_KEEP = "default";
|
|
817
|
+
function startupEffortOptions(model) {
|
|
818
|
+
if (!model) return [];
|
|
819
|
+
const config = model.reasoningConfig;
|
|
820
|
+
if (!(model.reasoning ?? config !== void 0)) return [];
|
|
821
|
+
if (config?.effortSupported === false) return [];
|
|
822
|
+
const documented = config?.effortSupported ? config.effortLevels ?? [] : [];
|
|
823
|
+
const levels = documented.length > 0 ? REASONING_EFFORT_LEVELS.filter((level) => documented.includes(level)) : [...REASONING_EFFORT_LEVELS];
|
|
824
|
+
if (levels.length === 0) return [];
|
|
825
|
+
return [EFFORT_KEEP, ...levels];
|
|
826
|
+
}
|
|
827
|
+
function cycleStartupEffort(options, current, delta) {
|
|
828
|
+
if (options.length === 0) return EFFORT_KEEP;
|
|
829
|
+
const base = Math.max(0, options.indexOf(current));
|
|
830
|
+
return options[(base + delta + options.length) % options.length] ?? EFFORT_KEEP;
|
|
831
|
+
}
|
|
832
|
+
function reasoningEffortVocabulary(rc) {
|
|
833
|
+
if (rc?.effortSupported === false) return [];
|
|
834
|
+
if (rc?.effortSupported && rc.effortLevels?.length) return [...rc.effortLevels];
|
|
835
|
+
return void 0;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// src/auth-menu/add-provider.ts
|
|
839
|
+
import { color as color9 } from "@wrongstack/core/utils";
|
|
840
|
+
import {
|
|
841
|
+
authProfileAliasError as authProfileAliasError2,
|
|
842
|
+
catalogProviderIdFor,
|
|
843
|
+
PROVIDER_DEFINITIONS
|
|
844
|
+
} from "@wrongstack/providers";
|
|
845
|
+
|
|
812
846
|
// src/picker.ts
|
|
813
847
|
import os from "node:os";
|
|
848
|
+
import { color as color8, expectDefined as expectDefined2, toErrorMessage, withFileLock } from "@wrongstack/core/utils";
|
|
849
|
+
|
|
850
|
+
// src/picker-model-picker.ts
|
|
814
851
|
import {
|
|
815
|
-
color as
|
|
816
|
-
expectDefined
|
|
817
|
-
setOutputLineGuard
|
|
818
|
-
setRawMode
|
|
819
|
-
|
|
820
|
-
toErrorMessage,
|
|
821
|
-
withFileLock,
|
|
822
|
-
writeOut as writeOut2
|
|
852
|
+
color as color6,
|
|
853
|
+
expectDefined,
|
|
854
|
+
setOutputLineGuard,
|
|
855
|
+
setRawMode,
|
|
856
|
+
writeOut
|
|
823
857
|
} from "@wrongstack/core/utils";
|
|
824
858
|
|
|
825
859
|
// src/picker-key-state.ts
|
|
@@ -855,15 +889,6 @@ function applyPickerKey(state, chunk, matchCount) {
|
|
|
855
889
|
return { query, selected, status };
|
|
856
890
|
}
|
|
857
891
|
|
|
858
|
-
// src/picker-model-picker.ts
|
|
859
|
-
import {
|
|
860
|
-
color as color6,
|
|
861
|
-
expectDefined,
|
|
862
|
-
setOutputLineGuard,
|
|
863
|
-
setRawMode,
|
|
864
|
-
writeOut
|
|
865
|
-
} from "@wrongstack/core/utils";
|
|
866
|
-
|
|
867
892
|
// src/picker-ui.ts
|
|
868
893
|
import { color as color5, stripAnsi } from "@wrongstack/core/utils";
|
|
869
894
|
var theme = {
|
|
@@ -939,7 +964,17 @@ function filterModels(query, models) {
|
|
|
939
964
|
if (!q) return [...models];
|
|
940
965
|
return models.filter((m) => m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q));
|
|
941
966
|
}
|
|
942
|
-
function
|
|
967
|
+
function renderEffortStrip(strip) {
|
|
968
|
+
const label = color6.dim("effort (\u2190/\u2192):");
|
|
969
|
+
if (strip.options.length === 0) {
|
|
970
|
+
return `${label} ${color6.dim("not adjustable for this model")}`;
|
|
971
|
+
}
|
|
972
|
+
const levels = strip.options.map(
|
|
973
|
+
(option) => option === strip.choice ? theme.accent(color6.bold(`[${option}]`)) : color6.dim(option)
|
|
974
|
+
).join(color6.dim(" \xB7 "));
|
|
975
|
+
return `${label} ${levels}`;
|
|
976
|
+
}
|
|
977
|
+
function renderLiveModelList(query, filtered, selectedIdx, header, effort) {
|
|
943
978
|
const ordered = [...filtered].sort(
|
|
944
979
|
(a, b) => (b.release_date ?? "").localeCompare(a.release_date ?? "")
|
|
945
980
|
);
|
|
@@ -973,10 +1008,15 @@ function renderLiveModelList(query, filtered, selectedIdx, header) {
|
|
|
973
1008
|
);
|
|
974
1009
|
}
|
|
975
1010
|
lines.push(boxDivider());
|
|
1011
|
+
if (effort) {
|
|
1012
|
+
lines.push(boxRow(renderEffortStrip(effort)));
|
|
1013
|
+
lines.push(boxDivider());
|
|
1014
|
+
}
|
|
976
1015
|
lines.push(
|
|
977
1016
|
boxRow(
|
|
978
1017
|
keyHints([
|
|
979
1018
|
["\u2191\u2193", "move"],
|
|
1019
|
+
...effort && effort.options.length > 0 ? [["\u2190\u2192", "effort"]] : [],
|
|
980
1020
|
["Enter", "select"],
|
|
981
1021
|
["Esc", "clear"],
|
|
982
1022
|
["Ctrl+C", "quit"]
|
|
@@ -986,6 +1026,8 @@ function renderLiveModelList(query, filtered, selectedIdx, header) {
|
|
|
986
1026
|
lines.push(boxBottom());
|
|
987
1027
|
return lines.join("\n");
|
|
988
1028
|
}
|
|
1029
|
+
var ARROW_RIGHT = "\x1B[C";
|
|
1030
|
+
var ARROW_LEFT = "\x1B[D";
|
|
989
1031
|
async function runLiveModelPicker(provider, defaultModel) {
|
|
990
1032
|
const stdin = process.stdin;
|
|
991
1033
|
const out = process.stdout;
|
|
@@ -1007,9 +1049,19 @@ async function runLiveModelPicker(provider, defaultModel) {
|
|
|
1007
1049
|
if (state.selected >= visibleCount()) state.selected = Math.max(0, visibleCount() - 1);
|
|
1008
1050
|
};
|
|
1009
1051
|
clamp();
|
|
1052
|
+
let effortChoice = EFFORT_KEEP;
|
|
1053
|
+
let effortOwner;
|
|
1054
|
+
const effortStrip = () => {
|
|
1055
|
+
const focused = ordered[state.selected];
|
|
1056
|
+
if (focused?.id !== effortOwner) {
|
|
1057
|
+
effortOwner = focused?.id;
|
|
1058
|
+
effortChoice = EFFORT_KEEP;
|
|
1059
|
+
}
|
|
1060
|
+
return { options: startupEffortOptions(focused), choice: effortChoice };
|
|
1061
|
+
};
|
|
1010
1062
|
const preamble = codexPickerPreamble(provider);
|
|
1011
1063
|
if (preamble) writeOut(preamble);
|
|
1012
|
-
let frame = renderLiveModelList(state.query, ordered, state.selected, header);
|
|
1064
|
+
let frame = renderLiveModelList(state.query, ordered, state.selected, header, effortStrip());
|
|
1013
1065
|
writeOut(frame);
|
|
1014
1066
|
return new Promise((resolve) => {
|
|
1015
1067
|
const wasRaw = stdin.isRaw;
|
|
@@ -1027,10 +1079,17 @@ async function runLiveModelPicker(provider, defaultModel) {
|
|
|
1027
1079
|
writeOut(`\x1B[${ups}A\r\x1B[J`);
|
|
1028
1080
|
ordered = order(filterModels(state.query, provider.models));
|
|
1029
1081
|
clamp();
|
|
1030
|
-
frame = renderLiveModelList(state.query, ordered, state.selected, header);
|
|
1082
|
+
frame = renderLiveModelList(state.query, ordered, state.selected, header, effortStrip());
|
|
1031
1083
|
writeOut(frame);
|
|
1032
1084
|
};
|
|
1033
1085
|
const onData = (chunk) => {
|
|
1086
|
+
if (chunk === ARROW_RIGHT || chunk === ARROW_LEFT) {
|
|
1087
|
+
const { options } = effortStrip();
|
|
1088
|
+
if (options.length === 0) return;
|
|
1089
|
+
effortChoice = cycleStartupEffort(options, effortChoice, chunk === ARROW_RIGHT ? 1 : -1);
|
|
1090
|
+
repaint();
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1034
1093
|
ordered = order(filterModels(state.query, provider.models));
|
|
1035
1094
|
state = applyPickerKey(state, chunk, visibleCount());
|
|
1036
1095
|
ordered = order(filterModels(state.query, provider.models));
|
|
@@ -1048,9 +1107,10 @@ async function runLiveModelPicker(provider, defaultModel) {
|
|
|
1048
1107
|
return;
|
|
1049
1108
|
}
|
|
1050
1109
|
const pick = ordered[state.selected] ?? expectDefined(ordered[0]);
|
|
1110
|
+
const effort = startupEffortOptions(pick).length > 0 ? effortStrip().choice : EFFORT_KEEP;
|
|
1051
1111
|
cleanup();
|
|
1052
1112
|
writeOut("\n");
|
|
1053
|
-
resolve(pick);
|
|
1113
|
+
resolve({ model: pick, effort });
|
|
1054
1114
|
return;
|
|
1055
1115
|
}
|
|
1056
1116
|
repaint();
|
|
@@ -1059,7 +1119,8 @@ async function runLiveModelPicker(provider, defaultModel) {
|
|
|
1059
1119
|
});
|
|
1060
1120
|
}
|
|
1061
1121
|
|
|
1062
|
-
// src/picker.ts
|
|
1122
|
+
// src/picker-provider-list.ts
|
|
1123
|
+
import { color as color7, setOutputLineGuard as setOutputLineGuard2, setRawMode as setRawMode2, stripAnsi as stripAnsi2, writeOut as writeOut2 } from "@wrongstack/core/utils";
|
|
1063
1124
|
function appendLocalPresetProviders(merged) {
|
|
1064
1125
|
const existing = new Set(merged.map((p) => p.id));
|
|
1065
1126
|
for (const preset of LOCAL_LLM_PRESETS) {
|
|
@@ -1170,58 +1231,6 @@ function renderLiveProviderList(query, filtered, selectedIdx, savedSet) {
|
|
|
1170
1231
|
lines.push(boxBottom());
|
|
1171
1232
|
return lines.join("\n");
|
|
1172
1233
|
}
|
|
1173
|
-
async function saveToGlobalConfig(configPath, provider, model, homeFn = () => process.env.HOME ?? os.homedir()) {
|
|
1174
|
-
try {
|
|
1175
|
-
return await withFileLock(configPath, async () => {
|
|
1176
|
-
const { atomicWrite } = await import("@wrongstack/core/utils");
|
|
1177
|
-
const fs = await import("node:fs/promises");
|
|
1178
|
-
let existing = {};
|
|
1179
|
-
try {
|
|
1180
|
-
const raw = await fs.readFile(configPath, "utf8");
|
|
1181
|
-
existing = JSON.parse(raw);
|
|
1182
|
-
} catch (err) {
|
|
1183
|
-
if (err.code !== "ENOENT") throw err;
|
|
1184
|
-
}
|
|
1185
|
-
const oldCfg = { ...existing };
|
|
1186
|
-
existing.provider = provider;
|
|
1187
|
-
existing.model = model;
|
|
1188
|
-
try {
|
|
1189
|
-
await backupCurrent(homeFn, configPath);
|
|
1190
|
-
} catch (err) {
|
|
1191
|
-
console.warn(
|
|
1192
|
-
JSON.stringify({
|
|
1193
|
-
level: "warn",
|
|
1194
|
-
event: "picker.backup_failed",
|
|
1195
|
-
message: toErrorMessage(err),
|
|
1196
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1197
|
-
})
|
|
1198
|
-
);
|
|
1199
|
-
}
|
|
1200
|
-
await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
1201
|
-
try {
|
|
1202
|
-
await appendHistory(
|
|
1203
|
-
oldCfg,
|
|
1204
|
-
existing,
|
|
1205
|
-
`Provider/model changed: ${oldCfg.provider ?? "(none)"} \u2192 ${provider}, ${oldCfg.model ?? "(none)"} \u2192 ${model}`,
|
|
1206
|
-
homeFn,
|
|
1207
|
-
configPath
|
|
1208
|
-
);
|
|
1209
|
-
} catch {
|
|
1210
|
-
}
|
|
1211
|
-
return true;
|
|
1212
|
-
});
|
|
1213
|
-
} catch (err) {
|
|
1214
|
-
console.warn(
|
|
1215
|
-
JSON.stringify({
|
|
1216
|
-
level: "warn",
|
|
1217
|
-
event: "picker.save_failed",
|
|
1218
|
-
message: toErrorMessage(err),
|
|
1219
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1220
|
-
})
|
|
1221
|
-
);
|
|
1222
|
-
return false;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
1234
|
var QUERY_MARKER = "Select provider:";
|
|
1226
1235
|
function cursorToQuery(frame, query) {
|
|
1227
1236
|
const rows = frame.split("\n");
|
|
@@ -1302,14 +1311,74 @@ async function runLiveProviderPicker(displayList, savedSet) {
|
|
|
1302
1311
|
stdin.on("data", onData);
|
|
1303
1312
|
});
|
|
1304
1313
|
}
|
|
1314
|
+
|
|
1315
|
+
// src/picker.ts
|
|
1316
|
+
async function saveToGlobalConfig(configPath, provider, model, options = {}) {
|
|
1317
|
+
const { effort, homeFn = () => process.env.HOME ?? os.homedir() } = options;
|
|
1318
|
+
try {
|
|
1319
|
+
return await withFileLock(configPath, async () => {
|
|
1320
|
+
const { atomicWrite } = await import("@wrongstack/core/utils");
|
|
1321
|
+
const fs = await import("node:fs/promises");
|
|
1322
|
+
let existing = {};
|
|
1323
|
+
try {
|
|
1324
|
+
const raw = await fs.readFile(configPath, "utf8");
|
|
1325
|
+
existing = JSON.parse(raw);
|
|
1326
|
+
} catch (err) {
|
|
1327
|
+
if (err.code !== "ENOENT") throw err;
|
|
1328
|
+
}
|
|
1329
|
+
const oldCfg = { ...existing };
|
|
1330
|
+
existing.provider = provider;
|
|
1331
|
+
existing.model = model;
|
|
1332
|
+
if (effort) {
|
|
1333
|
+
const modelRuntime = isPlainRecord(existing.modelRuntime) ? existing.modelRuntime : {};
|
|
1334
|
+
const reasoning = isPlainRecord(modelRuntime.reasoning) ? modelRuntime.reasoning : {};
|
|
1335
|
+
existing.modelRuntime = { ...modelRuntime, reasoning: { ...reasoning, effort } };
|
|
1336
|
+
}
|
|
1337
|
+
try {
|
|
1338
|
+
await backupCurrent(homeFn, configPath);
|
|
1339
|
+
} catch (err) {
|
|
1340
|
+
console.warn(
|
|
1341
|
+
JSON.stringify({
|
|
1342
|
+
level: "warn",
|
|
1343
|
+
event: "picker.backup_failed",
|
|
1344
|
+
message: toErrorMessage(err),
|
|
1345
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1346
|
+
})
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
1350
|
+
try {
|
|
1351
|
+
await appendHistory(
|
|
1352
|
+
oldCfg,
|
|
1353
|
+
existing,
|
|
1354
|
+
`Provider/model changed: ${oldCfg.provider ?? "(none)"} \u2192 ${provider}, ${oldCfg.model ?? "(none)"} \u2192 ${model}`,
|
|
1355
|
+
homeFn,
|
|
1356
|
+
configPath
|
|
1357
|
+
);
|
|
1358
|
+
} catch {
|
|
1359
|
+
}
|
|
1360
|
+
return true;
|
|
1361
|
+
});
|
|
1362
|
+
} catch (err) {
|
|
1363
|
+
console.warn(
|
|
1364
|
+
JSON.stringify({
|
|
1365
|
+
level: "warn",
|
|
1366
|
+
event: "picker.save_failed",
|
|
1367
|
+
message: toErrorMessage(err),
|
|
1368
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1369
|
+
})
|
|
1370
|
+
);
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1305
1374
|
async function runPicker(deps) {
|
|
1306
1375
|
const { modelsRegistry, renderer, reader, config, defaultProvider, defaultModel } = deps;
|
|
1307
1376
|
renderer.write(
|
|
1308
1377
|
`
|
|
1309
|
-
${theme.accent(
|
|
1378
|
+
${theme.accent(color8.bold("\u258C WrongStack"))} ${color8.dim("Provider & Model Selection")}
|
|
1310
1379
|
`
|
|
1311
1380
|
);
|
|
1312
|
-
renderer.write(
|
|
1381
|
+
renderer.write(color8.dim(`${theme.chrome("\xB7")} Loading provider catalog\u2026
|
|
1313
1382
|
`));
|
|
1314
1383
|
let providers;
|
|
1315
1384
|
try {
|
|
@@ -1356,7 +1425,7 @@ ${theme.accent(color7.bold("\u258C WrongStack"))} ${color7.dim("Provider & Mode
|
|
|
1356
1425
|
const inherited = catalogType ? catalogById.get(catalogType) : void 0;
|
|
1357
1426
|
merged.push({
|
|
1358
1427
|
id,
|
|
1359
|
-
name: inherited ? `${inherited.name} ${
|
|
1428
|
+
name: inherited ? `${inherited.name} ${color8.dim("(alias)")}` : id,
|
|
1360
1429
|
family: cfg.family,
|
|
1361
1430
|
apiBase: cfg.baseUrl ?? inherited?.apiBase,
|
|
1362
1431
|
envVars: cfg.envVars ?? inherited?.envVars ?? [],
|
|
@@ -1384,7 +1453,7 @@ ${theme.accent(color7.bold("\u258C WrongStack"))} ${color7.dim("Provider & Mode
|
|
|
1384
1453
|
if (process.stdin.isTTY) {
|
|
1385
1454
|
const chosen2 = await runLiveProviderPicker(displayList);
|
|
1386
1455
|
if (!chosen2) {
|
|
1387
|
-
renderer.write(
|
|
1456
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1388
1457
|
return void 0;
|
|
1389
1458
|
}
|
|
1390
1459
|
return pickModel(chosen2, modelsRegistry, renderer, reader, defaultModel);
|
|
@@ -1420,19 +1489,19 @@ ${theme.accent(color7.bold("\u258C WrongStack"))} ${color7.dim("Provider & Mode
|
|
|
1420
1489
|
(a, b) => a.id.toLowerCase().localeCompare(b.id.toLowerCase())
|
|
1421
1490
|
);
|
|
1422
1491
|
if (!list || list.length === 0) continue;
|
|
1423
|
-
renderer.write(`${boxRow(`${theme.accent("\xB7")} ${
|
|
1492
|
+
renderer.write(`${boxRow(`${theme.accent("\xB7")} ${color8.dim(fam.toUpperCase())}`)}
|
|
1424
1493
|
`);
|
|
1425
1494
|
for (const p of list) {
|
|
1426
1495
|
const envFound = p.envVars.some((v) => !!process.env[v]);
|
|
1427
1496
|
const entry = config?.providers?.[p.id];
|
|
1428
1497
|
const configKey = typeof entry?.apiKey === "string" && entry.apiKey.length > 0 || Array.isArray(entry?.apiKeys) && entry?.apiKeys?.some((k) => k?.apiKey);
|
|
1429
|
-
const marker = envFound ?
|
|
1498
|
+
const marker = envFound ? color8.green("\u25CF") : configKey ? color8.cyan("\u25C9") : color8.dim("\u25CB");
|
|
1430
1499
|
const isDefault = p.id === defaultProvider;
|
|
1431
1500
|
if (isDefault) defaultIdx = idx;
|
|
1432
|
-
const idLabel = isDefault ? theme.accent(
|
|
1433
|
-
const suffix = isDefault ?
|
|
1501
|
+
const idLabel = isDefault ? theme.accent(color8.bold(p.id)) : p.id;
|
|
1502
|
+
const suffix = isDefault ? color8.dim(" (default)") : "";
|
|
1434
1503
|
renderer.write(
|
|
1435
|
-
`${boxRow(`${
|
|
1504
|
+
`${boxRow(`${color8.dim(`${idx}.`.padStart(4))} ${marker} ${padVisible(idLabel, 22)} ${color8.dim(p.name)}${suffix}`)}
|
|
1436
1505
|
`
|
|
1437
1506
|
);
|
|
1438
1507
|
ordered.push({ provider: p, index: idx });
|
|
@@ -1443,22 +1512,22 @@ ${theme.accent(color7.bold("\u258C WrongStack"))} ${color7.dim("Provider & Mode
|
|
|
1443
1512
|
`);
|
|
1444
1513
|
if (showingFallback) {
|
|
1445
1514
|
renderer.write(
|
|
1446
|
-
`${boxRow(`${
|
|
1515
|
+
`${boxRow(`${color8.yellow("\u26A0 No API keys detected.")} ${color8.dim("Run `wstack auth <provider>` after picking.")}`)}
|
|
1447
1516
|
`
|
|
1448
1517
|
);
|
|
1449
1518
|
} else {
|
|
1450
|
-
renderer.write(`${boxRow(
|
|
1519
|
+
renderer.write(`${boxRow(color8.dim("\u25CF env key \u25C9 stored in config \u25CB no key"))}
|
|
1451
1520
|
`);
|
|
1452
1521
|
}
|
|
1453
1522
|
renderer.write(`${boxBottom()}
|
|
1454
1523
|
`);
|
|
1455
|
-
const defaultHint = defaultIdx !== void 0 && defaultProvider ? ` ${
|
|
1524
|
+
const defaultHint = defaultIdx !== void 0 && defaultProvider ? ` ${color8.dim(`[Enter = ${defaultProvider}]`)}` : "";
|
|
1456
1525
|
const providerAnswer = (await reader.readLine(
|
|
1457
1526
|
`
|
|
1458
|
-
${
|
|
1527
|
+
${color8.amber("?")} Select provider (1-${ordered.length})${defaultHint} ${color8.dim("[q to quit]")}: `
|
|
1459
1528
|
)).trim();
|
|
1460
1529
|
if (providerAnswer.toLowerCase() === "q") {
|
|
1461
|
-
renderer.write(
|
|
1530
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1462
1531
|
return void 0;
|
|
1463
1532
|
}
|
|
1464
1533
|
if (!providerAnswer) {
|
|
@@ -1466,7 +1535,7 @@ ${color7.amber("?")} Select provider (1-${ordered.length})${defaultHint} ${color
|
|
|
1466
1535
|
const def = ordered[defaultIdx - 1];
|
|
1467
1536
|
if (def) return pickModel(def.provider, modelsRegistry, renderer, reader, defaultModel);
|
|
1468
1537
|
}
|
|
1469
|
-
renderer.write(
|
|
1538
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1470
1539
|
return void 0;
|
|
1471
1540
|
}
|
|
1472
1541
|
const providerIdx = Number.parseInt(providerAnswer, 10);
|
|
@@ -1488,7 +1557,7 @@ async function pickModel(provider, registry, renderer, reader, defaultModel) {
|
|
|
1488
1557
|
${boxTop("Select a model")}
|
|
1489
1558
|
`);
|
|
1490
1559
|
renderer.write(
|
|
1491
|
-
`${boxRow(`${
|
|
1560
|
+
`${boxRow(`${color8.bold(provider.name)} ${color8.dim(`(${provider.id})`)} models:`)}
|
|
1492
1561
|
`
|
|
1493
1562
|
);
|
|
1494
1563
|
renderer.write(`${boxBottom()}
|
|
@@ -1500,18 +1569,18 @@ ${boxTop("Select a model")}
|
|
|
1500
1569
|
);
|
|
1501
1570
|
if (models.length === 0) {
|
|
1502
1571
|
renderer.write(
|
|
1503
|
-
|
|
1572
|
+
color8.dim(
|
|
1504
1573
|
" No models listed yet for this provider \u2014 type a model id to use it (local servers auto-discover models at launch).\n"
|
|
1505
1574
|
)
|
|
1506
1575
|
);
|
|
1507
1576
|
const typed = (await reader.readLine(`
|
|
1508
|
-
${
|
|
1577
|
+
${color8.amber("?")} Model id ${color8.dim("(or Enter to cancel)")}: `)).trim();
|
|
1509
1578
|
if (!typed) {
|
|
1510
|
-
renderer.write(
|
|
1579
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1511
1580
|
return void 0;
|
|
1512
1581
|
}
|
|
1513
1582
|
renderer.write(`
|
|
1514
|
-
${
|
|
1583
|
+
${color8.green("\u2713")} ${color8.bold(provider.id)} / ${color8.bold(typed)}
|
|
1515
1584
|
|
|
1516
1585
|
`);
|
|
1517
1586
|
return { provider: provider.id, model: typed };
|
|
@@ -1519,16 +1588,18 @@ ${color7.amber("?")} Model id ${color7.dim("(or Enter to cancel)")}: `)).trim();
|
|
|
1519
1588
|
if (process.stdin.isTTY) {
|
|
1520
1589
|
const chosen = await runLiveModelPicker(provider, defaultModel);
|
|
1521
1590
|
if (!chosen) {
|
|
1522
|
-
renderer.write(
|
|
1591
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1523
1592
|
return void 0;
|
|
1524
1593
|
}
|
|
1594
|
+
const effort = chosen.effort === EFFORT_KEEP ? void 0 : chosen.effort;
|
|
1595
|
+
const effortSuffix = effort ? color8.dim(` \xB7 effort ${effort}`) : "";
|
|
1525
1596
|
renderer.write(
|
|
1526
1597
|
`
|
|
1527
|
-
${
|
|
1598
|
+
${color8.green("\u2713")} ${color8.bold(provider.id)} / ${color8.bold(chosen.model.id)}${effortSuffix}
|
|
1528
1599
|
|
|
1529
1600
|
`
|
|
1530
1601
|
);
|
|
1531
|
-
return { provider: provider.id, model: chosen.id };
|
|
1602
|
+
return { provider: provider.id, model: chosen.model.id, ...effort ? { effort } : {} };
|
|
1532
1603
|
}
|
|
1533
1604
|
const defaultIdxInModels = defaultModel !== void 0 ? models.findIndex((m) => m.id === defaultModel) : -1;
|
|
1534
1605
|
const pageSize = 30;
|
|
@@ -1550,11 +1621,11 @@ ${color7.amber("?")} Model id ${color7.dim("(or Enter to cancel)")}: `)).trim();
|
|
|
1550
1621
|
if (m.tool_call) capTags.push("tools");
|
|
1551
1622
|
if (m.reasoning) capTags.push("reason");
|
|
1552
1623
|
if (m.modalities?.input?.includes("image")) capTags.push("vision");
|
|
1553
|
-
const capStr = capTags.map((c) => theme.caps(c)).join(
|
|
1624
|
+
const capStr = capTags.map((c) => theme.caps(c)).join(color8.dim(" "));
|
|
1554
1625
|
const isDefault = m.id === defaultModel;
|
|
1555
|
-
const idLabel = isDefault ? theme.accent(
|
|
1556
|
-
const suffix = isDefault ?
|
|
1557
|
-
const num5 =
|
|
1626
|
+
const idLabel = isDefault ? theme.accent(color8.bold(m.id)) : m.id;
|
|
1627
|
+
const suffix = isDefault ? color8.dim(" (default)") : "";
|
|
1628
|
+
const num5 = color8.dim(`${num}.`.padStart(5));
|
|
1558
1629
|
renderer.write(
|
|
1559
1630
|
`${boxRow(`${num5} ${padVisible(idLabel, 34)} ${ctx} ${padVisible(costCol, 11)} ${capStr}${suffix}`)}
|
|
1560
1631
|
`
|
|
@@ -1566,36 +1637,36 @@ ${color7.amber("?")} Model id ${color7.dim("(or Enter to cancel)")}: `)).trim();
|
|
|
1566
1637
|
if (offset < models.length) {
|
|
1567
1638
|
const more = (await reader.readLine(
|
|
1568
1639
|
`
|
|
1569
|
-
${
|
|
1640
|
+
${color8.amber("?")} Showing ${Math.min(offset, models.length)}/${models.length} \u2014 Enter number, ${color8.dim("Enter")} for more, or ${color8.dim("q")} to quit: `
|
|
1570
1641
|
)).trim();
|
|
1571
1642
|
if (more.toLowerCase() === "q") {
|
|
1572
|
-
renderer.write(
|
|
1643
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1573
1644
|
return void 0;
|
|
1574
1645
|
}
|
|
1575
1646
|
if (!more) continue;
|
|
1576
1647
|
return resolveModelSelection(more, models, provider, registry, renderer, reader);
|
|
1577
1648
|
}
|
|
1578
1649
|
}
|
|
1579
|
-
const defaultHint = defaultIdxInModels >= 0 && defaultModel ? ` ${
|
|
1650
|
+
const defaultHint = defaultIdxInModels >= 0 && defaultModel ? ` ${color8.dim(`[Enter = ${defaultModel}]`)}` : "";
|
|
1580
1651
|
const answer = (await reader.readLine(
|
|
1581
1652
|
`
|
|
1582
|
-
${
|
|
1653
|
+
${color8.amber("?")} Select model (1-${models.length})${defaultHint} ${color8.dim("[q to quit]")}: `
|
|
1583
1654
|
)).trim();
|
|
1584
1655
|
if (answer.toLowerCase() === "q") {
|
|
1585
|
-
renderer.write(
|
|
1656
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1586
1657
|
return void 0;
|
|
1587
1658
|
}
|
|
1588
1659
|
if (!answer) {
|
|
1589
1660
|
if (defaultIdxInModels >= 0 && defaultModel) {
|
|
1590
1661
|
renderer.write(
|
|
1591
1662
|
`
|
|
1592
|
-
${
|
|
1663
|
+
${color8.green("\u2713")} ${color8.bold(provider.id)} / ${color8.bold(defaultModel)}
|
|
1593
1664
|
|
|
1594
1665
|
`
|
|
1595
1666
|
);
|
|
1596
1667
|
return { provider: provider.id, model: defaultModel };
|
|
1597
1668
|
}
|
|
1598
|
-
renderer.write(
|
|
1669
|
+
renderer.write(color8.dim("Cancelled.\n"));
|
|
1599
1670
|
return void 0;
|
|
1600
1671
|
}
|
|
1601
1672
|
return resolveModelSelection(answer, models, provider, registry, renderer, reader);
|
|
@@ -1624,19 +1695,14 @@ async function resolveModelSelection(answer, models, provider, _registry, render
|
|
|
1624
1695
|
modelId = answer;
|
|
1625
1696
|
}
|
|
1626
1697
|
renderer.write(`
|
|
1627
|
-
${
|
|
1698
|
+
${color8.green("\u2713")} ${color8.bold(provider.id)} / ${color8.bold(modelId)}
|
|
1628
1699
|
|
|
1629
1700
|
`);
|
|
1630
1701
|
return { provider: provider.id, model: modelId };
|
|
1631
1702
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
import {
|
|
1636
|
-
authProfileAliasError as authProfileAliasError2,
|
|
1637
|
-
catalogProviderIdFor,
|
|
1638
|
-
PROVIDER_DEFINITIONS
|
|
1639
|
-
} from "@wrongstack/providers";
|
|
1703
|
+
function isPlainRecord(value) {
|
|
1704
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1705
|
+
}
|
|
1640
1706
|
|
|
1641
1707
|
// src/provider-id.ts
|
|
1642
1708
|
function nextCustomProviderId(existing) {
|
|
@@ -1674,12 +1740,12 @@ async function addFromCatalog(deps) {
|
|
|
1674
1740
|
catalog = [...catalog, ...ownDefinitionsAsCatalog(new Set(catalog.map((p) => p.id)))];
|
|
1675
1741
|
const saved = new Set(Object.keys(await loadProviders(deps)));
|
|
1676
1742
|
deps.renderer.write(
|
|
1677
|
-
|
|
1743
|
+
color9.dim(
|
|
1678
1744
|
` Catalog: ${catalog.length} providers. Type to filter, \u2191/\u2193 navigate, Enter to select.
|
|
1679
1745
|
`
|
|
1680
1746
|
)
|
|
1681
1747
|
);
|
|
1682
|
-
deps.renderer.write(` ${
|
|
1748
|
+
deps.renderer.write(` ${color9.dim("\u25C9 already saved \u25CB no key yet")}
|
|
1683
1749
|
|
|
1684
1750
|
`);
|
|
1685
1751
|
renderOAuthLoginOptions(deps);
|
|
@@ -1688,10 +1754,10 @@ async function addFromCatalog(deps) {
|
|
|
1688
1754
|
if (!chosen) {
|
|
1689
1755
|
deps.renderer.write(
|
|
1690
1756
|
`
|
|
1691
|
-
${
|
|
1757
|
+
${color9.dim("OAuth login options: enter a registered strategy name, or q to quit.")}
|
|
1692
1758
|
`
|
|
1693
1759
|
);
|
|
1694
|
-
const answer = (await deps.reader.readLine(` ${
|
|
1760
|
+
const answer = (await deps.reader.readLine(` ${color9.amber("?")} OAuth strategy ${color9.dim("(or q)")}: `)).trim();
|
|
1695
1761
|
if (answer && await runOAuthLoginChoice(deps, answer, { allowNumeric: false })) {
|
|
1696
1762
|
return true;
|
|
1697
1763
|
}
|
|
@@ -1701,12 +1767,12 @@ async function addFromCatalog(deps) {
|
|
|
1701
1767
|
}
|
|
1702
1768
|
async function addKeyForCatalogProvider(deps, chosen) {
|
|
1703
1769
|
deps.renderer.write(
|
|
1704
|
-
|
|
1770
|
+
color9.dim(`
|
|
1705
1771
|
Defaults from models.dev \u2014 press Enter to keep, or type overrides.
|
|
1706
1772
|
`)
|
|
1707
1773
|
);
|
|
1708
1774
|
const famRaw = (await deps.reader.readLine(
|
|
1709
|
-
` ${
|
|
1775
|
+
` ${color9.amber("?")} Family ${color9.dim(`[${chosen.family}]`)} ${color9.dim("(q to quit)")}: `
|
|
1710
1776
|
)).trim();
|
|
1711
1777
|
if (famRaw === "q") return false;
|
|
1712
1778
|
let family = chosen.family;
|
|
@@ -1721,7 +1787,7 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1721
1787
|
family = validated;
|
|
1722
1788
|
}
|
|
1723
1789
|
const baseRaw = (await deps.reader.readLine(
|
|
1724
|
-
` ${
|
|
1790
|
+
` ${color9.amber("?")} Base URL ${color9.dim(`[${chosen.apiBase ?? "unset"}]`)} ${color9.dim("(q to quit)")}: `
|
|
1725
1791
|
)).trim();
|
|
1726
1792
|
if (baseRaw === "q") return false;
|
|
1727
1793
|
const baseUrl = baseRaw || chosen.apiBase;
|
|
@@ -1738,7 +1804,7 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1738
1804
|
suggestedAlias = candidate;
|
|
1739
1805
|
}
|
|
1740
1806
|
const aliasRaw = (await deps.reader.readLine(
|
|
1741
|
-
` ${
|
|
1807
|
+
` ${color9.amber("?")} Save as alias ${color9.dim(`[${suggestedAlias}]`)} ${color9.dim("(used with --provider <alias>)")}: `
|
|
1742
1808
|
)).trim();
|
|
1743
1809
|
const alias = aliasRaw || suggestedAlias;
|
|
1744
1810
|
const aliasError = authProfileAliasError2(alias);
|
|
@@ -1774,25 +1840,25 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1774
1840
|
async function addCustomProvider(deps) {
|
|
1775
1841
|
deps.renderer.write(
|
|
1776
1842
|
`
|
|
1777
|
-
${
|
|
1843
|
+
${color9.bold("Custom provider")} ${color9.dim("\u2014 for local models or proxies not in the catalog.")}
|
|
1778
1844
|
`
|
|
1779
1845
|
);
|
|
1780
1846
|
const providersNow = await loadProviders(deps);
|
|
1781
1847
|
const idRaw = (await deps.reader.readLine(
|
|
1782
|
-
` ${
|
|
1848
|
+
` ${color9.amber("?")} Provider id ${color9.dim('(e.g. "local-llama", "my-proxy"; blank = auto custom-N, q to quit)')}: `
|
|
1783
1849
|
)).trim();
|
|
1784
1850
|
if (idRaw === "q") return false;
|
|
1785
1851
|
let type = idRaw;
|
|
1786
1852
|
if (!type) {
|
|
1787
1853
|
type = nextCustomProviderId(Object.keys(providersNow));
|
|
1788
|
-
deps.renderer.write(` ${
|
|
1854
|
+
deps.renderer.write(` ${color9.dim("Using generated id:")} ${color9.bold(type)}
|
|
1789
1855
|
`);
|
|
1790
1856
|
} else if (providersNow[type]) {
|
|
1791
1857
|
deps.renderer.writeWarning(`"${type}" already exists. Pick it from the main menu to edit.`);
|
|
1792
1858
|
return false;
|
|
1793
1859
|
}
|
|
1794
1860
|
const familyRaw = (await deps.reader.readLine(
|
|
1795
|
-
` ${
|
|
1861
|
+
` ${color9.amber("?")} Wire family ${color9.dim("(anthropic | openai | openai-compatible | google)")} ${color9.dim("(q to quit)")}: `
|
|
1796
1862
|
)).trim();
|
|
1797
1863
|
if (familyRaw === "q") return false;
|
|
1798
1864
|
const family = validateFamily(familyRaw);
|
|
@@ -1801,14 +1867,14 @@ ${color8.bold("Custom provider")} ${color8.dim("\u2014 for local models or proxi
|
|
|
1801
1867
|
return false;
|
|
1802
1868
|
}
|
|
1803
1869
|
const baseUrl = (await deps.reader.readLine(
|
|
1804
|
-
` ${
|
|
1870
|
+
` ${color9.amber("?")} Base URL ${color9.dim("(e.g. http://localhost:11434/v1, optional)")}: `
|
|
1805
1871
|
)).trim();
|
|
1806
1872
|
const modelsRaw = (await deps.reader.readLine(
|
|
1807
|
-
` ${
|
|
1873
|
+
` ${color9.amber("?")} Model ids ${color9.dim("(comma-separated, optional)")}: `
|
|
1808
1874
|
)).trim();
|
|
1809
1875
|
const models = modelsRaw ? modelsRaw.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
1810
1876
|
const envVarsRaw = (await deps.reader.readLine(
|
|
1811
|
-
` ${
|
|
1877
|
+
` ${color9.amber("?")} Env var names ${color9.dim("(comma-separated, optional)")}: `
|
|
1812
1878
|
)).trim();
|
|
1813
1879
|
const envVars = envVarsRaw ? envVarsRaw.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
1814
1880
|
return addKeyForProvider(type, deps, {
|
|
@@ -1820,17 +1886,17 @@ ${color8.bold("Custom provider")} ${color8.dim("\u2014 for local models or proxi
|
|
|
1820
1886
|
});
|
|
1821
1887
|
}
|
|
1822
1888
|
async function addManualEntry(deps) {
|
|
1823
|
-
const pid = (await deps.reader.readLine(` ${
|
|
1889
|
+
const pid = (await deps.reader.readLine(` ${color9.amber("?")} Provider id ${color9.dim("[q to quit]")}: `)).trim();
|
|
1824
1890
|
if (!pid || pid === "q") return false;
|
|
1825
1891
|
const famRaw = (await deps.reader.readLine(
|
|
1826
|
-
` ${
|
|
1892
|
+
` ${color9.amber("?")} Family ${color9.dim("(anthropic/openai/openai-compatible/google)")}: `
|
|
1827
1893
|
)).trim();
|
|
1828
1894
|
const family = validateFamily(famRaw);
|
|
1829
1895
|
if (!family) {
|
|
1830
1896
|
deps.renderer.writeError(`Invalid family: "${famRaw}"`);
|
|
1831
1897
|
return false;
|
|
1832
1898
|
}
|
|
1833
|
-
const baseUrl = (await deps.reader.readLine(` ${
|
|
1899
|
+
const baseUrl = (await deps.reader.readLine(` ${color9.amber("?")} Base URL ${color9.dim("(optional)")}: `)).trim();
|
|
1834
1900
|
return addKeyForProvider(pid, deps, {
|
|
1835
1901
|
type: pid,
|
|
1836
1902
|
family,
|
|
@@ -1873,10 +1939,10 @@ async function addKeyForProvider(providerId, deps, template) {
|
|
|
1873
1939
|
deps.profileConfigPath
|
|
1874
1940
|
);
|
|
1875
1941
|
deps.renderer.write(
|
|
1876
|
-
` ${
|
|
1942
|
+
` ${color9.green("\u2713")} Saved ${color9.bold(providerId)}/${color9.bold(label)}.
|
|
1877
1943
|
`
|
|
1878
1944
|
);
|
|
1879
|
-
deps.renderer.write(
|
|
1945
|
+
deps.renderer.write(color9.dim(` Launch: wstack --provider ${providerId} "<task>"
|
|
1880
1946
|
`));
|
|
1881
1947
|
try {
|
|
1882
1948
|
await adoptAsDefaultIfUnset(deps, providerId, template);
|
|
@@ -1907,7 +1973,7 @@ async function adoptAsDefaultIfUnset(deps, providerId, template) {
|
|
|
1907
1973
|
);
|
|
1908
1974
|
if (adopted) {
|
|
1909
1975
|
deps.renderer.write(
|
|
1910
|
-
` ${
|
|
1976
|
+
` ${color9.green("\u2713")} Set ${color9.bold(providerId)}/${color9.bold(modelId)} as the default.
|
|
1911
1977
|
`
|
|
1912
1978
|
);
|
|
1913
1979
|
}
|
|
@@ -1915,7 +1981,7 @@ async function adoptAsDefaultIfUnset(deps, providerId, template) {
|
|
|
1915
1981
|
async function promptForLabel(deps, usedLabels) {
|
|
1916
1982
|
const defaultLabel = suggestLabel(usedLabels);
|
|
1917
1983
|
const labelRaw = (await deps.reader.readLine(
|
|
1918
|
-
` ${
|
|
1984
|
+
` ${color9.amber("?")} Label for this key ${color9.dim(`[${defaultLabel}]`)}: `
|
|
1919
1985
|
)).trim();
|
|
1920
1986
|
const label = labelRaw || defaultLabel;
|
|
1921
1987
|
if (usedLabels.has(label)) {
|
|
@@ -1943,6 +2009,7 @@ export {
|
|
|
1943
2009
|
resolveOAuthKind,
|
|
1944
2010
|
runOAuthLoginKind,
|
|
1945
2011
|
runOAuthLoginMenu,
|
|
2012
|
+
reasoningEffortVocabulary,
|
|
1946
2013
|
theme,
|
|
1947
2014
|
boxTop,
|
|
1948
2015
|
boxBottom,
|
|
@@ -1957,4 +2024,4 @@ export {
|
|
|
1957
2024
|
addCustomProvider,
|
|
1958
2025
|
addKeyForProvider
|
|
1959
2026
|
};
|
|
1960
|
-
//# sourceMappingURL=chunk-
|
|
2027
|
+
//# sourceMappingURL=chunk-GZSKLXYG.js.map
|