@wrongstack/cli 1.0.19 → 1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/{acp-INCNOH42.js → acp-AJWSKWE5.js} +18 -7
  2. package/dist/arg-parser.d.ts +1 -0
  3. package/dist/{auth-YXK3EDUL.js → auth-GRBZ7Y3D.js} +61 -15
  4. package/dist/auth-menu/direct.d.ts +1 -0
  5. package/dist/auth-menu/local.d.ts +2 -0
  6. package/dist/auth-menu/oauth-menu.d.ts +3 -1
  7. package/dist/auth-menu/panel-service.d.ts +20 -0
  8. package/dist/{bench-YBU6BVQP.js → bench-N5K7Z5O3.js} +2 -2
  9. package/dist/boot/config-backup-recovery.d.ts +2 -1
  10. package/dist/boot/dispatch-webui.d.ts +11 -0
  11. package/dist/boot/short-circuit-desktop.d.ts +1 -0
  12. package/dist/boot/tui-project-picker-callback.d.ts +1 -1
  13. package/dist/boot/tui-settings-adapter.d.ts +15 -2
  14. package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
  15. package/dist/{chunk-6WRKAACA.js → chunk-2BKFWIER.js} +4 -2
  16. package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
  17. package/dist/chunk-3OCUS3VN.js +46 -0
  18. package/dist/chunk-424ORSE7.js +56 -0
  19. package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
  20. package/dist/chunk-BBHWW6LR.js +549 -0
  21. package/dist/{chunk-CJTBLTS4.js → chunk-BLD5DSVA.js} +4 -3
  22. package/dist/{chunk-KK2LB3ZS.js → chunk-DRM7PSW7.js} +9 -5
  23. package/dist/{chunk-XJ7K67PP.js → chunk-JF2MULWF.js} +17 -10
  24. package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
  25. package/dist/{chunk-RDHFXOJM.js → chunk-LFMVHT3R.js} +106 -57
  26. package/dist/chunk-LUMETJFO.js +171 -0
  27. package/dist/{chunk-C3Z4N6A6.js → chunk-MHEBWVXL.js} +6 -2
  28. package/dist/{chunk-2ENZU66X.js → chunk-PGKJ2OQP.js} +5 -5
  29. package/dist/{chunk-672UXYL3.js → chunk-QBBF7GIK.js} +2 -2
  30. package/dist/{chunk-DE7BZDNK.js → chunk-QFPQXKCG.js} +11 -3
  31. package/dist/chunk-R4QGL6GB.js +10 -0
  32. package/dist/chunk-S4FFHDJG.js +93 -0
  33. package/dist/chunk-SFBFYIOW.js +271 -0
  34. package/dist/{chunk-JX6KL7OF.js → chunk-SKPDE62W.js} +4 -3
  35. package/dist/{chunk-RMQNCHGO.js → chunk-U46QR4WR.js} +5 -9
  36. package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
  37. package/dist/chunk-YBUCXXYZ.js +36 -0
  38. package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
  39. package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
  40. package/dist/{chunk-YLQEGYV4.js → chunk-ZZRSG7VK.js} +14 -4
  41. package/dist/{cli-context-33F74CSZ.js → cli-context-34Q5IJRA.js} +121 -89
  42. package/dist/cli-entry-point.d.ts +2 -0
  43. package/dist/{cli-main-FNGMKPBA.js → cli-main-AELJDBGU.js} +1439 -1276
  44. package/dist/config-doctor.d.ts +10 -2
  45. package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
  46. package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-WIFJH3XH.js} +2 -2
  47. package/dist/execute-deps.d.ts +2 -1
  48. package/dist/{execution-A6WJLSOC.js → execution-PYC5FCS4.js} +303 -256
  49. package/dist/{hq-XQWQTRDA.js → hq-JTUTFI4L.js} +274 -258
  50. package/dist/hq-command-controller.d.ts +1 -1
  51. package/dist/{hq-server-IIBZQZU4.js → hq-server-PC7GZMPT.js} +2 -2
  52. package/dist/{hq-service-L5INQFM4.js → hq-service-NW56MUP2.js} +11 -4
  53. package/dist/index.d.ts +1 -1
  54. package/dist/index.js +17 -12
  55. package/dist/kanban-supervisor-67ECABTD.js +7 -0
  56. package/dist/live-settings-input.d.ts +7 -0
  57. package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-WDOCH6KR.js} +3 -3
  58. package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
  59. package/dist/modeldiag-36OGAL5C.js +828 -0
  60. package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-XE77MTGJ.js} +3 -3
  61. package/dist/permission-prompt-mirror.d.ts +1 -1
  62. package/dist/permission-prompt.d.ts +2 -2
  63. package/dist/plugin-config.d.ts +12 -0
  64. package/dist/plugin-management-types.d.ts +31 -0
  65. package/dist/plugin-management.d.ts +2 -30
  66. package/dist/plugin-package-install.d.ts +3 -0
  67. package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-S5LVGMBW.js} +6 -5
  68. package/dist/{plugins-WJLW6ULV.js → plugins-RHBIVLI7.js} +4 -3
  69. package/dist/provider-config-utils.d.ts +1 -6
  70. package/dist/{providers-models-LFNZ5WI7.js → providers-models-2CFG46RD.js} +41 -31
  71. package/dist/release-asset-download.d.ts +3 -0
  72. package/dist/services/dispatch-classifier.d.ts +39 -5
  73. package/dist/{sessions-config-UL45XKX7.js → sessions-config-IQUH2GXT.js} +13 -5
  74. package/dist/settings-menu.d.ts +2 -0
  75. package/dist/short-circuit-flags-SDT53OML.js +10 -0
  76. package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
  77. package/dist/skill-suggest-L2EVWB6R.js +290 -0
  78. package/dist/slash-commands/effort.d.ts +1 -1
  79. package/dist/slash-commands/fallback.d.ts +1 -1
  80. package/dist/slash-commands/gitid.d.ts +1 -1
  81. package/dist/slash-commands/jev.d.ts +4 -0
  82. package/dist/slash-commands/openai-quota.d.ts +15 -0
  83. package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
  84. package/dist/slash-commands/settings-keys.d.ts +2 -0
  85. package/dist/slash-commands/settings-reset.d.ts +6 -0
  86. package/dist/standalone-update-MW47J3AK.js +164 -0
  87. package/dist/standalone-update.d.ts +19 -0
  88. package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
  89. package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
  90. package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
  91. package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
  92. package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
  93. package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
  94. package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
  95. package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
  96. package/dist/subcommands/handlers/typesafe.d.ts +23 -0
  97. package/dist/{subcommands-XSLXMIDP.js → subcommands-ZTSIN7LG.js} +2 -2
  98. package/dist/typesafe-HVEVPA6R.js +316 -0
  99. package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
  100. package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
  101. package/dist/typesafe-topic-replay-4W73BOLV.js +218 -0
  102. package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
  103. package/dist/{update-5DPB4YD4.js → update-7XIOEXTD.js} +4 -3
  104. package/dist/{update-check-BS3DHTSI.js → update-check-2POMBHFB.js} +3 -2
  105. package/dist/update-check.d.ts +1 -1
  106. package/dist/version-help-WZ623NWM.js +10 -0
  107. package/dist/version.d.ts +3 -2
  108. package/dist/webui-client-observability.d.ts +7 -0
  109. package/dist/{webui-server-MRPGTTKL.js → webui-server-L2SICPTB.js} +158 -94
  110. package/dist/webui-server-options.d.ts +11 -0
  111. package/dist/webui-server.d.ts +15 -1
  112. package/dist/wiring/domain-glossary.d.ts +5 -4
  113. package/dist/wiring/plugins.d.ts +1 -1
  114. package/dist/wiring/provider-persisters.d.ts +24 -0
  115. package/dist/wiring/provider-runtime.d.ts +9 -1
  116. package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
  117. package/package.json +28 -28
  118. package/dist/chunk-2CZEORLV.js +0 -54
  119. package/dist/chunk-DR2OXU46.js +0 -174
  120. package/dist/chunk-JACOMTIH.js +0 -275
  121. package/dist/chunk-XJXDOF63.js +0 -28
  122. package/dist/modeldiag-CJSFHZ3J.js +0 -1356
  123. package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
  124. package/dist/version-help-WXI42PZ3.js +0 -10
