@wrongstack/cli 0.309.1 → 0.310.1

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 (86) hide show
  1. package/dist/{acp-7NWCC2GO.js → acp-GZIASCLH.js} +6 -4
  2. package/dist/acp-server-agent.d.ts +1 -1
  3. package/dist/{audit-BBR22QH3.js → audit-ZPCLCC3C.js} +1 -1
  4. package/dist/{auth-GZ2FK5KR.js → auth-VQMSZGKE.js} +4 -4
  5. package/dist/{bench-XNDUJOSZ.js → bench-XYG56AMO.js} +1 -1
  6. package/dist/boot/tui-session-stub-enrich.d.ts +20 -0
  7. package/dist/{chronicle-63MFCZN6.js → chronicle-6EPPMUC5.js} +1 -1
  8. package/dist/chunk-3FHFGIIN.js +58 -0
  9. package/dist/chunk-3MAUU765.js +120 -0
  10. package/dist/{chunk-53STH6CX.js → chunk-4S52MIIM.js} +4 -3
  11. package/dist/{chunk-SZ42FYPT.js → chunk-BXFYBQKR.js} +4 -6
  12. package/dist/{chunk-CB35UVXO.js → chunk-J3XBHGEO.js} +34 -9
  13. package/dist/{chunk-UINEP3E7.js → chunk-J4QSP6T2.js} +41 -10
  14. package/dist/{chunk-XSG33WHN.js → chunk-QAC263FZ.js} +4 -2
  15. package/dist/{chunk-XQ6FI2K6.js → chunk-QYIIOMLE.js} +2 -2
  16. package/dist/{chunk-ZRZ54GVL.js → chunk-USYOJIV2.js} +3 -3
  17. package/dist/{chunk-T6YAVFXA.js → chunk-X3N5TS2S.js} +2 -1
  18. package/dist/{cli-main-XGDOIPN5.js → cli-main-UDWMWX55.js} +3114 -2883
  19. package/dist/{diag-doctor-WTBHPOMB.js → diag-doctor-Z6JDXBVX.js} +48 -2
  20. package/dist/{execution-TYUXABWI.js → execution-ZEHK4II6.js} +217 -68
  21. package/dist/{export-CCUXRJOU.js → export-ROG3DKTZ.js} +1 -1
  22. package/dist/{hq-PA6RH2UW.js → hq-3BEUEXJQ.js} +18 -10
  23. package/dist/hq-server/handle-types.d.ts +32 -0
  24. package/dist/hq-server/login-attempt-store.d.ts +5 -0
  25. package/dist/{hq-server-PBRU275L.js → hq-server-4MIW3S4J.js} +2 -2
  26. package/dist/hq-server.d.ts +2 -20
  27. package/dist/index.js +107 -77
  28. package/dist/{init-E2NDDOHI.js → init-4JQSG66Q.js} +1 -1
  29. package/dist/live-settings-input.d.ts +14 -0
  30. package/dist/{mailbox-serve-V3QIJBDH.js → mailbox-serve-5S3PHG5D.js} +1 -1
  31. package/dist/{mcp-CMLFHRG2.js → mcp-RRPKNRSN.js} +3 -1
  32. package/dist/mcp-serve.d.ts +1 -1
  33. package/dist/{modeldiag-ICMPHT5L.js → modeldiag-H6DKWJ2N.js} +6 -12
  34. package/dist/{plugin-usage-26LIIW3P.js → plugin-usage-GCTYOZPH.js} +1 -1
  35. package/dist/{projects-XE76NFNZ.js → projects-5J727S4L.js} +1 -1
  36. package/dist/provider-config-utils.d.ts +1 -2
  37. package/dist/{providers-models-D23WUD74.js → providers-models-663NDPRQ.js} +2 -2
  38. package/dist/proxy-wiring-7RPGBHZP.js +15 -0
  39. package/dist/{quick-VIO2BEHS.js → quick-XLYLZX4B.js} +1 -1
  40. package/dist/{replay-WBRMEWQ5.js → replay-RZXZKP2U.js} +1 -1
  41. package/dist/{rewind-7RE6ONIC.js → rewind-2FFNOOKS.js} +1 -1
  42. package/dist/{sessions-config-YX2ZPAFM.js → sessions-config-7Q7QJBKJ.js} +1 -1
  43. package/dist/subcommands/handlers/acp.d.ts +1 -1
  44. package/dist/subcommands/handlers/audit.d.ts +1 -1
  45. package/dist/subcommands/handlers/auth.d.ts +1 -1
  46. package/dist/subcommands/handlers/bench.d.ts +1 -1
  47. package/dist/subcommands/handlers/chronicle.d.ts +1 -1
  48. package/dist/subcommands/handlers/config-history.d.ts +1 -1
  49. package/dist/subcommands/handlers/diag-doctor.d.ts +15 -1
  50. package/dist/subcommands/handlers/export.d.ts +1 -1
  51. package/dist/subcommands/handlers/hq.d.ts +1 -1
  52. package/dist/subcommands/handlers/init.d.ts +1 -1
  53. package/dist/subcommands/handlers/mailbox-serve.d.ts +1 -1
  54. package/dist/subcommands/handlers/mcp.d.ts +1 -1
  55. package/dist/subcommands/handlers/modeldiag-bench.d.ts +1 -1
  56. package/dist/subcommands/handlers/modeldiag-eval.d.ts +1 -1
  57. package/dist/subcommands/handlers/modeldiag-test.d.ts +1 -1
  58. package/dist/subcommands/handlers/modeldiag.d.ts +1 -1
  59. package/dist/subcommands/handlers/plugin-usage.d.ts +1 -1
  60. package/dist/subcommands/handlers/projects.d.ts +1 -1
  61. package/dist/subcommands/handlers/providers-models.d.ts +1 -1
  62. package/dist/subcommands/handlers/quick.d.ts +1 -1
  63. package/dist/subcommands/handlers/replay.d.ts +1 -1
  64. package/dist/subcommands/handlers/rewind.d.ts +1 -1
  65. package/dist/subcommands/handlers/sessions-config.d.ts +1 -1
  66. package/dist/subcommands/handlers/sessions-fleet.d.ts +1 -1
  67. package/dist/subcommands/handlers/tools-skills.d.ts +1 -1
  68. package/dist/subcommands/handlers/update.d.ts +1 -1
  69. package/dist/subcommands/handlers/version-help.d.ts +1 -1
  70. package/dist/subcommands/index.d.ts +2 -3
  71. package/dist/{tools-skills-UNKLOB7M.js → tools-skills-Q4P27URS.js} +1 -1
  72. package/dist/{update-VZSOZGYC.js → update-ZXNC6I6G.js} +2 -2
  73. package/dist/{version-help-TFD6VPF3.js → version-help-WMPSEL4U.js} +2 -2
  74. package/dist/webui-server/prefs-seeding.d.ts +4 -0
  75. package/dist/{webui-server-JXJ4CGIX.js → webui-server-UB75UHWX.js} +14 -10
  76. package/dist/webui-server-options.d.ts +8 -0
  77. package/dist/wiring/director-announcement.d.ts +31 -0
  78. package/dist/wiring/provider-runtime.d.ts +25 -0
  79. package/dist/wiring/proxy-probe.d.ts +62 -0
  80. package/dist/wiring/proxy-wiring.d.ts +59 -0
  81. package/dist/wiring/session-establishment.d.ts +45 -0
  82. package/dist/wiring/session-registry.d.ts +1 -1
  83. package/dist/wiring/session-runtime.d.ts +64 -0
  84. package/dist/wiring/teardown-registrar.d.ts +41 -0
  85. package/dist/wiring/vector-memory-setup.d.ts +30 -0
  86. package/package.json +27 -25
