@wrongstack/cli 0.319.1 → 1.0.0

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 (100) hide show
  1. package/data/providers.json +22 -15
  2. package/dist/{acp-5ANIAOZC.js → acp-3LARESEO.js} +113 -10
  3. package/dist/acp-hq-telemetry.d.ts +44 -0
  4. package/dist/{audit-ZPCLCC3C.js → audit-46YK5DSC.js} +1 -2
  5. package/dist/{auth-ND7J7DTD.js → auth-KIBJZZIE.js} +5 -6
  6. package/dist/auth-menu/add-provider.d.ts +7 -0
  7. package/dist/auth-menu/panel-service.d.ts +2 -20
  8. package/dist/{auto-discover-providers-MHFLDSD3.js → auto-discover-providers-VQU3IZMR.js} +1 -2
  9. package/dist/{bench-XYG56AMO.js → bench-YBU6BVQP.js} +175 -35
  10. package/dist/boot/brain-decision-log.d.ts +22 -2
  11. package/dist/{boot-auto-thin-BZ675EVT.js → boot-auto-thin-MANHOYHE.js} +1 -2
  12. package/dist/{chronicle-6EPPMUC5.js → chronicle-UTFETHP6.js} +1 -2
  13. package/dist/{chunk-LIWVIEZM.js → chunk-4HV5RKZH.js} +5 -5
  14. package/dist/{chunk-HF5VQWIY.js → chunk-5IA5337I.js} +3 -3
  15. package/dist/{chunk-TALOKMIC.js → chunk-C2E24IXZ.js} +31 -15
  16. package/dist/{chunk-XPX432BZ.js → chunk-DR2OXU46.js} +50 -39
  17. package/dist/chunk-ETYHZPXP.js +52 -0
  18. package/dist/{chunk-TYO2OVAD.js → chunk-EWKESL4L.js} +8 -4
  19. package/dist/{chunk-QAC263FZ.js → chunk-FPIWTJ2G.js} +2 -3
  20. package/dist/{chunk-7YLN7YUA.js → chunk-IMWXXF4J.js} +61 -9
  21. package/dist/{chunk-IMT6PNV5.js → chunk-MNQQ4ZNF.js} +26 -22
  22. package/dist/{chunk-P2OKBDCH.js → chunk-MXEJEYT7.js} +53 -14
  23. package/dist/{chunk-PCBJSXYV.js → chunk-O4A3HHKD.js} +2 -2
  24. package/dist/{chunk-XYKYXFEE.js → chunk-TE3Q32JP.js} +10 -4
  25. package/dist/{chunk-635WW3II.js → chunk-TEBMCYZN.js} +67 -18
  26. package/dist/{chunk-E4I2TF5S.js → chunk-TNK6237M.js} +2 -2
  27. package/dist/{chunk-GGGUZSAU.js → chunk-Z7A5MXKJ.js} +18 -12
  28. package/dist/{chunk-F5GA2QW2.js → chunk-ZSZ3EYWH.js} +2 -2
  29. package/dist/{cli-context-K73EIND5.js → cli-context-CYMKNOK3.js} +58 -307
  30. package/dist/{cli-main-QXSKKANW.js → cli-main-TTIVR4DI.js} +897 -286
  31. package/dist/{diag-doctor-QZVKUAE5.js → diag-doctor-7LYUYU35.js} +1 -2
  32. package/dist/execute-deps.d.ts +5 -1
  33. package/dist/{execution-7ZFY4FJY.js → execution-3Y55IWBK.js} +37 -20
  34. package/dist/{export-ROG3DKTZ.js → export-VVRIOWFV.js} +1 -2
  35. package/dist/{governance-JSGHHA2R.js → governance-RYSHV675.js} +1 -2
  36. package/dist/{hq-4QQJO2GN.js → hq-IG3YRGCO.js} +2 -3
  37. package/dist/hq-command-controller.d.ts +37 -7
  38. package/dist/hq-server/ws.d.ts +1 -1
  39. package/dist/{hq-server-CVAYICIS.js → hq-server-OILU3NPI.js} +2 -3
  40. package/dist/{hq-ttl-KUO3AU7X.js → hq-ttl-VJR65OBJ.js} +1 -2
  41. package/dist/{hq-tunnel-LO55RCZE.js → hq-tunnel-NIJ5EP2Y.js} +1 -2
  42. package/dist/index.js +5 -6
  43. package/dist/{init-4JQSG66Q.js → init-DRMMFG2G.js} +1 -2
  44. package/dist/{kanban-run-mirror-EKVNGXWW.js → kanban-run-mirror-22HQ5FNG.js} +1 -2
  45. package/dist/live-settings-input.d.ts +2 -0
  46. package/dist/{mailbox-serve-VKQIRCCB.js → mailbox-serve-VUCWZ2SJ.js} +2 -3
  47. package/dist/{mcp-AQKSASHD.js → mcp-HOMLC4WE.js} +1 -2
  48. package/dist/{modeldiag-ZL4ROTQ5.js → modeldiag-FMJT37SN.js} +2 -3
  49. package/dist/{per-subcommand-help-6VCIKDUW.js → per-subcommand-help-BWBHYVJO.js} +2 -3
  50. package/dist/{permissions-2PWBL4YU.js → permissions-CFDLXETM.js} +1 -2
  51. package/dist/{plugin-usage-7WCZW4NP.js → plugin-usage-HFBI3TFT.js} +2 -3
  52. package/dist/{plugins-7N3TF2QF.js → plugins-PZ2VZL7V.js} +4 -5
  53. package/dist/{project-BLQ3ALVL.js → project-AOQI5XTK.js} +1 -2
  54. package/dist/{project-manifest-RV5FXGQI.js → project-manifest-7NSFVBM3.js} +1 -2
  55. package/dist/{project-picker-CCQR3W4I.js → project-picker-SVBXMPKX.js} +1 -2
  56. package/dist/{projects-5J727S4L.js → projects-L6C6XLDY.js} +1 -2
  57. package/dist/provider-config-utils.d.ts +1 -1
  58. package/dist/{providers-models-OKKQZIWU.js → providers-models-YVMVYWRS.js} +3 -4
  59. package/dist/{proxy-wiring-QCI7EWQC.js → proxy-wiring-MGRSKZZB.js} +1 -2
  60. package/dist/{quick-XLYLZX4B.js → quick-CNB4Z3HS.js} +1 -2
  61. package/dist/{replay-RZXZKP2U.js → replay-JJ2NOWD6.js} +1 -2
  62. package/dist/{replay-FJ2JBXUA.js → replay-Z3FTJEMM.js} +1 -2
  63. package/dist/{rewind-2FFNOOKS.js → rewind-JA3ZLCNM.js} +1 -2
  64. package/dist/{sdd-runtime-R6FAK2G2.js → sdd-runtime-PTOSPYI4.js} +1 -2
  65. package/dist/services/statusline-config.d.ts +43 -13
  66. package/dist/{sessions-config-KAMEBVOX.js → sessions-config-UL45XKX7.js} +2 -3
  67. package/dist/{sessions-doctor-EXHAZSSE.js → sessions-doctor-QUL37U32.js} +1 -2
  68. package/dist/short-circuit-flags-6PSP56L7.js +10 -0
  69. package/dist/{simpleui-dist-JKNRCRRK.js → simpleui-dist-CXSIDAXZ.js} +1 -2
  70. package/dist/slash-commands/command-context.d.ts +10 -0
  71. package/dist/slash-commands/statusline.d.ts +1 -1
  72. package/dist/subcommands/handlers/bench-run-config.d.ts +18 -0
  73. package/dist/subcommands/handlers/bench.d.ts +8 -7
  74. package/dist/subcommands-HZQKA4G2.js +9 -0
  75. package/dist/{tools-skills-Q4P27URS.js → tools-skills-GH24UCBY.js} +1 -2
  76. package/dist/{update-K45CS6SS.js → update-5DPB4YD4.js} +1 -2
  77. package/dist/{update-check-PKSMSMD6.js → update-check-BS3DHTSI.js} +1 -2
  78. package/dist/version-help-MYKF724O.js +10 -0
  79. package/dist/webui-server/client-registration.d.ts +9 -1
  80. package/dist/{webui-server-F7MSRHOF.js → webui-server-T6AMOXJJ.js} +51 -12
  81. package/dist/wiring/brain-and-orchestration.d.ts +2 -0
  82. package/dist/wiring/cli-execute-builder.d.ts +4 -0
  83. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  84. package/dist/wiring/command-host-state.d.ts +50 -5
  85. package/dist/wiring/external-plugins.d.ts +9 -0
  86. package/dist/wiring/provider-runtime-setup.d.ts +2 -0
  87. package/dist/wiring/runtime-controller-deps.d.ts +3 -0
  88. package/dist/wiring/vector-memory-setup.d.ts +12 -0
  89. package/dist/wiring/wrongtrace-prompt-contributor.d.ts +5 -2
  90. package/dist/{wrongtrace-gate-counters-GSVY372D.js → wrongtrace-gate-counters-7C2EAAZL.js} +1 -2
  91. package/dist/{wrongtrace-telemetry-KBBM5NLQ.js → wrongtrace-telemetry-3ASFKOZO.js} +1 -2
  92. package/package.json +28 -28
  93. package/dist/chunk-7OCVIDC7.js +0 -11
  94. package/dist/chunk-KYDJJLJI.js +0 -52
  95. package/dist/launch-hints.d.ts +0 -49
  96. package/dist/short-circuit-flags-7YUCERBB.js +0 -11
  97. package/dist/subcommands-KE6MEQQP.js +0 -10
  98. package/dist/version-help-WMPSEL4U.js +0 -11
  99. package/dist/webui-server/privileged-actions.d.ts +0 -14
  100. package/dist/wiring/cli-heap-watchdog.d.ts +0 -34
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createHqCommandDispatcher
3
- } from "./chunk-7YLN7YUA.js";
3
+ } from "./chunk-IMWXXF4J.js";
4
4
  import {
5
5
  runProjectPicker
6
6
  } from "./chunk-WQZW3RDP.js";
@@ -25,7 +25,7 @@ import {
25
25
  } from "./chunk-SXJTVNWF.js";
26
26
  import {
27
27
  setupPlugins
28
- } from "./chunk-HF5VQWIY.js";
28
+ } from "./chunk-5IA5337I.js";
29
29
  import {
30
30
  deriveFsAccessPair,
31
31
  filterSafeForProject,
@@ -44,7 +44,11 @@ import {
44
44
  fmtTaskResultLine,
45
45
  fmtTok,
46
46
  patchConfig
47
- } from "./chunk-TYO2OVAD.js";
47
+ } from "./chunk-EWKESL4L.js";
48
+ import {
49
+ renderDeepHelpToString,
50
+ renderFocusedHelpToString
51
+ } from "./chunk-MXEJEYT7.js";
48
52
  import {
49
53
  awaitFirstWrongProxyProbe,
50
54
  bootstrapWrongProxy
@@ -59,13 +63,10 @@ import {
59
63
  matchTaskNode,
60
64
  sddState
61
65
  } from "./chunk-JHUJUIOH.js";
62
- import {
63
- startCliHqConnection
64
- } from "./chunk-XYKYXFEE.js";
65
66
  import {
66
67
  PLUGIN_AUDIT_ENTRIES,
67
68
  runPluginManagementCommand
68
- } from "./chunk-635WW3II.js";
69
+ } from "./chunk-TEBMCYZN.js";
69
70
  import "./chunk-JHPXJRRI.js";
70
71
  import {
71
72
  recordGateDecision
@@ -80,18 +81,23 @@ import {
80
81
  refreshAcpRegistry,
81
82
  resolveProviderCfg,
82
83
  setupProvider
83
- } from "./chunk-F5GA2QW2.js";
84
+ } from "./chunk-ZSZ3EYWH.js";
85
+ import {
86
+ startCliHqConnection
87
+ } from "./chunk-TE3Q32JP.js";
84
88
  import {
85
89
  LOCAL_LLM_PRESETS,
86
90
  addCustomProvider,
87
91
  addKeyForCatalogProvider,
88
92
  addKeyForProvider,
89
93
  nextCustomProviderId,
94
+ ownDefinitionsAsCatalog,
90
95
  runAuthLocal,
91
96
  runClaudeOAuthLogin,
92
97
  runCopilotOAuthLogin,
93
98
  validateFamily
94
- } from "./chunk-IMT6PNV5.js";
99
+ } from "./chunk-MNQQ4ZNF.js";
100
+ import "./chunk-2VMJ3E5Z.js";
95
101
  import {
96
102
  appendHistory
97
103
  } from "./chunk-B4JLSXZB.js";
@@ -104,10 +110,10 @@ import {
104
110
  } from "./chunk-YMXXOOFN.js";
105
111
  import {
106
112
  parseSpawnFlags
107
- } from "./chunk-GGGUZSAU.js";
113
+ } from "./chunk-Z7A5MXKJ.js";
108
114
  import {
109
115
  runCodexOAuthLogin
110
- } from "./chunk-E4I2TF5S.js";
116
+ } from "./chunk-TNK6237M.js";
111
117
  import {
112
118
  activeLabel,
113
119
  loadConfigProviders,
@@ -115,19 +121,16 @@ import {
115
121
  normalizeKeys,
116
122
  nowIso,
117
123
  writeKeysBack
118
- } from "./chunk-XPX432BZ.js";
124
+ } from "./chunk-DR2OXU46.js";
119
125
  import {
120
126
  buildWin32CmdShimInvocation
121
127
  } from "./chunk-U3SS4NRH.js";
122
128
  import {
123
129
  checkForUpdate
124
130
  } from "./chunk-YLQEGYV4.js";
125
- import {
126
- __require
127
- } from "./chunk-7OCVIDC7.js";
128
131
 
129
132
  // src/cli-main.ts
130
- import { mailboxSessionTag as mailboxSessionTag6 } from "@wrongstack/core/coordination";
133
+ import { mailboxSessionTag as mailboxSessionTag7 } from "@wrongstack/core/coordination";
131
134
  import { TOKENS as TOKENS13 } from "@wrongstack/core/kernel";
132
135
  import { writeErr as writeErr3 } from "@wrongstack/core/utils";
133
136
  import { setProxyTransitionLogger } from "@wrongstack/core/wiring/proxy-rewrite";
@@ -1094,7 +1097,7 @@ async function loadOnlineAgentsForPrompt(projectDir, skip) {
1094
1097
  }
1095
1098
  }
1096
1099
  async function getSddRuntimeStateForCli() {
1097
- const sdd = await import("./sdd-runtime-R6FAK2G2.js");
1100
+ const sdd = await import("./sdd-runtime-PTOSPYI4.js");
1098
1101
  return {
1099
1102
  tracker: sdd.getTaskTracker(),
1100
1103
  builder: sdd.getActiveBuilder(),
@@ -1136,10 +1139,12 @@ import {
1136
1139
  } from "@wrongstack/core/types";
1137
1140
 
1138
1141
  // src/boot/brain-decision-log.ts
1142
+ import { BrainTierCounter } from "@wrongstack/core/coordination";
1139
1143
  var MAX_BRAIN_LOG_ENTRIES = 20;
1140
1144
  function subscribeBrainDecisionLog(events) {
1141
1145
  const listeners = [];
1142
1146
  const brainLog = [];
1147
+ const tierCounter = new BrainTierCounter();
1143
1148
  const pushBrainLog = (entry) => {
1144
1149
  brainLog.push(entry);
1145
1150
  if (brainLog.length > MAX_BRAIN_LOG_ENTRIES) brainLog.shift();
@@ -1154,8 +1159,10 @@ function subscribeBrainDecisionLog(events) {
1154
1159
  at: e.at,
1155
1160
  kind: "answered",
1156
1161
  question: e.request.question,
1157
- outcome: e.decision.type === "answer" ? e.decision.optionId ?? e.decision.text ?? "" : ""
1162
+ outcome: e.decision.type === "answer" ? e.decision.optionId ?? e.decision.text ?? "" : "",
1163
+ ...e.tier ? { tier: e.tier } : {}
1158
1164
  });
1165
+ tierCounter.record(e.tier);
1159
1166
  });
1160
1167
  subscribe("brain.decision_ask_human", (raw) => {
1161
1168
  const e = raw;
@@ -1163,8 +1170,13 @@ function subscribeBrainDecisionLog(events) {
1163
1170
  at: e.at,
1164
1171
  kind: "ask_human",
1165
1172
  question: e.request.question,
1166
- outcome: "escalated to human"
1173
+ // A pending ask_human is the prompt; the same request lands again as
1174
+ // answered/denied once the human replies. Labelling them apart keeps
1175
+ // the ring readable when both rows are present.
1176
+ outcome: e.pending ? "waiting on a human" : "escalated to human",
1177
+ ...e.tier ? { tier: e.tier } : {}
1167
1178
  });
1179
+ if (!e.pending) tierCounter.record(e.tier);
1168
1180
  });