@@ -7,10 +7,8 @@ import {
7
7
  } from "./chunk-OWNC7LMD.js";
8
8
  import {
9
9
  deriveFsAccessPair,
10
- filterSafeForProject,
11
- resolveActualTarget,
12
- resolvePersistPath
13
- } from "./chunk-JACOMTIH.js";
10
+ persistConfigSetting
11
+ } from "./chunk-SFBFYIOW.js";
14
12
  import "./chunk-WHOIR577.js";
15
13
  import {
16
14
  advanceToNextTask,
@@ -35,29 +33,33 @@ import {
35
33
  WEBUI_SESSION_CHILD_CAPABILITIES,
36
34
  writeWebuiSessionChildError,
37
35
  writeWebuiSessionChildReady
38
- } from "./chunk-GPPRNAKW.js";
36
+ } from "./chunk-ZMX5HRLI.js";
39
37
  import {
40
38
  terminalLink,
41
39
  terminalText
42
40
  } from "./chunk-HXJYHAR4.js";
43
- import {
44
- startCliHqConnection
45
- } from "./chunk-CJTBLTS4.js";
46
- import {
47
- CLI_VERSION
48
- } from "./chunk-XJXDOF63.js";
49
41
  import {
50
42
  activeProfileConfigPath
51
43
  } from "./chunk-YMXXOOFN.js";
44
+ import {
45
+ backupCurrent
46
+ } from "./chunk-WSTVGC2C.js";
47
+ import {
48
+ startCliHqConnection
49
+ } from "./chunk-BLD5DSVA.js";
52
50
  import {
53
51
  resolveActiveApiKey
54
- } from "./chunk-DR2OXU46.js";
52
+ } from "./chunk-LUMETJFO.js";
53
+ import {
54
+ CLI_VERSION
55
+ } from "./chunk-YBUCXXYZ.js";
55
56
 
56
57
  // src/execution.ts
57
- import * as path14 from "node:path";
58
+ import * as path13 from "node:path";
58
59
  import { effectiveFallbackChain as effectiveFallbackChain2, setQueuedMessagesSnapshot as setQueuedMessagesSnapshot2 } from "@wrongstack/core/agent";
59
60
  import { LeaderAutoWakeController } from "@wrongstack/core/coordination";
60
61
  import { updateReviewReportEvidence } from "@wrongstack/core/plugin";
62
+ import { noOpVault } from "@wrongstack/core/security";
61
63
  import { attachTodosCheckpoint as attachTodosCheckpoint2 } from "@wrongstack/core/storage";
62
64
  import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
63
65
  import { hasOpenTodos as hasOpenTodos3, mergeCustomModelDefs } from "@wrongstack/core/utils";
@@ -214,7 +216,7 @@ async function runWebUIDispatch(ctx) {
214
216
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
215
217
  agent.disableInteractiveConfirmation();
216
218
  renderer.setSilent(true);
217
- const { runWebUI } = await import("./webui-server-MRPGTTKL.js");
219
+ const { runWebUI } = await import("./webui-server-L2SICPTB.js");
218
220
  const flagValue = (names) => {
219
221
  for (const name of names) {
220
222
  if (!Object.hasOwn(flags, name)) continue;
@@ -269,7 +271,7 @@ async function runWebUIDispatch(ctx) {
269
271
  webuiPublicWsUrl = webuiSessionChild?.publicWsUrl ?? flagValue(["webui-public-ws-url", "public-ws-url"]) ?? process.env["WEBUI_PUBLIC_WS_URL"];
270
272
  webuiRequireToken = webuiSessionChild?.requireToken ?? flagBoolean(["webui-require-token", "require-token"]) ?? envFlag("WEBUI_REQUIRE_TOKEN");
271
273
  if (isSimpleUi) {
272
- const { ensureSimpleUiDistDir } = await import("./simpleui-dist-CXSIDAXZ.js");
274
+ const { ensureSimpleUiDistDir } = await import("./simpleui-dist-7BQISSEP.js");
273
275
  frontendDistDir = await ensureSimpleUiDistDir();
274
276
  }
275
277
  } catch (err) {
@@ -912,15 +914,16 @@ async function onProjectSelect(ctx, slug, kind) {
912
914
  const err2 = await switchProjectInPlace2(state.projectRoot, name);
913
915
  if (err2) renderer.write(color3.red(`Project switch failed: ${err2}
914
916
  `));
917
+ return err2;
915
918
  }
916
- return;
919
+ return null;
917
920
  }
918
921
  const { loadManifest, saveManifest } = await import("./project-manifest-7NSFVBM3.js");
919
922
  const manifest = await loadManifest(state.wpaths.globalConfig);
920
923
  const project = manifest.projects.find((p) => p.slug === slug);
921
- if (!project) return;
924
+ if (!project) return `Project not found: ${slug}`;
922
925
  const targetRoot = path4.resolve(project.root);
923
- if (path4.resolve(state.projectRoot) === targetRoot) return;
926
+ if (path4.resolve(state.projectRoot) === targetRoot) return null;
924
927
  const fleetStatus = director?.status();
925
928
  const fleetRunning = fleetStatus?.subagents.filter((a) => a.status === "running").length ?? 0;
926
929
  const eternalActive = getEternalEngine?.()?.currentState === "running";
@@ -947,11 +950,13 @@ ${parts.join("\n")}
947
950
  const err = await switchProjectInPlace2(targetRoot, project.name);
948
951
  if (err) renderer.write(color3.red(`Project switch failed: ${err}
949
952
  `));
953
+ return err;
950
954
  } catch (err) {
951
955
  renderer.write(
952
956
  color3.red(`Project switch failed: ${err instanceof Error ? err.message : String(err)}
953
957
  `)
954
958
  );
959
+ return err instanceof Error ? err.message : String(err);
955
960
  }
956
961
  }
957
962
 
@@ -960,6 +965,7 @@ import { spawn } from "node:child_process";
960
965
  import * as fs from "node:fs/promises";
961
966
  import { createRequire } from "node:module";
962
967
  import * as path5 from "node:path";
968
+ import { cliSpawnArgs } from "@wrongstack/core/utils";
963
969
  import { color as color4 } from "@wrongstack/core/utils";
964
970
  async function handleProjectSwitchSpawn(opts) {
965
971
  const PROJECT_SWITCH_EXIT_CODE = 42;
@@ -983,7 +989,7 @@ async function handleProjectSwitchSpawn(opts) {
983
989
  }
984
990
  }
985
991
  const nodeExe = process.execPath;
986
- const spawnArgs = [cliPath, "--no-interactive"];
992
+ const spawnArgs = cliSpawnArgs(cliPath, ["--no-interactive"]);
987
993
  if (resumeSessionId) spawnArgs.push("--resume", resumeSessionId);
988
994
  const child = spawn(nodeExe, spawnArgs, {
989
995
  cwd: root,
@@ -1211,8 +1217,12 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1211
1217
  );
1212
1218
  }
1213
1219
  await oldSessionStore?.dispose?.().catch(() => void 0);
1214
- const emitUntyped = events.emit;
1215
- emitUntyped("project.switched", { from: oldProjectRoot, to: resolved, name: displayName });
1220
+ events.emitCustom("project.switched", {
1221
+ from: oldProjectRoot,
1222
+ to: resolved,
1223
+ name: displayName,
1224
+ sessionId: nextWriter.id
1225
+ });
1216
1226
  return null;
1217
1227
  }
1218
1228
 
@@ -1499,11 +1509,16 @@ async function resumeSession(ctx, sessionId) {
1499
1509
  }
