@wrongstack/cli 1.1.2 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/{acp-HCGUTFNE.js → acp-NKUEYJDZ.js} +14 -5
  2. package/dist/acp-leader/acp-leader-confirm.d.ts +20 -0
  3. package/dist/acp-leader/acp-leader-context.d.ts +29 -0
  4. package/dist/acp-leader/acp-leader-fleet.d.ts +26 -0
  5. package/dist/acp-leader/acp-leader-host-binding.d.ts +17 -0
  6. package/dist/acp-leader/acp-leader-host.d.ts +82 -0
  7. package/dist/acp-leader/acp-leader-picker.d.ts +24 -0
  8. package/dist/acp-leader/acp-leader-provider.d.ts +85 -0
  9. package/dist/acp-leader/acp-leader-resume.d.ts +10 -0
  10. package/dist/acp-leader/acp-leader-stream.d.ts +83 -0
  11. package/dist/{auth-ANOVZVHE.js → auth-2ZG5DBHS.js} +62 -66
  12. package/dist/auth-menu/index.d.ts +1 -2
  13. package/dist/boot/dispatch-webui.d.ts +16 -0
  14. package/dist/boot/launch-menu-arrow.d.ts +20 -0
  15. package/dist/boot/launch-menu-types.d.ts +36 -0
  16. package/dist/boot/launch-menu.d.ts +1 -57
  17. package/dist/boot/tui-session-resume-rollback.d.ts +31 -0
  18. package/dist/{boot-auto-thin-7D4OVEWA.js → boot-auto-thin-N2CIGTXE.js} +3 -3
  19. package/dist/{chunk-TZPKOS5G.js → chunk-2XQ6SRKG.js} +2 -2
  20. package/dist/chunk-3LEIFO5D.js +65 -0
  21. package/dist/chunk-5SGMUDP5.js +752 -0
  22. package/dist/{chunk-3EXRPTAU.js → chunk-5TQ65PXQ.js} +17 -17
  23. package/dist/{chunk-GRAGMA4B.js → chunk-7BM4LGKQ.js} +18 -18
  24. package/dist/{chunk-VAQXOZKP.js → chunk-AJM4EFCM.js} +139 -136
  25. package/dist/{chunk-C2BBH4S4.js → chunk-E3MJFAFR.js} +2 -2
  26. package/dist/{chunk-5TRZZHMN.js → chunk-JCZ2D3VV.js} +4 -65
  27. package/dist/{chunk-AWRZWPJ3.js → chunk-JFYQGMMM.js} +99 -75
  28. package/dist/{chunk-BIGSVBPI.js → chunk-KNYIEQAY.js} +64 -61
  29. package/dist/chunk-LUEO5HLZ.js +50 -0
  30. package/dist/chunk-LYWOV4OX.js +252 -0
  31. package/dist/chunk-M7FNHCE3.js +2070 -0
  32. package/dist/{chunk-75OLD563.js → chunk-M7PSENGF.js} +3 -1
  33. package/dist/{chunk-NMXQFQ26.js → chunk-MEBXWI7U.js} +5 -5
  34. package/dist/{chunk-RAWHRRUJ.js → chunk-MKMM5RIW.js} +209 -201
  35. package/dist/{chunk-3R3OADC5.js → chunk-P7MEEUGT.js} +281 -252
  36. package/dist/chunk-QLYPIJ7X.js +258 -0
  37. package/dist/chunk-RN5CFAVQ.js +292 -0
  38. package/dist/{chunk-WDXNBYGD.js → chunk-TDP7CZGE.js} +6 -1
  39. package/dist/{chunk-6VPWQ4TG.js → chunk-UROB7MK5.js} +2 -1
  40. package/dist/chunk-VEESMPTX.js +254 -0
  41. package/dist/{chunk-IJLIAPCW.js → chunk-VPSAKGLK.js} +47 -47
  42. package/dist/{cli-context-YIT4FEDM.js → cli-context-CQYGIWOU.js} +254 -237
  43. package/dist/{cli-main-JIADJ5OL.js → cli-main-VRUJNUBX.js} +2081 -1594
  44. package/dist/cli-main-boot.d.ts +1 -1
  45. package/dist/config-doctor-known-keys.d.ts +33 -0
  46. package/dist/config-doctor.d.ts +2 -47
  47. package/dist/config-history-support.d.ts +36 -0
  48. package/dist/config-history.d.ts +1 -1
  49. package/dist/{config-transfer-Y7XJMJRN.js → config-transfer-B4GOZTFC.js} +2 -2
  50. package/dist/{execution-BAP566QC.js → execution-IV72RUSM.js} +5354 -5258
  51. package/dist/execution-tui.d.ts +30 -0
  52. package/dist/fleet/acp-live-steer.d.ts +28 -0
  53. package/dist/fleet/acp-permission-bridge.d.ts +49 -0
  54. package/dist/fleet/acp-quota-hold.d.ts +3 -0
  55. package/dist/fleet/acp-quota-reading.d.ts +3 -0
  56. package/dist/fleet/acp-turn-reminders.d.ts +15 -0
  57. package/dist/fleet/acp-wrongstack-bridge.d.ts +50 -0
  58. package/dist/fleet/host-acp.d.ts +23 -2
  59. package/dist/fleet/wrongforge-client.d.ts +116 -0
  60. package/dist/fleet/wrongforge-gateway.d.ts +20 -0
  61. package/dist/fleet/wrongforge-info.d.ts +32 -0
  62. package/dist/fleet/wrongforge-quota.d.ts +10 -0
  63. package/dist/fleet/wrongforge-runner.d.ts +37 -0
  64. package/dist/fleet/wrongforge-runtime.d.ts +10 -0
  65. package/dist/{hq-JD5AZVMG.js → hq-54PQYR5O.js} +311 -307
  66. package/dist/hq-server/sweeps.d.ts +28 -0
  67. package/dist/{hq-server-BI23EPM7.js → hq-server-YK7FBLL6.js} +3 -3
  68. package/dist/index.js +8 -5
  69. package/dist/mcp-22CFBX4H.js +236 -0
  70. package/dist/mcp-serve-project.d.ts +18 -0
  71. package/dist/mcp-serve.d.ts +0 -63
  72. package/dist/{modeldiag-HDIKG37X.js → modeldiag-5PBB777J.js} +4 -4
  73. package/dist/{per-subcommand-help-D6J4ZXW2.js → per-subcommand-help-MQGERD4E.js} +2 -2
  74. package/dist/plugin-llm-command.d.ts +9 -0
  75. package/dist/{plugin-usage-TYF5HY4K.js → plugin-usage-UWKYMNQU.js} +3 -3
  76. package/dist/{plugins-XGAXDLPT.js → plugins-VP7JQH47.js} +4 -4
  77. package/dist/{sdd-runtime-6MFUXWJK.js → sdd-runtime-HIJ4Z5TF.js} +2 -2
  78. package/dist/services/sdd/state.d.ts +2 -0
  79. package/dist/session-event-wiring-types.d.ts +62 -0
  80. package/dist/session-event-wiring.d.ts +2 -52
  81. package/dist/{sessions-config-SJVQXCIE.js → sessions-config-7MK742OW.js} +2 -2
  82. package/dist/short-circuit-flags-AGHURHMQ.js +11 -0
  83. package/dist/slash-commands/command-context-fleet.d.ts +187 -0
  84. package/dist/slash-commands/command-context-sdd-goal.d.ts +102 -0
  85. package/dist/slash-commands/command-context.d.ts +3 -282
  86. package/dist/slash-commands/project-switch-interactive.d.ts +11 -0
  87. package/dist/slash-commands/setmodel-helpers.d.ts +36 -0
  88. package/dist/subcommands/handlers/hq-token.d.ts +3 -0
  89. package/dist/subcommands/handlers/hq.d.ts +0 -21
  90. package/dist/subcommands/handlers/per-subcommand-help-operations.d.ts +8 -0
  91. package/dist/subcommands/handlers/tools-cli-args.d.ts +57 -0
  92. package/dist/subcommands/handlers/tools-cli.d.ts +5 -0
  93. package/dist/subcommands/handlers/tools-serve.d.ts +4 -0
  94. package/dist/{subcommands-VTMIZQBP.js → subcommands-OCJNO57E.js} +2 -2
  95. package/dist/tool-gateway-http.d.ts +30 -0
  96. package/dist/tool-gateway.d.ts +185 -0
  97. package/dist/tools-cli-44MLIUQO.js +509 -0
  98. package/dist/tools-serve-TRCET2M7.js +102 -0
  99. package/dist/{tools-skills-55QVTMSK.js → tools-skills-WDTMCE46.js} +7 -2
  100. package/dist/tuneup-runtime-checks.d.ts +7 -0
  101. package/dist/tuneup-types.d.ts +118 -0
  102. package/dist/tuneup.d.ts +3 -122
  103. package/dist/{typesafe-YBEADNAH.js → typesafe-QLSMFU7J.js} +1 -1
  104. package/dist/{version-help-RBZC5GZZ.js → version-help-X6CC4CFY.js} +2 -2
  105. package/dist/{webui-server-HIUY3RHD.js → webui-server-V2R5WQUK.js} +79 -3
  106. package/dist/wiring/provider-runtime-setup.d.ts +3 -1
  107. package/dist/wiring/session-runtime.d.ts +1 -1
  108. package/dist/wrongforge-gateway-UOFBK56J.js +92 -0
  109. package/dist/wrongforge-leader/wrongforge-leader-gateway.d.ts +9 -0
  110. package/dist/wrongforge-leader/wrongforge-leader-picker.d.ts +12 -0
  111. package/dist/wrongforge-leader/wrongforge-leader-provider.d.ts +49 -0
  112. package/package.json +34 -30
  113. package/dist/auth-menu/anthropic-oauth.d.ts +0 -43
  114. package/dist/chunk-XT3NAHRX.js +0 -337
  115. package/dist/chunk-ZNNFEKDZ.js +0 -319
  116. package/dist/mcp-2XWBJEQN.js +0 -464
  117. package/dist/short-circuit-flags-CPCT5MWB.js +0 -11