@@ -8,10 +8,7 @@ import {
8
8
  runGit,
9
9
  setAutoSuggestions,
10
10
  setSuggestions
11
- } from "./chunk-T6YAVFXA.js";
12
- import {
13
- startCliHqConnection
14
- } from "./chunk-FKWHSFX4.js";
11
+ } from "./chunk-X3N5TS2S.js";
15
12
  import "./chunk-WHOIR577.js";
16
13
  import {
17
14
  advanceToNextTask,
@@ -26,6 +23,9 @@ import {
26
23
  trySaveSpecFromAIOutput,
27
24
  trySaveTasksFromAIOutput
28
25
  } from "./chunk-DGXNL7OT.js";
26
+ import {
27
+ startCliHqConnection
28
+ } from "./chunk-FKWHSFX4.js";
29
29
  import {
30
30
  theme
31
31
  } from "./chunk-QD544J2B.js";
@@ -49,11 +49,11 @@ import {
49
49
  } from "./chunk-YMXXOOFN.js";
50
50
  import {
51
51
  resolveActiveApiKey
52
- } from "./chunk-SZ42FYPT.js";
52
+ } from "./chunk-BXFYBQKR.js";
53
53
  import "./chunk-7OCVIDC7.js";
54
54
 
55
55
  // src/execution.ts
56
- import * as path13 from "node:path";
56
+ import * as path14 from "node:path";
57
57
  import { effectiveFallbackChain as effectiveFallbackChain2, setQueuedMessagesSnapshot as setQueuedMessagesSnapshot2 } from "@wrongstack/core/agent";
58
58
  import { updateReviewReportEvidence } from "@wrongstack/core/plugin";
59
59
  import { attachTodosCheckpoint as attachTodosCheckpoint2 } from "@wrongstack/core/storage";