1500
1510
  setStage("restore_model");
1501
1511
  const currentProviderId = agent.ctx.provider.id;
1502
- const targetProviderId = typeof meta.provider === "string" && meta.provider.length > 0 ? meta.provider : currentProviderId;
1503
- const targetModel = typeof meta.model === "string" && meta.model.length > 0 ? meta.model : agent.ctx.model;
1512
+ const savedProvider = typeof meta.provider === "string" ? meta.provider.trim() : "";
1513
+ const savedModel = typeof meta.model === "string" ? meta.model.trim() : "";
1514
+ const hasSavedRoute = savedProvider.length > 0 && savedProvider.toLowerCase() !== "unknown" && savedModel.length > 0 && savedModel.toLowerCase() !== "unknown";
1515
+ const targetProviderId = hasSavedRoute ? savedProvider : currentProviderId;
1516
+ const targetModel = hasSavedRoute ? savedModel : agent.ctx.model;
1504
1517
  if (switchProviderAndModel && targetProviderId && (targetProviderId !== currentProviderId || targetModel !== agent.ctx.model)) {
1505
1518
  try {
1506
- await Promise.resolve(switchProviderAndModel(targetProviderId, targetModel));
1519
+ const error = await Promise.resolve(switchProviderAndModel(targetProviderId, targetModel));
1520
+ if (typeof error === "string" && error)
1521
+ warn(`could not restore ${targetProviderId}/${targetModel}`, error);
1507
1522
  } catch (err) {
1508
1523
  console.error(
1509
1524
  JSON.stringify({
@@ -1830,11 +1845,7 @@ async function enrichStubSummaries(summaries, sessionsDir) {
1830
1845
  }
1831
1846
 
1832
1847
  // src/boot/tui-settings-adapter.ts
1833
- import * as fs4 from "node:fs/promises";
1834
- import * as path9 from "node:path";
1835
- import { decryptConfigSecrets, encryptConfigSecrets, noOpVault } from "@wrongstack/core/security";
1836
1848
  import { normalizeTokenSavingTier, resolveFleetChatVerbosity } from "@wrongstack/core/types";
1837
- import { atomicWrite, deepMerge } from "@wrongstack/core/utils";
1838
1849
  import { getProcessRegistry } from "@wrongstack/tools";
1839
1850
  var PANEL_IDS_CLI = [
1840
1851
  "projectPicker",
@@ -1878,7 +1889,7 @@ function normalizeAnimationStyle(raw) {
1878
1889
  return typeof raw === "string" && ANIMATION_STYLES.includes(raw) ? raw : "rainbow";
1879
1890
  }
1880
1891
  function createSettingsAdapter(ctx) {
1881
- const { configStore, wpaths, fleetStreamController, applyLiveSettings } = ctx;
1892
+ const { configStore, wpaths, vault, fleetStreamController, applyLiveSettings } = ctx;
1882
1893
  const deriveFsAccess = deriveFsAccessPair;
1883
1894
  function getSettings() {
1884
1895
  const cfg = configStore.get();
@@ -1953,6 +1964,7 @@ function createSettingsAdapter(ctx) {
1953
1964
  toolResultViewMode: autonomy?.toolResultViewMode === "minimal" || autonomy?.toolResultViewMode === "full" ? autonomy.toolResultViewMode : "normal",
1954
1965
  showAgentSwarmPanel: coerceAgentSwarmMode(autonomy?.showAgentSwarmPanel),
1955
1966
  showSidebar: autonomy?.showSidebar ?? true,
1967
+ lastSettingsField: autonomy?.lastSettingsField ?? 0,
1956
1968
  // Migrate the legacy `autonomy.showAgentSwarmPanel: 'sidebar'` into
1957
1969
  // the new per-panel `panelPositions.fleet` map at the read boundary
1958
1970
  // so users with old configs (no `panelPositions` key on disk) get
@@ -1977,7 +1989,7 @@ function createSettingsAdapter(ctx) {
1977
1989
  }
1978
1990
  async function saveSettings(s) {
1979
1991
  try {
1980
- 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.multiDiffSummaryThreshold !== 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.preRefineSeconds !== 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.toolResultViewMode !== void 0 || s.showAgentSwarmPanel !== void 0 || s.showSidebar !== 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
1992
+ 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.multiDiffSummaryThreshold !== 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.preRefineSeconds !== 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.toolResultViewMode !== void 0 || s.showAgentSwarmPanel !== void 0 || s.showSidebar !== void 0 || s.panelPositions !== void 0 || s.lastSettingsField !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
1981
1993
  // either key being present in the live patch. Without this, a
1982
1994
  // picker toggle round-trip would silently no-op the persistence
1983
1995
  // layer (the runtime probe would never read the change).
@@ -1991,183 +2003,190 @@ function createSettingsAdapter(ctx) {
1991
2003
  // delegated; now it is.
1992
2004
  profileConfigPath: activeProfileConfigPath(wpaths, cfg),
1993
2005
  inProjectConfigPath: wpaths.inProjectConfig,
1994
- vault: noOpVault,
2006
+ vault,
1995
2007
  resolveProfilePath: (name) => wpaths.profileConfig(name)
1996
2008
  };
1997
- const targetPath = resolvePersistPath(persistDeps);
1998
- let raw;
1999
- try {
2000
- raw = await fs4.readFile(targetPath, "utf8");
2001
- } catch (err) {
2002
- if (err.code !== "ENOENT") {
2003
- throw new Error(
2004
- `Failed to read config at ${targetPath}: ${err instanceof Error ? err.message : String(err)}`,
2005
- { cause: err }
2006
- );
2009
+ let fsAccess;
2010
+ let decrypted = {};
2011
+ await persistConfigSetting(persistDeps, (nextConfig) => {
2012
+ decrypted = nextConfig;
2013
+ const autonomy = decrypted.autonomy ?? {};
2014
+ if (s.mode !== void 0) autonomy.defaultMode = s.mode;
2015
+ if (s.delayMs !== void 0) autonomy.autoProceedDelayMs = s.delayMs;
2016
+ if (s.titleAnimation !== void 0) autonomy.terminalTitleAnimation = s.titleAnimation;
2017
+ if (s.yolo !== void 0) autonomy.yolo = s.yolo;
2018
+ if (s.fleetChatVerbosity !== void 0) {
2019
+ autonomy.fleetChatVerbosity = s.fleetChatVerbosity;
2007
2020
  }
2008
- raw = "{}";
2009
- }
2010
- const parsed = JSON.parse(raw);
2011
- const decrypted = decryptConfigSecrets(parsed, noOpVault);
2012
- const autonomy = decrypted.autonomy ?? {};
2013
- if (s.mode !== void 0) autonomy.defaultMode = s.mode;
2014
- if (s.delayMs !== void 0) autonomy.autoProceedDelayMs = s.delayMs;
2015
- if (s.titleAnimation !== void 0) autonomy.terminalTitleAnimation = s.titleAnimation;
2016
- if (s.yolo !== void 0) autonomy.yolo = s.yolo;
2017
- if (s.fleetChatVerbosity !== void 0) {
2018
- autonomy.fleetChatVerbosity = s.fleetChatVerbosity;
2019
- }
2020
- if (s.chime !== void 0) autonomy.chime = s.chime;
2021
- if (s.confirmExit !== void 0) autonomy.confirmExit = s.confirmExit;
2022
- if (s.mouseMode !== void 0) autonomy.mouseMode = s.mouseMode;
2023
- if (s.enhanceDelayMs !== void 0) autonomy.enhanceDelayMs = s.enhanceDelayMs;
2024
- if (s.enhanceEnabled !== void 0) autonomy.enhance = s.enhanceEnabled;
2025
- if (s.preRefineSeconds !== void 0) autonomy.preRefineSeconds = s.preRefineSeconds;
2026
- if (s.enhanceLanguage !== void 0) autonomy.enhanceLanguage = s.enhanceLanguage;
2027
- if (s.midRunSendPicker !== void 0) autonomy.midRunSendPicker = s.midRunSendPicker;
2028
- if (s.shellBangWarningDontShowAgain !== void 0)
2029
- autonomy.shellBangWarningDontShowAgain = s.shellBangWarningDontShowAgain;
2030
- if (s.statuslineMode !== void 0) autonomy.statuslineMode = s.statuslineMode;
2031
- if (s.thinkingWord !== void 0)
2032
- autonomy.thinkingWord = normalizeTuiThinkingWord(s.thinkingWord);
2033
- if (s.animationStyle !== void 0) autonomy.animationStyle = s.animationStyle;
2034
- if (s.showModelReasoning !== void 0) autonomy.showModelReasoning = s.showModelReasoning;
2035
- if (s.toolResultViewMode !== void 0) autonomy.toolResultViewMode = s.toolResultViewMode;
2036
- if (s.showAgentSwarmPanel !== void 0)
2037
- autonomy.showAgentSwarmPanel = s.showAgentSwarmPanel;
2038
- if (s.showSidebar !== void 0) autonomy.showSidebar = s.showSidebar;
2039
- if (s.panelPositions !== void 0) autonomy.panelPositions = s.panelPositions;
2040
- if (s.showSageMemoryInject !== void 0)
2041
- autonomy.showSageMemoryInject = s.showSageMemoryInject;
2042
- if (s.readSymbols !== void 0) autonomy.readAdvancedMode = s.readSymbols;
2043
- if (s.autonomyNextPrompt !== void 0) autonomy.autonomyNextPrompt = s.autonomyNextPrompt;
2044
- if (s.autoProceedMaxIterations !== void 0)
2045
- autonomy.autoProceedMaxIterations = s.autoProceedMaxIterations;
2046
- decrypted.autonomy = autonomy;
2047
- if (s.nextPrediction !== void 0) decrypted.nextPrediction = s.nextPrediction;
2048
- if (s.yolo !== void 0) decrypted.yolo = s.yolo;
2049
- const fsAccess = deriveFsAccess(s);
2050
- if (s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || fsAccess !== void 0) {
2051
- const feats = decrypted.features ?? {};
2052
- if (s.featureMcp !== void 0) feats.mcp = s.featureMcp;
2053
- if (s.featurePlugins !== void 0) feats.plugins = s.featurePlugins;
2054
- if (s.featureMemory !== void 0) feats.memory = s.featureMemory;
2055
- if (s.featureSkills !== void 0) feats.skills = s.featureSkills;
2056
- if (s.featureModelsRegistry !== void 0) feats.modelsRegistry = s.featureModelsRegistry;
2057
- if (s.featureTokenSaving !== void 0) feats.tokenSavingMode = s.featureTokenSaving;
2058
- if (fsAccess !== void 0)
2059
- feats.allowOutsideProjectRoot = fsAccess.allowOutsideProjectRoot;
2060
- decrypted.features = feats;
2061
- }
2062
- if (s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0) {
2063
- const c = decrypted.context ?? {};
2064
- if (s.contextAutoCompact !== void 0) c.autoCompact = s.contextAutoCompact;
2065
- if (s.contextStrategy !== void 0) c.strategy = s.contextStrategy;
2066
- if (s.contextMode !== void 0) c.mode = s.contextMode;
2067
- decrypted.context = c;
2068
- }
2069
- if (s.maxConcurrent !== void 0) decrypted.maxConcurrent = s.maxConcurrent;
2070
- if (s.logLevel !== void 0) {
2071
- const log = decrypted.log ?? {};
2072
- log.level = s.logLevel;
2073
- decrypted.log = log;
2074
- }
2075
- if (s.auditLevel !== void 0) {
2076
- const sess = decrypted.session ?? {};
2077
- sess.auditLevel = s.auditLevel;
2078
- decrypted.session = sess;
2079
- }
2080
- if (s.indexOnStart !== void 0) {
2081
- const idx = decrypted.indexing ?? {};
2082
- idx.onSessionStart = s.indexOnStart;
2083
- decrypted.indexing = idx;
2084
- }
2085
- if (s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 || // WrongProxy / WrongTrace: include either key in the tools-section
2086
- // write guard so a picker toggle round-trip actually persists to
2087
- // `tools.wrongProxy.{enabled,url}`. Without this, the gate at
2088
- // line 279 would short-circuit and skip the whole section write.
2089
- s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
2090
- const tools = decrypted.tools ?? {};
2091
- if (s.maxIterations !== void 0) tools.maxIterations = s.maxIterations;
2092
- if (s.multiDiffSummaryThreshold !== void 0) {
2093
- tools.multiDiffSummaryThreshold = s.multiDiffSummaryThreshold;
2021
+ if (s.chime !== void 0) autonomy.chime = s.chime;
2022
+ if (s.confirmExit !== void 0) autonomy.confirmExit = s.confirmExit;
2023
+ if (s.mouseMode !== void 0) autonomy.mouseMode = s.mouseMode;
2024
+ if (s.enhanceDelayMs !== void 0) autonomy.enhanceDelayMs = s.enhanceDelayMs;
2025
+ if (s.enhanceEnabled !== void 0) autonomy.enhance = s.enhanceEnabled;
2026
+ if (s.preRefineSeconds !== void 0) autonomy.preRefineSeconds = s.preRefineSeconds;
2027
+ if (s.enhanceLanguage !== void 0) autonomy.enhanceLanguage = s.enhanceLanguage;
2028
+ if (s.midRunSendPicker !== void 0) autonomy.midRunSendPicker = s.midRunSendPicker;
2029
+ if (s.shellBangWarningDontShowAgain !== void 0)
2030
+ autonomy.shellBangWarningDontShowAgain = s.shellBangWarningDontShowAgain;
2031
+ if (s.statuslineMode !== void 0) autonomy.statuslineMode = s.statuslineMode;
2032
+ if (s.thinkingWord !== void 0)
2033
+ autonomy.thinkingWord = normalizeTuiThinkingWord(s.thinkingWord);
2034
+ if (s.animationStyle !== void 0) autonomy.animationStyle = s.animationStyle;
2035
+ if (s.showModelReasoning !== void 0)
2036
+ autonomy.showModelReasoning = s.showModelReasoning;
2037
+ if (s.toolResultViewMode !== void 0)
2038
+ autonomy.toolResultViewMode = s.toolResultViewMode;
2039
+ if (s.showAgentSwarmPanel !== void 0)
2040
+ autonomy.showAgentSwarmPanel = s.showAgentSwarmPanel;
2041
+ if (s.showSidebar !== void 0) autonomy.showSidebar = s.showSidebar;
2042
+ if (s.panelPositions !== void 0) autonomy.panelPositions = s.panelPositions;
2043
+ if (s.lastSettingsField !== void 0) autonomy.lastSettingsField = s.lastSettingsField;
2044
+ if (s.showSageMemoryInject !== void 0)
2045
+ autonomy.showSageMemoryInject = s.showSageMemoryInject;
2046
+ if (s.readSymbols !== void 0) autonomy.readAdvancedMode = s.readSymbols;
2047
+ if (s.autonomyNextPrompt !== void 0)
2048
+ autonomy.autonomyNextPrompt = s.autonomyNextPrompt;
2049
+ if (s.autoProceedMaxIterations !== void 0)
2050
+ autonomy.autoProceedMaxIterations = s.autoProceedMaxIterations;
2051
+ decrypted.autonomy = autonomy;
2052
+ if (s.nextPrediction !== void 0) decrypted.nextPrediction = s.nextPrediction;
2053
+ if (s.yolo !== void 0) decrypted.yolo = s.yolo;
2054
+ fsAccess = deriveFsAccess(s);
2055
+ if (s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || fsAccess !== void 0) {
2056
+ const feats = decrypted.features ?? {};
2057
+ if (s.featureMcp !== void 0) feats.mcp = s.featureMcp;
2058
+ if (s.featurePlugins !== void 0) feats.plugins = s.featurePlugins;
2059
+ if (s.featureMemory !== void 0) feats.memory = s.featureMemory;
2060
+ if (s.featureSkills !== void 0) feats.skills = s.featureSkills;
2061
+ if (s.featureModelsRegistry !== void 0)
2062
+ feats.modelsRegistry = s.featureModelsRegistry;
2063
+ if (s.featureTokenSaving !== void 0) feats.tokenSavingMode = s.featureTokenSaving;
2064
+ if (fsAccess !== void 0)
2065
+ feats.allowOutsideProjectRoot = fsAccess.allowOutsideProjectRoot;
2066
+ decrypted.features = feats;
2094
2067
  }
2095
- if (s.nextStepsTool !== void 0) tools.nextsteps = { enabled: s.nextStepsTool };
2096
- if (fsAccess !== void 0) tools.restrictToProjectRoot = fsAccess.restrictToProjectRoot;
2097
- if (s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
2098
- const wp = tools.wrongProxy ?? {};
2099
- if (s.wrongProxyEnabled !== void 0) wp.enabled = s.wrongProxyEnabled;
2100
- if (s.wrongProxyUrl !== void 0) wp.url = s.wrongProxyUrl;
2101
- tools.wrongProxy = wp;
2068
+ if (s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0) {
2069
+ const c = decrypted.context ?? {};
2070
+ if (s.contextAutoCompact !== void 0) c.autoCompact = s.contextAutoCompact;
2071
+ if (s.contextStrategy !== void 0) c.strategy = s.contextStrategy;
2072
+ if (s.contextMode !== void 0) c.mode = s.contextMode;
2073
+ decrypted.context = c;
2102
2074
  }
2103
- decrypted.tools = tools;
2104
- }
2105
- if (s.debugStream !== void 0) {
2106
- decrypted.debugStream = s.debugStream;
2107
- const { setDebugStreamEnabled } = await import("@wrongstack/providers");
2108
- setDebugStreamEnabled(s.debugStream);
2109
- }
2110
- if (s.configScope !== void 0) decrypted.configScope = s.configScope;
2111
- if (s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0) {
2112
- const modelRuntime = decrypted.modelRuntime ?? {};
2113
- if (s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0) {
2114
- const reasoning = modelRuntime.reasoning ?? {};
2115
- if (s.reasoningMode !== void 0) reasoning.mode = s.reasoningMode;
2116
- if (s.reasoningEffort !== void 0) reasoning.effort = s.reasoningEffort;
2117
- if (s.reasoningPreserve !== void 0) reasoning.preserve = s.reasoningPreserve;
2118
- modelRuntime.reasoning = reasoning;
2075
+ if (s.maxConcurrent !== void 0) decrypted.maxConcurrent = s.maxConcurrent;
2076
+ if (s.logLevel !== void 0) {
2077
+ const log = decrypted.log ?? {};
2078
+ log.level = s.logLevel;
2079
+ decrypted.log = log;
2119
2080
  }
2120
- if (s.cacheTtl !== void 0) {
2121
- const cache = modelRuntime.cache ?? {};
2122
- if (s.cacheTtl === "default") {
2123
- delete cache.ttl;
2124
- } else {
2125
- cache.ttl = s.cacheTtl;
2081
+ if (s.auditLevel !== void 0) {
2082
+ const sess = decrypted.session ?? {};
2083
+ sess.auditLevel = s.auditLevel;
2084
+ decrypted.session = sess;
2085
+ }
2086
+ if (s.indexOnStart !== void 0) {
2087
+ const idx = decrypted.indexing ?? {};
2088
+ idx.onSessionStart = s.indexOnStart;
2089
+ decrypted.indexing = idx;
2090
+ }
2091
+ if (s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 || // WrongProxy / WrongTrace: include either key in the tools-section
2092
+ // write guard so a picker toggle round-trip actually persists to
2093
+ // `tools.wrongProxy.{enabled,url}`. Without this, the gate at
2094
+ // line 279 would short-circuit and skip the whole section write.
2095
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
2096
+ const tools = decrypted.tools ?? {};
2097
+ if (s.maxIterations !== void 0) tools.maxIterations = s.maxIterations;
2098
+ if (s.multiDiffSummaryThreshold !== void 0) {
2099
+ tools.multiDiffSummaryThreshold = s.multiDiffSummaryThreshold;
2100
+ }
2101
+ if (s.nextStepsTool !== void 0) tools.nextsteps = { enabled: s.nextStepsTool };
2102
+ if (fsAccess !== void 0)
2103
+ tools.restrictToProjectRoot = fsAccess.restrictToProjectRoot;
2104
+ if (s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
2105
+ const wp = tools.wrongProxy ?? {};
2106
+ if (s.wrongProxyEnabled !== void 0) wp.enabled = s.wrongProxyEnabled;
2107
+ if (s.wrongProxyUrl !== void 0) wp.url = s.wrongProxyUrl;
2108
+ tools.wrongProxy = wp;
2126
2109
  }
2127
- if (Object.keys(cache).length > 0) modelRuntime.cache = cache;
2128
- else delete modelRuntime.cache;
2110
+ decrypted.tools = tools;
2129
2111
  }
2130
- decrypted.modelRuntime = modelRuntime;
2131
- }
2132
- if (s.sageMemoryInjectThreshold !== void 0) {
2133
- const sageSec = decrypted.Sage ?? {};
2134
- const inject = sageSec.inject ?? {};
2135
- inject.relationFloor = s.sageMemoryInjectThreshold;
2136
- sageSec.inject = inject;
2137
- decrypted.Sage = sageSec;
2138
- }
2139
- if (s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0) {
2140
- const cb = decrypted.circuitBreaker ?? {};
2141
- if (s.breakerEnabled !== void 0) cb.enabled = s.breakerEnabled;
2142
- if (s.breakerAutoKillResetMs !== void 0) cb.autoKillResetMs = s.breakerAutoKillResetMs;
2143
- decrypted.circuitBreaker = cb;
2144
- }
2145
- const actualTarget = resolveActualTarget(
2146
- persistDeps,
2147
- decrypted,
2148
- targetPath
2149
- );
2150
- let mergedToWrite = decrypted;
2151
- if (actualTarget !== targetPath) {
2152
- try {
2153
- const destRaw = await fs4.readFile(actualTarget, "utf8");
2154
- const destParsed = JSON.parse(destRaw);
2155
- const destDecrypted = decryptConfigSecrets(destParsed, noOpVault);
2156
- mergedToWrite = deepMerge(destDecrypted, decrypted);
2157
- } catch (err) {
2158
- if (err.code !== "ENOENT") {
2159
- throw new Error(
2160
- `Failed to read destination config at ${actualTarget}: ${err instanceof Error ? err.message : String(err)}`,
2161
- { cause: err }
2162
- );
2112
+ if (s.debugStream !== void 0) {
2113
+ decrypted.debugStream = s.debugStream;
2114
+ }
2115
+ if (s.configScope !== void 0) decrypted.configScope = s.configScope;
2116
+ if (s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0) {
2117
+ const modelRuntime = decrypted.modelRuntime ?? {};
2118
+ if (s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0) {
2119
+ const reasoning = modelRuntime.reasoning ?? {};
2120
+ if (s.reasoningMode !== void 0) reasoning.mode = s.reasoningMode;
2121
+ if (s.reasoningEffort !== void 0) reasoning.effort = s.reasoningEffort;
2122
+ if (s.reasoningPreserve !== void 0) reasoning.preserve = s.reasoningPreserve;
2123
+ modelRuntime.reasoning = reasoning;
2124
+ }
2125
+ if (s.cacheTtl !== void 0) {
2126
+ const cache = modelRuntime.cache ?? {};
2127
+ if (s.cacheTtl === "default") {
2128
+ delete cache.ttl;
2129
+ } else {
2130
+ cache.ttl = s.cacheTtl;
2131
+ }
2132
+ if (Object.keys(cache).length > 0) modelRuntime.cache = cache;
2133
+ else delete modelRuntime.cache;
2163
2134
  }
2135
+ decrypted.modelRuntime = modelRuntime;
2164
2136
  }
2137
+ if (s.sageMemoryInjectThreshold !== void 0) {
2138
+ const sageSec = decrypted.Sage ?? {};
2139
+ const inject = sageSec.inject ?? {};
2140
+ inject.relationFloor = s.sageMemoryInjectThreshold;
2141
+ sageSec.inject = inject;
2142
+ decrypted.Sage = sageSec;
2143
+ }
2144
+ if (s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0) {
2145
+ const cb = decrypted.circuitBreaker ?? {};
2146
+ if (s.breakerEnabled !== void 0) cb.enabled = s.breakerEnabled;
2147
+ if (s.breakerAutoKillResetMs !== void 0)
2148
+ cb.autoKillResetMs = s.breakerAutoKillResetMs;
2149
+ decrypted.circuitBreaker = cb;
2150
+ }
2151
+ });
2152
+ const effectiveScope = s.configScope ?? cfg.configScope;
2153
+ const hasProfileOnlySettings = s.mode !== void 0 || s.yolo !== void 0 || fsAccess !== void 0 || s.maxIterations !== void 0 || s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0;
2154
+ if (effectiveScope === "project" && hasProfileOnlySettings) {
2155
+ await persistConfigSetting(
2156
+ { ...persistDeps, forceGlobal: true, updateStore: false },
2157
+ (profileConfig) => {
2158
+ if (s.mode !== void 0 || s.yolo !== void 0) {
2159
+ const autonomy = profileConfig.autonomy ?? {};
2160
+ if (s.mode !== void 0) autonomy.defaultMode = s.mode;
2161
+ if (s.yolo !== void 0) autonomy.yolo = s.yolo;
2162
+ profileConfig.autonomy = autonomy;
2163
+ }
2164
+ if (s.yolo !== void 0) profileConfig.yolo = s.yolo;
2165
+ if (fsAccess !== void 0) {
2166
+ const features = profileConfig.features ?? {};
2167
+ features.allowOutsideProjectRoot = fsAccess.allowOutsideProjectRoot;
2168
+ profileConfig.features = features;
2169
+ }
2170
+ if (fsAccess !== void 0 || s.maxIterations !== void 0 || s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
2171
+ const tools = profileConfig.tools ?? {};
2172
+ if (fsAccess !== void 0)
2173
+ tools.restrictToProjectRoot = fsAccess.restrictToProjectRoot;
2174
+ if (s.maxIterations !== void 0) tools.maxIterations = s.maxIterations;
2175
+ if (s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
2176
+ const wrongProxy = tools.wrongProxy ?? {};
2177
+ if (s.wrongProxyEnabled !== void 0) wrongProxy.enabled = s.wrongProxyEnabled;
2178
+ if (s.wrongProxyUrl !== void 0) wrongProxy.url = s.wrongProxyUrl;
2179
+ tools.wrongProxy = wrongProxy;
2180
+ }
2181
+ profileConfig.tools = tools;
2182
+ }
2183
+ }
2184
+ );
2185
+ }
2186
+ if (s.debugStream !== void 0) {
2187
+ const { setDebugStreamEnabled } = await import("@wrongstack/providers");
2188
+ setDebugStreamEnabled(s.debugStream);
2165
2189
  }
2166
- const isProjectTarget = actualTarget === wpaths.inProjectConfig;
2167
- const toWrite = isProjectTarget ? filterSafeForProject(mergedToWrite) : mergedToWrite;
2168
- const encrypted = encryptConfigSecrets(toWrite, noOpVault);
2169
- await fs4.mkdir(path9.dirname(actualTarget), { recursive: true });
2170
- await atomicWrite(actualTarget, JSON.stringify(encrypted, null, 2), { mode: 384 });
2171
2190
  const currentConfig = configStore.get();
2172
2191
  const nextModelRuntime = {
2173
2192
  ...currentConfig.modelRuntime,
@@ -2276,10 +2295,10 @@ function createSettingsAdapter(ctx) {
2276
2295
  }
2277
2296
 
2278
2297
  // src/boot/tui-theme-adapter.ts
2279
- import * as fs5 from "node:fs/promises";
2280
- import * as path10 from "node:path";
2298
+ import * as fs4 from "node:fs/promises";
2299
+ import * as path9 from "node:path";
2281
2300
  import { THEME_PRESET_IDS } from "@wrongstack/core/types";
2282
- import { atomicWrite as atomicWrite2 } from "@wrongstack/core/utils";
2301
+ import { updateJsonObjectFile } from "@wrongstack/core/utils";
2283
2302
  var VALID_PRESETS = new Set(THEME_PRESET_IDS);
2284
2303
  function createThemeAdapter({ configStore, wpaths }) {
2285
2304
  return {
@@ -2292,21 +2311,13 @@ function createThemeAdapter({ configStore, wpaths }) {
2292
2311
  if (!VALID_PRESETS.has(preset)) {
2293
2312
  throw new Error(`Unknown theme preset: ${preset}`);
2294
2313
  }
2295
- configStore.update({ themePreset: preset });
2296
2314
  const configPath = activeProfileConfigPath(wpaths, configStore.get());
2297
- let parsed = {};
2298
- try {
2299
- const raw = await fs5.readFile(configPath, "utf8");
2300
- parsed = JSON.parse(raw);
2301
- } catch (err) {
2302
- const e = err;
2303
- if (e.code !== "ENOENT") {
2304
- throw err;
2305
- }
2306
- }
2307
- parsed.themePreset = preset;
2308
- await fs5.mkdir(path10.dirname(configPath), { recursive: true });
2309
- await atomicWrite2(configPath, JSON.stringify(parsed, null, 2), { mode: 384 });
2315
+ await fs4.mkdir(path9.dirname(configPath), { recursive: true });
2316
+ await updateJsonObjectFile(configPath, async (config) => {
2317
+ await backupCurrent(void 0, configPath);
2318
+ config.themePreset = preset;
2319
+ });
2320
+ configStore.update({ themePreset: preset });
2310
2321
  }
2311
2322
  };
2312
2323
  }
@@ -2915,32 +2926,45 @@ ${loaded.join("\n\n")}`;
2915
2926
  }
2916
2927
  }
2917
2928
  void (async () => {
2918
- const built = await sddSubagentFactory({
2919
- id: subagentId,
2920
- name,
2921
- role: "kanban-agent",
2922
- prompt: agentDescription,
2923
- allowedCapabilities: spawnOpts?.allowedCapabilities ?? WIDE_SUBAGENT_CAPABILITIES,
2924
- ...resolvedProvider ? { provider: resolvedProvider } : {},
2925
- ...resolvedModel ? { model: resolvedModel } : {},
2926
- ...resolvedFallbackModels ? { fallbackModels: resolvedFallbackModels } : {},
2927
- ...spawnOpts?.tools ? { tools: spawnOpts.tools } : {}
2928
- });
2929
+ let built;
2930
+ let completionReported = false;
2929
2931
  try {
2930
- const result = await built.agent.run(agentDescription);
2932
+ if (spawnOpts?.signal?.aborted) throw new Error("Kanban dispatch cancelled.");
2933
+ built = await sddSubagentFactory(
2934
+ {
2935
+ id: subagentId,
2936
+ name,
2937
+ role: "kanban-agent",
2938
+ prompt: agentDescription,
2939
+ allowedCapabilities: spawnOpts?.allowedCapabilities ?? WIDE_SUBAGENT_CAPABILITIES,
2940
+ ...resolvedProvider ? { provider: resolvedProvider } : {},
2941
+ ...resolvedModel ? { model: resolvedModel } : {},
2942
+ ...resolvedFallbackModels ? { fallbackModels: resolvedFallbackModels } : {},
2943
+ ...spawnOpts?.tools ? { tools: spawnOpts.tools } : {}
2944
+ },
2945
+ ...spawnOpts?.context ? [{ id: taskId, description: agentDescription, context: spawnOpts.context }] : []
2946
+ );
2947
+ if (spawnOpts?.signal?.aborted) throw new Error("Kanban dispatch cancelled.");
2948
+ const result = await built.agent.run(
2949
+ agentDescription,
2950
+ ...spawnOpts?.signal ? [{ signal: spawnOpts.signal }] : []
2951
+ );
2952
+ completionReported = true;
2931
2953
  await spawnOpts?.onDone?.({
2932
2954
  status: result.status === "done" ? "completed" : "failed",
2933
2955
  result: result.finalText,
2934
2956
  ..."error" in result && result.error?.message ? { error: result.error.message } : {}
2935
2957
  });
2936
2958
  } catch (err) {
2937
- await spawnOpts?.onDone?.({
2938
- status: "failed",
2939
- error: err instanceof Error ? err.message : String(err)
2940
- });
2959
+ if (!completionReported) {
2960
+ await spawnOpts?.onDone?.({
2961
+ status: "failed",
2962
+ error: err instanceof Error ? err.message : String(err)
2963
+ });
2964
+ }
2941
2965
  throw err;
2942
2966
  } finally {
2943
- await built.dispose?.();
2967
+ await built?.dispose?.();
2944
2968
  }
2945
2969
  })().catch((err) => {
2946
2970
  events.emit("error", {
@@ -3324,7 +3348,7 @@ function createChimeraWorkRegistry() {
3324
3348
 
3325
3349
  // src/execution-chimera-cascade.ts
3326
3350
  import * as fsp from "node:fs/promises";
3327
- import * as path11 from "node:path";
3351
+ import * as path10 from "node:path";
3328
3352
  import { emitReviewIfChanged } from "@wrongstack/core/plugin";
3329
3353
 
3330
3354
  // src/chimera-cascade-evidence.ts
@@ -3950,7 +3974,7 @@ async function maybeReReviewCascade({
3950
3974
  const reReadFiles = [];
3951
3975
  for (const f of evidenceBundle.files) {
3952
3976
  try {
3953
- const absPath = path11.join(evidenceBundle.cwd, f.path);
3977
+ const absPath = path10.join(evidenceBundle.cwd, f.path);
3954
3978
  const content = await fsp.readFile(absPath, "utf8");
3955
3979
  reReadFiles.push({ path: f.path, status: "modified", content });
3956
3980
  } catch {
@@ -4027,7 +4051,7 @@ function errorText2(error) {
4027
4051
 
4028
4052
  // src/execution-chimera-review.ts
4029
4053
  import { randomUUID as randomUUID3 } from "node:crypto";
4030
- import path12 from "node:path";
4054
+ import path11 from "node:path";
4031
4055
  import { effectiveFallbackChain, fallbackProfileChain as fallbackProfileChain2 } from "@wrongstack/core/agent";
4032
4056
  import {
4033
4057
  areSubagentsAllowedForSession
@@ -4045,7 +4069,7 @@ import {
4045
4069
  function normalizeFileKeyForCitation(raw, cwd) {
4046
4070
  const forward = raw.replace(/\\/g, "/").replace(/^\.\//, "");
4047
4071
  const isAbsolute = forward.startsWith("/") || /^[a-zA-Z]:\//.test(forward);
4048
- const pathMod = process.platform === "win32" ? path12.win32 : path12;
4072
+ const pathMod = process.platform === "win32" ? path11.win32 : path11;
4049
4073
  const relative = isAbsolute ? pathMod.relative(cwd, forward).replace(/\\/g, "/").replace(/^\.\//, "") : forward;
4050
4074
  return process.platform === "win32" ? relative.toLowerCase() : relative;
4051
4075
  }
@@ -4272,7 +4296,7 @@ function installChimeraReviewHandler({
4272
4296
  const changedBasenameIndex = /* @__PURE__ */ new Map();
4273
4297
  for (const file of p.files) {
4274
4298
  const normalized = normalizeFileKeyForCitation(file.path, p.cwd);
4275
- const basename7 = path12.basename(file.path).toLowerCase();
4299
+ const basename7 = path11.basename(file.path).toLowerCase();
4276
4300
  const bucket = changedBasenameIndex.get(basename7);
4277
4301
  if (bucket) bucket.push(normalized);
4278
4302
  else changedBasenameIndex.set(basename7, [normalized]);
@@ -4284,7 +4308,7 @@ function installChimeraReviewHandler({
4284
4308
  (cp) => cp.endsWith(`/${citedKey}`) || cp === citedKey
4285
4309
  );
4286
4310
  if (suffixMatches.length === 1) return true;
4287
- const basename7 = path12.basename(finding.location.file).toLowerCase();
4311
+ const basename7 = path11.basename(finding.location.file).toLowerCase();
4288
4312
  const bucket = changedBasenameIndex.get(basename7);
4289
4313
  return !!(bucket && bucket.length === 1);
4290
4314
  });
@@ -4854,7 +4878,7 @@ async function runContextCompaction(opts, _signal) {
4854
4878
 
4855
4879
  // src/repl-client-registration.ts
4856
4880
  import * as crypto from "node:crypto";
4857
- import * as path13 from "node:path";
4881
+ import * as path12 from "node:path";
4858
4882
  import { getSharedProjectMailbox, resolveProjectDir } from "@wrongstack/core/coordination";
4859
4883
  import { wstackGlobalRoot } from "@wrongstack/core/utils";
4860
4884
  function registerReplClient(opts) {
@@ -4864,7 +4888,7 @@ function registerReplClient(opts) {
4864
4888
  const hqConnection = startCliHqConnection({
4865
4889
  clientKind: "repl",
4866
4890
  projectRoot: replProjectRoot,
4867
- projectName: path13.basename(replProjectRoot),
4891
+ projectName: path12.basename(replProjectRoot),
4868
4892
  appConfig: opts.appConfig,
4869
4893
  capabilities: ["telemetry.publish", "mailbox.summary"]
4870
4894
  });
@@ -4878,11 +4902,14 @@ function registerReplClient(opts) {
4878
4902
  clientMailbox.registerClient({
4879
4903
  clientId,
4880
4904
  sessionId: opts.getSessionId?.() ?? replProjectRoot,
4881
- name: `REPL [${path13.basename(replProjectRoot)}]`,
4905
+ name: `REPL [${path12.basename(replProjectRoot)}]`,
4882
4906
  source: "repl",
4883
4907
  pid: process.pid
4884
4908
  }).then(() => {
4885
- if (closed) return;
4909
+ if (closed) {
4910
+ void clientMailbox.deregisterClient(clientId).catch(() => void 0);
4911
+ return;
4912
+ }
4886
4913
  clientHeartbeat = setInterval(() => {
4887
4914
  clientMailbox.clientHeartbeat({ clientId, sessionId: opts.getSessionId?.() ?? replProjectRoot }).catch(() => {
4888
4915
  });
@@ -4892,6 +4919,7 @@ function registerReplClient(opts) {
4892
4919
  return {
4893
4920
  clientId,
4894
4921
  close() {
4922
+ if (closed) return;
4895
4923
  closed = true;
4896
4924
  if (clientHeartbeat) clearInterval(clientHeartbeat);
4897
4925
  clientMailbox.deregisterClient(clientId).catch(() => void 0);
@@ -5973,8 +6001,8 @@ async function profileMenu(store, paths) {
5973
6001
  }
5974
6002
  const items = await Promise.all(
5975
6003
  names.map(async (name) => {
5976
- const path15 = paths.profileConfig(name);
5977
- const data = await readJsonObjectFile(path15);
6004
+ const path14 = paths.profileConfig(name);
6005
+ const data = await readJsonObjectFile(path14);
5978
6006
  const provider = typeof data["provider"] === "string" ? data["provider"] : "unset";
5979
6007
  const model = typeof data["model"] === "string" ? data["model"] : "unset";
5980
6008
  const fallbackCount = Array.isArray(data["fallbackModels"]) ? data["fallbackModels"].length : 0;
@@ -5995,7 +6023,7 @@ async function profileMenu(store, paths) {
5995
6023
  },
5996
6024
  { label: "fallbacks", value: String(fallbackCount) },
5997
6025
  { label: "fallback profiles", value: String(profileCount) },
5998
- { label: "config", value: path15 }
6026
+ { label: "config", value: path14 }
5999
6027
  ],
6000
6028
  body: isActive ? "This profile owns the current session configuration." : "Switching profiles closes this session so every service restarts with the selected configuration.",
6001
6029
  actions: isActive ? [] : [{ key: "s", label: "switch", command: `/profile switch ${name}`, confirm: true }]
@@ -6125,19 +6153,19 @@ async function gitMenu(projectRoot) {
6125
6153
  },
6126
6154
  ...lines.map((line, index) => {
6127
6155
  const code = line.slice(0, 2);
6128
- const path15 = line.slice(3);
6156
+ const path14 = line.slice(3);
6129
6157
  const staged = code[0] !== " " && code[0] !== "?";
6130
6158
  const unstaged = code[1] !== " " || code === "??";
6131
6159
  return {
6132
- id: `change:${index}:${path15}`,
6133
- label: path15,
6160
+ id: `change:${index}:${path14}`,
6161
+ label: path14,
6134
6162
  status: staged ? "good" : "warn",
6135
6163
  summary: `${code} \xB7 ${staged ? "staged" : "not staged"}${unstaged ? " \xB7 working tree" : ""}`,
6136
6164
  details: [
6137
6165
  { label: "status", value: code },
6138
6166
  { label: "staged", value: staged ? "yes" : "no" },
6139
6167
  { label: "unstaged", value: unstaged ? "yes" : "no" },
6140
- { label: "path", value: path15 }
6168
+ { label: "path", value: path14 }
6141
6169
  ],
6142
6170
  actions: [
6143
6171
  { key: "d", label: "diff summary", command: staged ? "/git diff --staged" : "/git diff" }
@@ -6166,20 +6194,20 @@ async function worktreeMenu(projectRoot) {
6166
6194
  return split < 0 ? [line, "yes"] : [line.slice(0, split), line.slice(split + 1)];
6167
6195
  })
6168
6196
  );
6169
- const path15 = fields["worktree"] ?? "(unknown path)";
6197
+ const path14 = fields["worktree"] ?? "(unknown path)";
6170
6198
  const branchRef = fields["branch"];
6171
6199
  const branch = branchRef?.replace(/^refs\/heads\//, "") ?? (fields["detached"] ? "(detached)" : "(bare)");
6172
- const status = path15 === "(unknown path)" || fields["prunable"] ? null : await runGit(["status", "--porcelain=v1"], path15);
6200
+ const status = path14 === "(unknown path)" || fields["prunable"] ? null : await runGit(["status", "--porcelain=v1"], path14);
6173
6201
  const changes = status?.code === 0 ? status.stdout.split(/\r?\n/).filter(Boolean) : [];
6174
6202
  const dirty = changes.length > 0;
6175
6203
  const isMain = index === 0;
6176
6204
  return {
6177
- id: path15,
6205
+ id: path14,
6178
6206
  label: branch,
6179
6207
  status: fields["prunable"] ? "bad" : dirty ? "warn" : "good",
6180
6208
  summary: `${isMain ? "main" : "linked"} \xB7 ${dirty ? `${changes.length} changes` : "clean"}`,
6181
6209
  details: [
6182
- { label: "path", value: path15 },
6210
+ { label: "path", value: path14 },
6183
6211
  { label: "branch", value: branch },
6184
6212
  { label: "HEAD", value: fields["HEAD"]?.slice(0, 12) ?? "unknown" },
6185
6213
  { label: "working tree", value: dirty ? `${changes.length} changed paths` : "clean" },
@@ -6229,6 +6257,7 @@ async function execute(deps) {
6229
6257
  events,
6230
6258
  config,
6231
6259
  configStore,
6260
+ vault,
6232
6261
  wpaths: initialWpaths,
6233
6262
  projectRoot: initialProjectRoot,
6234
6263
  flags,
@@ -6412,6 +6441,7 @@ async function execute(deps) {
6412
6441
  }
6413
6442
  });
6414
6443
  let code = 0;
6444
+ let backgroundKanbanSupervisor;
6415
6445
  let fleetStatusLine = null;
6416
6446
  try {
6417
6447
  const visionAdapters = () => createToolVisionAdapters(agent.tools);
@@ -6440,6 +6470,20 @@ async function execute(deps) {
6440
6470
  flags.tui = true;
6441
6471
  }
6442
6472
  const executionMode = resolveExecutionMode(positional, flags);
6473
+ if (projectRoot && executionMode !== "webui") {
6474
+ backgroundKanbanSupervisor = (await import("./kanban-supervisor-67ECABTD.js")).createKanbanSupervisor({
6475
+ projectRoot,
6476
+ broadcast: () => {
6477
+ },
6478
+ dispatchTask: createKanbanDispatchHandler({
6479
+ config,
6480
+ events,
6481
+ skillLoader,
6482
+ sddSubagentFactory
6483
+ }).onKanbanDispatch,
6484
+ log: (message) => console.log(message)
6485
+ });
6486
+ }
6443
6487
  const enteringTui = executionMode === "tui";
6444
6488
  if (!enteringTui) {
6445
6489
  fleetStatusLine = new FleetStatusLine({ events, version: CLI_VERSION });
@@ -6597,6 +6641,7 @@ async function execute(deps) {
6597
6641
  ...createSettingsAdapter({
6598
6642
  configStore,
6599
6643
  wpaths,
6644
+ vault: vault ?? noOpVault,
6600
6645
  fleetStreamController,
6601
6646
  applyLiveSettings
6602
6647
  }),
@@ -6702,10 +6747,11 @@ async function execute(deps) {
6702
6747
  restoredToolCalls,
6703
6748
  restoredEvents,
6704
6749
  listSessions: async (limit = 20) => {
6705
- if (!activeSessionStore) return [];
6750
+ const currentStore = state.activeSessionStore;
6751
+ if (!currentStore) return [];
6706
6752
  const summaries = await selectPickerSessions(
6707
- (poolLimit) => activeSessionStore.list(poolLimit),
6708
- wpaths.projectSessions,
6753
+ (poolLimit) => currentStore.list(poolLimit),
6754
+ state.wpaths.projectSessions,
6709
6755
  limit
6710
6756
  );
6711
6757
  const liveBySession = /* @__PURE__ */ new Map();
@@ -6894,7 +6940,7 @@ async function execute(deps) {
6894
6940
  attachments,
6895
6941
  effectiveMaxContext,
6896
6942
  getEffectiveMaxContext,
6897
- projectName: path14.basename(projectRoot) || void 0,
6943
+ projectName: path13.basename(projectRoot) || void 0,
6898
6944
  projectRoot,
6899
6945
  appConfig: config,
6900
6946
  getSessionId: () => agent.ctx.session?.id ?? session.id,
@@ -6925,6 +6971,7 @@ async function execute(deps) {
6925
6971
  }
6926
6972
  }
6927
6973
  } finally {
6974
+ backgroundKanbanSupervisor?.dispose();
6928
6975
  for (const off of chimeraTeardowns.splice(0)) {
6929
6976
  try {
6930
6977
  off();
@@ -6959,4 +7006,4 @@ export {
6959
7006
  execute,
6960
7007
  resolveReviewerFallbackModels
6961
7008
  };
6962
- //# sourceMappingURL=execution-A6WJLSOC.js.map
7009
+ //# sourceMappingURL=execution-PYC5FCS4.js.map