1169
1181
  subscribe("brain.decision_denied", (raw) => {
1170
1182
  const e = raw;
@@ -1172,8 +1184,10 @@ function subscribeBrainDecisionLog(events) {
1172
1184
  at: e.at,
1173
1185
  kind: "denied",
1174
1186
  question: e.request.question,
1175
- outcome: e.decision.type === "deny" ? e.decision.reason ?? "" : ""
1187
+ outcome: e.decision.type === "deny" ? e.decision.reason ?? "" : "",
1188
+ ...e.tier ? { tier: e.tier } : {}
1176
1189
  });
1190
+ tierCounter.record(e.tier);
1177
1191
  });
1178
1192
  subscribe("brain.council_resolved", (raw) => {
1179
1193
  const e = raw;
@@ -1203,7 +1217,7 @@ function subscribeBrainDecisionLog(events) {
1203
1217
  );
1204
1218
  }
1205
1219
  };
1206
- return { brainLog, pushBrainLog, dispose };
1220
+ return { brainLog, pushBrainLog, getTierStats: () => tierCounter.snapshot(), dispose };
1207
1221
  }
1208
1222
 
1209
1223
  // src/fleet/subagent-hook-runner.ts
@@ -4497,7 +4511,7 @@ function setupBrainAndOrchestration(deps) {
4497
4511
  cwd,
4498
4512
  wpaths,
4499
4513
  teardownHandlers,
4500
- mailboxSessionTag: mailboxSessionTag7,
4514
+ mailboxSessionTag: mailboxSessionTag8,
4501
4515
  brainMailbox,
4502
4516
  agentMonitor,
4503
4517
  manifestPath,
@@ -4622,12 +4636,17 @@ function setupBrainAndOrchestration(deps) {
4622
4636
  brainRuntime.arbiter,
4623
4637
  brainQueue,
4624
4638
  () => brainRuntime.getMode(),
4625
- () => brainRuntime.getSnapshot().terminalPolicy
4639
+ () => brainRuntime.getSnapshot().terminalPolicy,
4640
+ events
4626
4641
  ),
4627
4642
  events
4628
4643
  );
4629
4644
  container.bind(TOKENS6.BrainArbiter, () => brain);
4630
- const { brainLog, dispose: disposeBrainLog } = subscribeBrainDecisionLog(events);
4645
+ const {
4646
+ brainLog,
4647
+ getTierStats: brainTierStats,
4648
+ dispose: disposeBrainLog
4649
+ } = subscribeBrainDecisionLog(events);
4631
4650
  teardownHandlers.push(disposeBrainLog);
4632
4651
  brainMonitor = new BrainMonitor({
4633
4652
  events,
@@ -4654,7 +4673,7 @@ function setupBrainAndOrchestration(deps) {
4654
4673
  body,
4655
4674
  sessionId
4656
4675
  }) => {
4657
- const tag = mailboxSessionTag7(sessionId || context.session?.id || session.id);
4676
+ const tag = mailboxSessionTag8(sessionId || context.session?.id || session.id);
4658
4677
  const leaderUniqueId = `leader@${tag}`;
4659
4678
  await brainMailbox.send({
4660
4679
  from: `brain@${tag}`,
@@ -4780,6 +4799,7 @@ function setupBrainAndOrchestration(deps) {
4780
4799
  return {
4781
4800
  brain,
4782
4801
  brainLog,
4802
+ brainTierStats,
4783
4803
  brainSettings,
4784
4804
  brainRuntime,
4785
4805
  brainQueue,
@@ -4795,6 +4815,7 @@ import { gatedEnhancerReasoning } from "@wrongstack/core/execution";
4795
4815
  import { TOKENS as TOKENS7 } from "@wrongstack/core/kernel";
4796
4816
 
4797
4817
  // src/auth-menu/panel-service.ts
4818
+ import { parseModelRef } from "@wrongstack/core/agent";
4798
4819
  var ANSI_RE = /\u001b\[[0-9;]*m/g;
4799
4820
  function stripAnsi(text) {
4800
4821
  return text.replace(ANSI_RE, "");
@@ -4829,9 +4850,10 @@ function flowDeps(base, io) {
4829
4850
  function isCancel(err) {
4830
4851
  return err instanceof Error && err.name === "AbortError" || err instanceof DOMException && err.name === "AbortError";
4831
4852
  }
4832
- async function runFlow(run) {
4853
+ async function runFlow(run, onSuccess) {
4833
4854
  try {
4834
4855
  const ok = await run();
4856
+ if (ok) await onSuccess?.();
4835
4857
  return { ok };
4836
4858
  } catch (err) {
4837
4859
  if (isCancel(err)) return { ok: false, message: "Cancelled." };
@@ -4843,6 +4865,141 @@ function plainMaskedKey(key) {
4843
4865
  if (key.length <= 8) return "\u2022".repeat(key.length);
4844
4866
  return `${key.slice(0, 4)}\u2026${key.slice(-4)}`;
4845
4867
  }
4868
+ function isRecord(value) {
4869
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4870
+ }
4871
+ function isProviderModelRef(value, providerId) {
4872
+ return typeof value === "string" && parseModelRef(value).provider === providerId;
4873
+ }
4874
+ function removeProviderFallbackReferences(config, providerId) {
4875
+ const removeModelRefs = (value) => Array.isArray(value) ? value.filter((ref) => !isProviderModelRef(ref, providerId)) : void 0;
4876
+ if (Array.isArray(config["fallbackModels"])) {
4877
+ config["fallbackModels"] = removeModelRefs(config["fallbackModels"]);
4878
+ }
4879
+ if (typeof config["fallbackBridge"] === "string" && isProviderModelRef(config["fallbackBridge"], providerId)) {
4880
+ delete config["fallbackBridge"];
4881
+ }
4882
+ if (Array.isArray(config["favoriteModels"])) {
4883
+ config["favoriteModels"] = removeModelRefs(config["favoriteModels"]);
4884
+ }
4885
+ if (isRecord(config["models"])) {
4886
+ for (const [modelId, definition] of Object.entries(config["models"])) {
4887
+ if (isRecord(definition) && definition["provider"] === providerId) {
4888
+ delete config["models"][modelId];
4889
+ }
4890
+ }
4891
+ if (Object.keys(config["models"]).length === 0) delete config["models"];
4892
+ }
4893
+ const removedProfiles = /* @__PURE__ */ new Set();
4894
+ if (isRecord(config["fallbackProfiles"])) {
4895
+ const profiles = config["fallbackProfiles"];
4896
+ for (const [name, chain] of Object.entries(profiles)) {
4897
+ if (!Array.isArray(chain)) continue;
4898
+ const next = chain.filter((ref) => !isProviderModelRef(ref, providerId));
4899
+ if (next.length === 0) {
4900
+ delete profiles[name];
4901
+ removedProfiles.add(name);
4902
+ } else {
4903
+ profiles[name] = next;
4904
+ }
4905
+ }
4906
+ if (Object.keys(profiles).length === 0) delete config["fallbackProfiles"];
4907
+ }
4908
+ const clearRemovedProfile = (entry) => {
4909
+ if (typeof entry["fallbackProfile"] === "string" && removedProfiles.has(entry["fallbackProfile"])) {
4910
+ delete entry["fallbackProfile"];
4911
+ }
4912
+ };
4913
+ if (typeof config["fallbackProfile"] === "string" && removedProfiles.has(config["fallbackProfile"])) {
4914
+ delete config["fallbackProfile"];
4915
+ }
4916
+ if (isRecord(config["modelMatrix"])) {
4917
+ for (const [role, value] of Object.entries(config["modelMatrix"])) {
4918
+ if (!isRecord(value)) continue;
4919
+ if (value["provider"] === providerId) {
4920
+ delete value["provider"];
4921
+ delete value["model"];
4922
+ }
4923
+ clearRemovedProfile(value);
4924
+ if (Object.keys(value).length === 0) delete config["modelMatrix"][role];
4925
+ }
4926
+ if (Object.keys(config["modelMatrix"]).length === 0) delete config["modelMatrix"];
4927
+ }
4928
+ if (isRecord(config["modelTiers"]) && isRecord(config["modelTiers"]["levels"])) {
4929
+ const levels = config["modelTiers"]["levels"];
4930
+ for (const level of Object.values(levels)) {
4931
+ if (!isRecord(level)) continue;
4932
+ if (level["provider"] === providerId) {
4933
+ delete level["provider"];
4934
+ delete level["model"];
4935
+ }
4936
+ clearRemovedProfile(level);
4937
+ }
4938
+ }
4939
+ if (isRecord(config["autonomy"])) {
4940
+ const autonomy = config["autonomy"];
4941
+ if (autonomy["refinerProvider"] === providerId) {
4942
+ delete autonomy["refinerProvider"];
4943
+ delete autonomy["refinerModel"];
4944
+ }
4945
+ if (isProviderModelRef(autonomy["enhanceFallbackModel"], providerId)) {
4946
+ delete autonomy["enhanceFallbackModel"];
4947
+ }
4948
+ if (typeof autonomy["refinerFallbackProfile"] === "string" && removedProfiles.has(autonomy["refinerFallbackProfile"])) {
4949
+ delete autonomy["refinerFallbackProfile"];
4950
+ }
4951
+ }
4952
+ if (isRecord(config["brain"])) {
4953
+ const brain = config["brain"];
4954
+ if (Array.isArray(brain["models"])) {
4955
+ brain["models"] = brain["models"].filter(
4956
+ (entry) => !isProviderModelRef(entry, providerId) && !(isRecord(entry) && entry["provider"] === providerId)
4957
+ );
4958
+ }
4959
+ if (isRecord(brain["council"])) {
4960
+ const council = brain["council"];
4961
+ if (Array.isArray(council["voters"])) {
4962
+ council["voters"] = council["voters"].filter(
4963
+ (entry) => !isProviderModelRef(entry, providerId) && !(isRecord(entry) && entry["provider"] === providerId)
4964
+ );
4965
+ }
4966
+ if (isProviderModelRef(council["judge"], providerId) || isRecord(council["judge"]) && council["judge"]["provider"] === providerId) {
4967
+ delete council["judge"];
4968
+ }
4969
+ }
4970
+ }
4971
+ const councilProfiles = isRecord(config["tools"]) && isRecord(config["tools"]["council"]) ? config["tools"]["council"]["profiles"] : void 0;
4972
+ if (Array.isArray(councilProfiles)) {
4973
+ for (const profile of councilProfiles) {
4974
+ if (!isRecord(profile)) continue;
4975
+ for (const seat of Array.isArray(profile["seats"]) ? profile["seats"] : []) {
4976
+ if (!isRecord(seat) || !isRecord(seat["target"])) continue;
4977
+ const target = seat["target"];
4978
+ if (target["providerId"] === providerId) {
4979
+ delete target["providerId"];
4980
+ delete target["model"];
4981
+ }
4982
+ if (Array.isArray(target["fallbackModels"])) {
4983
+ target["fallbackModels"] = removeModelRefs(target["fallbackModels"]);
4984
+ }
4985
+ clearRemovedProfile(target);
4986
+ if (Object.keys(target).length === 0) delete seat["target"];
4987
+ }
4988
+ if (isRecord(profile["judge"])) {
4989
+ const judge = profile["judge"];
4990
+ if (judge["providerId"] === providerId) {
4991
+ delete judge["providerId"];
4992
+ delete judge["model"];
4993
+ }
4994
+ if (Array.isArray(judge["fallbackModels"])) {
4995
+ judge["fallbackModels"] = removeModelRefs(judge["fallbackModels"]);
4996
+ }
4997
+ clearRemovedProfile(judge);
4998
+ if (Object.keys(judge).length === 0) delete profile["judge"];
4999
+ }
5000
+ }
5001
+ }
5002
+ }
4846
5003
  function createAuthPanelHost(deps) {
4847
5004
  const loadProviders = () => loadConfigProviders(deps.profileConfigPath, deps.vault);
4848
5005
  const mutate = async (mutator) => {
@@ -4851,14 +5008,21 @@ function createAuthPanelHost(deps) {
4851
5008
  await mutateConfigProviders(
4852
5009
  deps.profileConfigPath,
4853
5010
  deps.vault,
4854
- (all) => {
4855
- result = mutator(all);
5011
+ (all, config) => {
5012
+ result = mutator(all, config);
4856
5013
  },
4857
5014
  deps.profileConfigPath
4858
5015
  );
4859
5016
  } catch (err) {
4860
5017
  return err instanceof Error ? err.message : String(err);
4861
5018
  }
5019
+ if (result === null && deps.onProvidersChanged) {
5020
+ try {
5021
+ await deps.onProvidersChanged();
5022
+ } catch (err) {
5023
+ return `Saved, but live config reload failed: ${err instanceof Error ? err.message : String(err)}`;
5024
+ }
5025
+ }
4862
5026
  return result;
4863
5027
  };
4864
5028
  return {
@@ -4896,7 +5060,10 @@ function createAuthPanelHost(deps) {
4896
5060
  loadProviders()
4897
5061
  ]);
4898
5062
  const saved = new Set(Object.keys(providers));
4899
- return catalog.filter((p) => p.family !== "unsupported").sort((a, b) => a.id.localeCompare(b.id)).map((p) => ({
5063
+ return [
5064
+ ...catalog,
5065
+ ...ownDefinitionsAsCatalog(new Set(catalog.map((provider) => provider.id)))
5066
+ ].filter((p) => p.family !== "unsupported").sort((a, b) => a.id.localeCompare(b.id)).map((p) => ({
4900
5067
  id: p.id,
4901
5068
  name: p.name || p.id,
4902
5069
  family: p.family,
@@ -4932,9 +5099,10 @@ function createAuthPanelHost(deps) {
4932
5099
  });
4933
5100
  },
4934
5101
  removeProvider(providerId) {
4935
- return mutate((all) => {
5102
+ return mutate((all, config) => {
4936
5103
  if (!all[providerId]) return `Provider "${providerId}" no longer in config.`;
4937
5104
  delete all[providerId];
5105
+ removeProviderFallbackReferences(config, providerId);
4938
5106
  return null;
4939
5107
  });
4940
5108
  },
@@ -4943,6 +5111,157 @@ function createAuthPanelHost(deps) {
4943
5111
  const providers = await loadProviders();
4944
5112
  const template = providers[providerId] ?? { type: providerId };
4945
5113
  return addKeyForProvider(providerId, flowDeps(deps, io), template);
5114
+ }, deps.onProvidersChanged);
5115
+ },
5116
+ async saveProviderSetup(setup) {
5117
+ const type = setup.type.trim();
5118
+ const alias = setup.alias.trim();
5119
+ const keyLabel = setup.keyLabel.trim();
5120
+ const apiKey = setup.apiKey.trim();
5121
+ const family = validateFamily(setup.family);
5122
+ if (!type) return "Provider id is required.";
5123
+ if (!alias) return "Alias is required.";
5124
+ if (!family) return "Choose a supported protocol family.";
5125
+ if (!keyLabel) return "Key alias is required.";
5126
+ if (!apiKey) return "API key is required.";
5127
+ const split = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
5128
+ const baseUrl = setup.baseUrl.trim();
5129
+ const models = split(setup.models);
5130
+ const envVars = split(setup.envVars);
5131
+ let catalogDefaultModel;
5132
+ try {
5133
+ catalogDefaultModel = (await deps.modelsRegistry.getProvider(type))?.models?.[0]?.id;
5134
+ } catch {
5135
+ }
5136
+ const result = await mutate((all, config) => {
5137
+ const existing = all[alias];
5138
+ if (existing) {
5139
+ const existingFamily = existing.family ?? family;
5140
+ const existingBaseUrl = existing.baseUrl ?? "";
5141
+ if (existingFamily !== family || existingBaseUrl !== baseUrl) {
5142
+ return `Alias "${alias}" already uses ${existingFamily} / ${existingBaseUrl || "default endpoint"}. Choose a different alias.`;
5143
+ }
5144
+ if (existing.type && existing.type !== type) {
5145
+ return `Alias "${alias}" already belongs to provider type "${existing.type}".`;
5146
+ }
5147
+ }
5148
+ const provider = existing ?? { type, family };
5149
+ provider.type = type;
5150
+ provider.family = family;
5151
+ if (baseUrl) provider.baseUrl = baseUrl;
5152
+ else delete provider.baseUrl;
5153
+ if (models.length > 0) provider.models = models;
5154
+ else if (setup.source === "custom") delete provider.models;
5155
+ if (envVars.length > 0) provider.envVars = envVars;
5156
+ else if (setup.source === "custom") delete provider.envVars;
5157
+ const keys = normalizeKeys(provider);
5158
+ if (keys.some((key) => key.label === keyLabel)) {
5159
+ return `Key alias "${keyLabel}" already exists for "${alias}". Pick another key alias or update that key.`;
5160
+ }
5161
+ keys.push({ label: keyLabel, apiKey, createdAt: nowIso() });
5162
+ writeKeysBack(provider, keys);
5163
+ if (!provider.activeKey) provider.activeKey = keyLabel;
5164
+ all[alias] = provider;
5165
+ if ((!config["provider"] || !config["model"]) && catalogDefaultModel) {
5166
+ config["provider"] = alias;
5167
+ config["model"] = catalogDefaultModel;
5168
+ }
5169
+ return null;
5170
+ });
5171
+ return result;
5172
+ },
5173
+ async saveProviderEdit(edit) {
5174
+ const providerId = edit.providerId.trim();
5175
+ const family = validateFamily(edit.family);
5176
+ if (!providerId) return "Provider id is required.";
5177
+ if (!family) return "Choose a supported protocol family.";
5178
+ const list = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
5179
+ const baseUrl = edit.baseUrl.trim();
5180
+ const models = list(edit.models);
5181
+ const envVars = list(edit.envVars);
5182
+ return mutate((all) => {
5183
+ const provider = all[providerId];
5184
+ if (!provider) return `Provider "${providerId}" no longer in config.`;
5185
+ provider.family = family;
5186
+ if (baseUrl) provider.baseUrl = baseUrl;
5187
+ else delete provider.baseUrl;
5188
+ if (models.length > 0) provider.models = models;
5189
+ else delete provider.models;
5190
+ if (envVars.length > 0) provider.envVars = envVars;
5191
+ else delete provider.envVars;
5192
+ return null;
5193
+ });
5194
+ },
5195
+ async getModelEdit(providerId, modelId) {
5196
+ const provider = (await loadProviders())[providerId];
5197
+ if (!provider?.models?.includes(modelId)) return null;
5198
+ const details = provider.customModels?.[modelId];
5199
+ const modelsDev = details?.modelsDev ?? {};
5200
+ const limit = modelsDev["limit"];
5201
+ const cost = modelsDev["cost"];
5202
+ return {
5203
+ providerId,
5204
+ modelId,
5205
+ name: typeof modelsDev["name"] === "string" ? modelsDev["name"] : "",
5206
+ contextWindow: limit?.["context"] === void 0 ? "" : String(limit["context"]),
5207
+ maxOutput: details?.maxOutput === void 0 ? limit?.["output"] === void 0 ? "" : String(limit["output"]) : String(details.maxOutput),
5208
+ costInput: cost?.["input"] === void 0 ? "" : String(cost["input"]),
5209
+ costOutput: cost?.["output"] === void 0 ? "" : String(cost["output"])
5210
+ };
5211
+ },
5212
+ async saveModelEdit(edit) {
5213
+ const parse = (value, label) => {
5214
+ if (!value.trim()) return void 0;
5215
+ const number = Number(value);
5216
+ return Number.isFinite(number) && number >= 0 ? number : `${label} must be a non-negative number.`;
5217
+ };
5218
+ const context = parse(edit.contextWindow, "Context window");
5219
+ const output = parse(edit.maxOutput, "Max output");
5220
+ const inputCost = parse(edit.costInput, "Input cost");
5221
+ const outputCost = parse(edit.costOutput, "Output cost");
5222
+ for (const value of [context, output, inputCost, outputCost]) if (typeof value === "string") return value;
5223
+ return mutate((all) => {
5224
+ const provider = all[edit.providerId];
5225
+ if (!provider?.models?.includes(edit.modelId)) return `Model "${edit.modelId}" no longer exists.`;
5226
+ const existing = provider.customModels?.[edit.modelId] ?? {};
5227
+ const modelsDev = { ...existing.modelsDev ?? {} };
5228
+ if (edit.name.trim()) modelsDev["name"] = edit.name.trim();
5229
+ else delete modelsDev["name"];
5230
+ const limit = { ...modelsDev["limit"] ?? {} };
5231
+ if (context === void 0) delete limit["context"];
5232
+ else limit["context"] = context;
5233
+ if (output === void 0) delete limit["output"];
5234
+ else limit["output"] = output;
5235
+ if (Object.keys(limit).length) modelsDev["limit"] = limit;
5236
+ else delete modelsDev["limit"];
5237
+ const cost = { ...modelsDev["cost"] ?? {} };
5238
+ if (inputCost === void 0) delete cost["input"];
5239
+ else cost["input"] = inputCost;
5240
+ if (outputCost === void 0) delete cost["output"];
5241
+ else cost["output"] = outputCost;
5242
+ if (Object.keys(cost).length) modelsDev["cost"] = cost;
5243
+ else delete modelsDev["cost"];
5244
+ if (!provider.customModels) provider.customModels = {};
5245
+ provider.customModels[edit.modelId] = { ...existing, ...Object.keys(modelsDev).length ? { modelsDev } : {} };
5246
+ return null;
5247
+ });
5248
+ },
5249
+ async saveKeyEdit(edit) {
5250
+ const label = edit.label.trim();
5251
+ const apiKey = edit.apiKey.trim();
5252
+ if (!label) return "Key alias is required.";
5253
+ if (!apiKey) return "API key is required.";
5254
+ return mutate((all) => {
5255
+ const provider = all[edit.providerId];
5256
+ if (!provider) return `Provider "${edit.providerId}" no longer in config.`;
5257
+ const keys = normalizeKeys(provider);
5258
+ const original = edit.originalLabel;
5259
+ if (original && !keys.some((key) => key.label === original)) return `Key "${original}" not found.`;
5260
+ if (keys.some((key) => key.label === label && key.label !== original)) return `Key alias "${label}" already exists.`;
5261
+ const next = original ? keys.map((key) => key.label === original ? { ...key, label, apiKey, createdAt: nowIso() } : key) : [...keys, { label, apiKey, createdAt: nowIso() }];
5262
+ writeKeysBack(provider, next);
5263
+ if (!provider.activeKey || provider.activeKey === original) provider.activeKey = label;
5264
+ return null;
4946
5265
  });
4947
5266
  },
4948
5267
  updateKey(providerId, label, io) {
@@ -4969,7 +5288,7 @@ function createAuthPanelHost(deps) {
4969
5288
  }
4970
5289
  io.onLog(`\u2713 Updated ${providerId}/${label}.`);
4971
5290
  return true;
4972
- });
5291
+ }, deps.onProvidersChanged);
4973
5292
  },
4974
5293
  editField(providerId, field, io) {
4975
5294
  return runFlow(async () => {
@@ -5055,7 +5374,7 @@ function createAuthPanelHost(deps) {
5055
5374
  }
5056
5375
  io.onLog(`\u2713 models \u2192 ${list.length === 0 ? "(catalog default)" : list.join(", ")}`);
5057
5376
  return true;
5058
- });
5377
+ }, deps.onProvidersChanged);
5059
5378
  },
5060
5379
  editModelDetails(providerId, modelId, io) {
5061
5380
  return runFlow(async () => {
@@ -5149,7 +5468,7 @@ function createAuthPanelHost(deps) {
5149
5468
  }
5150
5469
  io.onLog(`\u2713 ${modelId} updated`);
5151
5470
  return true;
5152
- });
5471
+ }, deps.onProvidersChanged);
5153
5472
  },
5154
5473
  addModel(providerId, io, opts) {
5155
5474
  return runFlow(async () => {
@@ -5187,7 +5506,7 @@ function createAuthPanelHost(deps) {
5187
5506
  }
5188
5507
  io.onLog(`\u2713 Added model "${modelId}" to ${providerId}`);
5189
5508
  return true;
5190
- });
5509
+ }, deps.onProvidersChanged);
5191
5510
  },
5192
5511
  removeModel(providerId, modelId) {
5193
5512
  return (async () => {
@@ -5237,10 +5556,10 @@ function createAuthPanelHost(deps) {
5237
5556
  return false;
5238
5557
  }
5239
5558
  return addKeyForCatalogProvider(flowDeps(deps, io), chosen);
5240
- });
5559
+ }, deps.onProvidersChanged);
5241
5560
  },
5242
5561
  addCustomProvider(io) {
5243
- return runFlow(() => addCustomProvider(flowDeps(deps, io)));
5562
+ return runFlow(() => addCustomProvider(flowDeps(deps, io)), deps.onProvidersChanged);
5244
5563
  },
5245
5564
  addLocal(presetId, io) {
5246
5565
  return runFlow(async () => {
@@ -5256,7 +5575,7 @@ function createAuthPanelHost(deps) {
5256
5575
  models: "999"
5257
5576
  });
5258
5577
  return code === 0;
5259
- });
5578
+ }, deps.onProvidersChanged);
5260
5579
  },
5261
5580
  oauthLogin(kind, io) {
5262
5581
  return runFlow(async () => {
@@ -5264,7 +5583,7 @@ function createAuthPanelHost(deps) {
5264
5583
  const opts = { signal: io.signal };
5265
5584
  const code = kind === "chatgpt" ? await runCodexOAuthLogin(d, opts) : kind === "claude" ? await runClaudeOAuthLogin(d, opts) : await runCopilotOAuthLogin(d, opts);
5266
5585
  return code === 0;
5267
- });
5586
+ }, deps.onProvidersChanged);
5268
5587
  }
5269
5588
  };
5270
5589
  }