@@ -207,7 +207,7 @@ async function runWebUIDispatch(ctx) {
207
207
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
208
208
  agent.disableInteractiveConfirmation();
209
209
  renderer.setSilent(true);
210
- const { runWebUI } = await import("./webui-server-JXJ4CGIX.js");
210
+ const { runWebUI } = await import("./webui-server-UB75UHWX.js");
211
211
  const flagValue = (names) => {
212
212
  for (const name of names) {
213
213
  if (!Object.hasOwn(flags, name)) continue;
@@ -404,16 +404,21 @@ async function runWebUIDispatch(ctx) {
404
404
  },
405
405
  onYoloSwitch: (enabled) => {
406
406
  applyLiveSettings?.({ yolo: enabled });
407
+ },
408
+ onWrongProxyPrefsChange: (payload) => {
409
+ void import("./proxy-wiring-7RPGBHZP.js").then(
410
+ ({ applyWrongProxyPrefs }) => applyWrongProxyPrefs(payload)
411
+ );
407
412
  }
408
413
  });
409
- const webuiExit = new Promise((resolve3) => {
414
+ const webuiExit = new Promise((resolve4) => {
410
415
  webuiPromise.then(() => {
411
416
  renderer.setSilent(false);
412
417
  renderer.write("\n");
413
418
  renderer.writeInfo(
414
419
  color2.yellow(` Shutting down ${isSimpleUi ? "SimpleUI" : "WebUI"} server\u2026`)
415
420
  );
416
- resolve3(0);
421
+ resolve4(0);
417
422
  }).catch((err) => {
418
423
  if (webuiSessionChild) {
419
424
  void writeWebuiSessionChildError(webuiSessionChild.readyFile, {
@@ -431,7 +436,7 @@ async function runWebUIDispatch(ctx) {
431
436
  ` \u2717 ${isSimpleUi ? "SimpleUI" : "WebUI"} failed to start: ${err instanceof Error ? err.message : String(err)}`
432
437
  )
433
438
  );
434
- resolve3(1);
439
+ resolve4(1);
435
440
  });
436
441
  });
437
442
  return webuiExit;
@@ -1013,8 +1018,8 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1013
1018
  attachTodosCheckpoint: attachTodosCheckpoint3
1014
1019
  } = ctx;
1015
1020
  const resolved = path6.resolve(targetRoot);
1016
- const stat2 = await fs2.stat(resolved).catch(() => null);
1017
- if (!stat2?.isDirectory()) return `Cannot switch: not a directory: ${resolved}`;
1021
+ const stat3 = await fs2.stat(resolved).catch(() => null);
1022
+ if (!stat3?.isDirectory()) return `Cannot switch: not a directory: ${resolved}`;
1018
1023
  const oldWriter = context.session;
1019
1024
  const oldSessionStore = state.activeSessionStore;
1020
1025
  const oldUsage = tokenCounter.total();
@@ -1136,12 +1141,12 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1136
1141
  modeStore,
1137
1142
  modeId: modeId ?? "default",
1138
1143
  modePrompt: switchMode?.prompt ?? "",
1139
- tokenSavingMode: config.features.tokenSavingMode,
1144
+ tokenSavingMode: config.features?.tokenSavingMode,
1140
1145
  modelCapabilities: {
1141
- maxContextTokens: context.provider.capabilities.maxContext,
1142
- supportsTools: !!context.provider.capabilities.tools,
1143
- supportsVision: !!context.provider.capabilities.vision,
1144
- supportsReasoning: !!context.provider.capabilities.reasoning
1146
+ maxContextTokens: context.provider?.capabilities?.maxContext,
1147
+ supportsTools: !!context.provider?.capabilities?.tools,
1148
+ supportsVision: !!context.provider?.capabilities?.vision,
1149
+ supportsReasoning: !!context.provider?.capabilities?.reasoning
1145
1150
  },
1146
1151
  instructionPaths: {
1147
1152
  globalDir: nextWpaths.globalInstructions,
@@ -1152,12 +1157,12 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1152
1157
  context.systemPrompt = await switchBuilder.build({
1153
1158
  cwd: resolved,
1154
1159
  projectRoot: resolved,
1155
- tools: agent.tools.listForProvider(),
1156
- catalogTools: agent.tools.list(),
1160
+ tools: typeof agent.tools?.listForProvider === "function" ? agent.tools.listForProvider() : typeof agent.tools?.list === "function" ? agent.tools.list() : [],
1161
+ catalogTools: typeof agent.tools?.list === "function" ? agent.tools.list() : [],
1157
1162
  provider: context.provider.id,
1158
1163
  model: context.model
1159
1164
  });
1160
- if (agent.container.has(TOKENS.SystemPromptBuilder)) {
1165
+ if (agent.container?.has?.(TOKENS.SystemPromptBuilder)) {
1161
1166
  agent.container.override(TOKENS.SystemPromptBuilder, () => switchBuilder, {
1162
1167
  owner: "tui-project-switch"
1163
1168
  });
@@ -1482,9 +1487,124 @@ async function resumeSession(ctx, sessionId) {
1482
1487
  }
1483
1488
  }
1484
1489
 
1485
- // src/boot/tui-settings-adapter.ts
1490
+ // src/boot/tui-session-stub-enrich.ts
1486
1491
  import * as fs3 from "node:fs/promises";
1487
1492
  import * as path8 from "node:path";
1493
+ var SLICE_BYTES = 256 * 1024;
1494
+ var MAX_TITLE_CHARS = 80;
1495
+ function isStubSummary(s) {
1496
+ return !s.title && !s.endedAt;
1497
+ }
1498
+ function containedJsonlPath(sessionsDir, id) {
1499
+ const root = path8.resolve(sessionsDir);
1500
+ const file = path8.resolve(root, `${id}.jsonl`);
1501
+ if (file !== root && !file.startsWith(root + path8.sep)) return void 0;
1502
+ return file;
1503
+ }
1504
+ function stripControlChars(text) {
1505
+ return text.replaceAll(/\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07]*(?:\x07|\x1b\\)|[\u0000-\u001f\u007f-\u009f]/g, "");
1506
+ }
1507
+ function truncate(text) {
1508
+ const oneLine = stripControlChars(text).replaceAll(/\s+/g, " ").trim();
1509
+ return oneLine.length > MAX_TITLE_CHARS ? `${oneLine.slice(0, MAX_TITLE_CHARS - 1)}\u2026` : oneLine;
1510
+ }
1511
+ function contentToText(content) {
1512
+ if (typeof content === "string") return content;
1513
+ if (Array.isArray(content)) {
1514
+ return content.map(
1515
+ (block) => block && typeof block === "object" && "text" in block && typeof block.text === "string" ? block.text : ""
1516
+ ).filter(Boolean).join(" ");
1517
+ }
1518
+ return "";
1519
+ }
1520
+ function scanUserInputs(chunk) {
1521
+ let first;
1522
+ let last;
1523
+ for (const line of chunk.split("\n")) {
1524
+ const trimmed = line.trim();
1525
+ if (!trimmed.includes('"user_input"')) continue;
1526
+ try {
1527
+ const event = JSON.parse(trimmed);
1528
+ if (event.type !== "user_input" || typeof event.ts !== "string") continue;
1529
+ const text = contentToText(event.content).trim();
1530
+ if (!text) continue;
1531
+ const hit = { ts: event.ts, text };
1532
+ if (!first) first = hit;
1533
+ last = hit;
1534
+ } catch {
1535
+ }
1536
+ }
1537
+ return { first, last };
1538
+ }
1539
+ async function firstUserInput(file) {
1540
+ let handle;
1541
+ try {
1542
+ handle = await fs3.open(file, "r");
1543
+ const { size } = await handle.stat();
1544
+ const length = Math.min(SLICE_BYTES, size);
1545
+ const buffer = Buffer.alloc(length);
1546
+ await handle.read(buffer, 0, length, 0);
1547
+ const text = buffer.toString("utf8");
1548
+ const cutoff = text.lastIndexOf("\n");
1549
+ return scanUserInputs(cutoff > 0 ? text.slice(0, cutoff) : text).first;
1550
+ } catch {
1551
+ return void 0;
1552
+ } finally {
1553
+ await handle?.close().catch(() => void 0);
1554
+ }
1555
+ }
1556
+ async function lastUserInput(file) {
1557
+ let handle;
1558
+ try {
1559
+ handle = await fs3.open(file, "r");
1560
+ const { size } = await handle.stat();
1561
+ const start = Math.max(0, size - SLICE_BYTES);
1562
+ const length = size - start;
1563
+ const buffer = Buffer.alloc(length);
1564
+ await handle.read(buffer, 0, length, start);
1565
+ const text = buffer.toString("utf8");
1566
+ const from = text.indexOf("\n");
1567
+ return scanUserInputs(from >= 0 ? text.slice(from + 1) : text).last;
1568
+ } catch {
1569
+ return void 0;
1570
+ } finally {
1571
+ await handle?.close().catch(() => void 0);
1572
+ }
1573
+ }
1574
+ function effectiveLastActivity(s) {
1575
+ return s.lastActivityAt ?? s.endedAt ?? s.startedAt ?? "";
1576
+ }
1577
+ async function selectPickerSessions(storeList, sessionsDir, limit) {
1578
+ const poolSize = Math.min(200, Math.max(limit, limit * 3));
1579
+ const enriched = await enrichStubSummaries(await storeList(poolSize), sessionsDir);
1580
+ return enriched.sort((a, b) => effectiveLastActivity(b).localeCompare(effectiveLastActivity(a))).slice(0, limit);
1581
+ }
1582
+ async function enrichStubSummaries(summaries, sessionsDir) {
1583
+ return Promise.all(
1584
+ summaries.map(async (s) => {
1585
+ if (!isStubSummary(s)) return s;
1586
+ const file = containedJsonlPath(sessionsDir, s.id);
1587
+ if (!file) return s;
1588
+ try {
1589
+ const stat3 = await fs3.stat(file);
1590
+ const [first, last] = await Promise.all([firstUserInput(file), lastUserInput(file)]);
1591
+ const title = truncate(first?.text ?? "");
1592
+ return {
1593
+ ...s,
1594
+ ...title ? { title } : {},
1595
+ ...last ? { lastUserMessage: truncate(last.text) } : {},
1596
+ lastActivityAt: stat3.mtime.toISOString()
1597
+ };
1598
+ } catch {
1599
+ return s;
1600
+ }
1601
+ })
1602
+ );
1603
+ }
1604
+
1605
+ // src/boot/tui-settings-adapter.ts
1606
+ import * as fs4 from "node:fs/promises";
1607
+ import * as path9 from "node:path";
1488
1608
  import { decryptConfigSecrets, encryptConfigSecrets, noOpVault } from "@wrongstack/core/security";
1489
1609
  import { normalizeTokenSavingTier, resolveFleetChatVerbosity } from "@wrongstack/core/types";
1490
1610
  import { atomicWrite, deepMerge } from "@wrongstack/core/utils";
@@ -1601,12 +1721,23 @@ function createSettingsAdapter(ctx) {
1601
1721
  }),
1602
1722
  showSageMemoryInject: autonomy?.showSageMemoryInject ?? false,
1603
1723
  readSymbols: autonomy?.readAdvancedMode ?? false,
1604
- sageMemoryInjectThreshold: cfg.Sage?.inject ? cfg.Sage.inject?.relationFloor : void 0
1724
+ sageMemoryInjectThreshold: cfg.Sage?.inject ? cfg.Sage.inject?.relationFloor : void 0,
1725
+ // WrongProxy / WrongTrace: read from `tools.wrongProxy.{enabled,url}`
1726
+ // so the persistence shape mirrors the WebUI `LocalPrefs` shape
1727
+ // (single object with two fields, not two top-level keys). The
1728
+ // canonical type is `ToolsConfig.wrongProxy?: WrongProxyToolConfig`
1729
+ // — no index-signature widening cast needed.
1730
+ wrongProxyEnabled: cfg.tools?.wrongProxy?.enabled === true,
1731
+ wrongProxyUrl: cfg.tools?.wrongProxy?.url
1605
1732
  };
1606
1733
  }
1607
1734
  async function saveSettings(s) {
1608
1735
  try {
1609
- if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.showAgentSwarmPanel !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0) {
1736
+ if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.showAgentSwarmPanel !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
1737
+ // either key being present in the live patch. Without this, a
1738
+ // picker toggle round-trip would silently no-op the persistence
1739
+ // layer (the runtime probe would never read the change).
1740
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
1610
1741
  const cfg = configStore.get();
1611
1742
  const persistDeps = {
1612
1743
  configStore,
@@ -1622,7 +1753,7 @@ function createSettingsAdapter(ctx) {
1622
1753
  const targetPath = resolvePersistPath(persistDeps);
1623
1754
  let raw;
1624
1755
  try {
1625
- raw = await fs3.readFile(targetPath, "utf8");
1756
+ raw = await fs4.readFile(targetPath, "utf8");
1626
1757
  } catch (err) {
1627
1758
  if (err.code !== "ENOENT") {
1628
1759
  throw new Error(
@@ -1704,11 +1835,21 @@ function createSettingsAdapter(ctx) {
1704
1835
  idx.onSessionStart = s.indexOnStart;
1705
1836
  decrypted.indexing = idx;
1706
1837
  }
1707
- if (s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0) {
1838
+ if (s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 || // WrongProxy / WrongTrace: include either key in the tools-section
1839
+ // write guard so a picker toggle round-trip actually persists to
1840
+ // `tools.wrongProxy.{enabled,url}`. Without this, the gate at
1841
+ // line 279 would short-circuit and skip the whole section write.
1842
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
1708
1843
  const tools = decrypted.tools ?? {};
1709
1844
  if (s.maxIterations !== void 0) tools.maxIterations = s.maxIterations;
1710
1845
  if (s.nextStepsTool !== void 0) tools.nextsteps = { enabled: s.nextStepsTool };
1711
1846
  if (fsAccess !== void 0) tools.restrictToProjectRoot = fsAccess.restrictToProjectRoot;
1847
+ if (s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
1848
+ const wp = tools.wrongProxy ?? {};
1849
+ if (s.wrongProxyEnabled !== void 0) wp.enabled = s.wrongProxyEnabled;
1850
+ if (s.wrongProxyUrl !== void 0) wp.url = s.wrongProxyUrl;
1851
+ tools.wrongProxy = wp;
1852
+ }
1712
1853
  decrypted.tools = tools;
1713
1854
  }
1714
1855
  if (s.debugStream !== void 0) {
@@ -1759,7 +1900,7 @@ function createSettingsAdapter(ctx) {
1759
1900
  let mergedToWrite = decrypted;
1760
1901
  if (actualTarget !== targetPath) {
1761
1902
  try {
1762
- const destRaw = await fs3.readFile(actualTarget, "utf8");
1903
+ const destRaw = await fs4.readFile(actualTarget, "utf8");
1763
1904
  const destParsed = JSON.parse(destRaw);
1764
1905
  const destDecrypted = decryptConfigSecrets(destParsed, noOpVault);
1765
1906
  mergedToWrite = deepMerge(destDecrypted, decrypted);
@@ -1775,7 +1916,7 @@ function createSettingsAdapter(ctx) {
1775
1916
  const isProjectTarget = actualTarget === wpaths.inProjectConfig;
1776
1917
  const toWrite = isProjectTarget ? filterSafeForProject(mergedToWrite) : mergedToWrite;
1777
1918
  const encrypted = encryptConfigSecrets(toWrite, noOpVault);
1778
- await fs3.mkdir(path8.dirname(actualTarget), { recursive: true });
1919
+ await fs4.mkdir(path9.dirname(actualTarget), { recursive: true });
1779
1920
  await atomicWrite(actualTarget, JSON.stringify(encrypted, null, 2), { mode: 384 });
1780
1921
  const currentConfig = configStore.get();
1781
1922
  const nextModelRuntime = {
@@ -1819,7 +1960,11 @@ function createSettingsAdapter(ctx) {
1819
1960
  ...decrypted.indexing ?? {}
1820
1961
  }
1821
1962
  } : {},
1822
- ...s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 ? {
1963
+ ...s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 || // WrongProxy / WrongTrace: must be in the tools guard or the
1964
+ // in-memory ConfigStore never sees the freshly-saved values,
1965
+ // and the next picker open in the same process would overwrite
1966
+ // the on-disk selection with stale state. See Chimera review.
1967
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0 ? {
1823
1968
  tools: {
1824
1969
  ...currentConfig.tools,
1825
1970
  ...decrypted.tools ?? {}
@@ -1881,8 +2026,8 @@ function createSettingsAdapter(ctx) {
1881
2026
  }
1882
2027
 
1883
2028
  // src/boot/tui-theme-adapter.ts
1884
- import * as fs4 from "node:fs/promises";
1885
- import * as path9 from "node:path";
2029
+ import * as fs5 from "node:fs/promises";
2030
+ import * as path10 from "node:path";
1886
2031
  import { THEME_PRESET_IDS } from "@wrongstack/core/types";
1887
2032
  import { atomicWrite as atomicWrite2 } from "@wrongstack/core/utils";
1888
2033
  var VALID_PRESETS = new Set(THEME_PRESET_IDS);
@@ -1901,7 +2046,7 @@ function createThemeAdapter({ configStore, wpaths }) {
1901
2046
  const configPath = activeProfileConfigPath(wpaths, configStore.get());
1902
2047
  let parsed = {};
1903
2048
  try {
1904
- const raw = await fs4.readFile(configPath, "utf8");
2049
+ const raw = await fs5.readFile(configPath, "utf8");
1905
2050
  parsed = JSON.parse(raw);
1906
2051
  } catch (err) {
1907
2052
  const e = err;
@@ -1910,7 +2055,7 @@ function createThemeAdapter({ configStore, wpaths }) {
1910
2055
  }
1911
2056
  }
1912
2057
  parsed.themePreset = preset;
1913
- await fs4.mkdir(path9.dirname(configPath), { recursive: true });
2058
+ await fs5.mkdir(path10.dirname(configPath), { recursive: true });
1914
2059
  await atomicWrite2(configPath, JSON.stringify(parsed, null, 2), { mode: 384 });
1915
2060
  }
1916
2061
  };
@@ -2797,7 +2942,7 @@ function createChimeraWorkRegistry() {
2797
2942
 
2798
2943
  // src/execution-chimera-cascade.ts
2799
2944
  import * as fsp from "node:fs/promises";
2800
- import * as path10 from "node:path";
2945
+ import * as path11 from "node:path";
2801
2946
  import { emitReviewIfChanged } from "@wrongstack/core/plugin";
2802
2947
 
2803
2948
  // src/chimera-cascade-evidence.ts
@@ -2891,7 +3036,7 @@ var runCascadeVerificationCommand = (command, cwd, timeoutMs) => {
2891
3036
  const tokens = command.trim().split(/\s+/);
2892
3037
  const executable = tokens[0];
2893
3038
  const args = tokens.slice(1);
2894
- return new Promise((resolve3) => {
3039
+ return new Promise((resolve4) => {
2895
3040
  let child;
2896
3041
  try {
2897
3042
  child = spawn2(executable, args, {
@@ -2901,11 +3046,11 @@ var runCascadeVerificationCommand = (command, cwd, timeoutMs) => {
2901
3046
  signal: AbortSignal.timeout(timeoutMs)
2902
3047
  });
2903
3048
  } catch {
2904
- resolve3({ exitCode: CASCADE_EVIDENCE_RUN_ERROR_EXIT });
3049
+ resolve4({ exitCode: CASCADE_EVIDENCE_RUN_ERROR_EXIT });
2905
3050
  return;
2906
3051
  }
2907
- child.on("error", () => resolve3({ exitCode: CASCADE_EVIDENCE_RUN_ERROR_EXIT }));
2908
- child.on("close", (code) => resolve3({ exitCode: code ?? CASCADE_EVIDENCE_RUN_ERROR_EXIT }));
3052
+ child.on("error", () => resolve4({ exitCode: CASCADE_EVIDENCE_RUN_ERROR_EXIT }));
3053
+ child.on("close", (code) => resolve4({ exitCode: code ?? CASCADE_EVIDENCE_RUN_ERROR_EXIT }));
2909
3054
  });
2910
3055
  };
2911
3056
  async function verifyCascadeEvidence(evidence, cwd, runCommand = runCascadeVerificationCommand, timeoutMs = CASCADE_EVIDENCE_COMMAND_TIMEOUT_MS) {
@@ -3405,7 +3550,7 @@ async function maybeReReviewCascade({
3405
3550
  const reReadFiles = [];
3406
3551
  for (const f of evidenceBundle.files) {
3407
3552
  try {
3408
- const absPath = path10.join(evidenceBundle.cwd, f.path);
3553
+ const absPath = path11.join(evidenceBundle.cwd, f.path);
3409
3554
  const content = await fsp.readFile(absPath, "utf8");
3410
3555
  reReadFiles.push({ path: f.path, status: "modified", content });
3411
3556
  } catch {
@@ -3482,7 +3627,7 @@ function errorText2(error) {
3482
3627
 
3483
3628
  // src/execution-chimera-review.ts
3484
3629
  import { randomUUID as randomUUID3 } from "node:crypto";
3485
- import path11 from "node:path";
3630
+ import path12 from "node:path";
3486
3631
  import { effectiveFallbackChain, fallbackProfileChain as fallbackProfileChain2 } from "@wrongstack/core/agent";
3487
3632
  import {
3488
3633
  CHIMERA_REVIEW_PROMPT,
@@ -3497,7 +3642,7 @@ import {
3497
3642
  function normalizeFileKeyForCitation(raw, cwd) {
3498
3643
  const forward = raw.replace(/\\/g, "/").replace(/^\.\//, "");
3499
3644
  const isAbsolute = forward.startsWith("/") || /^[a-zA-Z]:\//.test(forward);
3500
- const pathMod = process.platform === "win32" ? path11.win32 : path11;
3645
+ const pathMod = process.platform === "win32" ? path12.win32 : path12;
3501
3646
  const relative = isAbsolute ? pathMod.relative(cwd, forward).replace(/\\/g, "/").replace(/^\.\//, "") : forward;
3502
3647
  return process.platform === "win32" ? relative.toLowerCase() : relative;
3503
3648
  }
@@ -3717,7 +3862,7 @@ function installChimeraReviewHandler({
3717
3862
  const changedBasenameIndex = /* @__PURE__ */ new Map();
3718
3863
  for (const file of p.files) {
3719
3864
  const normalized = normalizeFileKeyForCitation(file.path, p.cwd);
3720
- const basename7 = path11.basename(file.path).toLowerCase();
3865
+ const basename7 = path12.basename(file.path).toLowerCase();
3721
3866
  const bucket = changedBasenameIndex.get(basename7);
3722
3867
  if (bucket) bucket.push(normalized);
3723
3868
  else changedBasenameIndex.set(basename7, [normalized]);
@@ -3729,7 +3874,7 @@ function installChimeraReviewHandler({
3729
3874
  (cp) => cp.endsWith(`/${citedKey}`) || cp === citedKey
3730
3875
  );
3731
3876
  if (suffixMatches.length === 1) return true;
3732
- const basename7 = path11.basename(finding.location.file).toLowerCase();
3877
+ const basename7 = path12.basename(finding.location.file).toLowerCase();
3733
3878
  const bucket = changedBasenameIndex.get(basename7);
3734
3879
  return !!(bucket && bucket.length === 1);
3735
3880
  });
@@ -4159,12 +4304,12 @@ ${color6.cyan("\u23F3 Auto")} ${color6.dim("(Ctrl+C to cancel)")}
4159
4304
  let interval;
4160
4305
  let lastTickedSecond = sec + 1;
4161
4306
  let onAbort;
4162
- return new Promise((resolve3) => {
4163
- onAbort = () => resolve3(false);
4307
+ return new Promise((resolve4) => {
4308
+ onAbort = () => resolve4(false);
4164
4309
  signal.addEventListener("abort", onAbort, { once: true });
4165
4310
  interval = setInterval(() => {
4166
4311
  if (signal.aborted) {
4167
- resolve3(false);
4312
+ resolve4(false);
4168
4313
  return;
4169
4314
  }
4170
4315
  const elapsed = Date.now() - start;
@@ -4172,7 +4317,7 @@ ${color6.cyan("\u23F3 Auto")} ${color6.dim("(Ctrl+C to cancel)")}
4172
4317
  if (remaining <= 0) {
4173
4318
  opts.renderer.write(color6.dim(` \u21B3 ${truncated}
4174
4319
  `));
4175
- resolve3(true);
4320
+ resolve4(true);
4176
4321
  return;
4177
4322
  }
4178
4323
  if (opts.onCountdownTick && remaining !== lastTickedSecond) {
@@ -4183,7 +4328,7 @@ ${color6.cyan("\u23F3 Auto")} ${color6.dim("(Ctrl+C to cancel)")}
4183
4328
  opts.renderer.write(
4184
4329
  color6.yellow(" \u21B3 Countdown cancelled \u2014 switching to manual mode\n")
4185
4330
  );
4186
- resolve3(false);
4331
+ resolve4(false);
4187
4332
  return;
4188
4333
  }
4189
4334
  } catch {
@@ -4215,7 +4360,7 @@ async function runContextCompaction(opts, _signal) {
4215
4360
 
4216
4361
  // src/repl-client-registration.ts
4217
4362
  import * as crypto from "node:crypto";
4218
- import * as path12 from "node:path";
4363
+ import * as path13 from "node:path";
4219
4364
  import { getSharedProjectMailbox, resolveProjectDir } from "@wrongstack/core/coordination";
4220
4365
  import { wstackGlobalRoot } from "@wrongstack/core/utils";
4221
4366
  function registerReplClient(opts) {
@@ -4225,7 +4370,7 @@ function registerReplClient(opts) {
4225
4370
  const hqConnection = startCliHqConnection({
4226
4371
  clientKind: "repl",
4227
4372
  projectRoot: replProjectRoot,
4228
- projectName: path12.basename(replProjectRoot),
4373
+ projectName: path13.basename(replProjectRoot),
4229
4374
  appConfig: opts.appConfig,
4230
4375
  capabilities: ["telemetry.publish", "mailbox.summary"]
4231
4376
  });
@@ -4239,7 +4384,7 @@ function registerReplClient(opts) {
4239
4384
  clientMailbox.registerClient({
4240
4385
  clientId,
4241
4386
  sessionId: opts.getSessionId?.() ?? replProjectRoot,
4242
- name: `REPL [${path12.basename(replProjectRoot)}]`,
4387
+ name: `REPL [${path13.basename(replProjectRoot)}]`,
4243
4388
  source: "repl",
4244
4389
  pid: process.pid
4245
4390
  }).then(() => {
@@ -4379,7 +4524,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
4379
4524
  } catch (err) {
4380
4525
  opts.renderer.writeError(`[eternal] ${toErrorMessage2(err)}`);
4381
4526
  }
4382
- await new Promise((resolve3) => setTimeout(resolve3, 250));
4527
+ await new Promise((resolve4) => setTimeout(resolve4, 250));
4383
4528
  return true;
4384
4529
  }
4385
4530
  if (autonomy === "eternal-parallel") {
@@ -4454,7 +4599,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
4454
4599
  } catch (err) {
4455
4600
  opts.renderer.writeError(`[parallel] ${toErrorMessage2(err)}`);
4456
4601
  }
4457
- await new Promise((resolve3) => setTimeout(resolve3, 250));
4602
+ await new Promise((resolve4) => setTimeout(resolve4, 250));
4458
4603
  return true;
4459
4604
  }
4460
4605
  return false;
@@ -5236,8 +5381,8 @@ async function profileMenu(store, paths) {
5236
5381
  }
5237
5382
  const items = await Promise.all(
5238
5383
  names.map(async (name) => {
5239
- const path14 = paths.profileConfig(name);
5240
- const data = await readJsonObjectFile(path14);
5384
+ const path15 = paths.profileConfig(name);
5385
+ const data = await readJsonObjectFile(path15);
5241
5386
  const provider = typeof data["provider"] === "string" ? data["provider"] : "unset";
5242
5387
  const model = typeof data["model"] === "string" ? data["model"] : "unset";
5243
5388
  const fallbackCount = Array.isArray(data["fallbackModels"]) ? data["fallbackModels"].length : 0;
@@ -5258,7 +5403,7 @@ async function profileMenu(store, paths) {
5258
5403
  },
5259
5404
  { label: "fallbacks", value: String(fallbackCount) },
5260
5405
  { label: "fallback profiles", value: String(profileCount) },
5261
- { label: "config", value: path14 }
5406
+ { label: "config", value: path15 }
5262
5407
  ],
5263
5408
  body: isActive ? "This profile owns the current session configuration." : "Switching profiles closes this session so every service restarts with the selected configuration.",
5264
5409
  actions: isActive ? [] : [{ key: "s", label: "switch", command: `/profile switch ${name}`, confirm: true }]
@@ -5333,7 +5478,7 @@ async function memoryMenu(store) {
5333
5478
  emptyText: "No memories found.",
5334
5479
  items: entries.map((entry, index) => ({
5335
5480
  id: `${entry.ts}:${index}`,
5336
- label: truncate(entry.text.replace(/\s+/g, " "), 52),
5481
+ label: truncate2(entry.text.replace(/\s+/g, " "), 52),
5337
5482
  status: entry.priority === "critical" || entry.priority === "high" ? "warn" : "muted",
5338
5483
  summary: `${entry.scope} \xB7 ${entry.type ?? "fact"}`,
5339
5484
  details: [
@@ -5388,19 +5533,19 @@ async function gitMenu(projectRoot) {
5388
5533
  },
5389
5534
  ...lines.map((line, index) => {
5390
5535
  const code = line.slice(0, 2);
5391
- const path14 = line.slice(3);
5536
+ const path15 = line.slice(3);
5392
5537
  const staged = code[0] !== " " && code[0] !== "?";
5393
5538
  const unstaged = code[1] !== " " || code === "??";
5394
5539
  return {
5395
- id: `change:${index}:${path14}`,
5396
- label: path14,
5540
+ id: `change:${index}:${path15}`,
5541
+ label: path15,
5397
5542
  status: staged ? "good" : "warn",
5398
5543
  summary: `${code} \xB7 ${staged ? "staged" : "not staged"}${unstaged ? " \xB7 working tree" : ""}`,
5399
5544
  details: [
5400
5545
  { label: "status", value: code },
5401
5546
  { label: "staged", value: staged ? "yes" : "no" },
5402
5547
  { label: "unstaged", value: unstaged ? "yes" : "no" },
5403
- { label: "path", value: path14 }
5548
+ { label: "path", value: path15 }
5404
5549
  ],
5405
5550
  actions: [
5406
5551
  { key: "d", label: "diff summary", command: staged ? "/git diff --staged" : "/git diff" }
@@ -5429,20 +5574,20 @@ async function worktreeMenu(projectRoot) {
5429
5574
  return split < 0 ? [line, "yes"] : [line.slice(0, split), line.slice(split + 1)];
5430
5575
  })
5431
5576
  );
5432
- const path14 = fields["worktree"] ?? "(unknown path)";
5577
+ const path15 = fields["worktree"] ?? "(unknown path)";
5433
5578
  const branchRef = fields["branch"];
5434
5579
  const branch = branchRef?.replace(/^refs\/heads\//, "") ?? (fields["detached"] ? "(detached)" : "(bare)");
5435
- const status = path14 === "(unknown path)" || fields["prunable"] ? null : await runGit(["status", "--porcelain=v1"], path14);
5580
+ const status = path15 === "(unknown path)" || fields["prunable"] ? null : await runGit(["status", "--porcelain=v1"], path15);
5436
5581
  const changes = status?.code === 0 ? status.stdout.split(/\r?\n/).filter(Boolean) : [];
5437
5582
  const dirty = changes.length > 0;
5438
5583
  const isMain = index === 0;
5439
5584
  return {
5440
- id: path14,
5585
+ id: path15,
5441
5586
  label: branch,
5442
5587
  status: fields["prunable"] ? "bad" : dirty ? "warn" : "good",
5443
5588
  summary: `${isMain ? "main" : "linked"} \xB7 ${dirty ? `${changes.length} changes` : "clean"}`,
5444
5589
  details: [
5445
- { label: "path", value: path14 },
5590
+ { label: "path", value: path15 },
5446
5591
  { label: "branch", value: branch },
5447
5592
  { label: "HEAD", value: fields["HEAD"]?.slice(0, 12) ?? "unknown" },
5448
5593
  { label: "working tree", value: dirty ? `${changes.length} changed paths` : "clean" },
@@ -5480,7 +5625,7 @@ async function worktreeMenu(projectRoot) {
5480
5625
  function isRecord(value) {
5481
5626
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5482
5627
  }
5483
- function truncate(value, max) {
5628
+ function truncate2(value, max) {
5484
5629
  return value.length <= max ? value : `${value.slice(0, max - 1)}\u2026`;
5485
5630
  }
5486
5631
 
@@ -5915,7 +6060,11 @@ async function execute(deps) {
5915
6060
  restoredEvents,
5916
6061
  listSessions: async (limit = 20) => {
5917
6062
  if (!activeSessionStore) return [];
5918
- const summaries = await activeSessionStore.list(limit);
6063
+ const summaries = await selectPickerSessions(
6064
+ (poolLimit) => activeSessionStore.list(poolLimit),
6065
+ wpaths.projectSessions,
6066
+ limit
6067
+ );
5919
6068
  const currentId = agent.ctx.session?.id ?? session.id;
5920
6069
  return summaries.map((s) => ({
5921
6070
  id: s.id,
@@ -6035,7 +6184,7 @@ async function execute(deps) {
6035
6184
  attachments,
6036
6185
  effectiveMaxContext,
6037
6186
  getEffectiveMaxContext,
6038
- projectName: path13.basename(projectRoot) || void 0,
6187
+ projectName: path14.basename(projectRoot) || void 0,
6039
6188
  projectRoot,
6040
6189
  appConfig: config,
6041
6190
  getSessionId: () => agent.ctx.session?.id ?? session.id,
@@ -6094,4 +6243,4 @@ export {
6094
6243
  execute,
6095
6244
  resolveReviewerFallbackModels
6096
6245
  };
6097
- //# sourceMappingURL=execution-TYUXABWI.js.map
6246
+ //# sourceMappingURL=execution-ZEHK4II6.js.map
@@ -64,4 +64,4 @@ var exportCmd = async (args, deps) => {
64
64
  export {
65
65
  exportCmd
66
66
  };
67
- //# sourceMappingURL=export-CCUXRJOU.js.map
67
+ //# sourceMappingURL=export-ROG3DKTZ.js.map