@wrongstack/cli 1.1.4 → 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-MZ5MQBFN.js → acp-NKUEYJDZ.js} +6 -5
- package/dist/acp-leader/acp-leader-confirm.d.ts +2 -0
- package/dist/acp-leader/acp-leader-host-binding.d.ts +1 -0
- package/dist/acp-leader/acp-leader-host.d.ts +2 -0
- package/dist/acp-leader/acp-leader-picker.d.ts +6 -3
- package/dist/acp-leader/acp-leader-stream.d.ts +1 -0
- package/dist/{auth-IHQS6AFW.js → auth-2ZG5DBHS.js} +4 -4
- 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-JKTJSLUT.js → chunk-5SGMUDP5.js} +242 -18
- package/dist/{chunk-3EXRPTAU.js → chunk-5TQ65PXQ.js} +17 -17
- package/dist/{chunk-2LTHDKZX.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-AWRZWPJ3.js → chunk-JFYQGMMM.js} +99 -75
- package/dist/{chunk-BIGSVBPI.js → chunk-KNYIEQAY.js} +64 -61
- package/dist/{chunk-GKGWPFW2.js → chunk-LUEO5HLZ.js} +1 -1
- package/dist/chunk-LYWOV4OX.js +252 -0
- package/dist/{chunk-COGI7EQU.js → chunk-M7FNHCE3.js} +621 -9
- package/dist/{chunk-75OLD563.js → chunk-M7PSENGF.js} +3 -1
- package/dist/{chunk-TAE3EGBM.js → chunk-MEBXWI7U.js} +5 -5
- package/dist/{chunk-I5LJLKA3.js → chunk-MKMM5RIW.js} +12 -5
- package/dist/{chunk-ZF4HRR5F.js → chunk-P7MEEUGT.js} +275 -250
- 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-E44HQ4ZO.js → cli-context-CQYGIWOU.js} +247 -236
- package/dist/{cli-main-OT63I2FX.js → cli-main-VRUJNUBX.js} +1743 -1491
- 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-OK34CJKJ.js → execution-IV72RUSM.js} +5883 -5792
- package/dist/execution-tui.d.ts +30 -0
- package/dist/fleet/acp-wrongstack-bridge.d.ts +11 -3
- package/dist/fleet/host-acp.d.ts +3 -0
- 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 +5 -5
- package/dist/mcp-22CFBX4H.js +236 -0
- package/dist/mcp-serve.d.ts +0 -63
- package/dist/{modeldiag-HDIKG37X.js → modeldiag-5PBB777J.js} +4 -4
- package/dist/{per-subcommand-help-4GYSCMLU.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-YADUV7IJ.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-CB64CFDG.js → webui-server-V2R5WQUK.js} +44 -6
- 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 +1 -1
- package/dist/mcp-W7A5HUXV.js +0 -560
- package/dist/short-circuit-flags-QEXUS3BY.js +0 -11
|
@@ -2,10 +2,6 @@ import {
|
|
|
2
2
|
parseOutputFormat,
|
|
3
3
|
resolveJsonSchemaFlag
|
|
4
4
|
} from "./chunk-VI2HE4A5.js";
|
|
5
|
-
import {
|
|
6
|
-
parseWebuiSessionChildOptions,
|
|
7
|
-
writeWebuiSessionChildError
|
|
8
|
-
} from "./chunk-FUJHWQV4.js";
|
|
9
5
|
import {
|
|
10
6
|
announceSafeMode,
|
|
11
7
|
applySimpleUiFullAutoProfile,
|
|
@@ -20,6 +16,13 @@ import {
|
|
|
20
16
|
import {
|
|
21
17
|
theme as theme2
|
|
22
18
|
} from "./chunk-JTTV2EVA.js";
|
|
19
|
+
import {
|
|
20
|
+
parseWebuiSessionChildOptions,
|
|
21
|
+
writeWebuiSessionChildError
|
|
22
|
+
} from "./chunk-FUJHWQV4.js";
|
|
23
|
+
import {
|
|
24
|
+
handleHelpVersionShortCircuit
|
|
25
|
+
} from "./chunk-MEBXWI7U.js";
|
|
23
26
|
import {
|
|
24
27
|
fmtTok,
|
|
25
28
|
patchConfig
|
|
@@ -29,24 +32,21 @@ import {
|
|
|
29
32
|
} from "./chunk-NL2ABOAS.js";
|
|
30
33
|
import {
|
|
31
34
|
subcommands
|
|
32
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-7BM4LGKQ.js";
|
|
33
36
|
import {
|
|
34
37
|
renderDeepHelp,
|
|
35
38
|
renderFocusedHelp
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import {
|
|
38
|
-
handleHelpVersionShortCircuit
|
|
39
|
-
} from "./chunk-TAE3EGBM.js";
|
|
39
|
+
} from "./chunk-P7MEEUGT.js";
|
|
40
40
|
import {
|
|
41
41
|
DEFAULT_PORT
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-JFYQGMMM.js";
|
|
43
43
|
import "./chunk-QVITQ425.js";
|
|
44
44
|
import {
|
|
45
45
|
resolveHqPasswordInput
|
|
46
46
|
} from "./chunk-HQBY6OFT.js";
|
|
47
47
|
import {
|
|
48
48
|
normalizeHqPublicOrigin
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-5TQ65PXQ.js";
|
|
50
50
|
import {
|
|
51
51
|
parseHqIpAllowlist
|
|
52
52
|
} from "./chunk-OGVSKS4Q.js";
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
runPicker,
|
|
69
69
|
saveToGlobalConfig,
|
|
70
70
|
theme
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-MKMM5RIW.js";
|
|
72
72
|
import "./chunk-ZXX3MJRL.js";
|
|
73
73
|
import {
|
|
74
74
|
isKeylessLocalProvider,
|
|
@@ -80,10 +80,13 @@ import {
|
|
|
80
80
|
import {
|
|
81
81
|
activeProfileConfigPath
|
|
82
82
|
} from "./chunk-SPSHEZ46.js";
|
|
83
|
-
import "./chunk-
|
|
83
|
+
import "./chunk-KNYIEQAY.js";
|
|
84
84
|
import {
|
|
85
85
|
activateRestrictedMode
|
|
86
86
|
} from "./chunk-3LEIFO5D.js";
|
|
87
|
+
import {
|
|
88
|
+
WRONGFORGE_AGENT_ID
|
|
89
|
+
} from "./chunk-VEESMPTX.js";
|
|
87
90
|
import "./chunk-OZCYZYN2.js";
|
|
88
91
|
import {
|
|
89
92
|
runUpdateCommand
|
|
@@ -97,15 +100,15 @@ import {
|
|
|
97
100
|
} from "./chunk-CVVQ5NCN.js";
|
|
98
101
|
import {
|
|
99
102
|
parseArgs
|
|
100
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-M7PSENGF.js";
|
|
101
104
|
import {
|
|
102
105
|
ACP_LEADER_PROVIDER_ID
|
|
103
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-LUEO5HLZ.js";
|
|
104
107
|
import "./chunk-H53EXXAU.js";
|
|
105
108
|
import {
|
|
106
109
|
applyAsciiMode
|
|
107
110
|
} from "./chunk-UVF3BGET.js";
|
|
108
|
-
import "./chunk-
|
|
111
|
+
import "./chunk-UROB7MK5.js";
|
|
109
112
|
import {
|
|
110
113
|
CLI_VERSION
|
|
111
114
|
} from "./chunk-HKMOIIPQ.js";
|
|
@@ -241,7 +244,7 @@ function wireContainer(deps) {
|
|
|
241
244
|
// src/boot/launch-menu.ts
|
|
242
245
|
import * as fs from "node:fs/promises";
|
|
243
246
|
import { HQ_CLI_DEFAULT_HOST } from "@wrongstack/core/hq";
|
|
244
|
-
import { atomicWrite, color, isStdinTTY
|
|
247
|
+
import { atomicWrite, color as color2, isStdinTTY as isStdinTTY2, withFileLock } from "@wrongstack/core/utils";
|
|
245
248
|
|
|
246
249
|
// src/boot/launch-banner.ts
|
|
247
250
|
var STACK_ORANGE = { r: 253, g: 159, b: 2 };
|
|
@@ -354,20 +357,15 @@ function launchBannerLines(columns, version) {
|
|
|
354
357
|
];
|
|
355
358
|
}
|
|
356
359
|
|
|
357
|
-
// src/boot/launch-menu.ts
|
|
360
|
+
// src/boot/launch-menu-arrow.ts
|
|
361
|
+
import { color, isStdinTTY, setRawMode } from "@wrongstack/core/utils";
|
|
362
|
+
|
|
363
|
+
// src/boot/launch-menu-types.ts
|
|
358
364
|
var DEFAULT_PORTS = {
|
|
359
365
|
webui: 3456,
|
|
360
366
|
simpleui: 3466,
|
|
361
367
|
hq: DEFAULT_PORT
|
|
362
368
|
};
|
|
363
|
-
var DEFAULT_HOST = "127.0.0.1";
|
|
364
|
-
var HQ_DEFAULT_HOST = HQ_CLI_DEFAULT_HOST;
|
|
365
|
-
function bindsPort(mode) {
|
|
366
|
-
return mode !== "tui-repl" && mode !== "desktop";
|
|
367
|
-
}
|
|
368
|
-
function defaultHostFor(mode) {
|
|
369
|
-
return mode === "hq" ? HQ_DEFAULT_HOST : DEFAULT_HOST;
|
|
370
|
-
}
|
|
371
369
|
var MODE_OPTIONS = [
|
|
372
370
|
{
|
|
373
371
|
key: 1,
|
|
@@ -406,88 +404,8 @@ var MODE_OPTIONS = [
|
|
|
406
404
|
}
|
|
407
405
|
];
|
|
408
406
|
var MENU_TIMEOUT_MS = 8e3;
|
|
409
|
-
var SUMMARY_TIMEOUT_MS = 5e3;
|
|
410
|
-
var PORT_TIMEOUT_MS = 8e3;
|
|
411
|
-
function shouldSkipMenu(argv, flags, positional) {
|
|
412
|
-
if (flags["no-menu"] === true) return true;
|
|
413
|
-
if (flags["webui"] === true) return true;
|
|
414
|
-
if (flags["webui-session-child"] === true) return true;
|
|
415
|
-
if (flags["simpleui"] === true) return true;
|
|
416
|
-
if (flags["hq"] === true) return true;
|
|
417
|
-
if (flags["desktop"] === true) return true;
|
|
418
|
-
if (flags["no-interactive"] === true) return true;
|
|
419
|
-
if (flags["skip"] === true) return true;
|
|
420
|
-
if (typeof flags["prompt"] === "string") return true;
|
|
421
|
-
if (!isStdinTTY()) return true;
|
|
422
|
-
if (positional.length > 0) return true;
|
|
423
|
-
void argv;
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
426
|
-
async function runLaunchMenu(deps) {
|
|
427
|
-
if (shouldSkipMenu(deps.argv, deps.flags, deps.positional)) {
|
|
428
|
-
return null;
|
|
429
|
-
}
|
|
430
|
-
const { renderer, reader, lastChoice } = deps;
|
|
431
|
-
const ports = { ...DEFAULT_PORTS, ...deps.defaultPorts ?? {} };
|
|
432
|
-
writeBanner(renderer);
|
|
433
|
-
if (lastChoice) {
|
|
434
|
-
const accept = await promptSummaryGate(deps);
|
|
435
|
-
if (accept === "use-last") {
|
|
436
|
-
return finalize(lastChoice, ports);
|
|
437
|
-
}
|
|
438
|
-
if (accept === "cancel") {
|
|
439
|
-
return { ...lastChoice, cancelled: true };
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
renderer.write(`
|
|
443
|
-
${color.amber("?")} Choose how to run WrongStack:
|
|
444
407
|
|
|
445
|
-
|
|
446
|
-
const arrowPick = await promptModeArrow(deps);
|
|
447
|
-
let choice;
|
|
448
|
-
if (arrowPick) {
|
|
449
|
-
if (arrowPick.cancelled) {
|
|
450
|
-
return { mode: "tui-repl", cancelled: true };
|
|
451
|
-
}
|
|
452
|
-
choice = { mode: arrowPick.mode };
|
|
453
|
-
} else {
|
|
454
|
-
for (const opt of MODE_OPTIONS) {
|
|
455
|
-
renderer.write(
|
|
456
|
-
` ${color.bold(String(opt.key))}) ${opt.icon} ${color.bold(opt.label)} ${color.dim(opt.hint)}
|
|
457
|
-
`
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
renderer.write(`
|
|
461
|
-
${color.dim("\u2500".repeat(48))}
|
|
462
|
-
`);
|
|
463
|
-
const answer = (await reader.readLine(
|
|
464
|
-
` ${color.amber("?")} Mode ${color.dim("[1-5, q to quit]")} ${color.dim(`(auto 1 in ${MENU_TIMEOUT_MS / 1e3}s)`)} `,
|
|
465
|
-
{ timeoutMs: MENU_TIMEOUT_MS, defaultAnswer: "1" }
|
|
466
|
-
)).trim().toLowerCase();
|
|
467
|
-
if (answer === "q" || answer === "quit") {
|
|
468
|
-
renderer.write(color.dim(" Goodbye!\n"));
|
|
469
|
-
return { mode: "tui-repl", cancelled: true };
|
|
470
|
-
}
|
|
471
|
-
const picked = MODE_OPTIONS.find((o) => String(o.key) === answer || o.mode === answer);
|
|
472
|
-
choice = picked ? { mode: picked.mode } : { mode: "tui-repl" };
|
|
473
|
-
}
|
|
474
|
-
if (bindsPort(choice.mode)) {
|
|
475
|
-
const port = await promptPort(deps, ports[choice.mode]);
|
|
476
|
-
choice.port = port;
|
|
477
|
-
const defaultHost = defaultHostFor(choice.mode);
|
|
478
|
-
const host = await promptHost(deps, defaultHost);
|
|
479
|
-
if (host !== defaultHost) choice.host = host;
|
|
480
|
-
}
|
|
481
|
-
return finalize(choice, ports);
|
|
482
|
-
}
|
|
483
|
-
function writeBanner(renderer) {
|
|
484
|
-
const columns = process.stdout.columns ?? 80;
|
|
485
|
-
renderer.write("\n");
|
|
486
|
-
for (const line of launchBannerLines(columns, CLI_VERSION)) {
|
|
487
|
-
renderer.write(` ${line}
|
|
488
|
-
`);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
408
|
+
// src/boot/launch-menu-arrow.ts
|
|
491
409
|
function canUseArrowMenu() {
|
|
492
410
|
if (process.env.VITEST || process.env.NODE_ENV === "test") return false;
|
|
493
411
|
const stdin = process.stdin;
|
|
@@ -629,27 +547,119 @@ async function promptModeArrow(deps) {
|
|
|
629
547
|
}, 1e3);
|
|
630
548
|
});
|
|
631
549
|
}
|
|
550
|
+
|
|
551
|
+
// src/boot/launch-menu.ts
|
|
552
|
+
var DEFAULT_HOST = "127.0.0.1";
|
|
553
|
+
var HQ_DEFAULT_HOST = HQ_CLI_DEFAULT_HOST;
|
|
554
|
+
function bindsPort(mode) {
|
|
555
|
+
return mode !== "tui-repl" && mode !== "desktop";
|
|
556
|
+
}
|
|
557
|
+
function defaultHostFor(mode) {
|
|
558
|
+
return mode === "hq" ? HQ_DEFAULT_HOST : DEFAULT_HOST;
|
|
559
|
+
}
|
|
560
|
+
var SUMMARY_TIMEOUT_MS = 5e3;
|
|
561
|
+
var PORT_TIMEOUT_MS = 8e3;
|
|
562
|
+
function shouldSkipMenu(argv, flags, positional) {
|
|
563
|
+
if (flags["no-menu"] === true) return true;
|
|
564
|
+
if (flags["webui"] === true) return true;
|
|
565
|
+
if (flags["webui-session-child"] === true) return true;
|
|
566
|
+
if (flags["simpleui"] === true) return true;
|
|
567
|
+
if (flags["hq"] === true) return true;
|
|
568
|
+
if (flags["desktop"] === true) return true;
|
|
569
|
+
if (flags["no-interactive"] === true) return true;
|
|
570
|
+
if (flags["skip"] === true) return true;
|
|
571
|
+
if (typeof flags["prompt"] === "string") return true;
|
|
572
|
+
if (!isStdinTTY2()) return true;
|
|
573
|
+
if (positional.length > 0) return true;
|
|
574
|
+
void argv;
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
async function runLaunchMenu(deps) {
|
|
578
|
+
if (shouldSkipMenu(deps.argv, deps.flags, deps.positional)) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
const { renderer, reader, lastChoice } = deps;
|
|
582
|
+
const ports = { ...DEFAULT_PORTS, ...deps.defaultPorts ?? {} };
|
|
583
|
+
writeBanner(renderer);
|
|
584
|
+
if (lastChoice) {
|
|
585
|
+
const accept = await promptSummaryGate(deps);
|
|
586
|
+
if (accept === "use-last") {
|
|
587
|
+
return finalize(lastChoice, ports);
|
|
588
|
+
}
|
|
589
|
+
if (accept === "cancel") {
|
|
590
|
+
return { ...lastChoice, cancelled: true };
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
renderer.write(`
|
|
594
|
+
${color2.amber("?")} Choose how to run WrongStack:
|
|
595
|
+
|
|
596
|
+
`);
|
|
597
|
+
const arrowPick = await promptModeArrow(deps);
|
|
598
|
+
let choice;
|
|
599
|
+
if (arrowPick) {
|
|
600
|
+
if (arrowPick.cancelled) {
|
|
601
|
+
return { mode: "tui-repl", cancelled: true };
|
|
602
|
+
}
|
|
603
|
+
choice = { mode: arrowPick.mode };
|
|
604
|
+
} else {
|
|
605
|
+
for (const opt of MODE_OPTIONS) {
|
|
606
|
+
renderer.write(
|
|
607
|
+
` ${color2.bold(String(opt.key))}) ${opt.icon} ${color2.bold(opt.label)} ${color2.dim(opt.hint)}
|
|
608
|
+
`
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
renderer.write(`
|
|
612
|
+
${color2.dim("\u2500".repeat(48))}
|
|
613
|
+
`);
|
|
614
|
+
const answer = (await reader.readLine(
|
|
615
|
+
` ${color2.amber("?")} Mode ${color2.dim("[1-5, q to quit]")} ${color2.dim(`(auto 1 in ${MENU_TIMEOUT_MS / 1e3}s)`)} `,
|
|
616
|
+
{ timeoutMs: MENU_TIMEOUT_MS, defaultAnswer: "1" }
|
|
617
|
+
)).trim().toLowerCase();
|
|
618
|
+
if (answer === "q" || answer === "quit") {
|
|
619
|
+
renderer.write(color2.dim(" Goodbye!\n"));
|
|
620
|
+
return { mode: "tui-repl", cancelled: true };
|
|
621
|
+
}
|
|
622
|
+
const picked = MODE_OPTIONS.find((o) => String(o.key) === answer || o.mode === answer);
|
|
623
|
+
choice = picked ? { mode: picked.mode } : { mode: "tui-repl" };
|
|
624
|
+
}
|
|
625
|
+
if (bindsPort(choice.mode)) {
|
|
626
|
+
const port = await promptPort(deps, ports[choice.mode]);
|
|
627
|
+
choice.port = port;
|
|
628
|
+
const defaultHost = defaultHostFor(choice.mode);
|
|
629
|
+
const host = await promptHost(deps, defaultHost);
|
|
630
|
+
if (host !== defaultHost) choice.host = host;
|
|
631
|
+
}
|
|
632
|
+
return finalize(choice, ports);
|
|
633
|
+
}
|
|
634
|
+
function writeBanner(renderer) {
|
|
635
|
+
const columns = process.stdout.columns ?? 80;
|
|
636
|
+
renderer.write("\n");
|
|
637
|
+
for (const line of launchBannerLines(columns, CLI_VERSION)) {
|
|
638
|
+
renderer.write(` ${line}
|
|
639
|
+
`);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
632
642
|
async function promptSummaryGate(deps) {
|
|
633
643
|
const { renderer, reader, lastChoice } = deps;
|
|
634
644
|
if (!lastChoice) return "re-prompt";
|
|
635
645
|
const modeLabel = describeMode(lastChoice.mode);
|
|
636
|
-
const portStr = typeof lastChoice.port === "number" ? ` \xB7 port ${
|
|
637
|
-
const hostStr = typeof lastChoice.host === "string" ? ` \xB7 host ${
|
|
646
|
+
const portStr = typeof lastChoice.port === "number" ? ` \xB7 port ${color2.bold(String(lastChoice.port))}` : "";
|
|
647
|
+
const hostStr = typeof lastChoice.host === "string" ? ` \xB7 host ${color2.dim(lastChoice.host)}` : "";
|
|
638
648
|
renderer.write(`
|
|
639
|
-
${
|
|
649
|
+
${color2.dim("\u2500".repeat(48))}
|
|
640
650
|
`);
|
|
641
651
|
renderer.write(
|
|
642
|
-
` ${
|
|
652
|
+
` ${color2.cyan("\u23CE")} ${color2.dim("Last settings:")} ${color2.bold(modeLabel)}${portStr}${hostStr}
|
|
643
653
|
`
|
|
644
654
|
);
|
|
645
|
-
renderer.write(` ${
|
|
655
|
+
renderer.write(` ${color2.dim("\u2500".repeat(48))}
|
|
646
656
|
`);
|
|
647
657
|
const answer = (await reader.readLine(
|
|
648
|
-
` ${
|
|
658
|
+
` ${color2.amber("?")} Continue with these? ${color2.dim("[Y/n/q]")} ${color2.dim("(auto Y in 5s)")} `,
|
|
649
659
|
{ timeoutMs: SUMMARY_TIMEOUT_MS, defaultAnswer: "y" }
|
|
650
660
|
)).trim().toLowerCase();
|
|
651
661
|
if (answer === "q" || answer === "quit") {
|
|
652
|
-
renderer.write(
|
|
662
|
+
renderer.write(color2.dim(" Goodbye!\n"));
|
|
653
663
|
return "cancel";
|
|
654
664
|
}
|
|
655
665
|
if (answer === "n" || answer === "no") return "re-prompt";
|
|
@@ -660,7 +670,7 @@ async function promptPort(deps, defaultPort) {
|
|
|
660
670
|
const maxRetries = 3;
|
|
661
671
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
662
672
|
const answer = (await reader.readLine(
|
|
663
|
-
` ${
|
|
673
|
+
` ${color2.amber("?")} Port ${color2.dim(`[${defaultPort}]`)} ${color2.dim("(Enter = default, q = cancel)")} `,
|
|
664
674
|
{ timeoutMs: PORT_TIMEOUT_MS, defaultAnswer: "" }
|
|
665
675
|
)).trim();
|
|
666
676
|
if (answer === "" || answer === "\n") return defaultPort;
|
|
@@ -677,11 +687,11 @@ async function promptPort(deps, defaultPort) {
|
|
|
677
687
|
async function promptHost(deps, defaultHost) {
|
|
678
688
|
const { renderer, reader } = deps;
|
|
679
689
|
renderer.write(
|
|
680
|
-
` ${
|
|
690
|
+
` ${color2.dim("\u2139")} Press Enter to bind to ${color2.bold(defaultHost)}${defaultHost === HQ_DEFAULT_HOST ? " (all interfaces)" : " (loopback)"}.
|
|
681
691
|
`
|
|
682
692
|
);
|
|
683
693
|
const answer = (await reader.readLine(
|
|
684
|
-
` ${
|
|
694
|
+
` ${color2.amber("?")} Host ${color2.dim(`[${defaultHost}]`)} ${color2.dim("(Enter = default, q = cancel)")} `,
|
|
685
695
|
{ timeoutMs: PORT_TIMEOUT_MS, defaultAnswer: "" }
|
|
686
696
|
)).trim();
|
|
687
697
|
if (answer === "" || answer === "q" || answer === "quit") return defaultHost;
|
|
@@ -791,7 +801,7 @@ import { statSync } from "node:fs";
|
|
|
791
801
|
import { createRequire as createRequire3 } from "node:module";
|
|
792
802
|
import { homedir } from "node:os";
|
|
793
803
|
import * as path3 from "node:path";
|
|
794
|
-
import { color as
|
|
804
|
+
import { color as color3 } from "@wrongstack/core/utils";
|
|
795
805
|
function desktopExecutableCandidates(platform, home, env) {
|
|
796
806
|
const join7 = platform === "win32" ? path3.win32.join : path3.posix.join;
|
|
797
807
|
const managed = join7(home, ".wrongstack", "desktop");
|
|
@@ -867,7 +877,7 @@ async function launchDesktop(args) {
|
|
|
867
877
|
} catch {
|
|
868
878
|
process.stderr.write(
|
|
869
879
|
[
|
|
870
|
-
|
|
880
|
+
color3.red("\u2717 WrongStack Desktop is not installed."),
|
|
871
881
|
"",
|
|
872
882
|
"Download WrongStack Desktop from GitHub Releases:",
|
|
873
883
|
" https://github.com/WrongStack/WrongStack/releases/latest",
|
|
@@ -889,7 +899,7 @@ async function launchDesktop(args) {
|
|
|
889
899
|
});
|
|
890
900
|
child.once("error", (err) => {
|
|
891
901
|
process.stderr.write(
|
|
892
|
-
`${
|
|
902
|
+
`${color3.red("\u2717 Failed to start WrongStack Desktop:")} ${err.message}
|
|
893
903
|
`
|
|
894
904
|
);
|
|
895
905
|
resolve3(1);
|
|
@@ -909,7 +919,7 @@ import {
|
|
|
909
919
|
readHqRuntimeFileSync,
|
|
910
920
|
resolveHqDataDir
|
|
911
921
|
} from "@wrongstack/core/hq";
|
|
912
|
-
import { color as
|
|
922
|
+
import { color as color4, isPidAlive } from "@wrongstack/core/utils";
|
|
913
923
|
function isReusedContainerPid(markerPid, containerMode, currentPid = process.pid) {
|
|
914
924
|
return containerMode === "1" && markerPid === currentPid;
|
|
915
925
|
}
|
|
@@ -938,7 +948,7 @@ async function isPortInUse(host, port) {
|
|
|
938
948
|
}
|
|
939
949
|
async function handleHqShortCircuit(flags) {
|
|
940
950
|
if (flags["hq"] !== true) return null;
|
|
941
|
-
const { startHqServer } = await import("./hq-server-
|
|
951
|
+
const { startHqServer } = await import("./hq-server-YK7FBLL6.js");
|
|
942
952
|
const tunnelRequested = flags["tunnel"] === true;
|
|
943
953
|
const rawPublicUrl = typeof flags["hq-public-url"] === "string" ? flags["hq-public-url"] : process.env.WRONGSTACK_HQ_PUBLIC_URL;
|
|
944
954
|
let publicOrigin;
|
|
@@ -947,14 +957,14 @@ async function handleHqShortCircuit(flags) {
|
|
|
947
957
|
publicOrigin = normalizeHqPublicOrigin(rawPublicUrl);
|
|
948
958
|
} catch (cause) {
|
|
949
959
|
process.stderr.write(
|
|
950
|
-
`${
|
|
960
|
+
`${color4.red("\u2717")} ${cause instanceof Error ? cause.message : String(cause)}
|
|
951
961
|
`
|
|
952
962
|
);
|
|
953
963
|
return 1;
|
|
954
964
|
}
|
|
955
965
|
}
|
|
956
966
|
if (tunnelRequested && publicOrigin !== void 0) {
|
|
957
|
-
process.stderr.write(`${
|
|
967
|
+
process.stderr.write(`${color4.red("\u2717")} Use either --tunnel or --hq-public-url, not both.
|
|
958
968
|
`);
|
|
959
969
|
return 1;
|
|
960
970
|
}
|
|
@@ -962,7 +972,7 @@ async function handleHqShortCircuit(flags) {
|
|
|
962
972
|
const host = typeof flags["host"] === "string" ? flags["host"] : externallyPublished ? "127.0.0.1" : HQ_CLI_DEFAULT_HOST2;
|
|
963
973
|
if (externallyPublished && !isLoopbackHost(host)) {
|
|
964
974
|
process.stderr.write(
|
|
965
|
-
`${
|
|
975
|
+
`${color4.red("\u2717")} Public HQ publishing requires a loopback bind. Remove --host or use --host 127.0.0.1.
|
|
966
976
|
`
|
|
967
977
|
);
|
|
968
978
|
return 1;
|
|
@@ -974,7 +984,7 @@ async function handleHqShortCircuit(flags) {
|
|
|
974
984
|
if (Number.isFinite(parsed) && parsed > 0 && parsed < 65536) {
|
|
975
985
|
port = parsed;
|
|
976
986
|
} else {
|
|
977
|
-
process.stderr.write(`${
|
|
987
|
+
process.stderr.write(`${color4.red("\u2717")} Invalid --port value: ${flags["port"]}
|
|
978
988
|
`);
|
|
979
989
|
return 1;
|
|
980
990
|
}
|
|
@@ -987,7 +997,7 @@ async function handleHqShortCircuit(flags) {
|
|
|
987
997
|
});
|
|
988
998
|
} catch (cause) {
|
|
989
999
|
process.stderr.write(
|
|
990
|
-
`${
|
|
1000
|
+
`${color4.red("\u2717")} ${cause instanceof Error ? cause.message : String(cause)}
|
|
991
1001
|
`
|
|
992
1002
|
);
|
|
993
1003
|
return 1;
|
|
@@ -1002,13 +1012,13 @@ async function handleHqShortCircuit(flags) {
|
|
|
1002
1012
|
);
|
|
1003
1013
|
} catch (cause) {
|
|
1004
1014
|
process.stderr.write(
|
|
1005
|
-
`${
|
|
1015
|
+
`${color4.red("\u2717")} ${cause instanceof Error ? cause.message : String(cause)}
|
|
1006
1016
|
`
|
|
1007
1017
|
);
|
|
1008
1018
|
return 1;
|
|
1009
1019
|
}
|
|
1010
1020
|
if (password !== void 0 && password.length < 8) {
|
|
1011
|
-
process.stderr.write(`${
|
|
1021
|
+
process.stderr.write(`${color4.red("\u2717")} HQ password must be at least 8 characters.
|
|
1012
1022
|
`);
|
|
1013
1023
|
return 1;
|
|
1014
1024
|
}
|
|
@@ -1018,7 +1028,7 @@ async function handleHqShortCircuit(flags) {
|
|
|
1018
1028
|
const parsed = Number.parseInt(rawTrustedProxyHops, 10);
|
|
1019
1029
|
if (!Number.isFinite(parsed) || parsed < 0 || String(parsed) !== rawTrustedProxyHops.trim()) {
|
|
1020
1030
|
process.stderr.write(
|
|
1021
|
-
`${
|
|
1031
|
+
`${color4.red("\u2717")} --hq-trusted-proxy-hops must be a non-negative integer.
|
|
1022
1032
|
`
|
|
1023
1033
|
);
|
|
1024
1034
|
return 1;
|
|
@@ -1030,14 +1040,14 @@ async function handleHqShortCircuit(flags) {
|
|
|
1030
1040
|
const existing = await isHqAlreadyRunning(resolvedDataDir);
|
|
1031
1041
|
if (existing) {
|
|
1032
1042
|
process.stderr.write(
|
|
1033
|
-
`${
|
|
1043
|
+
`${color4.red("\u2717")} HQ is already running at ${existing.url} (PID ${existing.pid}). Stop it first or use a different --data-dir.
|
|
1034
1044
|
`
|
|
1035
1045
|
);
|
|
1036
1046
|
return 1;
|
|
1037
1047
|
}
|
|
1038
1048
|
if (await isPortInUse(host, port)) {
|
|
1039
1049
|
process.stderr.write(
|
|
1040
|
-
`${
|
|
1050
|
+
`${color4.red("\u2717")} Port ${port} is already in use. Choose a different port or stop the process using it.
|
|
1041
1051
|
`
|
|
1042
1052
|
);
|
|
1043
1053
|
return 1;
|
|
@@ -1048,7 +1058,7 @@ async function handleHqShortCircuit(flags) {
|
|
|
1048
1058
|
const { parseTokenTtlValue } = await import("./hq-ttl-RKRF7AQX.js");
|
|
1049
1059
|
const parsed = parseTokenTtlValue(rawTtl);
|
|
1050
1060
|
if (parsed.error) {
|
|
1051
|
-
process.stderr.write(`${
|
|
1061
|
+
process.stderr.write(`${color4.red("\u2717")} Invalid --hq-token-ttl: ${parsed.error}
|
|
1052
1062
|
`);
|
|
1053
1063
|
return 1;
|
|
1054
1064
|
}
|
|
@@ -1075,11 +1085,11 @@ async function handleHqShortCircuit(flags) {
|
|
|
1075
1085
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1076
1086
|
if (err instanceof Error && "code" in err && err.code === "EADDRINUSE") {
|
|
1077
1087
|
process.stderr.write(
|
|
1078
|
-
`${
|
|
1088
|
+
`${color4.red("\u2717")} Port ${port} is already in use. Please choose a different port.
|
|
1079
1089
|
`
|
|
1080
1090
|
);
|
|
1081
1091
|
} else {
|
|
1082
|
-
process.stderr.write(`${
|
|
1092
|
+
process.stderr.write(`${color4.red("\u2717")} Failed to start HQ server: ${msg}
|
|
1083
1093
|
`);
|
|
1084
1094
|
}
|
|
1085
1095
|
return 1;
|
|
@@ -1088,16 +1098,16 @@ async function handleHqShortCircuit(flags) {
|
|
|
1088
1098
|
if (handle.firstRunSetup?.passwordMode !== true) {
|
|
1089
1099
|
await handle.close();
|
|
1090
1100
|
process.stderr.write(
|
|
1091
|
-
`${
|
|
1101
|
+
`${color4.red("\u2717")} Persistent public HQ requires password mode. Set WRONGSTACK_HQ_PASSWORD and retry.
|
|
1092
1102
|
`
|
|
1093
1103
|
);
|
|
1094
1104
|
return 1;
|
|
1095
1105
|
}
|
|
1096
1106
|
handle.trustPublicOrigin(publicOrigin);
|
|
1097
1107
|
process.stdout.write(`
|
|
1098
|
-
${
|
|
1108
|
+
${color4.green("Persistent HQ origin ready:")} ${publicOrigin}/
|
|
1099
1109
|
`);
|
|
1100
|
-
process.stdout.write(`${
|
|
1110
|
+
process.stdout.write(`${color4.green("Mobile:")} ${publicOrigin}/mobile
|
|
1101
1111
|
`);
|
|
1102
1112
|
}
|
|
1103
1113
|
let tunnel;
|
|
@@ -1106,7 +1116,7 @@ ${color3.green("Persistent HQ origin ready:")} ${publicOrigin}/
|
|
|
1106
1116
|
if (handle.firstRunSetup !== void 0 && !handle.firstRunSetup.browserTokenMode && !handle.firstRunSetup.passwordMode) {
|
|
1107
1117
|
await handle.close();
|
|
1108
1118
|
process.stderr.write(
|
|
1109
|
-
`${
|
|
1119
|
+
`${color4.red("\u2717")} Refusing to publish HQ in open mode. Set --password or create a browser token first.
|
|
1110
1120
|
`
|
|
1111
1121
|
);
|
|
1112
1122
|
return 1;
|
|
@@ -1115,7 +1125,7 @@ ${color3.green("Persistent HQ origin ready:")} ${publicOrigin}/
|
|
|
1115
1125
|
const { buildPublicHqUrl, startHqQuickTunnel } = await import("./hq-tunnel-6VU4IWV4.js");
|
|
1116
1126
|
const originHost = handle.host === "::1" ? "[::1]" : handle.host;
|
|
1117
1127
|
tunnel = await startHqQuickTunnel(`http://${originHost}:${handle.port}`, {
|
|
1118
|
-
onUnexpectedExit: (message) => process.stderr.write(`${
|
|
1128
|
+
onUnexpectedExit: (message) => process.stderr.write(`${color4.yellow("!")} ${message}
|
|
1119
1129
|
`)
|
|
1120
1130
|
});
|
|
1121
1131
|
handle.trustPublicOrigin(new URL(tunnel.url).origin);
|
|
@@ -1125,22 +1135,22 @@ ${color3.green("Persistent HQ origin ready:")} ${publicOrigin}/
|
|
|
1125
1135
|
handle.firstRunSetup?.passwordMode !== true
|
|
1126
1136
|
);
|
|
1127
1137
|
process.stdout.write(`
|
|
1128
|
-
${
|
|
1138
|
+
${color4.green("Cloudflare Quick Tunnel ready:")} ${browserUrl}
|
|
1129
1139
|
`);
|
|
1130
1140
|
const tunnelMobileUrl = new URL(tunnel.url);
|
|
1131
1141
|
tunnelMobileUrl.pathname = "/mobile";
|
|
1132
1142
|
tunnelMobileUrl.search = "";
|
|
1133
1143
|
tunnelMobileUrl.hash = "";
|
|
1134
|
-
process.stdout.write(`${
|
|
1144
|
+
process.stdout.write(`${color4.green("Mobile:")} ${tunnelMobileUrl.toString()}
|
|
1135
1145
|
`);
|
|
1136
1146
|
process.stdout.write(
|
|
1137
|
-
`${
|
|
1147
|
+
`${color4.dim("Temporary development URL; DNS may need a few seconds, it changes on restart and ends when HQ stops.")}
|
|
1138
1148
|
`
|
|
1139
1149
|
);
|
|
1140
1150
|
} catch (err) {
|
|
1141
1151
|
await handle.close();
|
|
1142
1152
|
process.stderr.write(
|
|
1143
|
-
`${
|
|
1153
|
+
`${color4.red("\u2717")} Failed to start Cloudflare Quick Tunnel: ${err instanceof Error ? err.message : String(err)}
|
|
1144
1154
|
`
|
|
1145
1155
|
);
|
|
1146
1156
|
return 1;
|
|
@@ -1186,8 +1196,8 @@ import * as path9 from "node:path";
|
|
|
1186
1196
|
import { DefaultLogger } from "@wrongstack/core/infrastructure";
|
|
1187
1197
|
import { DefaultModelsRegistry, startCatalog } from "@wrongstack/core/models";
|
|
1188
1198
|
import {
|
|
1189
|
-
color as
|
|
1190
|
-
isStdinTTY as
|
|
1199
|
+
color as color14,
|
|
1200
|
+
isStdinTTY as isStdinTTY4,
|
|
1191
1201
|
toErrorMessage as toErrorMessage7,
|
|
1192
1202
|
writeErr as writeErr3
|
|
1193
1203
|
} from "@wrongstack/core/utils";
|
|
@@ -1220,7 +1230,7 @@ async function resolveAppendedSystemPrompt(flags, cwd) {
|
|
|
1220
1230
|
// src/boot/config-backup-recovery.ts
|
|
1221
1231
|
import * as fs3 from "node:fs/promises";
|
|
1222
1232
|
import * as path5 from "node:path";
|
|
1223
|
-
import { atomicWrite as atomicWrite2, backupConfigFile, color as
|
|
1233
|
+
import { atomicWrite as atomicWrite2, backupConfigFile, color as color5, toErrorMessage } from "@wrongstack/core/utils";
|
|
1224
1234
|
function isRecord(value) {
|
|
1225
1235
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1226
1236
|
}
|
|
@@ -1310,12 +1320,12 @@ async function maybeRestoreDefaultProfileFromBackup(opts) {
|
|
|
1310
1320
|
const providerSummary = remainder > 0 ? `${shownProviders} +${remainder}` : shownProviders;
|
|
1311
1321
|
opts.renderer.write(
|
|
1312
1322
|
`
|
|
1313
|
-
${
|
|
1314
|
-
${
|
|
1323
|
+
${color5.amber("\u25CB")} ${color5.bold(profileName)} profile has no saved providers.
|
|
1324
|
+
${color5.dim("Latest usable backup:")} ${color5.bold(backup.fileName)} ${color5.dim(`(${backup.providerIds.length} provider: ${providerSummary})`)}
|
|
1315
1325
|
`
|
|
1316
1326
|
);
|
|
1317
1327
|
const answer = (await opts.reader.readLine(
|
|
1318
|
-
` ${
|
|
1328
|
+
` ${color5.amber("?")} Restore all settings from this backup? ${color5.dim("[Y/n]")} `
|
|
1319
1329
|
)).trim().toLowerCase();
|
|
1320
1330
|
if (answer === "n" || answer === "no") return false;
|
|
1321
1331
|
try {
|
|
@@ -1325,7 +1335,7 @@ async function maybeRestoreDefaultProfileFromBackup(opts) {
|
|
|
1325
1335
|
profilePath: opts.profilePath
|
|
1326
1336
|
});
|
|
1327
1337
|
opts.renderer.write(
|
|
1328
|
-
` ${
|
|
1338
|
+
` ${color5.green("\u2713")} Restored all settings from ${color5.dim(backup.fileName)}
|
|
1329
1339
|
`
|
|
1330
1340
|
);
|
|
1331
1341
|
return true;
|
|
@@ -1362,7 +1372,7 @@ async function bootConfig(flags) {
|
|
|
1362
1372
|
}
|
|
1363
1373
|
|
|
1364
1374
|
// src/boot-launch-choices.ts
|
|
1365
|
-
import { color as
|
|
1375
|
+
import { color as color11, toErrorMessage as toErrorMessage5, writeErr } from "@wrongstack/core/utils";
|
|
1366
1376
|
|
|
1367
1377
|
// src/boot/system-prompt-menu.ts
|
|
1368
1378
|
import {
|
|
@@ -1372,11 +1382,11 @@ import {
|
|
|
1372
1382
|
SYSTEM_PROMPT_VARIANT_OPTIONS,
|
|
1373
1383
|
SYSTEM_PROMPT_VARIANTS
|
|
1374
1384
|
} from "@wrongstack/core/agent";
|
|
1375
|
-
import { color as
|
|
1385
|
+
import { color as color9 } from "@wrongstack/core/utils";
|
|
1376
1386
|
|
|
1377
1387
|
// src/pre-launch/first-run.ts
|
|
1378
1388
|
import { hasProviderCredential } from "@wrongstack/core/models";
|
|
1379
|
-
import { color as
|
|
1389
|
+
import { color as color6, toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils";
|
|
1380
1390
|
import { PROVIDER_DEFINITIONS } from "@wrongstack/providers/definitions";
|
|
1381
1391
|
async function hasAnyCredential(config, modelsRegistry, env = process.env) {
|
|
1382
1392
|
for (const cfg of Object.values(config.providers ?? {})) {
|
|
@@ -1402,39 +1412,39 @@ function renderWelcome(renderer) {
|
|
|
1402
1412
|
renderer.write(`${boxTop("Welcome to WrongStack")}
|
|
1403
1413
|
`);
|
|
1404
1414
|
renderer.write(
|
|
1405
|
-
`${boxRow(
|
|
1415
|
+
`${boxRow(color6.dim("No model is connected yet. Pick how you want to connect one:"))}
|
|
1406
1416
|
`
|
|
1407
1417
|
);
|
|
1408
1418
|
renderer.write(`${boxDivider()}
|
|
1409
1419
|
`);
|
|
1410
1420
|
renderer.write(
|
|
1411
1421
|
`${boxRow(
|
|
1412
|
-
`${theme.accent("1")} ${
|
|
1422
|
+
`${theme.accent("1")} ${color6.bold("Sign in with a subscription")} ${color6.dim("ChatGPT \xB7 Claude \xB7 GitHub Copilot")}`
|
|
1413
1423
|
)}
|
|
1414
1424
|
`
|
|
1415
1425
|
);
|
|
1416
1426
|
renderer.write(
|
|
1417
1427
|
`${boxRow(
|
|
1418
|
-
`${theme.accent("2")} ${
|
|
1428
|
+
`${theme.accent("2")} ${color6.bold("Add an API key")} ${color6.dim("Anthropic \xB7 OpenAI \xB7 Google \xB7 OpenRouter \xB7 \u2026")}`
|
|
1419
1429
|
)}
|
|
1420
1430
|
`
|
|
1421
1431
|
);
|
|
1422
1432
|
renderer.write(
|
|
1423
1433
|
`${boxRow(
|
|
1424
|
-
`${theme.accent("3")} ${
|
|
1434
|
+
`${theme.accent("3")} ${color6.bold("Use a local server")} ${color6.dim("Ollama \xB7 LM Studio \xB7 vLLM \xB7 OmniRoute")}`
|
|
1425
1435
|
)}
|
|
1426
1436
|
`
|
|
1427
1437
|
);
|
|
1428
1438
|
renderer.write(
|
|
1429
1439
|
`${boxRow(
|
|
1430
|
-
`${theme.accent("4")} ${
|
|
1440
|
+
`${theme.accent("4")} ${color6.bold("Continue without a key")} ${color6.dim("setup mode \u2014 explore the app, no model")}`
|
|
1431
1441
|
)}
|
|
1432
1442
|
`
|
|
1433
1443
|
);
|
|
1434
1444
|
renderer.write(`${boxDivider()}
|
|
1435
1445
|
`);
|
|
1436
1446
|
renderer.write(
|
|
1437
|
-
`${boxRow(
|
|
1447
|
+
`${boxRow(color6.dim("You can change this any time with /auth inside the app, or `wstack auth`."))}
|
|
1438
1448
|
`
|
|
1439
1449
|
);
|
|
1440
1450
|
renderer.write(`${boxBottom()}
|
|
@@ -1453,12 +1463,12 @@ async function runFirstRunSetup(deps) {
|
|
|
1453
1463
|
renderWelcome(renderer);
|
|
1454
1464
|
const answer = (await reader.readLine(
|
|
1455
1465
|
`
|
|
1456
|
-
${
|
|
1466
|
+
${color6.amber("?")} Choose ${color6.dim("(1-4)")} ${color6.dim("[q to quit]")}: `
|
|
1457
1467
|
)).trim().toLowerCase();
|
|
1458
1468
|
if (!answer || answer === "q" || answer === "quit" || answer === "exit") {
|
|
1459
1469
|
renderer.write(
|
|
1460
1470
|
`
|
|
1461
|
-
${
|
|
1471
|
+
${color6.dim("No provider configured. Run")} ${color6.bold("wstack auth")} ${color6.dim("when you are ready.")}
|
|
1462
1472
|
|
|
1463
1473
|
`
|
|
1464
1474
|
);
|
|
@@ -1495,7 +1505,7 @@ ${color5.amber("?")} Choose ${color5.dim("(1-4)")} ${color5.dim("[q to quit]")}:
|
|
|
1495
1505
|
|
|
1496
1506
|
// src/pre-launch/launch-prompts.ts
|
|
1497
1507
|
import * as fs4 from "node:fs/promises";
|
|
1498
|
-
import { atomicWrite as atomicWrite3, color as
|
|
1508
|
+
import { atomicWrite as atomicWrite3, color as color7, withFileLock as withFileLock2 } from "@wrongstack/core/utils";
|
|
1499
1509
|
var LaunchAbortedError = class extends Error {
|
|
1500
1510
|
exitCode = 0;
|
|
1501
1511
|
constructor() {
|
|
@@ -1526,19 +1536,19 @@ async function runLaunchPrompts(opts) {
|
|
|
1526
1536
|
yolo: yoloPinned ?? lastChoices.yolo,
|
|
1527
1537
|
autonomy: autonomyPinned ?? lastChoices.autonomy
|
|
1528
1538
|
};
|
|
1529
|
-
const onOff = (v) => v ?
|
|
1539
|
+
const onOff = (v) => v ? color7.green("on") : color7.dim("off");
|
|
1530
1540
|
const modeLabel = effective.mode.toUpperCase();
|
|
1531
1541
|
renderer.write(
|
|
1532
1542
|
`
|
|
1533
|
-
${
|
|
1543
|
+
${color7.dim("Last settings:")} ${color7.bold(modeLabel)} \xB7 YOLO ${onOff(effective.yolo)} \xB7 Autonomy ${effective.autonomy === "auto" ? color7.green("auto") : color7.dim("off")}
|
|
1534
1544
|
`
|
|
1535
1545
|
);
|
|
1536
1546
|
const answer = reuseLast ? "y" : (await reader.readLine(
|
|
1537
|
-
` ${
|
|
1547
|
+
` ${color7.amber("?")} Continue with these? ${color7.dim("[Y/n/q]")} ${color7.dim("(auto Y in 5s)")} `,
|
|
1538
1548
|
{ timeoutMs: 5e3, defaultAnswer: "y" }
|
|
1539
1549
|
)).trim().toLowerCase();
|
|
1540
1550
|
if (answer === "q") {
|
|
1541
|
-
renderer.write(
|
|
1551
|
+
renderer.write(color7.dim(" Goodbye!\n"));
|
|
1542
1552
|
throw new LaunchAbortedError();
|
|
1543
1553
|
}
|
|
1544
1554
|
if (answer !== "n" && answer !== "no") {
|
|
@@ -1546,7 +1556,7 @@ async function runLaunchPrompts(opts) {
|
|
|
1546
1556
|
const badgeStr2 = badges2.length > 0 ? ` (${badges2.join(" \xB7 ")})` : "";
|
|
1547
1557
|
renderer.write(
|
|
1548
1558
|
`
|
|
1549
|
-
${
|
|
1559
|
+
${color7.green("\u25B6")} Launching in ${color7.bold(modeLabel)} mode${badgeStr2}
|
|
1550
1560
|
|
|
1551
1561
|
`
|
|
1552
1562
|
);
|
|
@@ -1559,10 +1569,10 @@ async function runLaunchPrompts(opts) {
|
|
|
1559
1569
|
} else {
|
|
1560
1570
|
const answer = (await reader.readLine(
|
|
1561
1571
|
`
|
|
1562
|
-
${
|
|
1572
|
+
${color7.amber("?")} Interactive mode: ${color7.bold("T")}UI / ${color7.bold("R")}EPL ${color7.dim("[T/r/q]")} `
|
|
1563
1573
|
)).trim().toLowerCase();
|
|
1564
1574
|
if (answer === "q") {
|
|
1565
|
-
renderer.write(
|
|
1575
|
+
renderer.write(color7.dim(" Goodbye!\n"));
|
|
1566
1576
|
throw new LaunchAbortedError();
|
|
1567
1577
|
}
|
|
1568
1578
|
mode = answer === "r" || answer === "repl" ? "repl" : "tui";
|
|
@@ -1572,10 +1582,10 @@ async function runLaunchPrompts(opts) {
|
|
|
1572
1582
|
yolo = yoloPinned;
|
|
1573
1583
|
} else {
|
|
1574
1584
|
const answer = (await reader.readLine(
|
|
1575
|
-
` ${
|
|
1585
|
+
` ${color7.amber("?")} YOLO mode ${color7.dim("(auto-approve tool calls)")} ${color7.dim("[Y/n/q]")} `
|
|
1576
1586
|
)).trim().toLowerCase();
|
|
1577
1587
|
if (answer === "q") {
|
|
1578
|
-
renderer.write(
|
|
1588
|
+
renderer.write(color7.dim(" Goodbye!\n"));
|
|
1579
1589
|
throw new LaunchAbortedError();
|
|
1580
1590
|
}
|
|
1581
1591
|
yolo = answer !== "n" && answer !== "no";
|
|
@@ -1585,10 +1595,10 @@ async function runLaunchPrompts(opts) {
|
|
|
1585
1595
|
autonomy = autonomyPinned;
|
|
1586
1596
|
} else {
|
|
1587
1597
|
const answer = (await reader.readLine(
|
|
1588
|
-
` ${
|
|
1598
|
+
` ${color7.amber("?")} Autonomy mode ${color7.dim("(auto-continue \u2014 agent picks next step)")} ${color7.dim("[Y/n/q]")} `
|
|
1589
1599
|
)).trim().toLowerCase();
|
|
1590
1600
|
if (answer === "q") {
|
|
1591
|
-
renderer.write(
|
|
1601
|
+
renderer.write(color7.dim(" Goodbye!\n"));
|
|
1592
1602
|
throw new LaunchAbortedError();
|
|
1593
1603
|
}
|
|
1594
1604
|
autonomy = answer !== "n" && answer !== "no" ? "auto" : "off";
|
|
@@ -1597,7 +1607,7 @@ async function runLaunchPrompts(opts) {
|
|
|
1597
1607
|
const badgeStr = badges.length > 0 ? ` (${badges.join(" \xB7 ")})` : "";
|
|
1598
1608
|
renderer.write(
|
|
1599
1609
|
`
|
|
1600
|
-
${
|
|
1610
|
+
${color7.green("\u25B6")} Launching in ${color7.bold(mode.toUpperCase())} mode${badgeStr}
|
|
1601
1611
|
|
|
1602
1612
|
`
|
|
1603
1613
|
);
|
|
@@ -1605,20 +1615,20 @@ async function runLaunchPrompts(opts) {
|
|
|
1605
1615
|
}
|
|
1606
1616
|
function buildBadges(chosen) {
|
|
1607
1617
|
const badges = [];
|
|
1608
|
-
if (chosen.yolo) badges.push(
|
|
1618
|
+
if (chosen.yolo) badges.push(color7.yellow("YOLO"));
|
|
1609
1619
|
if (chosen.autonomy !== "off")
|
|
1610
|
-
badges.push(
|
|
1620
|
+
badges.push(color7.magenta(`AUTONOMY:${chosen.autonomy.toUpperCase()}`));
|
|
1611
1621
|
return badges;
|
|
1612
1622
|
}
|
|
1613
1623
|
async function promptStopAskingStartupQuestions(opts) {
|
|
1614
1624
|
const answer = (await opts.reader.readLine(
|
|
1615
|
-
` ${
|
|
1625
|
+
` ${color7.amber("?")} Stop asking these startup questions? ${color7.dim("(reuse the last choices from now on)")} ${color7.dim("[y/N]")} ${color7.dim("(auto N in 5s)")} `,
|
|
1616
1626
|
{ timeoutMs: 5e3, defaultAnswer: "n" }
|
|
1617
1627
|
)).trim().toLowerCase();
|
|
1618
1628
|
const stop = answer === "y" || answer === "yes";
|
|
1619
1629
|
if (stop) {
|
|
1620
1630
|
opts.renderer.write(
|
|
1621
|
-
` ${
|
|
1631
|
+
` ${color7.green("\u25B6")} ${color7.dim("Startup questions off \u2014 turn back on with /settings reuse-startup-choices off.")}
|
|
1622
1632
|
|
|
1623
1633
|
`
|
|
1624
1634
|
);
|
|
@@ -1662,7 +1672,7 @@ async function persistLaunchChoices(configPath, choices, extra) {
|
|
|
1662
1672
|
import * as fs5 from "node:fs/promises";
|
|
1663
1673
|
import * as path6 from "node:path";
|
|
1664
1674
|
import {
|
|
1665
|
-
color as
|
|
1675
|
+
color as color8,
|
|
1666
1676
|
detectProjectKind,
|
|
1667
1677
|
isOutsideProject,
|
|
1668
1678
|
toErrorMessage as toErrorMessage3
|
|
@@ -1682,7 +1692,7 @@ async function runProjectCheck(opts) {
|
|
|
1682
1692
|
if (kind === "initialized") {
|
|
1683
1693
|
renderer.write(
|
|
1684
1694
|
`
|
|
1685
|
-
${
|
|
1695
|
+
${color8.green("\u2713")} Project initialized ${color8.dim(`(${path6.join(projectRoot, ".wrongstack", "AGENTS.md")})`)}
|
|
1686
1696
|
`
|
|
1687
1697
|
);
|
|
1688
1698
|
return true;
|
|
@@ -1690,20 +1700,20 @@ async function runProjectCheck(opts) {
|
|
|
1690
1700
|
if (kind === "project") {
|
|
1691
1701
|
renderer.write(
|
|
1692
1702
|
`
|
|
1693
|
-
${
|
|
1703
|
+
${color8.amber("\u25CF")} Project detected ${color8.dim(`(${projectRoot})`)} but ${color8.bold(".wrongstack/AGENTS.md")} is missing.
|
|
1694
1704
|
`
|
|
1695
1705
|
);
|
|
1696
1706
|
const answer2 = (await reader.readLine(
|
|
1697
|
-
` ${
|
|
1707
|
+
` ${color8.amber("?")} Scaffold ${color8.bold("AGENTS.md")} now? ${color8.dim("[y/N/q]")} `
|
|
1698
1708
|
)).trim().toLowerCase();
|
|
1699
1709
|
if (answer2 === "q") {
|
|
1700
|
-
renderer.write(
|
|
1710
|
+
renderer.write(color8.dim(" Cancelled.\n"));
|
|
1701
1711
|
return false;
|
|
1702
1712
|
}
|
|
1703
1713
|
if (answer2 === "y" || answer2 === "yes") {
|
|
1704
1714
|
try {
|
|
1705
1715
|
const file = await scaffoldAgentsMd(projectRoot);
|
|
1706
|
-
renderer.write(` ${
|
|
1716
|
+
renderer.write(` ${color8.green("\u2713")} Wrote ${color8.dim(file)}
|
|
1707
1717
|
`);
|
|
1708
1718
|
} catch (err) {
|
|
1709
1719
|
renderer.writeError(`Failed to scaffold AGENTS.md: ${toErrorMessage3(err)}`);
|
|
@@ -1721,14 +1731,14 @@ async function runProjectCheck(opts) {
|
|
|
1721
1731
|
if (!hasGit) {
|
|
1722
1732
|
renderer.write(
|
|
1723
1733
|
`
|
|
1724
|
-
${
|
|
1734
|
+
${color8.dim("\u25CB")} ${color8.dim(`No project manifest in ${projectRoot} \u2014 running in a scratch directory.`)}
|
|
1725
1735
|
`
|
|
1726
1736
|
);
|
|
1727
1737
|
const answer2 = (await reader.readLine(
|
|
1728
|
-
` ${
|
|
1738
|
+
` ${color8.amber("?")} No git repo found. ${color8.bold("Initialize git?")} ${color8.dim("[y/N/q]")} `
|
|
1729
1739
|
)).trim().toLowerCase();
|
|
1730
1740
|
if (answer2 === "q") {
|
|
1731
|
-
renderer.write(
|
|
1741
|
+
renderer.write(color8.dim(" Cancelled.\n"));
|
|
1732
1742
|
return false;
|
|
1733
1743
|
}
|
|
1734
1744
|
if (answer2 === "y" || answer2 === "yes") {
|
|
@@ -1746,7 +1756,7 @@ async function runProjectCheck(opts) {
|
|
|
1746
1756
|
(code) => code === 0 ? resolve3() : reject(new Error(`git init failed with ${code}`))
|
|
1747
1757
|
);
|
|
1748
1758
|
});
|
|
1749
|
-
renderer.write(` ${
|
|
1759
|
+
renderer.write(` ${color8.green("\u2713")} Git repository initialized
|
|
1750
1760
|
`);
|
|
1751
1761
|
} catch (err) {
|
|
1752
1762
|
renderer.writeError(`git init failed: ${toErrorMessage3(err)}
|
|
@@ -1756,13 +1766,13 @@ async function runProjectCheck(opts) {
|
|
|
1756
1766
|
} else {
|
|
1757
1767
|
renderer.write(
|
|
1758
1768
|
`
|
|
1759
|
-
${
|
|
1769
|
+
${color8.dim("\u25CB")} ${color8.dim(`No project manifest in ${projectRoot} \u2014 running in a scratch directory.`)}
|
|
1760
1770
|
`
|
|
1761
1771
|
);
|
|
1762
1772
|
}
|
|
1763
|
-
const answer = (await reader.readLine(` ${
|
|
1773
|
+
const answer = (await reader.readLine(` ${color8.amber("?")} Continue anyway? ${color8.dim("[Y/n/q]")} `)).trim().toLowerCase();
|
|
1764
1774
|
if (answer === "q" || answer === "n" || answer === "no") {
|
|
1765
|
-
renderer.write(
|
|
1775
|
+
renderer.write(color8.dim(" Cancelled.\n"));
|
|
1766
1776
|
return false;
|
|
1767
1777
|
}
|
|
1768
1778
|
return true;
|
|
@@ -1795,7 +1805,7 @@ async function runSystemPromptMenu(deps) {
|
|
|
1795
1805
|
const { renderer, reader, paths, lastVariant, suggestScout, reuseLast } = deps;
|
|
1796
1806
|
if (lastVariant && reuseLast) {
|
|
1797
1807
|
renderer.write(
|
|
1798
|
-
` ${
|
|
1808
|
+
` ${color9.green("\u25B6")} ${color9.bold(labelFor(lastVariant))} ${color9.dim("system prompt")}
|
|
1799
1809
|
`
|
|
1800
1810
|
);
|
|
1801
1811
|
return lastVariant;
|
|
@@ -1806,39 +1816,39 @@ async function runSystemPromptMenu(deps) {
|
|
|
1806
1816
|
if (suggestScout && lastVariant !== "scout") {
|
|
1807
1817
|
renderer.write(
|
|
1808
1818
|
`
|
|
1809
|
-
${
|
|
1819
|
+
${color9.dim("\u25CB")} ${color9.dim(`Not a project folder \u2014 ${labelFor("scout")} (general-purpose) may fit better; answer n to choose it.`)}
|
|
1810
1820
|
`
|
|
1811
1821
|
);
|
|
1812
1822
|
}
|
|
1813
1823
|
const answer2 = (await reader.readLine(
|
|
1814
|
-
` ${
|
|
1824
|
+
` ${color9.amber("?")} Continue with ${color9.bold(labelFor(lastVariant))} system prompt ${color9.dim(`(~${fmtTok(tokens[lastVariant])} tokens)`)}? ${color9.dim("[Y/n/q]")} ${color9.dim("(auto Y in 5s)")} `,
|
|
1815
1825
|
{ timeoutMs: SUMMARY_TIMEOUT_MS2, defaultAnswer: "y" }
|
|
1816
1826
|
)).trim().toLowerCase();
|
|
1817
1827
|
if (answer2 === "q" || answer2 === "quit") throw new LaunchAbortedError();
|
|
1818
1828
|
if (answer2 !== "n" && answer2 !== "no") return lastVariant;
|
|
1819
1829
|
}
|
|
1820
1830
|
renderer.write(`
|
|
1821
|
-
${
|
|
1831
|
+
${color9.amber("?")} System prompt:
|
|
1822
1832
|
`);
|
|
1823
1833
|
if (suggestScout) {
|
|
1824
1834
|
renderer.write(
|
|
1825
|
-
` ${
|
|
1835
|
+
` ${color9.dim(`Not a project folder \u2014 ${labelFor("scout")} is preselected.`)}
|
|
1826
1836
|
`
|
|
1827
1837
|
);
|
|
1828
1838
|
}
|
|
1829
1839
|
for (const [index, opt] of SYSTEM_PROMPT_OPTIONS.entries()) {
|
|
1830
1840
|
const num2 = index + 1;
|
|
1831
1841
|
const isDefault = opt.variant === defaultVariant;
|
|
1832
|
-
const marker = isDefault ?
|
|
1833
|
-
const label = isDefault ?
|
|
1842
|
+
const marker = isDefault ? color9.cyan("\u25CF") : color9.dim("\u25CB");
|
|
1843
|
+
const label = isDefault ? color9.bold(opt.label) : opt.label;
|
|
1834
1844
|
renderer.write(
|
|
1835
|
-
` ${
|
|
1845
|
+
` ${color9.dim(`${num2}.`)} ${marker} ${label.padEnd(9)} ${color9.dim(`~${fmtTok(tokens[opt.variant])} tokens`)} ${color9.dim(opt.hint)}
|
|
1836
1846
|
`
|
|
1837
1847
|
);
|
|
1838
1848
|
}
|
|
1839
1849
|
const answer = (await reader.readLine(
|
|
1840
1850
|
`
|
|
1841
|
-
${
|
|
1851
|
+
${color9.amber("?")} Select system prompt ${color9.dim(`[1-${SYSTEM_PROMPT_OPTIONS.length}, Enter = ${labelFor(defaultVariant)}, q to quit]`)}: `
|
|
1842
1852
|
)).trim().toLowerCase();
|
|
1843
1853
|
if (answer === "q" || answer === "quit") throw new LaunchAbortedError();
|
|
1844
1854
|
if (!answer) return defaultVariant;
|
|
@@ -1869,7 +1879,7 @@ async function maybeRunSystemPromptMenu(opts) {
|
|
|
1869
1879
|
if (chosen === savedVariant) return { variant: chosen, aborted: false, changed: false };
|
|
1870
1880
|
if (opts.outsideProject && chosen === "scout") {
|
|
1871
1881
|
opts.renderer.write(
|
|
1872
|
-
` ${
|
|
1882
|
+
` ${color9.dim(`${labelFor("scout")} for this launch only; the saved default stays ${labelFor(savedVariant ?? "default")}.`)}
|
|
1873
1883
|
`
|
|
1874
1884
|
);
|
|
1875
1885
|
return { variant: chosen, aborted: false, changed: true };
|
|
@@ -1892,7 +1902,7 @@ import { createRequire as createRequire4 } from "node:module";
|
|
|
1892
1902
|
import * as path7 from "node:path";
|
|
1893
1903
|
import { fileURLToPath } from "node:url";
|
|
1894
1904
|
import {
|
|
1895
|
-
color as
|
|
1905
|
+
color as color10,
|
|
1896
1906
|
moduleUrlFor,
|
|
1897
1907
|
toErrorMessage as toErrorMessage4,
|
|
1898
1908
|
wrongstackPackageJsonPath as wrongstackPackageJsonPath3
|
|
@@ -1913,6 +1923,7 @@ async function validateSavedProviderModel(config, modelsRegistry) {
|
|
|
1913
1923
|
if (!providerId || !modelId) return { ok: false, reason: "missing provider/model" };
|
|
1914
1924
|
if (isSetupProvider(providerId)) return { ok: true };
|
|
1915
1925
|
if (providerId === ACP_LEADER_PROVIDER_ID) return { ok: true };
|
|
1926
|
+
if (providerId === WRONGFORGE_AGENT_ID) return { ok: true };
|
|
1916
1927
|
const saved = config.providers?.[providerId];
|
|
1917
1928
|
const lookupId = saved?.type && saved.type !== providerId ? saved.type : providerId;
|
|
1918
1929
|
const catalogProvider = await modelsRegistry.getProvider(lookupId).catch(() => void 0);
|
|
@@ -1995,10 +2006,10 @@ async function checkGitInCwd(opts) {
|
|
|
1995
2006
|
if (!hasCwdGit) {
|
|
1996
2007
|
renderer.write(
|
|
1997
2008
|
`
|
|
1998
|
-
${
|
|
2009
|
+
${color10.amber("\u25CB")} This folder has no ${color10.bold(".git")} repository.
|
|
1999
2010
|
`
|
|
2000
2011
|
);
|
|
2001
|
-
const answer = (await reader.readLine(` ${
|
|
2012
|
+
const answer = (await reader.readLine(` ${color10.amber("?")} Initialize one here? ${color10.dim("[y/N]")} `)).trim().toLowerCase();
|
|
2002
2013
|
if (answer === "y" || answer === "yes") {
|
|
2003
2014
|
try {
|
|
2004
2015
|
const { spawn: spawn2 } = await import("node:child_process");
|
|
@@ -2014,7 +2025,7 @@ async function checkGitInCwd(opts) {
|
|
|
2014
2025
|
(code) => code === 0 ? resolve3() : reject(new Error(`git init failed with ${code}`))
|
|
2015
2026
|
);
|
|
2016
2027
|
});
|
|
2017
|
-
renderer.write(` ${
|
|
2028
|
+
renderer.write(` ${color10.green("\u2713")} Git repository initialized
|
|
2018
2029
|
`);
|
|
2019
2030
|
hasCwdGit = true;
|
|
2020
2031
|
} catch (err) {
|
|
@@ -2028,7 +2039,7 @@ async function checkGitInCwd(opts) {
|
|
|
2028
2039
|
try {
|
|
2029
2040
|
await fs6.access(path7.join(parentDir, ".git"));
|
|
2030
2041
|
renderer.write(
|
|
2031
|
-
` ${
|
|
2042
|
+
` ${color10.dim("\u2139")} A ${color10.bold(".git")} repo exists in the parent directory: ${color10.dim(parentDir)}
|
|
2032
2043
|
`
|
|
2033
2044
|
);
|
|
2034
2045
|
} catch {
|
|
@@ -2126,8 +2137,8 @@ async function applyBootLaunchChoices(input) {
|
|
|
2126
2137
|
if (shouldPrintYoloNotice(lastChoices, yoloPinned, choices.yolo)) {
|
|
2127
2138
|
writeErr(
|
|
2128
2139
|
`
|
|
2129
|
-
${
|
|
2130
|
-
${
|
|
2140
|
+
${color11.yellow("YOLO is on")}: non-denied tool calls, including shell and file writes, run without confirmation.
|
|
2141
|
+
${color11.dim("Damaging calls and calls your deny rules forbid still ask. Use")} --no-yolo ${color11.dim("or")} /yolo off ${color11.dim("to require prompts.")}
|
|
2131
2142
|
|
|
2132
2143
|
`
|
|
2133
2144
|
);
|
|
@@ -2138,7 +2149,7 @@ async function applyBootLaunchChoices(input) {
|
|
|
2138
2149
|
});
|
|
2139
2150
|
}
|
|
2140
2151
|
if (reuseLast && lastChoices) {
|
|
2141
|
-
renderer.write(` ${
|
|
2152
|
+
renderer.write(` ${color11.dim(REUSE_STARTUP_CHOICES_HINT)}
|
|
2142
2153
|
|
|
2143
2154
|
`);
|
|
2144
2155
|
}
|
|
@@ -2180,7 +2191,7 @@ async function applyBootLaunchChoices(input) {
|
|
|
2180
2191
|
}
|
|
2181
2192
|
|
|
2182
2193
|
// src/boot-provider-gate.ts
|
|
2183
|
-
import { color as
|
|
2194
|
+
import { color as color12, isStdinTTY as isStdinTTY3, toErrorMessage as toErrorMessage6, writeErr as writeErr2 } from "@wrongstack/core/utils";
|
|
2184
2195
|
import { isSetupProvider as isSetupProvider2, SETUP_MODEL_ID, SETUP_PROVIDER_ID } from "@wrongstack/providers";
|
|
2185
2196
|
async function resolveBootProviderModel(input) {
|
|
2186
2197
|
let { config, vault } = input;
|
|
@@ -2196,14 +2207,14 @@ async function resolveBootProviderModel(input) {
|
|
|
2196
2207
|
}
|
|
2197
2208
|
}
|
|
2198
2209
|
if (!(!!providerFlag && !!modelFlag)) {
|
|
2199
|
-
if (
|
|
2210
|
+
if (isStdinTTY3() && !noInteractiveMode) {
|
|
2200
2211
|
let picked;
|
|
2201
2212
|
let skipPicker = false;
|
|
2202
2213
|
if (isSetupProvider2(config.provider)) {
|
|
2203
2214
|
skipPicker = true;
|
|
2204
2215
|
renderer.write(
|
|
2205
2216
|
`
|
|
2206
|
-
${
|
|
2217
|
+
${color12.amber("\u25B6")} ${color12.bold("Setup mode")} ${color12.dim("\u2014 no model connected. Run")} ${color12.bold("/auth")} ${color12.dim("to connect one.")}
|
|
2207
2218
|
|
|
2208
2219
|
`
|
|
2209
2220
|
);
|
|
@@ -2243,7 +2254,7 @@ async function resolveBootProviderModel(input) {
|
|
|
2243
2254
|
const savedStatus = await validateSavedProviderModel(config, modelsRegistry);
|
|
2244
2255
|
renderer.write(
|
|
2245
2256
|
`
|
|
2246
|
-
${
|
|
2257
|
+
${color12.dim("Last settings:")} ${color12.bold(savedProvider)} / ${color12.bold(savedModel)}
|
|
2247
2258
|
`
|
|
2248
2259
|
);
|
|
2249
2260
|
if (!savedStatus.ok) {
|
|
@@ -2255,17 +2266,17 @@ async function resolveBootProviderModel(input) {
|
|
|
2255
2266
|
skipPicker = true;
|
|
2256
2267
|
renderer.write(
|
|
2257
2268
|
`
|
|
2258
|
-
${
|
|
2269
|
+
${color12.green("\u25B6")} ${color12.bold(savedProvider)} / ${color12.bold(savedModel)}
|
|
2259
2270
|
|
|
2260
2271
|
`
|
|
2261
2272
|
);
|
|
2262
2273
|
} else {
|
|
2263
2274
|
const answer = (await reader.readLine(
|
|
2264
|
-
` ${
|
|
2275
|
+
` ${color12.amber("?")} Continue with these? ${color12.dim("[Y/n/q]")} ${color12.dim("(auto Y in 5s)")} `,
|
|
2265
2276
|
{ timeoutMs: 5e3, defaultAnswer: "y" }
|
|
2266
2277
|
)).trim().toLowerCase();
|
|
2267
2278
|
if (answer === "q") {
|
|
2268
|
-
renderer.write(
|
|
2279
|
+
renderer.write(color12.dim(" Goodbye!\n"));
|
|
2269
2280
|
await reader.close();
|
|
2270
2281
|
return { kind: "exit", code: 0 };
|
|
2271
2282
|
}
|
|
@@ -2273,7 +2284,7 @@ async function resolveBootProviderModel(input) {
|
|
|
2273
2284
|
skipPicker = true;
|
|
2274
2285
|
renderer.write(
|
|
2275
2286
|
`
|
|
2276
|
-
${
|
|
2287
|
+
${color12.green("\u25B6")} ${color12.bold(savedProvider)} / ${color12.bold(savedModel)}
|
|
2277
2288
|
|
|
2278
2289
|
`
|
|
2279
2290
|
);
|
|
@@ -2294,9 +2305,9 @@ async function resolveBootProviderModel(input) {
|
|
|
2294
2305
|
if (!config.provider || !config.model) {
|
|
2295
2306
|
renderer.write(
|
|
2296
2307
|
`
|
|
2297
|
-
${
|
|
2298
|
-
${
|
|
2299
|
-
${
|
|
2308
|
+
${color12.dim("No provider selected.")}
|
|
2309
|
+
${color12.dim("Run")} ${color12.bold("wstack auth")} ${color12.dim("to add a key or sign in, or start with no model:")}
|
|
2310
|
+
${color12.bold(`wstack --provider ${SETUP_PROVIDER_ID} --model ${SETUP_MODEL_ID}`)}
|
|
2300
2311
|
|
|
2301
2312
|
`
|
|
2302
2313
|
);
|
|
@@ -2737,7 +2748,7 @@ function dim(s) {
|
|
|
2737
2748
|
}
|
|
2738
2749
|
|
|
2739
2750
|
// src/renderer.ts
|
|
2740
|
-
import { color as
|
|
2751
|
+
import { color as color13, sanitizeTerminalText } from "@wrongstack/core/utils";
|
|
2741
2752
|
var TerminalRenderer = class _TerminalRenderer {
|
|
2742
2753
|
out;
|
|
2743
2754
|
err;
|
|
@@ -2851,7 +2862,7 @@ var TerminalRenderer = class _TerminalRenderer {
|
|
|
2851
2862
|
const arrow = theme2.primary("\u2192");
|
|
2852
2863
|
const display = sanitizeTerminalText(formatInputSummary(input));
|
|
2853
2864
|
this.out.write(
|
|
2854
|
-
`${arrow} ${theme2.bold(sanitizeTerminalText(name))}${display ?
|
|
2865
|
+
`${arrow} ${theme2.bold(sanitizeTerminalText(name))}${display ? color13.dim(` ${display}`) : ""}
|
|
2855
2866
|
`
|
|
2856
2867
|
);
|
|
2857
2868
|
this.lineStart = true;
|
|
@@ -2871,7 +2882,7 @@ var TerminalRenderer = class _TerminalRenderer {
|
|
|
2871
2882
|
if (isError) {
|
|
2872
2883
|
const firstLine = txt.split("\n")[0] ?? "";
|
|
2873
2884
|
const truncated = firstLine.length > 200 ? `${firstLine.slice(0, 197)}\u2026` : firstLine;
|
|
2874
|
-
this.out.write(` ${prefix} ${
|
|
2885
|
+
this.out.write(` ${prefix} ${color13.dim(truncated)}
|
|
2875
2886
|
`);
|
|
2876
2887
|
this.lineStart = true;
|
|
2877
2888
|
return;
|
|
@@ -2879,7 +2890,7 @@ var TerminalRenderer = class _TerminalRenderer {
|
|
|
2879
2890
|
const isEditLike = name === "edit" || name === "write";
|
|
2880
2891
|
const diff = extractDiff(content);
|
|
2881
2892
|
if (isEditLike && diff) {
|
|
2882
|
-
this.out.write(` ${prefix} ${
|
|
2893
|
+
this.out.write(` ${prefix} ${color13.dim(sanitizeTerminalText(summarize(content, name)))}
|
|
2883
2894
|
`);
|
|
2884
2895
|
const rendered = renderDiff(diff).split("\n").map((l) => ` ${l}`).join("\n");
|
|
2885
2896
|
this.out.write(`${rendered}
|
|
@@ -2890,7 +2901,7 @@ var TerminalRenderer = class _TerminalRenderer {
|
|
|
2890
2901
|
const summary = sanitizeTerminalText(summarize(content, name));
|
|
2891
2902
|
const isReadLike = name === "read" || name === "grep" || name === "glob" || name === "bash" || name === "exec";
|
|
2892
2903
|
if (renderMode === "simple") {
|
|
2893
|
-
this.out.write(` ${prefix} ${
|
|
2904
|
+
this.out.write(` ${prefix} ${color13.dim(summary || compactSingleLine(bodyText))}
|
|
2894
2905
|
`);
|
|
2895
2906
|
this.lineStart = true;
|
|
2896
2907
|
return;
|
|
@@ -2899,16 +2910,16 @@ var TerminalRenderer = class _TerminalRenderer {
|
|
|
2899
2910
|
const lines = bodyText.split("\n");
|
|
2900
2911
|
const head = lines.slice(0, previewLines).map((l) => l.replace(/\s+$/, ""));
|
|
2901
2912
|
const moreCount = Math.max(0, lines.length - head.length);
|
|
2902
|
-
this.out.write(` ${prefix} ${
|
|
2913
|
+
this.out.write(` ${prefix} ${color13.dim(summary)}
|
|
2903
2914
|
`);
|
|
2904
2915
|
for (const l of head) {
|
|
2905
2916
|
const capped = l.length > 200 ? `${l.slice(0, 197)}\u2026` : l;
|
|
2906
|
-
this.out.write(` ${
|
|
2917
|
+
this.out.write(` ${color13.dim(capped)}
|
|
2907
2918
|
`);
|
|
2908
2919
|
}
|
|
2909
2920
|
if (moreCount > 0) {
|
|
2910
2921
|
this.out.write(
|
|
2911
|
-
` ${
|
|
2922
|
+
` ${color13.dim(`+${moreCount} more line${moreCount === 1 ? "" : "s"}`)}
|
|
2912
2923
|
`
|
|
2913
2924
|
);
|
|
2914
2925
|
}
|
|
@@ -3047,7 +3058,7 @@ function renderMarkdown(s) {
|
|
|
3047
3058
|
return theme2.primary(theme2.bold(`${hashes} ${text}`));
|
|
3048
3059
|
});
|
|
3049
3060
|
out = out.replace(/```([a-zA-Z0-9_+-]*)\n([\s\S]*?)```/g, (_m, _lang, code) => {
|
|
3050
|
-
return
|
|
3061
|
+
return color13.gray(`
|
|
3051
3062
|
\u250C\u2500
|
|
3052
3063
|
${code.replace(/^/gm, "\u2502 ")}\u2514\u2500`);
|
|
3053
3064
|
});
|
|
@@ -3055,7 +3066,7 @@ ${code.replace(/^/gm, "\u2502 ")}\u2514\u2500`);
|
|
|
3055
3066
|
out = out.replace(/\*\*([^*]+)\*\*/g, (_m, text) => theme2.bold(text));
|
|
3056
3067
|
out = out.replace(
|
|
3057
3068
|
/(^|[^*])\*([^*\n]+)\*([^*]|$)/g,
|
|
3058
|
-
(_m, l, t, r) => `${l}${
|
|
3069
|
+
(_m, l, t, r) => `${l}${color13.italic(t)}${r}`
|
|
3059
3070
|
);
|
|
3060
3071
|
return out;
|
|
3061
3072
|
}
|
|
@@ -3283,7 +3294,7 @@ async function boot(argv) {
|
|
|
3283
3294
|
return 2;
|
|
3284
3295
|
}
|
|
3285
3296
|
let first = positional[0];
|
|
3286
|
-
const mayOfferConfigRecovery =
|
|
3297
|
+
const mayOfferConfigRecovery = isStdinTTY4() && (positional.length === 0 || first === "quick") && typeof flags["prompt"] !== "string" && !flags["webui"] && !flags["no-interactive"] && !flags["skip"];
|
|
3287
3298
|
const machineOutput = flags["output-json"] === true || flags["output-format"] === "json" || flags["output-format"] === "stream-json";
|
|
3288
3299
|
const renderer = new TerminalRenderer(machineOutput ? { out: process.stderr } : void 0);
|
|
3289
3300
|
const reader = new ReadlineInputReader({ historyFile: paths.wpaths.historyFile });
|
|
@@ -3372,8 +3383,8 @@ async function boot(argv) {
|
|
|
3372
3383
|
if (isHomeDirectory(cwd, userHome)) {
|
|
3373
3384
|
writeErr3(
|
|
3374
3385
|
`
|
|
3375
|
-
${
|
|
3376
|
-
${
|
|
3386
|
+
${color14.red(color14.bold("\u26A0 This is not a working directory."))}
|
|
3387
|
+
${color14.red("Please open wstack in a project folder.")}
|
|
3377
3388
|
|
|
3378
3389
|
`
|
|
3379
3390
|
);
|
|
@@ -3398,7 +3409,7 @@ async function boot(argv) {
|
|
|
3398
3409
|
logger.debug(`provider auto-discovery skipped: ${toErrorMessage7(err)}`);
|
|
3399
3410
|
}
|
|
3400
3411
|
const isSingleShot = positional.length > 0 || typeof flags["prompt"] === "string";
|
|
3401
|
-
const isInteractiveTTY =
|
|
3412
|
+
const isInteractiveTTY = isStdinTTY4() && !isSingleShot && !flags["webui"] && !flags["no-interactive"] && !flags["skip"];
|
|
3402
3413
|
if (isInteractiveTTY) {
|
|
3403
3414
|
await checkGitInCwd({ cwd, renderer, reader });
|
|
3404
3415
|
const cont = await runProjectCheck({ projectRoot, cwd, renderer, reader });
|
|
@@ -3628,4 +3639,4 @@ async function initializeCli(argv, options = {}) {
|
|
|
3628
3639
|
export {
|
|
3629
3640
|
initializeCli
|
|
3630
3641
|
};
|
|
3631
|
-
//# sourceMappingURL=cli-context-
|
|
3642
|
+
//# sourceMappingURL=cli-context-CQYGIWOU.js.map
|