@@ -5292,6 +5611,9 @@ function createRuntimeControllerDeps(input) {
5292
5611
  statuslineLines: input.statuslineLines,
5293
5612
  setStatuslineLines: input.setStatuslineLines,
5294
5613
  saveStatuslineLines: input.saveStatuslineLines,
5614
+ statuslineDensities: input.statuslineDensities,
5615
+ setStatuslineDensities: input.setStatuslineDensities,
5616
+ saveStatuslineDensities: input.saveStatuslineDensities,
5295
5617
  getYolo: input.getYolo,
5296
5618
  onYolo: input.onYolo,
5297
5619
  getAutonomy: input.getAutonomy,
@@ -5647,6 +5969,7 @@ async function runCliExecution(params) {
5647
5969
  resolvedProvider,
5648
5970
  logger,
5649
5971
  switchProviderAndModel,
5972
+ reloadProviderConfig,
5650
5973
  applyMaxContext,
5651
5974
  renderer,
5652
5975
  reader,
@@ -5675,6 +5998,9 @@ async function runCliExecution(params) {
5675
5998
  statuslineLines,
5676
5999
  setStatuslineLines,
5677
6000
  saveStatuslineLines: saveStatuslineLines2,
6001
+ statuslineDensities,
6002
+ setStatuslineDensities,
6003
+ saveStatuslineDensities,
5678
6004
  setYoloMode,
5679
6005
  autonomyMode,
5680
6006
  setAutonomyMode,
@@ -5703,7 +6029,7 @@ async function runCliExecution(params) {
5703
6029
  governanceHandle,
5704
6030
  setConfig
5705
6031
  } = params;
5706
- const { execute } = await import("./execution-7ZFY4FJY.js");
6032
+ const { execute } = await import("./execution-3Y55IWBK.js");
5707
6033
  return execute(
5708
6034
  toExecuteDeps({
5709
6035
  core: {
@@ -5779,7 +6105,8 @@ async function runCliExecution(params) {
5779
6105
  authHost: createAuthPanelHost({
5780
6106
  vault,
5781
6107
  modelsRegistry,
5782
- profileConfigPath
6108
+ profileConfigPath,
6109
+ onProvidersChanged: reloadProviderConfig
5783
6110
  }),
5784
6111
  onPanelOpen
5785
6112
  },
@@ -5819,6 +6146,9 @@ async function runCliExecution(params) {
5819
6146
  statuslineLines,
5820
6147
  setStatuslineLines,
5821
6148
  saveStatuslineLines: saveStatuslineLines2,
6149
+ statuslineDensities,
6150
+ setStatuslineDensities,
6151
+ saveStatuslineDensities,
5822
6152
  getYolo: setYoloMode,
5823
6153
  onYolo: setYoloMode,
5824
6154
  getAutonomy: () => autonomyMode,
@@ -5911,6 +6241,7 @@ import { makeAutonomyPromptContributor } from "@wrongstack/core/execution";
5911
6241
  import { sessionScopedPath } from "@wrongstack/core/utils";
5912
6242
 
5913
6243
  // src/wiring/wrongtrace-prompt-contributor.ts
6244
+ import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
5914
6245
  import { digestAtlas, summarizeFriction } from "@wrongstack/wrongtrace";
5915
6246
  var CONTRIBUTOR_DEADLINE_MS = 800;
5916
6247
  function raceWithDeadline(p, ms) {
@@ -5929,8 +6260,11 @@ function raceWithDeadline(p, ms) {
5929
6260
  );
5930
6261
  });
5931
6262
  }
5932
- function createWrongTracePromptContributor() {
5933
- return async () => {
6263
+ function createWrongTracePromptContributor(options = {}) {
6264
+ const tier = normalizeTokenSavingTier2(options.tokenSavingMode);
6265
+ return async (ctx) => {
6266
+ if (ctx.subagent) return [];
6267
+ if (tier === "minimal" || tier === "aggressive") return [];
5934
6268
  try {
5935
6269
  const wt = await raceWithDeadline(getWrongTrace(), CONTRIBUTOR_DEADLINE_MS);
5936
6270
  if (!wt?.isAvailable) return [];
@@ -6026,7 +6360,9 @@ function bindSystemPromptBuilder(deps) {
6026
6360
  // is reachable, the leader prompt carries a compact atlas digest +
6027
6361
  // friction summary block. Fail-open and deadline-bounded (<1s), so
6028
6362
  // an absent/slow daemon never stalls the boot prompt.
6029
- createWrongTracePromptContributor()
6363
+ createWrongTracePromptContributor({
6364
+ tokenSavingMode: deps.tokenSavingMode
6365
+ })
6030
6366
  ]
6031
6367
  })
6032
6368
  );
@@ -6041,7 +6377,7 @@ import {
6041
6377
  makeSessionNoteTool as makeSessionNoteTool2
6042
6378
  } from "@wrongstack/core/coordination";
6043
6379
  import { createContextManagerTool } from "@wrongstack/core/infrastructure";
6044
- import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
6380
+ import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
6045
6381
  import { configureChildEnvGitIdentity } from "@wrongstack/core/utils";
6046
6382
  import { registerCanonicalHostTools } from "@wrongstack/runtime/tool-registration";
6047
6383
  import { configureDangerBypass, configureExecPolicy } from "@wrongstack/tools";
@@ -6674,7 +7010,7 @@ ${commit.out}`;
6674
7010
 
6675
7011
  // src/boot/tool-registry.ts
6676
7012
  function registerBuiltinTools(deps) {
6677
- const tier = normalizeTokenSavingTier2(deps.config.features.tokenSavingMode);
7013
+ const tier = normalizeTokenSavingTier3(deps.config.features.tokenSavingMode);
6678
7014
  registerCanonicalHostTools({
6679
7015
  registry: deps.toolRegistry,
6680
7016
  tier,
@@ -7595,9 +7931,9 @@ async function generateCommitMessageWithLLM(diff, opts) {
7595
7931
  const userPrompt = `Here is the git diff:
7596
7932
 
7597
7933
  ${diff}`;
7934
+ const signal = new AbortController();
7935
+ const timeout = setTimeout(() => signal.abort(), 15e3);
7598
7936
  try {
7599
- const signal = new AbortController();
7600
- const timeout = setTimeout(() => signal.abort(), 15e3);
7601
7937
  const resp = await opts.provider.complete(
7602
7938
  {
7603
7939
  model: opts.model,
@@ -7608,7 +7944,6 @@ ${diff}`;
7608
7944
  },
7609
7945
  { signal: signal.signal }
7610
7946
  );
7611
- clearTimeout(timeout);
7612
7947
  const rawContent = resp.content;
7613
7948
  const text = Array.isArray(rawContent) ? rawContent[0]?.text ?? "" : typeof rawContent === "object" && rawContent !== null ? rawContent.text ?? "" : String(rawContent);
7614
7949
  const message = expectDefined3(text.trim().split("\n")[0]);
@@ -7616,6 +7951,8 @@ ${diff}`;
7616
7951
  return message;
7617
7952
  }
7618
7953
  } catch {
7954
+ } finally {
7955
+ clearTimeout(timeout);
7619
7956
  }
7620
7957
  return "chore: update";
7621
7958
  }
@@ -8031,57 +8368,25 @@ function formatDiagnostics(input) {
8031
8368
  import * as fs3 from "node:fs/promises";
8032
8369
  import * as os from "node:os";
8033
8370
  import * as path9 from "node:path";
8371
+ import {
8372
+ clampLine,
8373
+ defaultChipEnabledMap,
8374
+ STATUSLINE_DENSITY_LEVELS,
8375
+ STATUSLINE_ITEMS
8376
+ } from "@wrongstack/core/statusline";
8034
8377
  import { ERROR_CODES, FsError } from "@wrongstack/core/types";
8035
8378
  import { atomicWrite, resolveWstackPaths, toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
8036
8379
  var CONFIG_ENV = "WRONGSTACK_STATUSLINE_CONFIG";
8037
- var STATUSLINE_CONFIG_VERSION = 2;
8038
- var STATUSLINE_CONFIG_KEYS = [
8039
- "state",
8040
- "model",
8041
- "context",
8042
- "tokens",
8043
- "cache",
8044
- "cost",
8045
- "queue",
8046
- "hint",
8047
- "index",
8048
- "breaker",
8049
- "yolo",
8050
- "autonomy",
8051
- "eternal_stage",
8052
- "elapsed",
8053
- "project",
8054
- "working_dir",
8055
- "goal",
8056
- "mode",
8057
- "auto_proceed",
8058
- "git",
8059
- "sessions",
8060
- "tools",
8061
- "theme",
8062
- "token_saving",
8063
- "processes",
8064
- "version",
8065
- "dropped_tools",
8066
- "prompt_variant",
8067
- "side_effects",
8068
- "todos",
8069
- "plan",
8070
- "tasks",
8071
- "fleet",
8072
- "brain",
8073
- "debug_stream",
8074
- "enhance",
8075
- "next_steps",
8076
- "mailbox",
8077
- "fleet_agents",
8078
- "memory_context"
8079
- ];
8080
- var DEFAULTS = Object.fromEntries(
8081
- STATUSLINE_CONFIG_KEYS.map((key) => [key, true])
8082
- );
8380
+ var STATUSLINE_CONFIG_VERSION = 3;
8381
+ var STATUSLINE_CONFIG_KEYS = STATUSLINE_ITEMS;
8382
+ var DEFAULTS = defaultChipEnabledMap();
8083
8383
  function emptyDocument() {
8084
- return { version: STATUSLINE_CONFIG_VERSION, chips: { ...DEFAULTS }, lines: {} };
8384
+ return {
8385
+ version: STATUSLINE_CONFIG_VERSION,
8386
+ chips: { ...DEFAULTS },
8387
+ lines: {},
8388
+ densities: {}
8389
+ };
8085
8390
  }
8086
8391
  function resolveConfigPath() {
8087
8392
  const override = process.env[CONFIG_ENV];
@@ -8092,12 +8397,12 @@ function resolveConfigPath() {
8092
8397
  });
8093
8398
  return paths.profileStatuslineConfig(paths.profileName);
8094
8399
  }
8095
- function isRecord(value) {
8400
+ function isRecord2(value) {
8096
8401
  return typeof value === "object" && value !== null && !Array.isArray(value);
8097
8402
  }
8098
8403
  function normalizeChips(value) {
8099
8404
  const config = { ...DEFAULTS };
8100
- if (!isRecord(value)) return config;
8405
+ if (!isRecord2(value)) return config;
8101
8406
  for (const key of STATUSLINE_CONFIG_KEYS) {
8102
8407
  if (typeof value[key] === "boolean") config[key] = value[key];
8103
8408
  }
@@ -8105,33 +8410,50 @@ function normalizeChips(value) {
8105
8410
  }
8106
8411
  function normalizeLines(value) {
8107
8412
  const lines = {};
8108
- if (!isRecord(value)) return lines;
8413
+ if (!isRecord2(value)) return lines;
8109
8414
  for (const key of STATUSLINE_CONFIG_KEYS) {
8110
8415
  const raw = value[key];
8111
8416
  if (typeof raw !== "number" || !Number.isInteger(raw)) continue;
8112
- lines[key] = Math.min(4, Math.max(1, raw));
8417
+ lines[key] = clampLine(raw);
8113
8418
  }
8114
8419
  return lines;
8115
8420
  }
8421
+ function normalizeDensities(value) {
8422
+ const densities = {};
8423
+ if (!isRecord2(value)) return densities;
8424
+ for (const key of STATUSLINE_CONFIG_KEYS) {
8425
+ const raw = value[key];
8426
+ if (typeof raw !== "string") continue;
8427
+ if (!STATUSLINE_DENSITY_LEVELS.includes(raw)) continue;
8428
+ densities[key] = raw;
8429
+ }
8430
+ return densities;
8431
+ }
8116
8432
  function parseDocument(value) {
8117
- if (isRecord(value) && (isRecord(value["chips"]) || isRecord(value["lines"]))) {
8433
+ if (isRecord2(value) && (isRecord2(value["chips"]) || isRecord2(value["lines"]) || isRecord2(value["densities"]))) {
8118
8434
  return {
8119
8435
  version: STATUSLINE_CONFIG_VERSION,
8120
8436
  chips: normalizeChips(value["chips"]),
8121
- lines: normalizeLines(value["lines"])
8437
+ lines: normalizeLines(value["lines"]),
8438
+ densities: normalizeDensities(value["densities"])
8122
8439
  };
8123
8440
  }
8124
- return { version: STATUSLINE_CONFIG_VERSION, chips: normalizeChips(value), lines: {} };
8441
+ return {
8442
+ version: STATUSLINE_CONFIG_VERSION,
8443
+ chips: normalizeChips(value),
8444
+ lines: {},
8445
+ densities: {}
8446
+ };
8125
8447
  }
8126
8448
  function isMissingKnownChips(value) {
8127
- return !isRecord(value) || STATUSLINE_CONFIG_KEYS.some((key) => typeof value[key] !== "boolean");
8449
+ return !isRecord2(value) || STATUSLINE_CONFIG_KEYS.some((key) => typeof value[key] !== "boolean");
8128
8450
  }
8129
8451
  function needsRewrite(value) {
8130
- if (isRecord(value) && isRecord(value["chips"])) {
8452
+ if (isRecord2(value) && isRecord2(value["chips"])) {
8131
8453
  if (value["version"] !== STATUSLINE_CONFIG_VERSION) return true;
8132
8454
  if (isMissingKnownChips(value["chips"])) return true;
8133
- if (!isRecord(value["lines"])) return true;
8134
- return JSON.stringify(normalizeLines(value["lines"])) !== JSON.stringify(value["lines"]);
8455
+ if (!isRecord2(value["lines"]) || !isRecord2(value["densities"])) return true;
8456
+ return JSON.stringify(normalizeLines(value["lines"])) !== JSON.stringify(value["lines"]) || JSON.stringify(normalizeDensities(value["densities"])) !== JSON.stringify(value["densities"]);
8135
8457
  }
8136
8458
  return true;
8137
8459
  }
@@ -8160,7 +8482,7 @@ async function ensureStatuslineConfig() {
8160
8482
  raw = JSON.parse(await fs3.readFile(resolveConfigPath(), "utf8"));
8161
8483
  config = parseDocument(raw);
8162
8484
  } catch (error) {
8163
- if (isRecord(error) && error["code"] === "ENOENT") {
8485
+ if (isRecord2(error) && error["code"] === "ENOENT") {
8164
8486
  sawFile = false;
8165
8487
  config = emptyDocument();
8166
8488
  } else {
@@ -8188,7 +8510,8 @@ async function saveStatuslineConfig(config) {
8188
8510
  {
8189
8511
  version: STATUSLINE_CONFIG_VERSION,
8190
8512
  chips: normalizeChips(config.chips),
8191
- lines: normalizeLines(config.lines)
8513
+ lines: normalizeLines(config.lines),
8514
+ densities: normalizeDensities(config.densities)
8192
8515
  },
8193
8516
  null,
8194
8517
  2
@@ -8206,9 +8529,33 @@ async function saveStatuslineConfig(config) {
8206
8529
  async function loadStatuslineLines() {
8207
8530
  return (await loadStatuslineConfig()).lines;
8208
8531
  }
8209
- async function saveStatuslineLines(lines) {
8210
- const doc = await ensureStatuslineConfig();
8211
- await saveStatuslineConfig({ ...doc, lines: normalizeLines(lines) });
8532
+ async function loadStatuslineDensities() {
8533
+ return (await loadStatuslineConfig()).densities;
8534
+ }
8535
+ var docMutationChain = Promise.resolve();
8536
+ function queueDocMutation(mutate) {
8537
+ const run = docMutationChain.then(mutate, mutate);
8538
+ docMutationChain = run.then(
8539
+ () => void 0,
8540
+ () => void 0
8541
+ );
8542
+ return run;
8543
+ }
8544
+ async function saveStatuslineLayout(layout) {
8545
+ await queueDocMutation(async () => {
8546
+ const doc = await ensureStatuslineConfig();
8547
+ await saveStatuslineConfig({
8548
+ ...doc,
8549
+ lines: normalizeLines(layout.lines ?? doc.lines),
8550
+ densities: normalizeDensities(layout.densities ?? doc.densities)
8551
+ });
8552
+ });
8553
+ }
8554
+ async function saveStatuslineChips(chips) {
8555
+ await queueDocMutation(async () => {
8556
+ const doc = await ensureStatuslineConfig();
8557
+ await saveStatuslineConfig({ ...doc, chips: normalizeChips(chips) });
8558
+ });
8212
8559
  }
8213
8560
 
8214
8561
  // src/slash-commands/helpers.ts
@@ -9246,7 +9593,7 @@ import { randomUUID as randomUUID6 } from "node:crypto";
9246
9593
  import { color as color15 } from "@wrongstack/core/utils";
9247
9594
 
9248
9595
  // src/slash-commands/brain-council.ts
9249
- import { parseModelRef } from "@wrongstack/core/agent";
9596
+ import { parseModelRef as parseModelRef2 } from "@wrongstack/core/agent";
9250
9597
  import {
9251
9598
  BUILTIN_COUNCIL_PERSONA_IDS,
9252
9599
  BUILTIN_COUNCIL_PERSONAS
@@ -9258,11 +9605,12 @@ var COUNCIL_NUMERIC_OPS = {
9258
9605
  timeout: "perCallTimeoutMs",
9259
9606
  concurrency: "maxConcurrency",
9260
9607
  votertokens: "voterMaxTokens",
9261
- judgetokens: "judgeMaxTokens"
9608
+ judgetokens: "judgeMaxTokens",
9609
+ rounds: "deliberationRounds"
9262
9610
  };
9263
9611
  var PERSONA_SHORTHANDS = new Set(BUILTIN_COUNCIL_PERSONA_IDS);
9264
9612
  function parseRefEntry(ref) {
9265
- const parsed = parseModelRef(ref);
9613
+ const parsed = parseModelRef2(ref);
9266
9614
  const model = parsed.model?.trim();
9267
9615
  if (!model) return null;
9268
9616
  return parsed.provider ? { provider: parsed.provider, model } : { model };
@@ -9391,22 +9739,19 @@ async function handleBrainCouncilSubcommand(rest, opts, applyPatch) {
9391
9739
  return `Brain council ${op} set to ${color13.cyan(applied === void 0 ? "default" : String(applied))}`;
9392
9740
  });
9393
9741
  }
9394
- const msg = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, votertokens, or judgetokens.`;
9742
+ const msg = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, votertokens, judgetokens, or rounds.`;
9395
9743
  opts.renderer.writeWarning(msg);
9396
9744
  return { message: msg };
9397
9745
  }
9398
9746
 
9399
9747
  // src/slash-commands/brain-status.ts
9400
9748
  import { readFile as readFile5 } from "node:fs/promises";
9749
+ import { DETERMINISTIC_BRAIN_TIERS } from "@wrongstack/core/coordination";
9401
9750
  import { color as color14 } from "@wrongstack/core/utils";
9402
- var DETERMINISTIC_TIER_NAMES = [
9403
- "rule",
9404
- "policy",
9405
- "heuristic",
9406
- "cache",
9407
- "ledger-guard",
9408
- "terminal"
9409
- ];
9751
+ function councilRoundsSummary(snapshot) {
9752
+ const rounds = snapshot.council.deliberationRounds ?? 2;
9753
+ return rounds > 1 ? `, ${rounds} rounds` : ", no deliberation";
9754
+ }
9410
9755
  function fmtAge(at) {
9411
9756
  const s = Math.max(0, Math.round((Date.now() - at) / 1e3));
9412
9757
  if (s < 60) return `${s}s ago`;
@@ -9440,7 +9785,7 @@ function formatBrainStatus(opts) {
9440
9785
  const councilSeats = opts.brainSettings?.councilLabels ?? [];
9441
9786
  if (councilSeats.length > 0) {
9442
9787
  lines.push(
9443
- ` council: ${color14.cyan(councilSeats.join(", "))}${snapshot ? color14.dim(` (minRisk: ${snapshot.council.minRisk}${judgeSummary(snapshot)})`) : ""}`
9788
+ ` council: ${color14.cyan(councilSeats.join(", "))}${snapshot ? color14.dim(` (minRisk: ${snapshot.council.minRisk}${judgeSummary(snapshot)}${councilRoundsSummary(snapshot)})`) : ""}`
9444
9789
  );
9445
9790
  } else if (snapshot) {
9446
9791
  lines.push(` council: ${color14.dim("disabled (/brain council on + voters)")}`);
@@ -9469,21 +9814,25 @@ function formatBrainStatus(opts) {
9469
9814
  }
9470
9815
  function formatBrainStats(opts) {
9471
9816
  const log = opts.getBrainLog?.() ?? [];
9817
+ const councilWarnings = log.filter((entry) => entry.kind === "council_warn");
9818
+ const lifetime = opts.brainTierStats?.();
9472
9819
  const counts = /* @__PURE__ */ new Map();
9473
- const councilWarnings = [];
9474
- for (const entry of log) {
9475
- if (entry.kind === "council_warn") {
9476
- councilWarnings.push(entry);
9477
- continue;
9820
+ if (lifetime) {
9821
+ for (const [tier, n] of Object.entries(lifetime.byTier)) counts.set(tier, n ?? 0);
9822
+ if (lifetime.unattributed > 0) counts.set("unattributed", lifetime.unattributed);
9823
+ } else {
9824
+ for (const entry of log) {
9825
+ if (entry.kind === "council_warn") continue;
9826
+ counts.set(entry.tier ?? "unattributed", (counts.get(entry.tier ?? "unattributed") ?? 0) + 1);
9478
9827
  }
9479
- const tier = entry.tier ?? "unattributed";
9480
- counts.set(tier, (counts.get(tier) ?? 0) + 1);
9481
9828
  }
9482
- let free = 0;
9483
- let paid = 0;
9484
- for (const [tier, n] of counts) {
9485
- if (DETERMINISTIC_TIER_NAMES.includes(tier)) free += n;
9486
- else if (tier === "llm" || tier === "council") paid += n;
9829
+ let free = lifetime?.deterministic ?? 0;
9830
+ let paid = lifetime?.llmBacked ?? 0;
9831
+ if (!lifetime) {
9832
+ for (const [tier, n] of counts) {
9833
+ if (DETERMINISTIC_BRAIN_TIERS.has(tier)) free += n;
9834
+ else if (tier === "llm" || tier === "council") paid += n;
9835
+ }
9487
9836
  }
9488
9837
  const lines = [color14.bold("Brain decision tiers"), ""];
9489
9838
  if (counts.size === 0) {
@@ -9516,7 +9865,9 @@ function formatBrainStats(opts) {
9516
9865
  }
9517
9866
  lines.push(
9518
9867
  "",
9519
- color14.dim(` Based on the last ${log.length} logged decision(s) of this session.`)
9868
+ color14.dim(
9869
+ lifetime ? ` ${lifetime.total} decision(s) this session.` : ` Based on the last ${log.length} logged decision(s) of this session.`
9870
+ )
9520
9871
  );
9521
9872
  return lines.join("\n");
9522
9873
  }
@@ -12447,7 +12798,7 @@ function buildDoctorCommand(opts) {
12447
12798
  ].join("\n");
12448
12799
  async function loadPluginSchemas() {
12449
12800
  try {
12450
- const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-7N3TF2QF.js");
12801
+ const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-PZ2VZL7V.js");
12451
12802
  const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
12452
12803
  const loaded = [];
12453
12804
  for (const s of settled) {
@@ -12851,7 +13202,7 @@ import * as fs7 from "node:fs/promises";
12851
13202
  import {
12852
13203
  diagnoseFallbackConfig,
12853
13204
  normalizeModelRef,
12854
- parseModelRef as parseModelRef2,
13205
+ parseModelRef as parseModelRef3,
12855
13206
  runtimeFallbackChain,
12856
13207
  simulateFallbackFailover,
12857
13208
  smartDefaultFallbackChain
@@ -12860,7 +13211,7 @@ import { decryptConfigSecrets, encryptConfigSecrets, noOpVault as noOpVault2 } f
12860
13211
  import { ConfigError } from "@wrongstack/core/types";
12861
13212
  import { atomicWrite as atomicWrite4, color as color25, toErrorMessage as toErrorMessage10 } from "@wrongstack/core/utils";
12862
13213
  function refInvalidReason(ref, config) {
12863
- const parsed = parseModelRef2(ref);
13214
+ const parsed = parseModelRef3(ref);
12864
13215
  if (!parsed.model) return "no model in reference";
12865
13216
  const favorites = config.favoriteModels ?? [];
12866
13217
  if (favorites.length === 0) return void 0;
@@ -12870,7 +13221,7 @@ function refInvalidReason(ref, config) {
12870
13221
  return void 0;
12871
13222
  }
12872
13223
  function refStaleModelListWarning(ref, config) {
12873
- const parsed = parseModelRef2(ref);
13224
+ const parsed = parseModelRef3(ref);
12874
13225
  if (!parsed.model) return "no model in reference";
12875
13226
  const providerId = parsed.provider ?? config.provider;
12876
13227
  const entry = config.providers?.[providerId];
@@ -13159,7 +13510,7 @@ function buildFallbackCommand(opts) {
13159
13510
  };
13160
13511
  }
13161
13512
  const ref = normalizeRef(parts.slice(2).join(" "));
13162
- const parsed = parseModelRef2(ref);
13513
+ const parsed = parseModelRef3(ref);
13163
13514
  if (!ref || !parsed.provider || !parsed.model) {
13164
13515
  return {
13165
13516
  message: `${color25.amber("Usage:")} /fallback bridge set <provider/model>`
@@ -13401,13 +13752,13 @@ ${color25.dim("Add favorites first: /fallback fav add <ref>, or fix provider mod
13401
13752
  return { message: `${color25.amber("Already favorite")}: ${color25.cyan(ref)}` };
13402
13753
  }
13403
13754
  const providerEntry = (() => {
13404
- const parsed = parseModelRef2(ref);
13755
+ const parsed = parseModelRef3(ref);
13405
13756
  const provId = parsed.provider ?? config.provider;
13406
13757
  return config.providers?.[provId];
13407
13758
  })();
13408
- if (providerEntry?.models && providerEntry.models.length > 0 && !providerEntry.models.includes(parseModelRef2(ref).model)) {
13759
+ if (providerEntry?.models && providerEntry.models.length > 0 && !providerEntry.models.includes(parseModelRef3(ref).model)) {
13409
13760
  return {
13410
- message: `${color25.red("Cannot favorite")}: "${ref}" \u2014 ${parseModelRef2(ref).model} not in ${parseModelRef2(ref).provider ?? config.provider} model list (${providerEntry.models.join(", ")}). ${color25.dim("Pick a model the provider actually exposes.")}`
13761
+ message: `${color25.red("Cannot favorite")}: "${ref}" \u2014 ${parseModelRef3(ref).model} not in ${parseModelRef3(ref).provider ?? config.provider} model list (${providerEntry.models.join(", ")}). ${color25.dim("Pick a model the provider actually exposes.")}`
13411
13762
  };
13412
13763
  }
13413
13764
  favorites.push(ref);
@@ -15841,6 +16192,75 @@ function buildHealthCommand(opts) {
15841
16192
  };
15842
16193
  }
15843
16194
 
16195
+ // src/slash-commands/slash-deep-help.ts
16196
+ var slashToSubcommand = {
16197
+ // ── Existing slash commands ───────────────────────────────────────
16198
+ // These slash commands ARE registered today. The wiring on the
16199
+ // slash side imports `renderSlashFocusedHelp` from this module
16200
+ // and short-circuits `help` / `--help` / `-h` to the focused
16201
+ // block. The entries here are the bridge that wires each
16202
+ // slash command to its top-level subcommand counterpart.
16203
+ auth: "auth",
16204
+ mcp: "mcp",
16205
+ plugin: "plugin",
16206
+ models: "models",
16207
+ sessions: "sessions",
16208
+ tools: "tools",
16209
+ init: "init",
16210
+ doctor: "doctor",
16211
+ // ── Forward-compatible bindings ───────────────────────────────────
16212
+ // No slash command with this name exists yet. When a future
16213
+ // contributor adds one (e.g. `packages/cli/src/slash-commands/config.ts`
16214
+ // with `name: 'config'`), the entry below is the wiring point
16215
+ // for `/help <name>` to render the same block `wstack <name> --help`
16216
+ // would write. The contributor still has to add the
16217
+ // `wantsDeepHelp` / focused-help short-circuit to the new slash
16218
+ // command's `run()` method (mirroring the pattern in
16219
+ // `auth.ts` / `mcp.ts` / etc.) — this map just registers the
16220
+ // dispatch target for the existing `/help <name>` renderer.
16221
+ //
16222
+ // Adding an entry here is a one-line, type-checked change.
16223
+ // There's no runtime cost when the slash command doesn't exist
16224
+ // yet — `renderSlashFocusedHelp` only fires when the user types
16225
+ // `/help <name>`, and if the slash command isn't registered,
16226
+ // the existing inline-help path is the fallback.
16227
+ config: "config",
16228
+ audit: "audit",
16229
+ replay: "replay",
16230
+ rewind: "rewind",
16231
+ export: "export",
16232
+ usage: "usage",
16233
+ providers: "providers",
16234
+ skills: "skills",
16235
+ update: "update",
16236
+ projects: "projects",
16237
+ acp: "acp",
16238
+ modeldiag: "modeldiag",
16239
+ bench: "bench",
16240
+ diag: "diag",
16241
+ version: "version",
16242
+ // `quick` is intercepted by `boot()` for the TUI launch, but
16243
+ // its focused-help entry (`wstack quick --help`) still resolves
16244
+ // through the per-subcommand-help table. Including it here
16245
+ // means a future `/quick` slash command (if one is ever added)
16246
+ // gets the focused-help wiring automatically.
16247
+ quick: "quick"
16248
+ };
16249
+ var slashesWithFocusedHelp = Object.keys(slashToSubcommand);
16250
+ function resolveSlashSubcommand(slashName) {
16251
+ return slashToSubcommand[slashName];
16252
+ }
16253
+ function renderSlashFocusedHelp(slashName) {
16254
+ const sub = resolveSlashSubcommand(slashName);
16255
+ if (!sub) return void 0;
16256
+ return renderFocusedHelpToString(sub);
16257
+ }
16258
+ function renderSlashDeepHelp(slashName, deep) {
16259
+ const sub = resolveSlashSubcommand(slashName);
16260
+ if (!sub) return void 0;
16261
+ return renderDeepHelpToString(`${sub}:${deep}`);
16262
+ }
16263
+
15844
16264
  // src/slash-commands/help.ts
15845
16265
  function buildHelpCommand(opts) {
15846
16266
  return {
@@ -15864,6 +16284,12 @@ function buildHelpCommand(opts) {
15864
16284
  return { message: "" };
15865
16285
  }
15866
16286
  if (query) {
16287
+ const queryParts = query.split(/\s+/).filter(Boolean);
16288
+ if (queryParts.length === 2) {
16289
+ const head = queryParts[0].replace(/^\//, "");
16290
+ const deepHelp = renderSlashDeepHelp(head, queryParts[1]);
16291
+ if (deepHelp) return { message: deepHelp };
16292
+ }
15867
16293
  const needle = query.startsWith("/") ? query.slice(1) : query;
15868
16294
  let match;
15869
16295
  for (const entry of opts.registry.listWithOwner()) {
@@ -15884,7 +16310,8 @@ function buildHelpCommand(opts) {
15884
16310
  const header = `/${prefix}${match.cmd.name}`;
15885
16311
  const aliasLine = match.cmd.aliases?.length ? `Aliases: ${match.cmd.aliases.map((a) => `/${prefix}${a}`).join(", ")}
15886
16312
  ` : "";
15887
- const body = match.cmd.help ?? match.cmd.description;
16313
+ const focused = renderSlashFocusedHelp(match.cmd.name);
16314
+ const body = [match.cmd.help ?? match.cmd.description, focused].filter(Boolean).join("\n\n");
15888
16315
  return {
15889
16316
  message: [
15890
16317
  header,
@@ -18529,7 +18956,7 @@ function errorMessage(err) {
18529
18956
 
18530
18957
  // src/slash-commands/memory.ts
18531
18958
  import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
18532
- import { getSageSurface as getSageSurface3 } from "@wrongstack/sage";
18959
+ import { getSageSurface as getSageSurface4 } from "@wrongstack/sage";
18533
18960
 
18534
18961
  // src/slash-commands/memory-audience.ts
18535
18962
  import { toErrorMessage as toErrorMessage14 } from "@wrongstack/core/utils";
@@ -19854,6 +20281,7 @@ import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
19854
20281
  import {
19855
20282
  fileTriageProposals,
19856
20283
  formatTriageReport,
20284
+ getSageSurface as getSageSurface3,
19857
20285
  runTriage
19858
20286
  } from "@wrongstack/sage";
19859
20287
  var DEFAULT_MAX_PHASE3 = 1e3;
@@ -19975,8 +20403,7 @@ Usage: /memory triage [--dry-run|--apply] [--limit N] [--max-phase3 N] [--max-ph
19975
20403
  function getSage(opts) {
19976
20404
  if (!opts.memoryStore) return null;
19977
20405
  try {
19978
- const { getSageSurface: getSageSurface4 } = __require("@wrongstack/sage");
19979
- return getSageSurface4(opts.memoryStore);
20406
+ return getSageSurface3(opts.memoryStore) ?? null;
19980
20407
  } catch {
19981
20408
  return null;
19982
20409
  }
@@ -20069,7 +20496,7 @@ function buildMemoryCommand(opts) {
20069
20496
  async run(args) {
20070
20497
  const store = opts.memoryStore;
20071
20498
  if (!store) return { message: "No memory store configured." };
20072
- const Sage = getSageSurface3(store);
20499
+ const Sage = getSageSurface4(store);
20073
20500
  const { cmd, rest } = parseSubcommand(args);
20074
20501
  const restJoined = rest.join(" ").trim();
20075
20502
  switch (cmd) {
@@ -20282,7 +20709,7 @@ function buildMemoryCommand(opts) {
20282
20709
  };
20283
20710
  }
20284
20711
  try {
20285
- const lexical = await Sage.searchSage(restJoined, { limit: 20 });
20712
+ const lexical = Sage.searchSageWithBreakdown ? (await Sage.searchSageWithBreakdown(restJoined, { limit: 20 })).filter((hit) => hit.lexicalScore !== null).sort((a, b) => (b.lexicalScore ?? 0) - (a.lexicalScore ?? 0)).map((hit) => hit.memory) : await Sage.searchSage(restJoined, { limit: 20 });
20286
20713
  const race = await runSearchRace(restJoined, lexical, vectorStore, { limit: 20 });
20287
20714
  return { message: formatSearchRace(race) };
20288
20715
  } catch (err) {
@@ -22057,7 +22484,7 @@ function buildPruneCommand(opts) {
22057
22484
  return {
22058
22485
  name: "prune",
22059
22486
  category: "Session",
22060
- description: "Delete old sessions. /prune (default 30d), /prune 7, /prune --rebuild-index.",
22487
+ description: "Delete old sessions. /prune (default 30d). To compress instead of delete, use /sessions archive.",
22061
22488
  help: "Usage:\n /prune Delete sessions older than 30 days.\n /prune 14 Delete sessions older than 14 days.\n /prune --dry-run Show what would be deleted without deleting.\n /prune --rebuild-index Rebuild the session index from disk.",
22062
22489
  async run(args) {
22063
22490
  const parts = args.split(/\s+/).filter(Boolean);
@@ -23452,7 +23879,11 @@ ${sddHelp()}`
23452
23879
  }
23453
23880
 
23454
23881
  // src/slash-commands/session.ts
23455
- import { extractInterruptedTools, SessionRecovery } from "@wrongstack/core/storage";
23882
+ import {
23883
+ extractInterruptedTools,
23884
+ getSessionRegistry,
23885
+ SessionRecovery
23886
+ } from "@wrongstack/core/storage";
23456
23887
  import { color as color47, isPidAlive, toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
23457
23888
  function statusIcon2(status) {
23458
23889
  switch (status) {
@@ -23484,6 +23915,12 @@ function agentStatusIcon(status) {
23484
23915
  return color47.dim("?");
23485
23916
  }
23486
23917
  }
23918
+ function formatBytes(value) {
23919
+ if (!value || !Number.isFinite(value) || value <= 0) return "0B";
23920
+ if (value < 1024) return `${value}B`;
23921
+ if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)}KB`;
23922
+ return `${(value / (1024 * 1024)).toFixed(1)}MB`;
23923
+ }
23487
23924
  function fmtDuration(startedAt) {
23488
23925
  const diff = Date.now() - new Date(startedAt).getTime();
23489
23926
  const min = Math.floor(diff / 6e4);
@@ -23501,8 +23938,7 @@ function fmtAgentLine(agent) {
23501
23938
  }
23502
23939
  function getRegistry() {
23503
23940
  try {
23504
- const mod = __require("@wrongstack/core/storage");
23505
- return mod.getSessionRegistry?.();
23941
+ return getSessionRegistry();
23506
23942
  } catch {
23507
23943
  return void 0;
23508
23944
  }
@@ -23529,7 +23965,7 @@ function buildLoadCommand(opts) {
23529
23965
  name: "sessions",
23530
23966
  category: "Session",
23531
23967
  aliases: ["resume", "load"],
23532
- description: "List recent sessions, show incomplete ones (--incomplete), or plan a recovery (--recover <id>).",
23968
+ description: "List, resume, archive, or recover sessions. /sessions archive compresses old JSONL logs.",
23533
23969
  async run(args) {
23534
23970
  const parts = args.split(/\s+/).filter(Boolean);
23535
23971
  const first = parts[0]?.toLowerCase();
@@ -23578,6 +24014,58 @@ function buildLoadCommand(opts) {
23578
24014
  return { message: color47.red(`Rename failed: ${toErrorMessage21(err)}`) };
23579
24015
  }
23580
24016
  }
24017
+ if (first === "archive") {
24018
+ if (!opts.sessionStore?.archive || !opts.sessionStore.archiveIdle) {
24019
+ return { message: color47.yellow("Session store does not support archive.") };
24020
+ }
24021
+ const apply = parts.includes("--apply");
24022
+ const targetId = parts.filter((p) => p !== "--apply" && p !== "archive")[0];
24023
+ if (targetId) {
24024
+ try {
24025
+ const result2 = await opts.sessionStore.archive(targetId);
24026
+ return {
24027
+ message: result2.action === "archived" ? color47.green(
24028
+ `Archived ${targetId} (${formatBytes(result2.uncompressedBytes)} \u2192 ${formatBytes(result2.compressedBytes)})`
24029
+ ) : color47.dim(`Archive ${result2.action}: ${targetId}${result2.reason ? ` (${result2.reason})` : ""}`)
24030
+ };
24031
+ } catch (err) {
24032
+ return { message: color47.red(`Archive failed: ${toErrorMessage21(err)}`) };
24033
+ }
24034
+ }
24035
+ if (!apply) {
24036
+ const preview = await opts.sessionStore.list(1e3);
24037
+ return {
24038
+ message: [
24039
+ color47.bold("Dry run \u2014 gzip existing closed session logs (JSONL stays the resume authority)."),
24040
+ color47.dim("Last 20 stay hot; everything else is gzipped immediately. /prune still deletes."),
24041
+ color47.dim(`Currently listed: ${preview.length} session(s).`),
24042
+ "",
24043
+ color47.dim("Run /sessions archive --apply to compress, or /sessions archive <id> for one session.")
24044
+ ].join("\n")
24045
+ };
24046
+ }
24047
+ const result = await opts.sessionStore.archiveIdle({ backfill: true });
24048
+ return {
24049
+ message: `Archived ${color47.green(String(result.archived))} \xB7 skipped ${color47.dim(String(result.skipped))} \xB7 failed ${result.failed ? color47.red(String(result.failed)) : color47.dim("0")}.`
24050
+ };
24051
+ }
24052
+ if (first === "rehydrate") {
24053
+ const targetId = parts[1];
24054
+ if (!targetId) {
24055
+ return { message: color47.yellow("Usage: /sessions rehydrate <sessionId>") };
24056
+ }
24057
+ if (!opts.sessionStore?.rehydrate) {
24058
+ return { message: color47.yellow("Session store does not support rehydrate.") };
24059
+ }
24060
+ try {
24061
+ const result = await opts.sessionStore.rehydrate(targetId);
24062
+ return {
24063
+ message: result.action === "rehydrated" ? color47.green(`Rehydrated ${targetId}`) : color47.dim(`Rehydrate ${result.action}: ${targetId}`)
24064
+ };
24065
+ } catch (err) {
24066
+ return { message: color47.red(`Rehydrate failed: ${toErrorMessage21(err)}`) };
24067
+ }
24068
+ }
23581
24069
  if (first === "delete") {
23582
24070
  const targetId = parts[1];
23583
24071
  if (!targetId) {
@@ -23712,10 +24200,11 @@ function buildLoadCommand(opts) {
23712
24200
  }
23713
24201
  const stat6 = parts2.join(" ");
23714
24202
  const date = color47.dim(s.startedAt.slice(0, 16).replace("T", " "));
24203
+ const archived = s.storageState === "cold" ? color47.dim(" gz") : "";
23715
24204
  const isCurrent = s.id === currentId;
23716
24205
  const marker = isCurrent ? color47.cyan(" (current)") : "";
23717
24206
  const label = s.name ? `${color47.bold(s.id)} ${color47.cyan(`(${s.name})`)}` : color47.bold(s.id);
23718
- return ` ${label}${marker}
24207
+ return ` ${label}${marker}${archived}
23719
24208
  ${date} ${stat6}
23720
24209
  ${color47.dim(s.title)}`;
23721
24210
  });
@@ -23992,7 +24481,7 @@ async function killSession(sessionId, confirm) {
23992
24481
 
23993
24482
  // src/slash-commands/setmodel.ts
23994
24483
  import * as fs15 from "node:fs/promises";
23995
- import { fallbackProfileChain, parseModelRef as parseModelRef3 } from "@wrongstack/core/agent";
24484
+ import { fallbackProfileChain, parseModelRef as parseModelRef4 } from "@wrongstack/core/agent";
23996
24485
  import { AGENT_CATALOG as AGENT_CATALOG2, AGENTS_BY_PHASE as AGENTS_BY_PHASE3 } from "@wrongstack/core/agent-catalog";
23997
24486
  import {
23998
24487
  MATRIX_PHASE_KEYS,
@@ -24390,7 +24879,7 @@ function buildSetModelCommand(opts) {
24390
24879
  const first = chain[0];
24391
24880
  if (!first)
24392
24881
  return { message: `${color48.red("Empty profile")}: ${color48.amber(profile)}` };
24393
- const parsed = parseModelRef3(first);
24882
+ const parsed = parseModelRef4(first);
24394
24883
  const provider2 = parsed.provider ?? config.provider;
24395
24884
  if (!keyed.includes(provider2)) {
24396
24885
  return {
@@ -25189,6 +25678,38 @@ var THEME_META = {
25189
25678
  "gruvbox-dark-hard": {
25190
25679
  name: "Gruvbox Dark Hard",
25191
25680
  desc: "Maximum contrast Gruvbox on deep pitch charcoal"
25681
+ },
25682
+ "oceanic-next": {
25683
+ name: "Oceanic Next",
25684
+ desc: "Teal-and-slate classic \u2014 calm blue, warm coral"
25685
+ },
25686
+ "one-half-dark": {
25687
+ name: "One Half Dark",
25688
+ desc: "Atom's One Half \u2014 One Dark with cleaner contrast"
25689
+ },
25690
+ "ayu-mirage": { name: "Ayu Mirage", desc: "Dusk-slate Ayu, between Dark and Light" },
25691
+ seti: { name: "Seti", desc: "Long-running VS Code classic \u2014 charcoal, gold, cyan" },
25692
+ "paraiso-dark": { name: "Paraiso Dark", desc: "Base16 plum \u2014 warm, muted, low-glare" },
25693
+ darcula: { name: "Darcula", desc: "JetBrains' default dark \u2014 grey-green with amber" },
25694
+ "slack-dark": { name: "Slack Aubergine", desc: "Deep aubergine with sky blue and lime" },
25695
+ "vitesse-black": { name: "Vitesse Black", desc: "Vitesse on true black \u2014 least glare here" },
25696
+ "atom-dark": { name: "Atom Dark", desc: "The original Atom grey \u2014 neutral, low-chroma" },
25697
+ "github-dark-high-contrast": {
25698
+ name: "GitHub Dark High Contrast",
25699
+ desc: "Accessible GitHub \u2014 boosted text and borders"
25700
+ },
25701
+ "contrast-max": {
25702
+ name: "Maximum Contrast",
25703
+ desc: "Original \u2014 pure black, AAA-targeted text and borders"
25704
+ },
25705
+ "colorblind-safe": {
25706
+ name: "Colorblind Safe",
25707
+ desc: "Original \u2014 blue/orange coding, no red-vs-green reliance"
25708
+ },
25709
+ sandstone: { name: "Sandstone", desc: "Original \u2014 warm stone neutrals with sage and clay" },
25710
+ "everforest-hard": {
25711
+ name: "Everforest Hard",
25712
+ desc: "Everforest on its deepest base \u2014 more depth, same greens"
25192
25713
  }
25193
25714
  };
25194
25715
  var THEME_OPTIONS = THEME_PRESET_IDS.map((id) => ({ id, ...THEME_META[id] }));
@@ -26608,7 +27129,6 @@ function formatDelay(ms) {
26608
27129
  var ALL_SETTINGS_KEYS = [
26609
27130
  "delay",
26610
27131
  "mode",
26611
- "hints",
26612
27132
  "debug-stream",
26613
27133
  "config-scope",
26614
27134
  "fs-access",
@@ -26750,19 +27270,6 @@ async function executeSettingsSubcommand(sub, rest, opts) {
26750
27270
  });
26751
27271
  return { message: `${color54.green("\u2713")} default autonomy \u2192 ${color54.bold(raw)}` };
26752
27272
  }
26753
- if (sub === "hints") {
26754
- const raw = (rest[0] ?? "").toLowerCase();
26755
- if (!["on", "off"].includes(raw)) {
26756
- return { message: `${color54.amber("Usage:")} /settings hints on|off` };
26757
- }
26758
- const on = raw === "on";
26759
- await persistConfigSetting(persistDeps, (cfg) => {
26760
- cfg.hints = on;
26761
- });
26762
- return {
26763
- message: `${color54.green("\u2713")} launch hints \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
26764
- };
26765
- }
26766
27273
  if (sub === "debug-stream") {
26767
27274
  const raw = (rest[0] ?? "").toLowerCase();
26768
27275
  if (!["on", "off"].includes(raw)) {
@@ -27466,7 +27973,6 @@ var SETTINGS_HELP = [
27466
27973
  " /settings stream-fleet off|full Fleet-chat verbosity (on = full)",
27467
27974
  " /settings chime on|off Ring terminal bell when a run completes",
27468
27975
  " /settings confirm-exit on|off Ask for confirmation before interrupt/exit",
27469
- " /settings hints on|off Show or suppress rotating launch hints",
27470
27976
  " /settings debug-stream on|off Raw SSE hex-dump to stderr for debugging",
27471
27977
  " /settings config-scope global|project Save settings globally or per-project",
27472
27978
  " /settings fs-access unrestricted|project File-tool access scope (project = confine to project root)",
@@ -27523,7 +28029,6 @@ function formatSettingsDefaults() {
27523
28029
  "",
27524
28030
  ` auto-proceed delay: ${color55.cyan("45s")} ${color55.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
27525
28031
  ` default autonomy mode: ${color55.cyan("off")}`,
27526
- ` launch hints: ${color55.cyan("on")}`,
27527
28032
  ` iteration timeout: ${color55.cyan("5 min")}`,
27528
28033
  ` session timeout: ${color55.cyan("30 min")}`,
27529
28034
  ` max iterations: ${color55.cyan("100")}`,
@@ -27535,7 +28040,6 @@ function formatCurrentSettingsView(opts) {
27535
28040
  const autonomy = opts.configStore.get().autonomy;
27536
28041
  const delay = autonomy?.autoProceedDelayMs ?? 45e3;
27537
28042
  const mode = autonomy?.defaultMode ?? "off";
27538
- const hints = opts.configStore.get().hints !== false;
27539
28043
  const debugStream = opts.configStore.get().debugStream === true;
27540
28044
  const configScope = opts.configStore.get().configScope ?? "global";
27541
28045
  const fsAccess = opts.configStore.get().tools?.restrictToProjectRoot === true ? "project" : "unrestricted";
@@ -27584,7 +28088,6 @@ function formatCurrentSettingsView(opts) {
27584
28088
  ` fleet chat: ${color55.cyan(resolveFleetChatVerbosity(au))} ${color55.dim("change: /settings stream-fleet off|full")}`,
27585
28089
  ` completion chime: ${au?.chime === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings chime on|off")}`,
27586
28090
  ` confirm before exit: ${au?.confirmExit !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings confirm-exit on|off")}`,
27587
- ` launch hints: ${hints ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hints on|off")}`,
27588
28091
  ` debug stream: ${debugStream ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings debug-stream on|off")}`,
27589
28092
  ` config scope: ${color55.cyan(configScope)} ${color55.dim("change: /settings config-scope global|project")}`,
27590
28093
  ` filesystem access: ${color55.cyan(fsAccess)} ${color55.dim("change: /settings fs-access unrestricted|project")}`,
@@ -28079,67 +28582,68 @@ function buildDirectorCommand(opts) {
28079
28582
  }
28080
28583
 
28081
28584
  // src/slash-commands/statusline.ts
28082
- var ITEM_DESCRIPTIONS = {
28083
- state: "Agent run state / thinking spinner",
28084
- model: "Current provider/model id",
28085
- todos: "Todo items (pending/in-progress/done counts)",
28086
- plan: "Plan board items (open/in-progress/done)",
28087
- tasks: "Task board items (structured work with type/priority)",
28088
- fleet: "Fleet agent status (running/idle/pending/completed)",
28089
- fleet_agents: "Per-agent live detail row",
28090
- git: "Git branch name",
28091
- elapsed: "Session elapsed time",
28092
- context: "Context window usage (input tokens)",
28093
- tokens: "Input/output token counters",
28094
- cache: "Prompt cache hit ratio",
28095
- cost: "Token cost estimate (input/output/total)",
28096
- queue: "Queued prompt count",
28097
- hint: "Transient status hint text",
28098
- index: "Codebase indexing status",
28099
- breaker: "Process breaker countdown",
28100
- working_dir: "Current working directory",
28101
- project: "Project name",
28102
- yolo: "YOLO permission mode",
28103
- autonomy: "Autonomy mode",
28104
- eternal_stage: "Autonomy stage",
28105
- goal: "Active goal summary",
28106
- mode: "Active agent mode label",
28107
- auto_proceed: "Auto-proceed countdown",
28108
- sessions: "Live session count",
28109
- tools: "Registered tool count",
28110
- theme: "Active color theme preset",
28111
- token_saving: "Token-saving mode indicator",
28112
- side_effects: "Side-effect / audit event count",
28113
- processes: "Tracked bash/exec process count",
28114
- version: "WrongStack version + update notice (right-anchored)",
28115
- dropped_tools: "Tools dropped from the provider request (maxTools limit)",
28116
- prompt_variant: "System prompt variant (Lite / Standard / Pro)",
28117
- brain: "Brain arbiter decisions",
28118
- mailbox: "Mailbox unread messages and peers",
28119
- enhance: "Prompt-enhance countdown",
28120
- debug_stream: "Stream debug telemetry",
28121
- next_steps: "Next-step auto-submit countdown",
28122
- memory_context: "Memory context detail (total records + active-in-context)"
28123
- };
28585
+ import {
28586
+ CHIP_DESCRIPTIONS,
28587
+ clampLine as clampLine2,
28588
+ effectiveDensity,
28589
+ effectiveLine,
28590
+ LINE_TITLES,
28591
+ STATUSLINE_DENSITY_LEVELS as STATUSLINE_DENSITY_LEVELS2
28592
+ } from "@wrongstack/core/statusline";
28124
28593
  var ALL_CONFIG_KEYS = STATUSLINE_CONFIG_KEYS;
28594
+ function isConfigKey(value) {
28595
+ return value != null && ALL_CONFIG_KEYS.includes(value);
28596
+ }
28597
+ function isDensity(value) {
28598
+ return value === "auto" || value != null && STATUSLINE_DENSITY_LEVELS2.includes(value);
28599
+ }
28600
+ function renderLayout(cfg) {
28601
+ const out = [];
28602
+ for (const line of [1, 2, 3, 4]) {
28603
+ const items = ALL_CONFIG_KEYS.filter(
28604
+ (key) => effectiveLine(key, cfg.lines) === line && cfg.chips[key] !== false
28605
+ );
28606
+ out.push(`Line ${line} \u2014 ${LINE_TITLES[line]}`);
28607
+ out.push(
28608
+ items.length === 0 ? " (empty)" : ` ${items.map((key) => {
28609
+ const density = effectiveDensity(key, cfg.densities);
28610
+ return density === "auto" ? key : `${key}:${density}`;
28611
+ }).join(" ")}`
28612
+ );
28613
+ }
28614
+ const off = ALL_CONFIG_KEYS.filter((key) => cfg.chips[key] === false);
28615
+ if (off.length > 0) out.push(`Off \u2014 ${off.join(" ")}`);
28616
+ return out;
28617
+ }
28125
28618
  function buildStatuslineCommand(deps) {
28126
28619
  return {
28127
28620
  name: "statusline",
28128
28621
  category: "Config",
28129
28622
  aliases: ["sl"],
28130
- description: "Customize status bar chips: /statusline [item] [on|off|reset]",
28623
+ description: "Customize status bar chips: /statusline [item] [on|off|line N|density D]",
28131
28624
  help: [
28132
- "Usage: /statusline [item] [on|off|reset]",
28133
- " /statusline \u2014 show current config",
28134
- " /statusline <item> \u2014 toggle item on/off",
28135
- " /statusline <item> on \u2014 enable a chip",
28136
- " /statusline <item> off \u2014 disable a chip",
28137
- " /statusline all on \u2014 enable all chips",
28138
- " /statusline all off \u2014 disable all chips",
28139
- " /statusline reset \u2014 restore defaults",
28625
+ "Usage: /statusline \u2014 open the picker (TUI) or list the config",
28626
+ " /statusline preview \u2014 show the four lines as they are laid out",
28627
+ " /statusline <item> \u2014 toggle a chip on/off",
28628
+ " /statusline <item> on|off \u2014 enable/disable a chip",
28629
+ " /statusline <item> line <1-4> \u2014 move a chip to another line",
28630
+ " /statusline <item> density <d> \u2014 pin a chip to auto|full|short|micro",
28631
+ " /statusline all on|off \u2014 enable/disable every chip",
28632
+ " /statusline layout reset \u2014 restore default lines and densities",
28633
+ " /statusline reset \u2014 restore default chip visibility",
28634
+ "",
28635
+ "Lines are assigned by volatility:",
28636
+ " 1 IDENTITY fixed for the session",
28637
+ " 2 VITALS redraws every token",
28638
+ " 3 SAFETY & WORK posture + work in flight",
28639
+ " 4 ASYNC background activity & countdowns",
28640
+ "",
28641
+ "Density controls how much of a chip renders. With `auto` the rail",
28642
+ "shortens the widest chip first and only drops a chip once every chip",
28643
+ "on that line is already at `micro`.",
28140
28644
  "",
28141
28645
  "Available items:",
28142
- ...ALL_CONFIG_KEYS.map((k) => ` ${k.padEnd(12)} ${ITEM_DESCRIPTIONS[k]}`),
28646
+ ...ALL_CONFIG_KEYS.map((k) => ` ${k.padEnd(16)} ${CHIP_DESCRIPTIONS[k]}`),
28143
28647
  "",
28144
28648
  "Density mode (minimum/detailed/no-color) is a separate setting \u2014 see /settings.",
28145
28649
  "These toggles set chip eligibility in any mode; some chips only render in detailed mode.",
@@ -28149,8 +28653,8 @@ function buildStatuslineCommand(deps) {
28149
28653
  async run(args) {
28150
28654
  const cfg = await deps.getConfig();
28151
28655
  const trimmed = args.trim();
28152
- const parts = trimmed.split(/\s+/);
28153
- const [item, action] = parts;
28656
+ const parts = trimmed.split(/\s+/).filter(Boolean);
28657
+ const [item, action, value] = parts;
28154
28658
  if (!item && deps.onPanelOpen?.current) {
28155
28659
  const opened = deps.onPanelOpen.current("statuslineOpen");
28156
28660
  if (opened) return { message: "Opened statusline picker." };
@@ -28160,14 +28664,26 @@ function buildStatuslineCommand(deps) {
28160
28664
  for (const k of ALL_CONFIG_KEYS) {
28161
28665
  const val = cfg.chips[k];
28162
28666
  if (val === void 0) continue;
28163
- lines.push(` ${val ? "\u25CF" : "\u25CB"} ${k.padEnd(12)} ${ITEM_DESCRIPTIONS[k]}`);
28667
+ const line = effectiveLine(k, cfg.lines);
28668
+ const density = effectiveDensity(k, cfg.densities);
28669
+ lines.push(
28670
+ ` ${val ? "\u25CF" : "\u25CB"} ${k.padEnd(16)} L${line} ${density === "auto" ? " " : density.padEnd(5)} ${CHIP_DESCRIPTIONS[k]}`
28671
+ );
28164
28672
  }
28165
28673
  return { message: lines.join("\n") };
28166
28674
  }
28675
+ if (item === "preview") {
28676
+ return { message: ["StatusBar layout:", ...renderLayout(cfg)].join("\n") };
28677
+ }
28167
28678
  if (item === "reset") {
28168
28679
  await deps.setConfig({ ...cfg, chips: { ...DEFAULTS } });
28169
- deps.setHiddenItems([]);
28170
- return { message: "StatusBar config reset to defaults." };
28680
+ deps.setHiddenItems(ALL_CONFIG_KEYS.filter((k) => DEFAULTS[k] === false));
28681
+ return { message: "StatusBar chip visibility reset to defaults." };
28682
+ }
28683
+ if (item === "layout") {
28684
+ if (action !== "reset") return { message: "Usage: /statusline layout reset" };
28685
+ await deps.setConfig({ ...cfg, lines: {}, densities: {} });
28686
+ return { message: "StatusBar layout reset: default lines and densities restored." };
28171
28687
  }
28172
28688
  if (item === "all") {
28173
28689
  const onOff2 = action?.toLowerCase();
@@ -28184,13 +28700,31 @@ function buildStatuslineCommand(deps) {
28184
28700
  message: `statusline all: ${onOff2 === "on" ? "showing all chips" : "hiding all chips"}`
28185
28701
  };
28186
28702
  }
28187
- const validItems = ALL_CONFIG_KEYS;
28188
- if (!validItems.includes(item)) {
28703
+ if (!isConfigKey(item)) {
28189
28704
  return {
28190
28705
  message: `Unknown item "${item}". Run /statusline to see available items.`
28191
28706
  };
28192
28707
  }
28193
28708
  const onOff = action?.toLowerCase();
28709
+ if (onOff === "line") {
28710
+ const parsed = Number(value);
28711
+ if (!Number.isInteger(parsed) || parsed < 1 || parsed > 4) {
28712
+ return { message: `Usage: /statusline ${item} line 1|2|3|4` };
28713
+ }
28714
+ const line = clampLine2(parsed);
28715
+ await deps.setConfig({ ...cfg, lines: { ...cfg.lines, [item]: line } });
28716
+ return { message: `statusline ${item}: line ${line} (${LINE_TITLES[line]})` };
28717
+ }
28718
+ if (onOff === "density") {
28719
+ if (!isDensity(value)) {
28720
+ return { message: `Usage: /statusline ${item} density auto|full|short|micro` };
28721
+ }
28722
+ const densities = { ...cfg.densities };
28723
+ if (value === "auto") delete densities[item];
28724
+ else densities[item] = value;
28725
+ await deps.setConfig({ ...cfg, densities });
28726
+ return { message: `statusline ${item}: density ${value}` };
28727
+ }
28194
28728
  if (!onOff) {
28195
28729
  const currentValue = cfg.chips[item] ?? true;
28196
28730
  const newValue = !currentValue;
@@ -28203,7 +28737,7 @@ function buildStatuslineCommand(deps) {
28203
28737
  return { message: `statusline ${item}: ${newValue ? "on" : "off"}` };
28204
28738
  }
28205
28739
  if (onOff !== "on" && onOff !== "off") {
28206
- return { message: `Usage: /statusline ${item} on|off` };
28740
+ return { message: `Usage: /statusline ${item} on|off|line <1-4>|density <level>` };
28207
28741
  }
28208
28742
  await deps.setConfig({ ...cfg, chips: { ...cfg.chips, [item]: onOff === "on" } });
28209
28743
  if (onOff === "off") {
@@ -29936,7 +30470,7 @@ function buildToolCommand(opts) {
29936
30470
  );
29937
30471
  }
29938
30472
  async function runAutoThinDryRun() {
29939
- const { runBootAutoThin } = await import("./boot-auto-thin-BZ675EVT.js");
30473
+ const { runBootAutoThin } = await import("./boot-auto-thin-MANHOYHE.js");
29940
30474
  const cfg = getAutoThin();
29941
30475
  const result = await runBootAutoThin({
29942
30476
  toolRegistry: opts.toolRegistry,
@@ -30000,7 +30534,7 @@ function buildToolCommand(opts) {
30000
30534
  if (!cfg.enabled) {
30001
30535
  return `${color63.amber("Auto-thinning is off")}. Run ${color63.cyan("/settings autothin on")} first.`;
30002
30536
  }
30003
- const { runBootAutoThin } = await import("./boot-auto-thin-BZ675EVT.js");
30537
+ const { runBootAutoThin } = await import("./boot-auto-thin-MANHOYHE.js");
30004
30538
  const result = await runBootAutoThin({
30005
30539
  toolRegistry: opts.toolRegistry,
30006
30540
  events: opts.events,
@@ -31517,6 +32051,7 @@ function setupCliSlashCommands(params) {
31517
32051
  brainSettings,
31518
32052
  brainRuntime,
31519
32053
  initialBrainLog,
32054
+ brainTierStats,
31520
32055
  coordinatorController,
31521
32056
  statusTracker,
31522
32057
  shadowController,
@@ -31603,6 +32138,7 @@ function setupCliSlashCommands(params) {
31603
32138
  brainSettings,
31604
32139
  brainRuntime,
31605
32140
  getBrainLog: () => initialBrainLog,
32141
+ brainTierStats,
31606
32142
  ...coordinatorController ? { coordinatorController } : {},
31607
32143
  statusTracker,
31608
32144
  shadowController,
@@ -31696,7 +32232,8 @@ function setupCliSlashCommands(params) {
31696
32232
  // src/wiring/command-host-state.ts
31697
32233
  import {
31698
32234
  areSubagentsAllowedForSession as areSubagentsAllowedForSession4,
31699
- FLEET_ROSTER as FLEET_ROSTER5
32235
+ FLEET_ROSTER as FLEET_ROSTER5,
32236
+ mailboxSessionTag as mailboxSessionTag6
31700
32237
  } from "@wrongstack/core/coordination";
31701
32238
  import {
31702
32239
  AgentError as AgentError3,
@@ -31759,8 +32296,7 @@ async function loadStatuslineHiddenItems() {
31759
32296
  for (const k of STATUSLINE_CONFIG_KEYS) {
31760
32297
  chips[k] = !items.includes(k);
31761
32298
  }
31762
- const doc2 = await ensureStatuslineConfig();
31763
- await saveStatuslineConfig({ ...doc2, chips });
32299
+ await saveStatuslineChips(chips);
31764
32300
  };
31765
32301
  return { hiddenItems: hiddenItemsList, setHiddenItems, saveHiddenItems };
31766
32302
  }
@@ -31772,15 +32308,12 @@ async function setupCommandHostState(input) {
31772
32308
  );
31773
32309
  const interruptController = createInterruptController();
31774
32310
  input.hqCommandController.interruptLeader = () => interruptController.abortLeader();
32311
+ const liveSessionId = () => input.sessionRef.current?.id ?? input.session.id;
32312
+ input.hqCommandController.sessionId = liveSessionId;
32313
+ input.hqCommandController.sessionTag = () => mailboxSessionTag6(liveSessionId());
31775
32314
  input.hqCommandController.killFleet = () => killFleet2(input.getDirector());
31776
32315
  input.hqCommandController.terminateAgent = (subagentId) => terminateAgent(input.getDirector(), subagentId);
31777
- input.hqCommandController.spawnAgent = (role, task, maxIterations) => spawnAgent2(
31778
- input.getDirector(),
31779
- input.sessionRef.current?.id ?? input.session.id,
31780
- role,
31781
- task,
31782
- maxIterations
31783
- );
32316
+ input.hqCommandController.spawnAgent = (role, task, maxIterations) => spawnAgent2(input.getDirector(), liveSessionId(), role, task, maxIterations);
31784
32317
  const enhanceController = createEnhanceController(input.getConfig());
31785
32318
  const statuslineConfigDeps = createStatuslineConfigDeps();
31786
32319
  const hidden = await loadStatuslineHiddenItems();
@@ -31799,7 +32332,16 @@ async function setupCommandHostState(input) {
31799
32332
  };
31800
32333
  const saveStatuslineLines2 = async (next) => {
31801
32334
  currentLines = { ...next };
31802
- await saveStatuslineLines(next);
32335
+ await saveStatuslineLayout({ lines: next });
32336
+ };
32337
+ const statuslineDensities = await loadStatuslineDensities();
32338
+ let currentDensities = { ...statuslineDensities };
32339
+ const setStatuslineDensities = (next) => {
32340
+ currentDensities = { ...next };
32341
+ };
32342
+ const saveStatuslineDensities = async (next) => {
32343
+ currentDensities = { ...next };
32344
+ await saveStatuslineLayout({ densities: next });
31803
32345
  };
31804
32346
  const agentsMonitorController = createAgentsMonitorController();
31805
32347
  const onPanelOpen = { current: null };
@@ -31849,6 +32391,10 @@ async function setupCommandHostState(input) {
31849
32391
  getCurrentStatuslineLines: () => currentLines,
31850
32392
  setStatuslineLines,
31851
32393
  saveStatuslineLines: saveStatuslineLines2,
32394
+ statuslineDensities: { ...statuslineDensities },
32395
+ getCurrentStatuslineDensities: () => currentDensities,
32396
+ setStatuslineDensities,
32397
+ saveStatuslineDensities,
31852
32398
  agentsMonitorController,
31853
32399
  onPanelOpen,
31854
32400
  goalHost,
@@ -32396,7 +32942,7 @@ function setupHqTelemetry(deps) {
32396
32942
  agentMonitor,
32397
32943
  brainMailbox,
32398
32944
  teardownHandlers,
32399
- mailboxSessionTag: mailboxSessionTag7,
32945
+ mailboxSessionTag: mailboxSessionTag8,
32400
32946
  hqPublisherRef,
32401
32947
  mcpRegistry
32402
32948
  } = deps;
@@ -32405,7 +32951,11 @@ function setupHqTelemetry(deps) {
32405
32951
  const hqCommandController = {
32406
32952
  steerMailbox: brainMailbox,
32407
32953
  interruptLeader: () => false,
32408
- sessionTag: () => mailboxSessionTag7(session.id),
32954
+ sessionTag: () => mailboxSessionTag8(session.id),
32955
+ // Boot-session seed. `setupCommandHostState` rebinds both to the LIVE
32956
+ // writer ref, because an in-process resume / session.new swaps
32957
+ // `ctx.session` for a new writer object and this captured one goes stale.
32958
+ sessionId: () => session.id,
32409
32959
  allowRunCommand: () => flags["hq-allow-exec"] === true
32410
32960
  };
32411
32961
  const hqOnCommand = createHqCommandDispatcher(hqCommandController);
@@ -32569,7 +33119,7 @@ import { NotifierImpl } from "@wrongstack/core/notifications";
32569
33119
  import {
32570
33120
  SlashCommandRegistry
32571
33121
  } from "@wrongstack/core/registry";
32572
- import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
33122
+ import { normalizeTokenSavingTier as normalizeTokenSavingTier4 } from "@wrongstack/core/types";
32573
33123
  import {
32574
33124
  CONTEXT_WINDOW_MODE_PINNED_META_KEY as CONTEXT_WINDOW_MODE_PINNED_META_KEY2,
32575
33125
  resolveContextWindowPolicy as resolveContextWindowPolicy3
@@ -33620,7 +34170,7 @@ async function setupLifecycleAndPlugins(deps) {
33620
34170
  toolRegistry,
33621
34171
  events,
33622
34172
  log: logger,
33623
- lazyMode: normalizeTokenSavingTier3(config.features.tokenSavingMode) !== "off",
34173
+ lazyMode: normalizeTokenSavingTier4(config.features.tokenSavingMode) !== "off",
33624
34174
  cacheDir: wpaths.cacheDir,
33625
34175
  authorizationProviderFactory: createVaultBackedMcpAuthorizationProviderFactory({
33626
34176
  store: mcpTokenStore
@@ -34105,7 +34655,10 @@ function setupProviderRuntime(deps) {
34105
34655
  "uiLocale"
34106
34656
  ];
34107
34657
  const activeProfileOf = (c) => typeof c.activeProfile === "string" && c.activeProfile ? c.activeProfile : "default";
34108
- if (process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
34658
+ let reloadProviderConfig = async () => {
34659
+ };
34660
+ const configWatchEnabled = process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1";
34661
+ {
34109
34662
  let activeProfile = activeProfileOf(cfg);
34110
34663
  let configLayers = [];
34111
34664
  const rebuildLayers = () => {
@@ -34196,6 +34749,7 @@ function setupProviderRuntime(deps) {
34196
34749
  );
34197
34750
  }
34198
34751
  };
34752
+ reloadProviderConfig = onAnyConfigChange;
34199
34753
  let watchers = [];
34200
34754
  const openWatchers = () => {
34201
34755
  watchers = configLayers.map(
@@ -34213,20 +34767,22 @@ function setupProviderRuntime(deps) {
34213
34767
  for (const w of watchers) w.close();
34214
34768
  watchers = [];
34215
34769
  };
34216
- openWatchers();
34217
- teardownHandlers.push(
34218
- configStore.watch((next) => {
34219
- const nextProfile = activeProfileOf(next);
34220
- if (nextProfile === activeProfile) return;
34221
- activeProfile = nextProfile;
34222
- closeWatchers();
34223
- rebuildLayers();
34224
- openWatchers();
34225
- previousSnapshotSerialized = void 0;
34226
- void onAnyConfigChange();
34227
- })
34228
- );
34229
- teardownHandlers.push(closeWatchers);
34770
+ if (configWatchEnabled) {
34771
+ openWatchers();
34772
+ teardownHandlers.push(
34773
+ configStore.watch((next) => {
34774
+ const nextProfile = activeProfileOf(next);
34775
+ if (nextProfile === activeProfile) return;
34776
+ activeProfile = nextProfile;
34777
+ closeWatchers();
34778
+ rebuildLayers();
34779
+ openWatchers();
34780
+ previousSnapshotSerialized = void 0;
34781
+ void onAnyConfigChange();
34782
+ })
34783
+ );
34784
+ teardownHandlers.push(closeWatchers);
34785
+ }
34230
34786
  }
34231
34787
  return {
34232
34788
  resolveProviderCfg: resolveProviderCfg2,
@@ -34234,7 +34790,8 @@ function setupProviderRuntime(deps) {
34234
34790
  buildProviderForModel,
34235
34791
  refreshMaxContextFor,
34236
34792
  refreshRuntimeModelStateFor,
34237
- switchProviderAndModel
34793
+ switchProviderAndModel,
34794
+ reloadProviderConfig
34238
34795
  };
34239
34796
  }
34240
34797
 
@@ -34455,7 +35012,7 @@ async function setupReplayAndGovernance({
34455
35012
  const replayFlag = flags["replay"];
34456
35013
  const recordFlag = flags["record"];
34457
35014
  if (typeof replayFlag === "string" || recordFlag === true) {
34458
- const { bindReplayToContainer } = await import("./replay-FJ2JBXUA.js");
35015
+ const { bindReplayToContainer } = await import("./replay-Z3FTJEMM.js");
34459
35016
  const mode = recordFlag === true ? "record" : "replay";
34460
35017
  bindReplayToContainer({
34461
35018
  container,
@@ -34643,7 +35200,7 @@ async function prepareRuntimeDispatch(input) {
34643
35200
  // src/wiring/session-establishment.ts
34644
35201
  import * as path31 from "node:path";
34645
35202
  import { TOKENS as TOKENS12 } from "@wrongstack/core/kernel";
34646
- import { getSessionRegistry as getSessionRegistry2 } from "@wrongstack/core/storage";
35203
+ import { getSessionRegistry as getSessionRegistry3 } from "@wrongstack/core/storage";
34647
35204
  import { addFatalSalvageHook } from "@wrongstack/core/utils";
34648
35205
 
34649
35206
  // src/wiring/session.ts
@@ -34680,7 +35237,7 @@ import {
34680
35237
  } from "@wrongstack/tools/session-kanban";
34681
35238
 
34682
35239
  // src/wiring/resume-candidate.ts
34683
- import { getSessionRegistry, SessionRecovery as SessionRecovery2 } from "@wrongstack/core/storage";
35240
+ import { getSessionRegistry as getSessionRegistry2, SessionRecovery as SessionRecovery2 } from "@wrongstack/core/storage";
34684
35241
  var MAX_CANDIDATES = 20;
34685
35242
  async function pickResumeCandidate(options) {
34686
35243
  const live = await liveSessionIds(options.globalRoot);
@@ -34701,7 +35258,7 @@ async function recentCandidates(sessionStore) {
34701
35258
  }
34702
35259
  async function liveSessionIds(globalRoot) {
34703
35260
  try {
34704
- const registry = getSessionRegistry(globalRoot);
35261
+ const registry = getSessionRegistry2(globalRoot);
34705
35262
  const entries = await registry.list();
34706
35263
  return new Set(entries.map((entry) => entry.sessionId));
34707
35264
  } catch {
@@ -35021,7 +35578,7 @@ async function setupSessionEstablishment(args) {
35021
35578
  const sessionStore = container.resolve(TOKENS12.SessionStore);
35022
35579
  const tokenCounter = container.resolve(TOKENS12.TokenCounter);
35023
35580
  tokenCounter.setSessionId?.(() => sessionRef.current?.id);
35024
- const sessionRegistry = getSessionRegistry2(wpaths.globalRoot);
35581
+ const sessionRegistry = getSessionRegistry3(wpaths.globalRoot);
35025
35582
  const sessResult = await setupSession({
35026
35583
  config: { model: config.model, provider: config.provider },
35027
35584
  wpaths,
@@ -35111,11 +35668,11 @@ async function setupSessionRegistry(deps) {
35111
35668
  };
35112
35669
  let ownershipEstablished = false;
35113
35670
  try {
35114
- const [{ getSessionRegistry: getSessionRegistry3 }, { AgentStatusTracker, FleetNotifier }] = await Promise.all([
35671
+ const [{ getSessionRegistry: getSessionRegistry4 }, { AgentStatusTracker, FleetNotifier }] = await Promise.all([
35115
35672
  import("@wrongstack/core/storage"),
35116
35673
  import("@wrongstack/core/coordination")
35117
35674
  ]);
35118
- const registry = getSessionRegistry3(wpaths.globalRoot);
35675
+ const registry = getSessionRegistry4(wpaths.globalRoot);
35119
35676
  const projectSlug = path32.basename(wpaths.projectDir);
35120
35677
  const projectName = path32.basename(projectRoot);
35121
35678
  let gitBranch = await new Promise((resolve8) => {
@@ -35208,7 +35765,9 @@ async function setupSessionRegistry(deps) {
35208
35765
  // src/session-event-wiring.ts
35209
35766
  import {
35210
35767
  createChronicleContext,
35768
+ createChronicleCounterSink,
35211
35769
  createChronicleEventJournal,
35770
+ resolveChronicleDetail,
35212
35771
  startChronicleFileObserver,
35213
35772
  startChronicleHealthMonitor,
35214
35773
  wireDecisionsToChronicle,
@@ -35232,6 +35791,10 @@ function resolveChronicleRetentionDays(config) {
35232
35791
  if (raw <= 0) return 0;
35233
35792
  return Math.max(MIN_CHRONICLE_RETENTION_DAYS, raw);
35234
35793
  }
35794
+ function chronicleLimit(config, key) {
35795
+ const raw = config.chronicle?.[key];
35796
+ return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : void 0;
35797
+ }
35235
35798
  function tryCreateChronicleJournal(options) {
35236
35799
  try {
35237
35800
  return createChronicleEventJournal(options);
@@ -35273,11 +35836,18 @@ function wireSessionEvents(deps) {
35273
35836
  let chronicleFileObserver;
35274
35837
  let stopChronicleHealth;
35275
35838
  let stopNetworkTelemetry;
35839
+ let disposeCounterSink;
35276
35840
  if (deps.events && wpaths.projectDir) {
35277
35841
  const retentionDays = resolveChronicleRetentionDays(config);
35278
35842
  chronicleHandle = tryCreateChronicleJournal({
35279
35843
  projectRoot,
35280
35844
  retentionDays,
35845
+ // Undefined means "whatever the daemon already runs with": these only
35846
+ // take effect for the client that wins the spawn race, so passing an
35847
+ // explicit fallback here would imply a control this layer does not have.
35848
+ maxEvents: chronicleLimit(config, "maxEvents"),
35849
+ maxBytes: chronicleLimit(config, "maxBytes"),
35850
+ metricsRowRetentionDays: chronicleLimit(config, "metricsRowRetentionDays"),
35281
35851
  projectPaths: {
35282
35852
  globalRoot: wpaths.globalRoot,
35283
35853
  projectId: wpaths.projectHash ?? wpaths.projectSlug,
@@ -35287,7 +35857,12 @@ function wireSessionEvents(deps) {
35287
35857
  });
35288
35858
  }
35289
35859
  if (chronicleHandle && deps.events) {
35290
- chronicleJournal = chronicleHandle.journal;
35860
+ const counterSink = createChronicleCounterSink({
35861
+ inner: chronicleHandle.journal,
35862
+ level: resolveChronicleDetail(config)
35863
+ });
35864
+ chronicleJournal = counterSink;
35865
+ disposeCounterSink = () => counterSink.dispose();
35291
35866
  const location = chronicleHandle.identity;
35292
35867
  const chronicleContext = createChronicleContext(
35293
35868
  {
@@ -35613,6 +36188,7 @@ function wireSessionEvents(deps) {
35613
36188
  stopChronicleHealth?.();
35614
36189
  stopNetworkTelemetry?.();
35615
36190
  unsubscribeChronicle?.();
36191
+ await disposeCounterSink?.();
35616
36192
  if (chronicleFileObserver) {
35617
36193
  try {
35618
36194
  await (await chronicleFileObserver).close();
@@ -35899,12 +36475,17 @@ import * as path33 from "node:path";
35899
36475
  import {
35900
36476
  startFirstBootSageSync,
35901
36477
  subscribeVectorMemoryToSage,
36478
+ sweepStaleSageMirrors,
35902
36479
  TransformersEmbeddingProvider,
35903
36480
  VectorMemoryStore,
35904
36481
  wrapMemoryPortWithVectorRecall
35905
36482
  } from "@wrongstack/vector-memory";
36483
+ var DEFAULT_VECTOR_WEIGHT = 0.3;
35906
36484
  async function setupVectorMemory(args) {
35907
- const { projectRoot, flags, logger, memoryStore, teardownHandlers } = args;
36485
+ const { projectRoot, flags, logger, memoryStore, teardownHandlers, tuning } = args;
36486
+ if (tuning?.enabled === false) {
36487
+ return { memoryStore, vectorMemoryStore: void 0, vectorMemoryModelCacheDir: "" };
36488
+ }
35908
36489
  let vectorMemoryStore;
35909
36490
  const vectorMemoryModelCacheDir = path33.join(
35910
36491
  projectRoot,
@@ -35935,7 +36516,10 @@ async function setupVectorMemory(args) {
35935
36516
  });
35936
36517
  wrapped = wrapMemoryPortWithVectorRecall(wrapped, {
35937
36518
  store: vectorMemoryStore,
35938
- weight: 0.3
36519
+ weight: tuning?.weight ?? DEFAULT_VECTOR_WEIGHT,
36520
+ ...tuning?.threshold !== void 0 ? { threshold: tuning.threshold } : {},
36521
+ ...tuning?.vectorOnlyThreshold !== void 0 ? { vectorOnlyThreshold: tuning.vectorOnlyThreshold } : {},
36522
+ ...tuning?.maxMaterializations !== void 0 ? { maxMaterializations: tuning.maxMaterializations } : {}
35939
36523
  });
35940
36524
  const mirrorHandle = subscribeVectorMemoryToSage({
35941
36525
  store: vectorMemoryStore,
@@ -35943,6 +36527,11 @@ async function setupVectorMemory(args) {
35943
36527
  logger
35944
36528
  });
35945
36529
  teardownHandlers.push(() => mirrorHandle.dispose());
36530
+ void sweepStaleSageMirrors({
36531
+ store: vectorMemoryStore,
36532
+ memoryStore: wrapped,
36533
+ logger
36534
+ });
35946
36535
  if (flags["vector-sync"] === true) {
35947
36536
  const forced = await startFirstBootSageSync({
35948
36537
  store: vectorMemoryStore,
@@ -36011,7 +36600,8 @@ async function runInteractive(cliCtx) {
36011
36600
  flags,
36012
36601
  logger,
36013
36602
  memoryStore,
36014
- teardownHandlers
36603
+ teardownHandlers,
36604
+ tuning: config.Sage?.vector
36015
36605
  });
36016
36606
  memoryStore = vectorWrappedMemoryStore;
36017
36607
  const skillLoader = container.resolve(TOKENS13.SkillLoader);
@@ -36227,7 +36817,12 @@ async function runInteractive(cliCtx) {
36227
36817
  container.override(TOKENS13.ProviderModelStatusTracker, () => statusTracker);
36228
36818
  bootstrapWrongProxy(config.tools?.wrongProxy);
36229
36819
  await awaitFirstWrongProxyProbe();
36230
- const { buildProviderForId: buildProviderForId2, buildProviderForModel, switchProviderAndModel } = setupProviderRuntime({
36820
+ const {
36821
+ buildProviderForId: buildProviderForId2,
36822
+ buildProviderForModel,
36823
+ switchProviderAndModel,
36824
+ reloadProviderConfig
36825
+ } = setupProviderRuntime({
36231
36826
  config,
36232
36827
  onConfigUpdate: (newConfig) => {
36233
36828
  config = newConfig;
@@ -36300,7 +36895,15 @@ async function runInteractive(cliCtx) {
36300
36895
  events,
36301
36896
  autonomyModeRef
36302
36897
  });
36303
- const { brain, brainLog, brainSettings, brainRuntime, multiAgentHost, shadowController } = setupBrainAndOrchestration({
36898
+ const {
36899
+ brain,
36900
+ brainLog,
36901
+ brainTierStats,
36902
+ brainSettings,
36903
+ brainRuntime,
36904
+ multiAgentHost,
36905
+ shadowController
36906
+ } = setupBrainAndOrchestration({
36304
36907
  events,
36305
36908
  config,
36306
36909
  vault,
@@ -36319,7 +36922,7 @@ async function runInteractive(cliCtx) {
36319
36922
  cwd,
36320
36923
  wpaths,
36321
36924
  teardownHandlers,
36322
- mailboxSessionTag: mailboxSessionTag6,
36925
+ mailboxSessionTag: mailboxSessionTag7,
36323
36926
  brainMailbox,
36324
36927
  agentMonitor,
36325
36928
  manifestPath,
@@ -36350,7 +36953,7 @@ async function runInteractive(cliCtx) {
36350
36953
  agentMonitor,
36351
36954
  brainMailbox,
36352
36955
  teardownHandlers,
36353
- mailboxSessionTag: mailboxSessionTag6,
36956
+ mailboxSessionTag: mailboxSessionTag7,
36354
36957
  hqPublisherRef,
36355
36958
  mcpRegistry
36356
36959
  });
@@ -36388,6 +36991,9 @@ async function runInteractive(cliCtx) {
36388
36991
  statuslineLines,
36389
36992
  setStatuslineLines,
36390
36993
  saveStatuslineLines: saveStatuslineLines2,
36994
+ statuslineDensities,
36995
+ setStatuslineDensities,
36996
+ saveStatuslineDensities,
36391
36997
  agentsMonitorController,
36392
36998
  onPanelOpen,
36393
36999
  goalHost,
@@ -36456,6 +37062,7 @@ async function runInteractive(cliCtx) {
36456
37062
  brainSettings,
36457
37063
  brainRuntime,
36458
37064
  initialBrainLog: brainLog,
37065
+ brainTierStats,
36459
37066
  coordinatorController,
36460
37067
  statusTracker,
36461
37068
  shadowController,
@@ -36600,6 +37207,7 @@ async function runInteractive(cliCtx) {
36600
37207
  resolvedProvider,
36601
37208
  logger,
36602
37209
  switchProviderAndModel,
37210
+ reloadProviderConfig,
36603
37211
  applyMaxContext,
36604
37212
  renderer,
36605
37213
  reader,
@@ -36627,6 +37235,9 @@ async function runInteractive(cliCtx) {
36627
37235
  statuslineLines,
36628
37236
  setStatuslineLines,
36629
37237
  saveStatuslineLines: saveStatuslineLines2,
37238
+ statuslineDensities,
37239
+ setStatuslineDensities,
37240
+ saveStatuslineDensities,
36630
37241
  setYoloMode,
36631
37242
  autonomyMode,
36632
37243
  setAutonomyMode: (mode) => {
@@ -36668,4 +37279,4 @@ export {
36668
37279
  CLI_VERSION,
36669
37280
  runInteractive
36670
37281
  };
36671
- //# sourceMappingURL=cli-main-QXSKKANW.js.map
37282
+ //# sourceMappingURL=cli-main-TTIVR4DI.js.map