@@ -20,7 +20,7 @@ import {
20
20
  runOAuthLoginKind,
21
21
  runOAuthLoginMenu,
22
22
  validateFamily
23
- } from "./chunk-RAWHRRUJ.js";
23
+ } from "./chunk-MKMM5RIW.js";
24
24
  import {
25
25
  renderAuthLocalHelpToString,
26
26
  wantsLocalHelp
@@ -37,29 +37,20 @@ import {
37
37
  import {
38
38
  activeProfileConfigPath
39
39
  } from "./chunk-SPSHEZ46.js";
40
- import "./chunk-BIGSVBPI.js";
40
+ import "./chunk-KNYIEQAY.js";
41
41
  import {
42
42
  restoreFlags
43
43
  } from "./chunk-QC6CLAK7.js";
44
44
  import "./chunk-BCKVNORU.js";
45
45
  import {
46
46
  parseAuthFlags
47
- } from "./chunk-75OLD563.js";
47
+ } from "./chunk-M7PSENGF.js";
48
48
  import "./chunk-W23PY4IJ.js";
49
49
 
50
50
  // src/subcommands/handlers/auth.ts
51
- import { color as color6 } from "@wrongstack/core/utils";
51
+ import { color as color5 } from "@wrongstack/core/utils";
52
52
  import { authProfileAliasError as authProfileAliasError2 } from "@wrongstack/providers";
53
-
54
- // src/auth-menu/anthropic-oauth.ts
55
- import {
56
- FetchError,
57
- ParseError
58
- } from "@wrongstack/core/types";
59
- import { color } from "@wrongstack/core/utils";
60
- var REDIRECT_PORT = 53692;
61
- var REDIRECT_PATH = "/callback";
62
- var REDIRECT_URI = `http://localhost:${REDIRECT_PORT}${REDIRECT_PATH}`;
53
+ import { retiredProviderAuthLoginHint } from "@wrongstack/providers/oauth";
63
54
 
64
55
  // src/auth-menu/direct.ts
65
56
  import { authProfileAliasError } from "@wrongstack/providers";
@@ -142,16 +133,16 @@ async function runAuthDirect(deps, opts) {
142
133
 
143
134
  // src/auth-menu/github-copilot-oauth.ts
144
135
  import {
145
- FetchError as FetchError2,
146
- ParseError as ParseError2
136
+ FetchError,
137
+ ParseError
147
138
  } from "@wrongstack/core/types";
148
- import { color as color2 } from "@wrongstack/core/utils";
139
+ import { color } from "@wrongstack/core/utils";
149
140
  import { copilotBaseUrlFromToken, refreshCopilotToken } from "@wrongstack/providers";
150
141
  import { fetchCopilotModels as fetchAccountCopilotModels } from "@wrongstack/providers/oauth";
151
142
  import { isUsableCopilotChatModel } from "@wrongstack/providers/oauth";
152
143
 
153
144
  // src/auth-menu/openai-codex-oauth.ts
154
- import { color as color3 } from "@wrongstack/core/utils";
145
+ import { color as color2 } from "@wrongstack/core/utils";
155
146
  import {
156
147
  buildCodexAuthorizeUrl,
157
148
  CODEX_BASE_URL,
@@ -187,10 +178,10 @@ import {
187
178
  } from "@wrongstack/providers/oauth";
188
179
 
189
180
  // src/auth-menu/top-menu.ts
190
- import { color as color5 } from "@wrongstack/core/utils";
181
+ import { color as color4 } from "@wrongstack/core/utils";
191
182
 
192
183
  // src/auth-menu/provider-menu.ts
193
- import { color as color4, expectDefined } from "@wrongstack/core/utils";
184
+ import { color as color3, expectDefined } from "@wrongstack/core/utils";
194
185
  async function manageProvider(providerId, deps) {
195
186
  for (; ; ) {
196
187
  const providers = await loadProviders(deps);
@@ -203,7 +194,7 @@ async function manageProvider(providerId, deps) {
203
194
  renderProviderHeader(deps.renderer, providerId, cfg);
204
195
  renderActions(deps.renderer, keys.length);
205
196
  const raw = (await deps.reader.readLine(`
206
- ${color4.amber("?")} ${providerId} > `)).trim();
197
+ ${color3.amber("?")} ${providerId} > `)).trim();
207
198
  if (!raw || raw === "b" || raw === "back" || raw === "q" || raw === "quit") {
208
199
  return;
209
200
  }
@@ -234,7 +225,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
234
225
  },
235
226
  deps.profileConfigPath
236
227
  );
237
- deps.renderer.write(` ${color4.green("\u2713")} Removed ${providerId}.
228
+ deps.renderer.write(` ${color3.green("\u2713")} Removed ${providerId}.
238
229
  `);
239
230
  return "exit";
240
231
  }
@@ -258,7 +249,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
258
249
  },
259
250
  deps.profileConfigPath
260
251
  );
261
- deps.renderer.write(` ${color4.green("\u2713")} Updated ${providerId}/${target.label}.
252
+ deps.renderer.write(` ${color3.green("\u2713")} Updated ${providerId}/${target.label}.
262
253
  `);
263
254
  return "continue";
264
255
  }
@@ -285,7 +276,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
285
276
  },
286
277
  deps.profileConfigPath
287
278
  );
288
- deps.renderer.write(` ${color4.green("\u2713")} Deleted ${providerId}/${target.label}.
279
+ deps.renderer.write(` ${color3.green("\u2713")} Deleted ${providerId}/${target.label}.
289
280
  `);
290
281
  return "continue";
291
282
  }
@@ -304,14 +295,14 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
304
295
  },
305
296
  deps.profileConfigPath
306
297
  );
307
- deps.renderer.write(` ${color4.green("\u2713")} Active key \u2192 ${color4.bold(target.label)}.
298
+ deps.renderer.write(` ${color3.green("\u2713")} Active key \u2192 ${color3.bold(target.label)}.
308
299
  `);
309
300
  return "continue";
310
301
  }
311
302
  if (verb === "f" || verb === "family") {
312
303
  const current = cfg.family ?? "";
313
304
  const ans = (await deps.reader.readLine(
314
- ` ${color4.amber("?")} Family ${color4.dim(`(anthropic | openai | openai-compatible | google, empty = unset, current: ${current || "unset"})`)}: `
305
+ ` ${color3.amber("?")} Family ${color3.dim(`(anthropic | openai | openai-compatible | google, empty = unset, current: ${current || "unset"})`)}: `
315
306
  )).trim();
316
307
  if (ans !== "") {
317
308
  const validated = validateFamily(ans);
@@ -331,7 +322,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
331
322
  },
332
323
  deps.profileConfigPath
333
324
  );
334
- deps.renderer.write(` ${color4.green("\u2713")} family \u2192 ${validated}
325
+ deps.renderer.write(` ${color3.green("\u2713")} family \u2192 ${validated}
335
326
  `);
336
327
  } else {
337
328
  await mutateConfigProviders(
@@ -344,7 +335,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
344
335
  },
345
336
  deps.profileConfigPath
346
337
  );
347
- deps.renderer.write(` ${color4.green("\u2713")} family \u2192 (unset)
338
+ deps.renderer.write(` ${color3.green("\u2713")} family \u2192 (unset)
348
339
  `);
349
340
  }
350
341
  return "continue";
@@ -352,7 +343,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
352
343
  if (verb === "B" || verb === "baseurl" || verb === "base-url" || verb === "url") {
353
344
  const current = cfg.baseUrl ?? "";
354
345
  const ans = (await deps.reader.readLine(
355
- ` ${color4.amber("?")} Base URL ${color4.dim(`(empty = unset, current: ${current || "unset"})`)}: `
346
+ ` ${color3.amber("?")} Base URL ${color3.dim(`(empty = unset, current: ${current || "unset"})`)}: `
356
347
  )).trim();
357
348
  await mutateConfigProviders(
358
349
  deps.profileConfigPath,
@@ -365,14 +356,14 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
365
356
  },
366
357
  deps.profileConfigPath
367
358
  );
368
- deps.renderer.write(` ${color4.green("\u2713")} baseUrl \u2192 ${ans || "(unset)"}
359
+ deps.renderer.write(` ${color3.green("\u2713")} baseUrl \u2192 ${ans || "(unset)"}
369
360
  `);
370
361
  return "continue";
371
362
  }
372
363
  if (verb === "m" || verb === "models") {
373
364
  const current = (cfg.models ?? []).join(", ");
374
365
  const ans = (await deps.reader.readLine(
375
- ` ${color4.amber("?")} Model ids ${color4.dim(`(comma-separated, empty = catalog default, current: ${current || "none"})`)}: `
366
+ ` ${color3.amber("?")} Model ids ${color3.dim(`(comma-separated, empty = catalog default, current: ${current || "none"})`)}: `
376
367
  )).trim();
377
368
  const list = ans ? ans.split(",").map((s) => s.trim()).filter(Boolean) : [];
378
369
  await mutateConfigProviders(
@@ -387,7 +378,7 @@ async function dispatchAction(verb, arg, providerId, keys, cfg, deps) {
387
378
  deps.profileConfigPath
388
379
  );
389
380
  deps.renderer.write(
390
- ` ${color4.green("\u2713")} models \u2192 ${list.length === 0 ? "(catalog default)" : list.join(", ")}
381
+ ` ${color3.green("\u2713")} models \u2192 ${list.length === 0 ? "(catalog default)" : list.join(", ")}
391
382
  `
392
383
  );
393
384
  return "continue";
@@ -410,9 +401,9 @@ async function runTopMenu(deps) {
410
401
  renderTopMenu(deps.renderer, providers);
411
402
  const ids = Object.keys(providers).sort();
412
403
  const choice = (await deps.reader.readLine(`
413
- ${color5.amber("?")} Pick: `)).trim().toLowerCase();
404
+ ${color4.amber("?")} Pick: `)).trim().toLowerCase();
414
405
  if (!choice || choice === "q" || choice === "quit" || choice === "exit") {
415
- deps.renderer.write(color5.dim("Done.\n"));
406
+ deps.renderer.write(color4.dim("Done.\n"));
416
407
  return 0;
417
408
  }
418
409
  if (choice === "a" || choice === "add") {
@@ -589,17 +580,22 @@ var authCmd = async (args, deps) => {
589
580
  if (first === "login") {
590
581
  const pid = (flags.positional[1] ?? "").toLowerCase();
591
582
  if (!pid) return runOAuthLoginKind(menuDeps, "chatgpt", { providerId: flags.alias });
583
+ const retiredHint = retiredProviderAuthLoginHint(pid);
584
+ if (retiredHint) {
585
+ deps.renderer.writeError(retiredHint);
586
+ return 1;
587
+ }
592
588
  const kind = resolveOAuthKind(pid, { allowNumeric: false, deps: menuDeps });
593
589
  if (kind) return runOAuthLoginKind(menuDeps, kind, { providerId: flags.alias });
594
590
  const available = providerAuthStrategiesFor(menuDeps);
595
591
  deps.renderer.writeError(`Unknown OAuth login strategy "${pid}".`);
596
592
  for (const strategy of available) {
597
593
  deps.renderer.write(
598
- color6.dim(` Sign in with ${strategy.label}: `) + color6.bold(`wstack auth login ${strategy.id}`) + "\n"
594
+ color5.dim(` Sign in with ${strategy.label}: `) + color5.bold(`wstack auth login ${strategy.id}`) + "\n"
599
595
  );
600
596
  }
601
597
  deps.renderer.write(
602
- color6.dim(" For an API key instead: ") + color6.bold(`wstack auth ${pid}`) + "\n"
598
+ color5.dim(" For an API key instead: ") + color5.bold(`wstack auth ${pid}`) + "\n"
603
599
  );
604
600
  return 1;
605
601
  }
@@ -623,14 +619,14 @@ async function runAuthList(deps) {
623
619
  const ids = Object.keys(providers).sort();
624
620
  if (ids.length === 0) {
625
621
  deps.renderer.write(
626
- `${color6.dim("No providers configured.")}
627
- ${color6.dim("Run")} ${color6.bold("wstack auth")} ${color6.dim("to add one.")}
622
+ `${color5.dim("No providers configured.")}
623
+ ${color5.dim("Run")} ${color5.bold("wstack auth")} ${color5.dim("to add one.")}
628
624
  `
629
625
  );
630
626
  return 0;
631
627
  }
632
628
  deps.renderer.write(`
633
- ${color6.bold("Saved providers")} ${color6.dim(`(${ids.length})`)}
629
+ ${color5.bold("Saved providers")} ${color5.dim(`(${ids.length})`)}
634
630
 
635
631
  `);
636
632
  for (const id of ids) {
@@ -638,34 +634,34 @@ ${color6.bold("Saved providers")} ${color6.dim(`(${ids.length})`)}
638
634
  if (!cfg) continue;
639
635
  const keys = normalizeKeys(cfg);
640
636
  const active = cfg.activeKey ?? keys[0]?.label;
641
- const famTag = cfg.family ? `${cfg.family}` : color6.amber("no-family");
642
- const aliasHint = cfg.type && cfg.type !== id ? color6.dim(` (\u2192 ${cfg.type})`) : "";
643
- const modelHint = cfg.models && cfg.models.length > 0 ? color6.dim(` [${cfg.models.length} models]`) : "";
644
- deps.renderer.write(` ${color6.bold(id)}${aliasHint}
637
+ const famTag = cfg.family ? `${cfg.family}` : color5.amber("no-family");
638
+ const aliasHint = cfg.type && cfg.type !== id ? color5.dim(` (\u2192 ${cfg.type})`) : "";
639
+ const modelHint = cfg.models && cfg.models.length > 0 ? color5.dim(` [${cfg.models.length} models]`) : "";
640
+ deps.renderer.write(` ${color5.bold(id)}${aliasHint}
645
641
  `);
646
642
  deps.renderer.write(
647
- ` family: ${famTag} baseUrl: ${cfg.baseUrl ?? color6.dim("unset")}${modelHint}
643
+ ` family: ${famTag} baseUrl: ${cfg.baseUrl ?? color5.dim("unset")}${modelHint}
648
644
  `
649
645
  );
650
646
  if (keys.length === 0) {
651
- deps.renderer.write(` ${color6.amber("no keys")}
647
+ deps.renderer.write(` ${color5.amber("no keys")}
652
648
  `);
653
649
  } else {
654
650
  deps.renderer.write(
655
- ` ${color6.dim(`${keys.length} key${keys.length === 1 ? "" : "s"}:`)}
651
+ ` ${color5.dim(`${keys.length} key${keys.length === 1 ? "" : "s"}:`)}
656
652
  `
657
653
  );
658
654
  for (const k of keys) {
659
- const marker = k.label === active ? color6.green("\u25CF") : color6.dim("\u25CB");
655
+ const marker = k.label === active ? color5.green("\u25CF") : color5.dim("\u25CB");
660
656
  deps.renderer.write(
661
- ` ${marker} ${k.label.padEnd(18)} ${maskedKey(k.apiKey)} ${color6.dim(k.createdAt)}
657
+ ` ${marker} ${k.label.padEnd(18)} ${maskedKey(k.apiKey)} ${color5.dim(k.createdAt)}
662
658
  `
663
659
  );
664
660
  }
665
661
  }
666
662
  deps.renderer.write("\n");
667
663
  }
668
- deps.renderer.write(color6.dim(`Manage: wstack auth Add key: wstack auth <provider>
664
+ deps.renderer.write(color5.dim(`Manage: wstack auth Add key: wstack auth <provider>
669
665
  `));
670
666
  return 0;
671
667
  }
@@ -681,7 +677,7 @@ async function runAuthStatus(deps, providerId) {
681
677
  if (!cfg) {
682
678
  deps.renderer.writeError(`Provider "${providerId}" not found in config.`);
683
679
  deps.renderer.write(
684
- color6.dim(`Run ${color6.bold("wstack auth list")} to see saved providers.
680
+ color5.dim(`Run ${color5.bold("wstack auth list")} to see saved providers.
685
681
  `)
686
682
  );
687
683
  return 1;
@@ -690,32 +686,32 @@ async function runAuthStatus(deps, providerId) {
690
686
  const active = cfg.activeKey ?? keys[0]?.label;
691
687
  const lines = [
692
688
  `
693
- ${color6.bold(providerId)} ${cfg.family ? color6.dim(`[${cfg.family}]`) : color6.amber("[no family]")}`,
689
+ ${color5.bold(providerId)} ${cfg.family ? color5.dim(`[${cfg.family}]`) : color5.amber("[no family]")}`,
694
690
  "",
695
- ` type: ${color6.cyan(cfg.type ?? providerId)}`,
696
- ` family: ${cfg.family ? color6.cyan(cfg.family) : color6.dim("unset")}`,
697
- ` baseUrl: ${cfg.baseUrl ? color6.cyan(cfg.baseUrl) : color6.dim("unset")}`
691
+ ` type: ${color5.cyan(cfg.type ?? providerId)}`,
692
+ ` family: ${cfg.family ? color5.cyan(cfg.family) : color5.dim("unset")}`,
693
+ ` baseUrl: ${cfg.baseUrl ? color5.cyan(cfg.baseUrl) : color5.dim("unset")}`
698
694
  ];
699
695
  if (cfg.models?.length) {
700
- lines.push(` models: ${color6.cyan(cfg.models.join(", "))}`);
696
+ lines.push(` models: ${color5.cyan(cfg.models.join(", "))}`);
701
697
  }
702
698
  if (cfg.envVars?.length) {
703
- lines.push(` envVars: ${color6.cyan(cfg.envVars.join(", "))}`);
699
+ lines.push(` envVars: ${color5.cyan(cfg.envVars.join(", "))}`);
704
700
  }
705
701
  lines.push("");
706
702
  if (keys.length === 0) {
707
- lines.push(color6.amber(" (no keys saved)"));
703
+ lines.push(color5.amber(" (no keys saved)"));
708
704
  } else {
709
- lines.push(` ${color6.dim("Keys:")}`);
705
+ lines.push(` ${color5.dim("Keys:")}`);
710
706
  for (const k of keys) {
711
- const marker = k.label === active ? color6.green("\u25CF") : color6.dim("\u25CB");
707
+ const marker = k.label === active ? color5.green("\u25CF") : color5.dim("\u25CB");
712
708
  lines.push(
713
- ` ${marker} ${color6.bold(k.label.padEnd(18))} ${maskedKey(k.apiKey)} ${color6.dim(k.createdAt)}`
709
+ ` ${marker} ${color5.bold(k.label.padEnd(18))} ${maskedKey(k.apiKey)} ${color5.dim(k.createdAt)}`
714
710
  );
715
711
  }
716
712
  }
717
713
  lines.push("");
718
- lines.push(color6.dim(`Manage: wstack auth \u2192 pick ${providerId}`));
714
+ lines.push(color5.dim(`Manage: wstack auth \u2192 pick ${providerId}`));
719
715
  deps.renderer.write(lines.join("\n") + "\n");
720
716
  return 0;
721
717
  }
@@ -726,19 +722,19 @@ async function runAuthRemove(deps, providerId) {
726
722
  return 1;
727
723
  }
728
724
  deps.renderer.write(
729
- `${color6.amber("!")} This will remove "${providerId}" and all its saved keys.
725
+ `${color5.amber("!")} This will remove "${providerId}" and all its saved keys.
730
726
  `
731
727
  );
732
- const answer = (await deps.reader.readLine(` ${color6.amber("?")} Confirm removal? ${color6.dim("[y/N]")} `)).trim().toLowerCase();
728
+ const answer = (await deps.reader.readLine(` ${color5.amber("?")} Confirm removal? ${color5.dim("[y/N]")} `)).trim().toLowerCase();
733
729
  if (answer !== "y" && answer !== "yes") {
734
- deps.renderer.write(color6.dim("Cancelled.\n"));
730
+ deps.renderer.write(color5.dim("Cancelled.\n"));
735
731
  return 0;
736
732
  }
737
733
  try {
738
734
  await mutateConfigProviders(deps.profileConfigPath, deps.vault, (all) => {
739
735
  delete all[providerId];
740
736
  });
741
- deps.renderer.write(` ${color6.green("\u2713")} Removed ${color6.bold(providerId)}.
737
+ deps.renderer.write(` ${color5.green("\u2713")} Removed ${color5.bold(providerId)}.
742
738
  `);
743
739
  return 0;
744
740
  } catch (err) {
@@ -749,4 +745,4 @@ async function runAuthRemove(deps, providerId) {
749
745
  export {
750
746
  authCmd
751
747
  };
752
- //# sourceMappingURL=auth-ANOVZVHE.js.map
748
+ //# sourceMappingURL=auth-2ZG5DBHS.js.map
@@ -1,10 +1,9 @@
1
- export { CLAUDE_PROVIDER_ID, type ClaudeLoginOptions, type ClaudeTokens, runClaudeOAuthLogin, } from './anthropic-oauth.js';
2
1
  export { runAuthDirect } from './direct.js';
3
- export { providerAuthRegistryFor, providerAuthStrategiesFor, runProviderAuthLogin, } from './provider-auth-login.js';
4
2
  export { COPILOT_PROVIDER_ID, type CopilotLoginOptions, runCopilotOAuthLogin, } from './github-copilot-oauth.js';
5
3
  export { LOCAL_LLM_PRESETS, type LocalLlmPresetEntry, type ProbeOptions, type ProbeResult, probeLocalLlm, type RunAuthLocalOptions, resolveModelList, runAuthLocal, } from './local.js';
6
4
  export { type OAuthMenuKind, resolveOAuthKind, runOAuthLoginChoice, runOAuthLoginKind, runOAuthLoginMenu, } from './oauth-menu.js';
7
5
  export { CODEX_BASE_URL, CODEX_CATALOG_FAMILIES, CODEX_PROVIDER_ID, type CodexLoginOptions, type CodexTokens, extractAccountId, FALLBACK_CODEX_MODELS, fallbackCodexModelIds, fallbackCodexProviderModels, fetchCodexModels, filterCurrentCodexModelIds, isCodexCatalogModel, refreshCodexToken, resolveCodexModels, runCodexOAuthLogin, } from './openai-codex-oauth.js';
6
+ export { providerAuthRegistryFor, providerAuthStrategiesFor, runProviderAuthLogin, } from './provider-auth-login.js';
8
7
  export { runTopMenu as runAuthMenu } from './top-menu.js';
9
8
  export type { AuthMenuDeps } from './types.js';
10
9
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,19 @@
1
+ /**
2
+ * WebUI dispatch — extracted from the tail of `execute()`.
3
+ *
4
+ * PR 6 of Issue #29 (partial). The TUI-vs-REPL-vs-WebUI fork at the
5
+ * end of `execute()` is a ~1,600-line `if/else if/else if/else`
6
+ * chain. The WebUI branch is the most self-contained of the four: it
7
+ * constructs a `runWebUI` options object from already-available deps,
8
+ * wires SIGINT handling, and returns an exit code. Extracting it
9
+ * first lets `execute()` shrink by ~100 lines and isolates the
10
+ * WebUI-specific wiring (port resolution, browser banner and autonomy
11
+ * forwarding) in a single named module.
12
+ *
13
+ * The TUI branch (~1,388 lines) and the single-shot branch are left
14
+ * inline — they are too deeply coupled to local mutable state for a
15
+ * single-PR extraction.
16
+ */
1
17
  import type { Agent } from '@wrongstack/core/agent';
2
18
  import type { BrainArbiter } from '@wrongstack/core/coordination';
3
19
  import type { JournalEntry } from '@wrongstack/core/goal';
@@ -0,0 +1,20 @@
1
+ import type { LaunchMenuMode, RunLaunchMenuDeps } from './launch-menu-types.js';
2
+ interface ArrowPickResult {
3
+ cancelled: boolean;
4
+ mode: LaunchMenuMode;
5
+ }
6
+ /**
7
+ * Raw-mode arrow-key selector over {@link MODE_OPTIONS}.
8
+ *
9
+ * Keys: ↑/↓ (or k/j) move, Enter launches, 1–5 jump-launch, q/Esc/Ctrl+C
10
+ * cancel. A live countdown auto-launches the highlighted option after
11
+ * {@link MENU_TIMEOUT_MS}; any keypress stops the countdown. On settle the
12
+ * whole block collapses to a single confirmation line so scrollback stays
13
+ * tidy.
14
+ *
15
+ * Returns `null` when raw mode is unavailable or fails to engage —
16
+ * the caller then runs the numbered readline prompt instead.
17
+ */
18
+ export declare function promptModeArrow(deps: RunLaunchMenuDeps): Promise<ArrowPickResult | null>;
19
+ export {};
20
+ //# sourceMappingURL=launch-menu-arrow.d.ts.map
@@ -0,0 +1,36 @@
1
+ import type { LaunchMenuChoice } from '@wrongstack/core/types';
2
+ import type { ReadlineInputReader } from '../input-reader.js';
3
+ import type { TerminalRenderer } from '../renderer.js';
4
+ /** Top-level surfaces the user can launch from the menu. */
5
+ export type LaunchMenuMode = LaunchMenuChoice['mode'];
6
+ /** Surfaces that bind a TCP listener and therefore need a port/host prompt. */
7
+ export type NetworkLaunchMode = Exclude<LaunchMenuMode, 'tui-repl' | 'desktop'>;
8
+ export declare const DEFAULT_PORTS: Record<NetworkLaunchMode, number>;
9
+ /** Numbered choices shown to the user. Order MUST match the menu printout. */
10
+ export declare const MODE_OPTIONS: ReadonlyArray<{
11
+ key: number;
12
+ mode: LaunchMenuMode;
13
+ label: string;
14
+ hint: string;
15
+ icon: string;
16
+ }>;
17
+ export declare const MENU_TIMEOUT_MS = 8000;
18
+ export interface RunLaunchMenuDeps {
19
+ argv: string[];
20
+ flags: Record<string, string | boolean>;
21
+ positional: string[];
22
+ renderer: TerminalRenderer;
23
+ reader: ReadlineInputReader;
24
+ /**
25
+ * Last saved menu choice, if any. When provided the menu shows a
26
+ * one-line summary + "Continue? [Y/n/q]" gate before re-asking,
27
+ * matching the `runLaunchPrompts` pattern.
28
+ */
29
+ lastChoice?: LaunchMenuChoice | undefined;
30
+ /**
31
+ * Override the default ports (used by tests). Production callers
32
+ * should leave this unset.
33
+ */
34
+ defaultPorts?: Partial<typeof DEFAULT_PORTS> | undefined;
35
+ }
36
+ //# sourceMappingURL=launch-menu-types.d.ts.map
@@ -1,40 +1,5 @@
1
- /**
2
- * Interactive launch menu — surfaced when `wstack` is invoked with no
3
- * mode flag (no `--webui`, `--simpleui`, `--hq`, or `--desktop`) and no
4
- * positional subcommand, on an interactive TTY.
5
- *
6
- * The menu asks the user **once** which top-level surface to launch:
7
- * 1) TUI / REPL — interactive terminal (the historical default)
8
- * 2) WebUI — browser-based project UI (port 3456 by default)
9
- * 3) SimpleUI — lightweight browser UI (port 3466 by default)
10
- * 4) HQ — project-independent HQ dashboard (port 3499)
11
- * 5) Desktop — Electron desktop shell (`wstack --desktop`)
12
- *
13
- * It returns either:
14
- * - `null` — caller should fall through to the historical
15
- * boot() flow unchanged (menu skipped).
16
- * - `LaunchChoice` — caller should honor the selection:
17
- * * `tui-repl` → proceed to boot() with no flag
18
- * changes (the inner pre-launch prompts still
19
- * ask TUI vs REPL + YOLO + autonomy).
20
- * * `webui` / `simpleui` → caller injects the
21
- * surface flag + chosen port into argv.
22
- * * `hq` → caller dispatches to the HQ
23
- * short-circuit with the chosen port/host.
24
- * * `desktop` → caller injects `--desktop` and
25
- * dispatches to the desktop short-circuit.
26
- *
27
- * Why this lives in `boot/`: it sits next to the other entry-point
28
- * short-circuits (`short-circuit-{flags,desktop,hq}.ts`) and is
29
- * consumed by `cli-context.ts` between those short-circuits and
30
- * `boot()`. It deliberately does NOT take any DI container, agent,
31
- * or session — those are owned by the post-boot phase.
32
- */
33
1
  import type { LaunchMenuChoice } from '@wrongstack/core/types';
34
- import type { ReadlineInputReader } from '../input-reader.js';
35
- import type { TerminalRenderer } from '../renderer.js';
36
- /** Top-level surfaces the user can launch from the menu. */
37
- type LaunchMenuMode = LaunchMenuChoice['mode'];
2
+ import type { RunLaunchMenuDeps } from './launch-menu-types.js';
38
3
  /** Resolved menu result — the caller must act on this, not re-derive. */
39
4
  interface LaunchMenuResult extends LaunchMenuChoice {
40
5
  /**
@@ -43,9 +8,6 @@ interface LaunchMenuResult extends LaunchMenuChoice {
43
8
  */
44
9
  cancelled: boolean;
45
10
  }
46
- /** Surfaces that bind a TCP listener and therefore need a port/host prompt. */
47
- type NetworkLaunchMode = Exclude<LaunchMenuMode, 'tui-repl' | 'desktop'>;
48
- declare const DEFAULT_PORTS: Record<NetworkLaunchMode, number>;
49
11
  /**
50
12
  * Pure predicate — extracted so unit tests can lock the skip
51
13
  * conditions down without booting a renderer or reader.
@@ -62,24 +24,6 @@ declare const DEFAULT_PORTS: Record<NetworkLaunchMode, number>;
62
24
  * query. The user already said what they wanted.
63
25
  */
64
26
  export declare function shouldSkipMenu(argv: string[], flags: Record<string, string | boolean>, positional: string[]): boolean;
65
- interface RunLaunchMenuDeps {
66
- argv: string[];
67
- flags: Record<string, string | boolean>;
68
- positional: string[];
69
- renderer: TerminalRenderer;
70
- reader: ReadlineInputReader;
71
- /**
72
- * Last saved menu choice, if any. When provided the menu shows a
73
- * one-line summary + "Continue? [Y/n/q]" gate before re-asking,
74
- * matching the `runLaunchPrompts` pattern.
75
- */
76
- lastChoice?: LaunchMenuChoice | undefined;
77
- /**
78
- * Override the default ports (used by tests). Production callers
79
- * should leave this unset.
80
- */
81
- defaultPorts?: Partial<typeof DEFAULT_PORTS> | undefined;
82
- }
83
27
  /**
84
28
  * Run the interactive launch menu.
85
29
  *
@@ -0,0 +1,31 @@
1
+ import type { TodoItem } from '@wrongstack/core/agent';
2
+ import type { SessionResumeClaim } from '@wrongstack/core/storage';
3
+ import type { SessionWriter } from '@wrongstack/core/types';
4
+ import type { SessionResumeContext } from './tui-session-resume-contracts.js';
5
+ type ResumeAgent = SessionResumeContext['agent'];
6
+ /** What a failed resume had claimed or swapped, and what it captured before. */
7
+ export interface FailedResumeState {
8
+ agent: ResumeAgent;
9
+ state: SessionResumeContext['state'];
10
+ previousSessionId: string | undefined;
11
+ identityClaimed: boolean;
12
+ resumeClaim: SessionResumeClaim | undefined;
13
+ writerSwapped: boolean;
14
+ openedWriter: SessionWriter | undefined;
15
+ oldWriter: ResumeAgent['ctx']['session'] | undefined;
16
+ oldMessages: ResumeAgent['ctx']['messages'] | undefined;
17
+ oldSessionRefCurrent: SessionWriter | undefined;
18
+ previousDetachFn: SessionResumeContext['state']['detachActiveTodosCheckpoint'];
19
+ oldTodos: TodoItem[];
20
+ oldPlanPath: unknown;
21
+ oldTaskPath: unknown;
22
+ }
23
+ /**
24
+ * Undo a failed resume: release or roll back the session identity, then close
25
+ * the writer it opened — or, after the writer swap, put the agent's writer,
26
+ * messages and sidecars back. Best-effort throughout: a throw here would mask
27
+ * the original failure, so every step swallows and logs.
28
+ */
29
+ export declare function rollbackFailedResume(r: FailedResumeState): Promise<void>;
30
+ export {};
31
+ //# sourceMappingURL=tui-session-resume-rollback.d.ts.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  persistConfigSetting
3
- } from "./chunk-C2BBH4S4.js";
3
+ } from "./chunk-E3MJFAFR.js";
4
4
  import {
5
5
  activeProfileConfigPath
6
6
  } from "./chunk-SPSHEZ46.js";
7
- import "./chunk-BIGSVBPI.js";
7
+ import "./chunk-KNYIEQAY.js";
8
8
  import "./chunk-W23PY4IJ.js";
9
9
 
10
10
  // src/boot/boot-auto-thin.ts
@@ -100,4 +100,4 @@ async function runBootAutoThin(deps) {
100
100
  export {
101
101
  runBootAutoThin
102
102
  };
103
- //# sourceMappingURL=boot-auto-thin-7D4OVEWA.js.map
103
+ //# sourceMappingURL=boot-auto-thin-N2CIGTXE.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  PLUGIN_AUDIT_ENTRIES,
6
6
  loadExternalPlugins
7
- } from "./chunk-VAQXOZKP.js";
7
+ } from "./chunk-AJM4EFCM.js";
8
8
 
9
9
  // src/wiring/plugins.ts
10
10
  import { join } from "node:path";
@@ -306,4 +306,4 @@ export {
306
306
  BUILTIN_PLUGIN_NAME_HINTS,
307
307
  setupPlugins
308
308
  };
309
- //# sourceMappingURL=chunk-TZPKOS5G.js.map
309
+ //# sourceMappingURL=chunk-2XQ6SRKG.js.map
@@ -0,0 +1,65 @@
1
+
2
+ // src/boot/restricted-mode.ts
3
+ import { lockToProjectRoot, lockYoloOff, ToolCapabilities } from "@wrongstack/core/security";
4
+ var RESTRICTED_ENV = "WRONGSTACK_RESTRICTED";
5
+ var RESTRICTED_DENY_CAPABILITIES = [
6
+ ToolCapabilities.SHELL_ARBITRARY,
7
+ ToolCapabilities.SHELL_RESTRICTED,
8
+ ToolCapabilities.SHELL_EXEC,
9
+ ToolCapabilities.NET_OUTBOUND,
10
+ ToolCapabilities.PACKAGE_INSTALL,
11
+ ToolCapabilities.CONFIG_MUTATE,
12
+ ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
13
+ ToolCapabilities.TOOL_MUTATE_ANY,
14
+ ToolCapabilities.MCP_PROXY
15
+ ];
16
+ var CONFLICTING_FLAGS = [
17
+ "yolo",
18
+ "yolo-plus",
19
+ "yolo-destructive",
20
+ "full-auto",
21
+ "mcp-config",
22
+ // Pre-approving a tool would let writes skip the prompt this mode promises.
23
+ "allowed-tools"
24
+ ];
25
+ function isRestrictedMode(flags) {
26
+ return flags["restricted"] === true || process.env[RESTRICTED_ENV] === "1";
27
+ }
28
+ function validateRestrictedMode(flags) {
29
+ if (!isRestrictedMode(flags)) return false;
30
+ const conflict = CONFLICTING_FLAGS.find(
31
+ (name) => flags[name] !== void 0 && flags[name] !== false
32
+ );
33
+ if (conflict) throw new Error(`--${conflict} cannot be combined with --restricted`);
34
+ return true;
35
+ }
36
+ function withRestrictedTools(restriction, restricted) {
37
+ if (!restricted) return restriction;
38
+ return {
39
+ ...restriction?.only ? { only: restriction.only } : {},
40
+ deny: [...restriction?.deny ?? [], "mcp__*"],
41
+ denyCapabilities: RESTRICTED_DENY_CAPABILITIES,
42
+ requireDeclaredCapabilities: true
43
+ };
44
+ }
45
+ var RESTRICTED_NOTICE = "Restricted mode: no shell, network, installs or MCP tools; files stay inside the project; YOLO is off.";
46
+ var announced = false;
47
+ function activateRestrictedMode(flags, write) {
48
+ if (!validateRestrictedMode(flags)) return false;
49
+ lockToProjectRoot();
50
+ lockYoloOff();
51
+ process.env[RESTRICTED_ENV] = "1";
52
+ if (!announced) {
53
+ announced = true;
54
+ write(`${RESTRICTED_NOTICE}
55
+ `);
56
+ }
57
+ return true;
58
+ }
59
+
60
+ export {
61
+ isRestrictedMode,
62
+ withRestrictedTools,
63
+ activateRestrictedMode
64
+ };
65
+ //# sourceMappingURL=chunk-3LEIFO5D.js.map