@wrongstack/cli 0.319.0 → 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 (113) 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-KF5TAD7V.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-VWCZL4OH.js → chunk-4HV5RKZH.js} +5 -5
  14. package/dist/{chunk-42JD25KU.js → chunk-5IA5337I.js} +3 -3
  15. package/dist/{chunk-7JBKXVMK.js → chunk-C2E24IXZ.js} +44 -32
  16. package/dist/{chunk-7CECQDNH.js → chunk-D3K4NYQL.js} +1 -1
  17. package/dist/{chunk-XPX432BZ.js → chunk-DR2OXU46.js} +50 -39
  18. package/dist/{chunk-4JRIWVJ4.js → chunk-ERX4BLKP.js} +1 -1
  19. package/dist/chunk-ETYHZPXP.js +52 -0
  20. package/dist/{chunk-TYO2OVAD.js → chunk-EWKESL4L.js} +8 -4
  21. package/dist/{chunk-QAC263FZ.js → chunk-FPIWTJ2G.js} +2 -3
  22. package/dist/{chunk-7YLN7YUA.js → chunk-IMWXXF4J.js} +61 -9
  23. package/dist/{chunk-G7337TTK.js → chunk-IS2PPBQV.js} +1 -1
  24. package/dist/{chunk-G3IMKQRH.js → chunk-JHPXJRRI.js} +1 -1
  25. package/dist/{chunk-XHIEA6LG.js → chunk-MNQQ4ZNF.js} +26 -22
  26. package/dist/{chunk-P2OKBDCH.js → chunk-MXEJEYT7.js} +53 -14
  27. package/dist/{chunk-PCBJSXYV.js → chunk-O4A3HHKD.js} +2 -2
  28. package/dist/{chunk-XYKYXFEE.js → chunk-TE3Q32JP.js} +10 -4
  29. package/dist/{chunk-H7GABTGS.js → chunk-TEBMCYZN.js} +69 -30
  30. package/dist/{chunk-E4I2TF5S.js → chunk-TNK6237M.js} +2 -2
  31. package/dist/{chunk-SYIBTG3X.js → chunk-VOTTENR5.js} +3 -5
  32. package/dist/chunk-WHOIR577.js +1 -0
  33. package/dist/{chunk-2ZNBRZ4W.js → chunk-WQZW3RDP.js} +2 -2
  34. package/dist/{chunk-GGGUZSAU.js → chunk-Z7A5MXKJ.js} +18 -12
  35. package/dist/{chunk-F5GA2QW2.js → chunk-ZSZ3EYWH.js} +2 -2
  36. package/dist/{cli-context-LH4QP4W2.js → cli-context-CYMKNOK3.js} +58 -307
  37. package/dist/{cli-main-72XUFUCL.js → cli-main-TTIVR4DI.js} +925 -329
  38. package/dist/{diag-doctor-LFCCBPMD.js → diag-doctor-7LYUYU35.js} +4 -6
  39. package/dist/execute-deps.d.ts +5 -1
  40. package/dist/{execution-DKJDNPYF.js → execution-3Y55IWBK.js} +512 -469
  41. package/dist/{export-ROG3DKTZ.js → export-VVRIOWFV.js} +1 -2
  42. package/dist/{governance-JSGHHA2R.js → governance-RYSHV675.js} +1 -2
  43. package/dist/{hq-3GWBFLON.js → hq-IG3YRGCO.js} +2 -3
  44. package/dist/hq-command-controller.d.ts +37 -7
  45. package/dist/hq-server/routes.d.ts +1 -1
  46. package/dist/hq-server/ws.d.ts +1 -1
  47. package/dist/{hq-server-OARPUSQJ.js → hq-server-OILU3NPI.js} +2 -3
  48. package/dist/{hq-ttl-KUO3AU7X.js → hq-ttl-VJR65OBJ.js} +1 -2
  49. package/dist/{hq-tunnel-LO55RCZE.js → hq-tunnel-NIJ5EP2Y.js} +1 -2
  50. package/dist/index.js +5 -6
  51. package/dist/{init-4JQSG66Q.js → init-DRMMFG2G.js} +1 -2
  52. package/dist/{kanban-run-mirror-EKVNGXWW.js → kanban-run-mirror-22HQ5FNG.js} +1 -2
  53. package/dist/live-settings-input.d.ts +2 -0
  54. package/dist/{mailbox-serve-VKQIRCCB.js → mailbox-serve-VUCWZ2SJ.js} +2 -3
  55. package/dist/{mcp-AQKSASHD.js → mcp-HOMLC4WE.js} +1 -2
  56. package/dist/{modeldiag-5FRMT6FQ.js → modeldiag-FMJT37SN.js} +2 -3
  57. package/dist/{per-subcommand-help-6VCIKDUW.js → per-subcommand-help-BWBHYVJO.js} +2 -3
  58. package/dist/{permissions-2PWBL4YU.js → permissions-CFDLXETM.js} +1 -2
  59. package/dist/{plugin-usage-CYUORYM6.js → plugin-usage-HFBI3TFT.js} +2 -3
  60. package/dist/{plugins-RV3OBBND.js → plugins-PZ2VZL7V.js} +4 -5
  61. package/dist/{project-BLQ3ALVL.js → project-AOQI5XTK.js} +1 -2
  62. package/dist/{project-manifest-YFTJ3D5N.js → project-manifest-7NSFVBM3.js} +2 -3
  63. package/dist/{project-picker-R5TYAE3Q.js → project-picker-SVBXMPKX.js} +3 -4
  64. package/dist/{projects-5J727S4L.js → projects-L6C6XLDY.js} +1 -2
  65. package/dist/provider-config-utils.d.ts +1 -1
  66. package/dist/{providers-models-OKKQZIWU.js → providers-models-YVMVYWRS.js} +3 -4
  67. package/dist/{proxy-wiring-EQB5X5YH.js → proxy-wiring-MGRSKZZB.js} +3 -4
  68. package/dist/{quick-XLYLZX4B.js → quick-CNB4Z3HS.js} +1 -2
  69. package/dist/{replay-RZXZKP2U.js → replay-JJ2NOWD6.js} +1 -2
  70. package/dist/{replay-FJ2JBXUA.js → replay-Z3FTJEMM.js} +1 -2
  71. package/dist/{rewind-2FFNOOKS.js → rewind-JA3ZLCNM.js} +1 -2
  72. package/dist/{sdd-runtime-FLKCSTYV.js → sdd-runtime-PTOSPYI4.js} +2 -3
  73. package/dist/services/sdd-runtime.d.ts +1 -1
  74. package/dist/services/statusline-config.d.ts +43 -13
  75. package/dist/{sessions-config-KAMEBVOX.js → sessions-config-UL45XKX7.js} +2 -3
  76. package/dist/{sessions-doctor-EXHAZSSE.js → sessions-doctor-QUL37U32.js} +1 -2
  77. package/dist/short-circuit-flags-6PSP56L7.js +10 -0
  78. package/dist/{simpleui-dist-JKNRCRRK.js → simpleui-dist-CXSIDAXZ.js} +1 -2
  79. package/dist/slash-commands/command-context.d.ts +10 -0
  80. package/dist/slash-commands/sdd.d.ts +1 -1
  81. package/dist/slash-commands/statusline.d.ts +1 -1
  82. package/dist/subcommands/handlers/bench-run-config.d.ts +18 -0
  83. package/dist/subcommands/handlers/bench.d.ts +8 -7
  84. package/dist/subcommands-HZQKA4G2.js +9 -0
  85. package/dist/{tools-skills-Q4P27URS.js → tools-skills-GH24UCBY.js} +1 -2
  86. package/dist/{update-K45CS6SS.js → update-5DPB4YD4.js} +1 -2
  87. package/dist/{update-check-PKSMSMD6.js → update-check-BS3DHTSI.js} +1 -2
  88. package/dist/version-help-MYKF724O.js +10 -0
  89. package/dist/webui-server/client-registration.d.ts +9 -1
  90. package/dist/{webui-server-SY4EQCKD.js → webui-server-T6AMOXJJ.js} +54 -13
  91. package/dist/wiring/brain-and-orchestration.d.ts +2 -0
  92. package/dist/wiring/cli-execute-builder.d.ts +4 -0
  93. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  94. package/dist/wiring/command-host-state.d.ts +50 -5
  95. package/dist/wiring/external-plugins.d.ts +9 -0
  96. package/dist/wiring/provider-runtime-setup.d.ts +2 -0
  97. package/dist/wiring/runtime-controller-deps.d.ts +3 -0
  98. package/dist/wiring/vector-memory-setup.d.ts +12 -0
  99. package/dist/wiring/wrongtrace-gate.d.ts +2 -2
  100. package/dist/wiring/wrongtrace-hooks.d.ts +1 -1
  101. package/dist/wiring/wrongtrace-prompt-contributor.d.ts +5 -2
  102. package/dist/{wrongtrace-gate-counters-P5BCBXQN.js → wrongtrace-gate-counters-7C2EAAZL.js} +2 -3
  103. package/dist/{wrongtrace-telemetry-FNLANZ5I.js → wrongtrace-telemetry-3ASFKOZO.js} +2 -3
  104. package/package.json +28 -28
  105. package/dist/chunk-7OCVIDC7.js +0 -11
  106. package/dist/chunk-ALE5KHCA.js +0 -1
  107. package/dist/chunk-OZDE3OWD.js +0 -52
  108. package/dist/launch-hints.d.ts +0 -49
  109. package/dist/short-circuit-flags-U6CJAF6J.js +0 -11
  110. package/dist/subcommands-J4JMWC5W.js +0 -10
  111. package/dist/version-help-WMPSEL4U.js +0 -11
  112. package/dist/webui-server/privileged-actions.d.ts +0 -14
  113. package/dist/wiring/cli-heap-watchdog.d.ts +0 -34
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  createHqCommandDispatcher
3
- } from "./chunk-7YLN7YUA.js";
3
+ } from "./chunk-IMWXXF4J.js";
4
4
  import {
5
5
  runProjectPicker
6
- } from "./chunk-2ZNBRZ4W.js";
6
+ } from "./chunk-WQZW3RDP.js";
7
7
  import {
8
8
  ensureProjectDataDir,
9
9
  findProject,
10
10
  generateSlug,
11
11
  loadManifest,
12
12
  saveManifest
13
- } from "./chunk-G7337TTK.js";
13
+ } from "./chunk-IS2PPBQV.js";
14
14
  import {
15
15
  getWrongTrace
16
- } from "./chunk-4JRIWVJ4.js";
16
+ } from "./chunk-ERX4BLKP.js";
17
17
  import {
18
18
  MAX_TUI_THINKING_WORD_LENGTH,
19
19
  clearSuggestions,
@@ -25,7 +25,7 @@ import {
25
25
  } from "./chunk-SXJTVNWF.js";
26
26
  import {
27
27
  setupPlugins
28
- } from "./chunk-42JD25KU.js";
28
+ } from "./chunk-5IA5337I.js";
29
29
  import {
30
30
  deriveFsAccessPair,
31
31
  filterSafeForProject,
@@ -44,11 +44,15 @@ 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
51
- } from "./chunk-SYIBTG3X.js";
55
+ } from "./chunk-VOTTENR5.js";
52
56
  import {
53
57
  advanceToNextTask,
54
58
  findSpec,
@@ -59,17 +63,14 @@ 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-H7GABTGS.js";
69
- import "./chunk-G3IMKQRH.js";
69
+ } from "./chunk-TEBMCYZN.js";
70
+ import "./chunk-JHPXJRRI.js";
70
71
  import {
71
72
  recordGateDecision
72
- } from "./chunk-7CECQDNH.js";
73
+ } from "./chunk-D3K4NYQL.js";
73
74
  import {
74
75
  CLI_VERSION
75
76
  } from "./chunk-XJXDOF63.js";
@@ -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-XHIEA6LG.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-FLKCSTYV.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
@@ -1219,12 +1233,7 @@ function createSubagentWrongTraceHookRunner(sessionId, emit) {
1219
1233
  const hooks = createWrongTraceHookPair(sessionId, {
1220
1234
  emit: (event) => emit?.(event)
1221
1235
  });
1222
- registry.registerInProcess(
1223
- "PreToolUse",
1224
- WRONGTRACE_MATCHER,
1225
- hooks.preToolUse,
1226
- "wrongtrace-gate"
1227
- );
1236
+ registry.registerInProcess("PreToolUse", WRONGTRACE_MATCHER, hooks.preToolUse, "wrongtrace-gate");
1228
1237
  registry.registerInProcess(
1229
1238
  "PostToolUse",
1230
1239
  WRONGTRACE_MATCHER,
@@ -1236,9 +1245,7 @@ function createSubagentWrongTraceHookRunner(sessionId, emit) {
1236
1245
 
1237
1246
  // src/fleet/host.ts
1238
1247
  import { randomUUID as randomUUID5 } from "node:crypto";
1239
- import {
1240
- createProjectAgentRoster
1241
- } from "@wrongstack/core/agent-catalog";
1248
+ import { createProjectAgentRoster } from "@wrongstack/core/agent-catalog";
1242
1249
  import {
1243
1250
  AdaptiveConcurrencyController,
1244
1251
  areSubagentsAllowedForSession as areSubagentsAllowedForSession2,
@@ -4504,7 +4511,7 @@ function setupBrainAndOrchestration(deps) {
4504
4511
  cwd,
4505
4512
  wpaths,
4506
4513
  teardownHandlers,
4507
- mailboxSessionTag: mailboxSessionTag7,
4514
+ mailboxSessionTag: mailboxSessionTag8,
4508
4515
  brainMailbox,
4509
4516
  agentMonitor,
4510
4517
  manifestPath,
@@ -4629,12 +4636,17 @@ function setupBrainAndOrchestration(deps) {
4629
4636
  brainRuntime.arbiter,
4630
4637
  brainQueue,
4631
4638
  () => brainRuntime.getMode(),
4632
- () => brainRuntime.getSnapshot().terminalPolicy
4639
+ () => brainRuntime.getSnapshot().terminalPolicy,
4640
+ events
4633
4641
  ),
4634
4642
  events
4635
4643
  );
4636
4644
  container.bind(TOKENS6.BrainArbiter, () => brain);
4637
- const { brainLog, dispose: disposeBrainLog } = subscribeBrainDecisionLog(events);
4645
+ const {
4646
+ brainLog,
4647
+ getTierStats: brainTierStats,
4648
+ dispose: disposeBrainLog
4649
+ } = subscribeBrainDecisionLog(events);
4638
4650
  teardownHandlers.push(disposeBrainLog);
4639
4651
  brainMonitor = new BrainMonitor({
4640
4652
  events,
@@ -4661,7 +4673,7 @@ function setupBrainAndOrchestration(deps) {
4661
4673
  body,
4662
4674
  sessionId
4663
4675
  }) => {
4664
- const tag = mailboxSessionTag7(sessionId || context.session?.id || session.id);
4676
+ const tag = mailboxSessionTag8(sessionId || context.session?.id || session.id);
4665
4677
  const leaderUniqueId = `leader@${tag}`;
4666
4678
  await brainMailbox.send({
4667
4679
  from: `brain@${tag}`,
@@ -4787,6 +4799,7 @@ function setupBrainAndOrchestration(deps) {
4787
4799
  return {
4788
4800
  brain,
4789
4801
  brainLog,
4802
+ brainTierStats,
4790
4803
  brainSettings,
4791
4804
  brainRuntime,
4792
4805
  brainQueue,
@@ -4802,6 +4815,7 @@ import { gatedEnhancerReasoning } from "@wrongstack/core/execution";
4802
4815
  import { TOKENS as TOKENS7 } from "@wrongstack/core/kernel";
4803
4816
 
4804
4817
  // src/auth-menu/panel-service.ts
4818
+ import { parseModelRef } from "@wrongstack/core/agent";
4805
4819
  var ANSI_RE = /\u001b\[[0-9;]*m/g;
4806
4820
  function stripAnsi(text) {
4807
4821
  return text.replace(ANSI_RE, "");
@@ -4836,9 +4850,10 @@ function flowDeps(base, io) {
4836
4850
  function isCancel(err) {
4837
4851
  return err instanceof Error && err.name === "AbortError" || err instanceof DOMException && err.name === "AbortError";
4838
4852
  }
4839
- async function runFlow(run) {
4853
+ async function runFlow(run, onSuccess) {
4840
4854
  try {
4841
4855
  const ok = await run();
4856
+ if (ok) await onSuccess?.();
4842
4857
  return { ok };
4843
4858
  } catch (err) {
4844
4859
  if (isCancel(err)) return { ok: false, message: "Cancelled." };
@@ -4850,6 +4865,141 @@ function plainMaskedKey(key) {
4850
4865
  if (key.length <= 8) return "\u2022".repeat(key.length);
4851
4866
  return `${key.slice(0, 4)}\u2026${key.slice(-4)}`;
4852
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
+ }
4853
5003
  function createAuthPanelHost(deps) {
4854
5004
  const loadProviders = () => loadConfigProviders(deps.profileConfigPath, deps.vault);
4855
5005
  const mutate = async (mutator) => {
@@ -4858,14 +5008,21 @@ function createAuthPanelHost(deps) {
4858
5008
  await mutateConfigProviders(
4859
5009
  deps.profileConfigPath,
4860
5010
  deps.vault,
4861
- (all) => {
4862
- result = mutator(all);
5011
+ (all, config) => {
5012
+ result = mutator(all, config);
4863
5013
  },
4864
5014
  deps.profileConfigPath
4865
5015
  );
4866
5016
  } catch (err) {
4867
5017
  return err instanceof Error ? err.message : String(err);
4868
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
+ }
4869
5026
  return result;
4870
5027
  };
4871
5028
  return {
@@ -4903,7 +5060,10 @@ function createAuthPanelHost(deps) {
4903
5060
  loadProviders()
4904
5061
  ]);
4905
5062
  const saved = new Set(Object.keys(providers));
4906
- 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) => ({
4907
5067
  id: p.id,
4908
5068
  name: p.name || p.id,
4909
5069
  family: p.family,
@@ -4939,9 +5099,10 @@ function createAuthPanelHost(deps) {
4939
5099
  });
4940
5100
  },
4941
5101
  removeProvider(providerId) {
4942
- return mutate((all) => {
5102
+ return mutate((all, config) => {
4943
5103
  if (!all[providerId]) return `Provider "${providerId}" no longer in config.`;
4944
5104
  delete all[providerId];
5105
+ removeProviderFallbackReferences(config, providerId);
4945
5106
  return null;
4946
5107
  });
4947
5108
  },
@@ -4950,6 +5111,157 @@ function createAuthPanelHost(deps) {
4950
5111
  const providers = await loadProviders();
4951
5112
  const template = providers[providerId] ?? { type: providerId };
4952
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;
4953
5265
  });
4954
5266
  },
4955
5267
  updateKey(providerId, label, io) {
@@ -4976,7 +5288,7 @@ function createAuthPanelHost(deps) {
4976
5288
  }
4977
5289
  io.onLog(`\u2713 Updated ${providerId}/${label}.`);
4978
5290
  return true;
4979
- });
5291
+ }, deps.onProvidersChanged);
4980
5292
  },
4981
5293
  editField(providerId, field, io) {
4982
5294
  return runFlow(async () => {
@@ -5062,7 +5374,7 @@ function createAuthPanelHost(deps) {
5062
5374
  }
5063
5375
  io.onLog(`\u2713 models \u2192 ${list.length === 0 ? "(catalog default)" : list.join(", ")}`);
5064
5376
  return true;
5065
- });
5377
+ }, deps.onProvidersChanged);
5066
5378
  },
5067
5379
  editModelDetails(providerId, modelId, io) {
5068
5380
  return runFlow(async () => {
@@ -5156,7 +5468,7 @@ function createAuthPanelHost(deps) {
5156
5468
  }
5157
5469
  io.onLog(`\u2713 ${modelId} updated`);
5158
5470
  return true;
5159
- });
5471
+ }, deps.onProvidersChanged);
5160
5472
  },
5161
5473
  addModel(providerId, io, opts) {
5162
5474
  return runFlow(async () => {
@@ -5194,7 +5506,7 @@ function createAuthPanelHost(deps) {
5194
5506
  }
5195
5507
  io.onLog(`\u2713 Added model "${modelId}" to ${providerId}`);
5196
5508
  return true;
5197
- });
5509
+ }, deps.onProvidersChanged);
5198
5510
  },
5199
5511
  removeModel(providerId, modelId) {
5200
5512
  return (async () => {
@@ -5244,10 +5556,10 @@ function createAuthPanelHost(deps) {
5244
5556
  return false;
5245
5557
  }
5246
5558
  return addKeyForCatalogProvider(flowDeps(deps, io), chosen);
5247
- });
5559
+ }, deps.onProvidersChanged);
5248
5560
  },
5249
5561
  addCustomProvider(io) {
5250
- return runFlow(() => addCustomProvider(flowDeps(deps, io)));
5562
+ return runFlow(() => addCustomProvider(flowDeps(deps, io)), deps.onProvidersChanged);
5251
5563
  },
5252
5564
  addLocal(presetId, io) {
5253
5565
  return runFlow(async () => {
@@ -5263,7 +5575,7 @@ function createAuthPanelHost(deps) {
5263
5575
  models: "999"
5264
5576
  });
5265
5577
  return code === 0;
5266
- });
5578
+ }, deps.onProvidersChanged);
5267
5579
  },
5268
5580
  oauthLogin(kind, io) {
5269
5581
  return runFlow(async () => {
@@ -5271,7 +5583,7 @@ function createAuthPanelHost(deps) {
5271
5583
  const opts = { signal: io.signal };
5272
5584
  const code = kind === "chatgpt" ? await runCodexOAuthLogin(d, opts) : kind === "claude" ? await runClaudeOAuthLogin(d, opts) : await runCopilotOAuthLogin(d, opts);
5273
5585
  return code === 0;
5274
- });
5586
+ }, deps.onProvidersChanged);
5275
5587
  }
5276
5588
  };
5277
5589
  }
@@ -5299,6 +5611,9 @@ function createRuntimeControllerDeps(input) {
5299
5611
  statuslineLines: input.statuslineLines,
5300
5612
  setStatuslineLines: input.setStatuslineLines,
5301
5613
  saveStatuslineLines: input.saveStatuslineLines,
5614
+ statuslineDensities: input.statuslineDensities,
5615
+ setStatuslineDensities: input.setStatuslineDensities,
5616
+ saveStatuslineDensities: input.saveStatuslineDensities,
5302
5617
  getYolo: input.getYolo,
5303
5618
  onYolo: input.onYolo,
5304
5619
  getAutonomy: input.getAutonomy,
@@ -5654,6 +5969,7 @@ async function runCliExecution(params) {
5654
5969
  resolvedProvider,
5655
5970
  logger,
5656
5971
  switchProviderAndModel,
5972
+ reloadProviderConfig,
5657
5973
  applyMaxContext,
5658
5974
  renderer,
5659
5975
  reader,
@@ -5682,6 +5998,9 @@ async function runCliExecution(params) {
5682
5998
  statuslineLines,
5683
5999
  setStatuslineLines,
5684
6000
  saveStatuslineLines: saveStatuslineLines2,
6001
+ statuslineDensities,
6002
+ setStatuslineDensities,
6003
+ saveStatuslineDensities,
5685
6004
  setYoloMode,
5686
6005
  autonomyMode,
5687
6006
  setAutonomyMode,
@@ -5710,7 +6029,7 @@ async function runCliExecution(params) {
5710
6029
  governanceHandle,
5711
6030
  setConfig
5712
6031
  } = params;
5713
- const { execute } = await import("./execution-DKJDNPYF.js");
6032
+ const { execute } = await import("./execution-3Y55IWBK.js");
5714
6033
  return execute(
5715
6034
  toExecuteDeps({
5716
6035
  core: {
@@ -5786,7 +6105,8 @@ async function runCliExecution(params) {
5786
6105
  authHost: createAuthPanelHost({
5787
6106
  vault,
5788
6107
  modelsRegistry,
5789
- profileConfigPath
6108
+ profileConfigPath,
6109
+ onProvidersChanged: reloadProviderConfig
5790
6110
  }),
5791
6111
  onPanelOpen
5792
6112
  },
@@ -5826,6 +6146,9 @@ async function runCliExecution(params) {
5826
6146
  statuslineLines,
5827
6147
  setStatuslineLines,
5828
6148
  saveStatuslineLines: saveStatuslineLines2,
6149
+ statuslineDensities,
6150
+ setStatuslineDensities,
6151
+ saveStatuslineDensities,
5829
6152
  getYolo: setYoloMode,
5830
6153
  onYolo: setYoloMode,
5831
6154
  getAutonomy: () => autonomyMode,
@@ -5918,6 +6241,7 @@ import { makeAutonomyPromptContributor } from "@wrongstack/core/execution";
5918
6241
  import { sessionScopedPath } from "@wrongstack/core/utils";
5919
6242
 
5920
6243
  // src/wiring/wrongtrace-prompt-contributor.ts
6244
+ import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
5921
6245
  import { digestAtlas, summarizeFriction } from "@wrongstack/wrongtrace";
5922
6246
  var CONTRIBUTOR_DEADLINE_MS = 800;
5923
6247
  function raceWithDeadline(p, ms) {
@@ -5936,16 +6260,16 @@ function raceWithDeadline(p, ms) {
5936
6260
  );
5937
6261
  });
5938
6262
  }
5939
- function createWrongTracePromptContributor() {
5940
- 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 [];
5941
6268
  try {
5942
6269
  const wt = await raceWithDeadline(getWrongTrace(), CONTRIBUTOR_DEADLINE_MS);
5943
6270
  if (!wt?.isAvailable) return [];
5944
6271
  const [atlas, friction] = await raceWithDeadline(
5945
- Promise.all([
5946
- wt.getAtlas({ includeSymbols: false }),
5947
- wt.getFrictionMatrix(50)
5948
- ]),
6272
+ Promise.all([wt.getAtlas({ includeSymbols: false }), wt.getFrictionMatrix(50)]),
5949
6273
  CONTRIBUTOR_DEADLINE_MS
5950
6274
  ) ?? [null, []];
5951
6275
  const digest = digestAtlas(atlas);
@@ -6036,7 +6360,9 @@ function bindSystemPromptBuilder(deps) {
6036
6360
  // is reachable, the leader prompt carries a compact atlas digest +
6037
6361
  // friction summary block. Fail-open and deadline-bounded (<1s), so
6038
6362
  // an absent/slow daemon never stalls the boot prompt.
6039
- createWrongTracePromptContributor()
6363
+ createWrongTracePromptContributor({
6364
+ tokenSavingMode: deps.tokenSavingMode
6365
+ })
6040
6366
  ]
6041
6367
  })
6042
6368
  );
@@ -6051,7 +6377,7 @@ import {
6051
6377
  makeSessionNoteTool as makeSessionNoteTool2
6052
6378
  } from "@wrongstack/core/coordination";
6053
6379
  import { createContextManagerTool } from "@wrongstack/core/infrastructure";
6054
- import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
6380
+ import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
6055
6381
  import { configureChildEnvGitIdentity } from "@wrongstack/core/utils";
6056
6382
  import { registerCanonicalHostTools } from "@wrongstack/runtime/tool-registration";
6057
6383
  import { configureDangerBypass, configureExecPolicy } from "@wrongstack/tools";
@@ -6684,7 +7010,7 @@ ${commit.out}`;
6684
7010
 
6685
7011
  // src/boot/tool-registry.ts
6686
7012
  function registerBuiltinTools(deps) {
6687
- const tier = normalizeTokenSavingTier2(deps.config.features.tokenSavingMode);
7013
+ const tier = normalizeTokenSavingTier3(deps.config.features.tokenSavingMode);
6688
7014
  registerCanonicalHostTools({
6689
7015
  registry: deps.toolRegistry,
6690
7016
  tier,
@@ -7605,9 +7931,9 @@ async function generateCommitMessageWithLLM(diff, opts) {
7605
7931
  const userPrompt = `Here is the git diff:
7606
7932
 
7607
7933
  ${diff}`;
7934
+ const signal = new AbortController();
7935
+ const timeout = setTimeout(() => signal.abort(), 15e3);
7608
7936
  try {
7609
- const signal = new AbortController();
7610
- const timeout = setTimeout(() => signal.abort(), 15e3);
7611
7937
  const resp = await opts.provider.complete(
7612
7938
  {
7613
7939
  model: opts.model,
@@ -7618,7 +7944,6 @@ ${diff}`;
7618
7944
  },
7619
7945
  { signal: signal.signal }
7620
7946
  );
7621
- clearTimeout(timeout);
7622
7947
  const rawContent = resp.content;
7623
7948
  const text = Array.isArray(rawContent) ? rawContent[0]?.text ?? "" : typeof rawContent === "object" && rawContent !== null ? rawContent.text ?? "" : String(rawContent);
7624
7949
  const message = expectDefined3(text.trim().split("\n")[0]);
@@ -7626,6 +7951,8 @@ ${diff}`;
7626
7951
  return message;
7627
7952
  }
7628
7953
  } catch {
7954
+ } finally {
7955
+ clearTimeout(timeout);
7629
7956
  }
7630
7957
  return "chore: update";
7631
7958
  }
@@ -8041,57 +8368,25 @@ function formatDiagnostics(input) {
8041
8368
  import * as fs3 from "node:fs/promises";
8042
8369
  import * as os from "node:os";
8043
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";
8044
8377
  import { ERROR_CODES, FsError } from "@wrongstack/core/types";
8045
8378
  import { atomicWrite, resolveWstackPaths, toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
8046
8379
  var CONFIG_ENV = "WRONGSTACK_STATUSLINE_CONFIG";
8047
- var STATUSLINE_CONFIG_VERSION = 2;
8048
- var STATUSLINE_CONFIG_KEYS = [
8049
- "state",
8050
- "model",
8051
- "context",
8052
- "tokens",
8053
- "cache",
8054
- "cost",
8055
- "queue",
8056
- "hint",
8057
- "index",
8058
- "breaker",
8059
- "yolo",
8060
- "autonomy",
8061
- "eternal_stage",
8062
- "elapsed",
8063
- "project",
8064
- "working_dir",
8065
- "goal",
8066
- "mode",
8067
- "auto_proceed",
8068
- "git",
8069
- "sessions",
8070
- "tools",
8071
- "theme",
8072
- "token_saving",
8073
- "processes",
8074
- "version",
8075
- "dropped_tools",
8076
- "prompt_variant",
8077
- "side_effects",
8078
- "todos",
8079
- "plan",
8080
- "tasks",
8081
- "fleet",
8082
- "brain",
8083
- "debug_stream",
8084
- "enhance",
8085
- "next_steps",
8086
- "mailbox",
8087
- "fleet_agents",
8088
- "memory_context"
8089
- ];
8090
- var DEFAULTS = Object.fromEntries(
8091
- STATUSLINE_CONFIG_KEYS.map((key) => [key, true])
8092
- );
8380
+ var STATUSLINE_CONFIG_VERSION = 3;
8381
+ var STATUSLINE_CONFIG_KEYS = STATUSLINE_ITEMS;
8382
+ var DEFAULTS = defaultChipEnabledMap();
8093
8383
  function emptyDocument() {
8094
- return { version: STATUSLINE_CONFIG_VERSION, chips: { ...DEFAULTS }, lines: {} };
8384
+ return {
8385
+ version: STATUSLINE_CONFIG_VERSION,
8386
+ chips: { ...DEFAULTS },
8387
+ lines: {},
8388
+ densities: {}
8389
+ };
8095
8390
  }
8096
8391
  function resolveConfigPath() {
8097
8392
  const override = process.env[CONFIG_ENV];
@@ -8102,12 +8397,12 @@ function resolveConfigPath() {
8102
8397
  });
8103
8398
  return paths.profileStatuslineConfig(paths.profileName);
8104
8399
  }
8105
- function isRecord(value) {
8400
+ function isRecord2(value) {
8106
8401
  return typeof value === "object" && value !== null && !Array.isArray(value);
8107
8402
  }
8108
8403
  function normalizeChips(value) {
8109
8404
  const config = { ...DEFAULTS };
8110
- if (!isRecord(value)) return config;
8405
+ if (!isRecord2(value)) return config;
8111
8406
  for (const key of STATUSLINE_CONFIG_KEYS) {
8112
8407
  if (typeof value[key] === "boolean") config[key] = value[key];
8113
8408
  }
@@ -8115,33 +8410,50 @@ function normalizeChips(value) {
8115
8410
  }
8116
8411
  function normalizeLines(value) {
8117
8412
  const lines = {};
8118
- if (!isRecord(value)) return lines;
8413
+ if (!isRecord2(value)) return lines;
8119
8414
  for (const key of STATUSLINE_CONFIG_KEYS) {
8120
8415
  const raw = value[key];
8121
8416
  if (typeof raw !== "number" || !Number.isInteger(raw)) continue;
8122
- lines[key] = Math.min(4, Math.max(1, raw));
8417
+ lines[key] = clampLine(raw);
8123
8418
  }
8124
8419
  return lines;
8125
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
+ }
8126
8432
  function parseDocument(value) {
8127
- if (isRecord(value) && (isRecord(value["chips"]) || isRecord(value["lines"]))) {
8433
+ if (isRecord2(value) && (isRecord2(value["chips"]) || isRecord2(value["lines"]) || isRecord2(value["densities"]))) {
8128
8434
  return {
8129
8435
  version: STATUSLINE_CONFIG_VERSION,
8130
8436
  chips: normalizeChips(value["chips"]),
8131
- lines: normalizeLines(value["lines"])
8437
+ lines: normalizeLines(value["lines"]),
8438
+ densities: normalizeDensities(value["densities"])
8132
8439
  };
8133
8440
  }
8134
- 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
+ };
8135
8447
  }
8136
8448
  function isMissingKnownChips(value) {
8137
- 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");
8138
8450
  }
8139
8451
  function needsRewrite(value) {
8140
- if (isRecord(value) && isRecord(value["chips"])) {
8452
+ if (isRecord2(value) && isRecord2(value["chips"])) {
8141
8453
  if (value["version"] !== STATUSLINE_CONFIG_VERSION) return true;
8142
8454
  if (isMissingKnownChips(value["chips"])) return true;
8143
- if (!isRecord(value["lines"])) return true;
8144
- 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"]);
8145
8457
  }
8146
8458
  return true;
8147
8459
  }
@@ -8170,7 +8482,7 @@ async function ensureStatuslineConfig() {
8170
8482
  raw = JSON.parse(await fs3.readFile(resolveConfigPath(), "utf8"));
8171
8483
  config = parseDocument(raw);
8172
8484
  } catch (error) {
8173
- if (isRecord(error) && error["code"] === "ENOENT") {
8485
+ if (isRecord2(error) && error["code"] === "ENOENT") {
8174
8486
  sawFile = false;
8175
8487
  config = emptyDocument();
8176
8488
  } else {
@@ -8198,7 +8510,8 @@ async function saveStatuslineConfig(config) {
8198
8510
  {
8199
8511
  version: STATUSLINE_CONFIG_VERSION,
8200
8512
  chips: normalizeChips(config.chips),
8201
- lines: normalizeLines(config.lines)
8513
+ lines: normalizeLines(config.lines),
8514
+ densities: normalizeDensities(config.densities)
8202
8515
  },
8203
8516
  null,
8204
8517
  2
@@ -8216,9 +8529,33 @@ async function saveStatuslineConfig(config) {
8216
8529
  async function loadStatuslineLines() {
8217
8530
  return (await loadStatuslineConfig()).lines;
8218
8531
  }
8219
- async function saveStatuslineLines(lines) {
8220
- const doc = await ensureStatuslineConfig();
8221
- 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
+ });
8222
8559
  }
8223
8560
 
8224
8561
  // src/slash-commands/helpers.ts
@@ -9256,7 +9593,7 @@ import { randomUUID as randomUUID6 } from "node:crypto";
9256
9593
  import { color as color15 } from "@wrongstack/core/utils";
9257
9594
 
9258
9595
  // src/slash-commands/brain-council.ts
9259
- import { parseModelRef } from "@wrongstack/core/agent";
9596
+ import { parseModelRef as parseModelRef2 } from "@wrongstack/core/agent";
9260
9597
  import {
9261
9598
  BUILTIN_COUNCIL_PERSONA_IDS,
9262
9599
  BUILTIN_COUNCIL_PERSONAS
@@ -9268,11 +9605,12 @@ var COUNCIL_NUMERIC_OPS = {
9268
9605
  timeout: "perCallTimeoutMs",
9269
9606
  concurrency: "maxConcurrency",
9270
9607
  votertokens: "voterMaxTokens",
9271
- judgetokens: "judgeMaxTokens"
9608
+ judgetokens: "judgeMaxTokens",
9609
+ rounds: "deliberationRounds"
9272
9610
  };
9273
9611
  var PERSONA_SHORTHANDS = new Set(BUILTIN_COUNCIL_PERSONA_IDS);
9274
9612
  function parseRefEntry(ref) {
9275
- const parsed = parseModelRef(ref);
9613
+ const parsed = parseModelRef2(ref);
9276
9614
  const model = parsed.model?.trim();
9277
9615
  if (!model) return null;
9278
9616
  return parsed.provider ? { provider: parsed.provider, model } : { model };
@@ -9342,10 +9680,7 @@ async function handleBrainCouncilSubcommand(rest, opts, applyPatch) {
9342
9680
  opts.renderer.writeWarning(msg2);
9343
9681
  return { message: msg2 };
9344
9682
  }
9345
- return applyPatch(
9346
- { council: { voters: seats } },
9347
- councilSummary
9348
- );
9683
+ return applyPatch({ council: { voters: seats } }, councilSummary);
9349
9684
  }
9350
9685
  if (op === "personas") {
9351
9686
  const lines = [
@@ -9404,22 +9739,19 @@ async function handleBrainCouncilSubcommand(rest, opts, applyPatch) {
9404
9739
  return `Brain council ${op} set to ${color13.cyan(applied === void 0 ? "default" : String(applied))}`;
9405
9740
  });
9406
9741
  }
9407
- 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.`;
9408
9743
  opts.renderer.writeWarning(msg);
9409
9744
  return { message: msg };
9410
9745
  }
9411
9746
 
9412
9747
  // src/slash-commands/brain-status.ts
9413
9748
  import { readFile as readFile5 } from "node:fs/promises";
9749
+ import { DETERMINISTIC_BRAIN_TIERS } from "@wrongstack/core/coordination";
9414
9750
  import { color as color14 } from "@wrongstack/core/utils";
9415
- var DETERMINISTIC_TIER_NAMES = [
9416
- "rule",
9417
- "policy",
9418
- "heuristic",
9419
- "cache",
9420
- "ledger-guard",
9421
- "terminal"
9422
- ];
9751
+ function councilRoundsSummary(snapshot) {
9752
+ const rounds = snapshot.council.deliberationRounds ?? 2;
9753
+ return rounds > 1 ? `, ${rounds} rounds` : ", no deliberation";
9754
+ }
9423
9755
  function fmtAge(at) {
9424
9756
  const s = Math.max(0, Math.round((Date.now() - at) / 1e3));
9425
9757
  if (s < 60) return `${s}s ago`;
@@ -9453,7 +9785,7 @@ function formatBrainStatus(opts) {
9453
9785
  const councilSeats = opts.brainSettings?.councilLabels ?? [];
9454
9786
  if (councilSeats.length > 0) {
9455
9787
  lines.push(
9456
- ` 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)})`) : ""}`
9457
9789
  );
9458
9790
  } else if (snapshot) {
9459
9791
  lines.push(` council: ${color14.dim("disabled (/brain council on + voters)")}`);
@@ -9482,21 +9814,25 @@ function formatBrainStatus(opts) {
9482
9814
  }
9483
9815
  function formatBrainStats(opts) {
9484
9816
  const log = opts.getBrainLog?.() ?? [];
9817
+ const councilWarnings = log.filter((entry) => entry.kind === "council_warn");
9818
+ const lifetime = opts.brainTierStats?.();
9485
9819
  const counts = /* @__PURE__ */ new Map();
9486
- const councilWarnings = [];
9487
- for (const entry of log) {
9488
- if (entry.kind === "council_warn") {
9489
- councilWarnings.push(entry);
9490
- 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);
9491
9827
  }
9492
- const tier = entry.tier ?? "unattributed";
9493
- counts.set(tier, (counts.get(tier) ?? 0) + 1);
9494
9828
  }
9495
- let free = 0;
9496
- let paid = 0;
9497
- for (const [tier, n] of counts) {
9498
- if (DETERMINISTIC_TIER_NAMES.includes(tier)) free += n;
9499
- 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
+ }
9500
9836
  }
9501
9837
  const lines = [color14.bold("Brain decision tiers"), ""];
9502
9838
  if (counts.size === 0) {
@@ -9529,7 +9865,9 @@ function formatBrainStats(opts) {
9529
9865
  }
9530
9866
  lines.push(
9531
9867
  "",
9532
- 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
+ )
9533
9871
  );
9534
9872
  return lines.join("\n");
9535
9873
  }
@@ -12460,7 +12798,7 @@ function buildDoctorCommand(opts) {
12460
12798
  ].join("\n");
12461
12799
  async function loadPluginSchemas() {
12462
12800
  try {
12463
- const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-RV3OBBND.js");
12801
+ const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-PZ2VZL7V.js");
12464
12802
  const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
12465
12803
  const loaded = [];
12466
12804
  for (const s of settled) {
@@ -12864,7 +13202,7 @@ import * as fs7 from "node:fs/promises";
12864
13202
  import {
12865
13203
  diagnoseFallbackConfig,
12866
13204
  normalizeModelRef,
12867
- parseModelRef as parseModelRef2,
13205
+ parseModelRef as parseModelRef3,
12868
13206
  runtimeFallbackChain,
12869
13207
  simulateFallbackFailover,
12870
13208
  smartDefaultFallbackChain
@@ -12873,7 +13211,7 @@ import { decryptConfigSecrets, encryptConfigSecrets, noOpVault as noOpVault2 } f
12873
13211
  import { ConfigError } from "@wrongstack/core/types";
12874
13212
  import { atomicWrite as atomicWrite4, color as color25, toErrorMessage as toErrorMessage10 } from "@wrongstack/core/utils";
12875
13213
  function refInvalidReason(ref, config) {
12876
- const parsed = parseModelRef2(ref);
13214
+ const parsed = parseModelRef3(ref);
12877
13215
  if (!parsed.model) return "no model in reference";
12878
13216
  const favorites = config.favoriteModels ?? [];
12879
13217
  if (favorites.length === 0) return void 0;
@@ -12883,7 +13221,7 @@ function refInvalidReason(ref, config) {
12883
13221
  return void 0;
12884
13222
  }
12885
13223
  function refStaleModelListWarning(ref, config) {
12886
- const parsed = parseModelRef2(ref);
13224
+ const parsed = parseModelRef3(ref);
12887
13225
  if (!parsed.model) return "no model in reference";
12888
13226
  const providerId = parsed.provider ?? config.provider;
12889
13227
  const entry = config.providers?.[providerId];
@@ -13172,7 +13510,7 @@ function buildFallbackCommand(opts) {
13172
13510
  };
13173
13511
  }
13174
13512
  const ref = normalizeRef(parts.slice(2).join(" "));
13175
- const parsed = parseModelRef2(ref);
13513
+ const parsed = parseModelRef3(ref);
13176
13514
  if (!ref || !parsed.provider || !parsed.model) {
13177
13515
  return {
13178
13516
  message: `${color25.amber("Usage:")} /fallback bridge set <provider/model>`
@@ -13414,13 +13752,13 @@ ${color25.dim("Add favorites first: /fallback fav add <ref>, or fix provider mod
13414
13752
  return { message: `${color25.amber("Already favorite")}: ${color25.cyan(ref)}` };
13415
13753
  }
13416
13754
  const providerEntry = (() => {
13417
- const parsed = parseModelRef2(ref);
13755
+ const parsed = parseModelRef3(ref);
13418
13756
  const provId = parsed.provider ?? config.provider;
13419
13757
  return config.providers?.[provId];
13420
13758
  })();
13421
- 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)) {
13422
13760
  return {
13423
- 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.")}`
13424
13762
  };
13425
13763
  }
13426
13764
  favorites.push(ref);
@@ -15854,6 +16192,75 @@ function buildHealthCommand(opts) {
15854
16192
  };
15855
16193
  }
15856
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
+
15857
16264
  // src/slash-commands/help.ts
15858
16265
  function buildHelpCommand(opts) {
15859
16266
  return {
@@ -15877,6 +16284,12 @@ function buildHelpCommand(opts) {
15877
16284
  return { message: "" };
15878
16285
  }
15879
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
+ }
15880
16293
  const needle = query.startsWith("/") ? query.slice(1) : query;
15881
16294
  let match;
15882
16295
  for (const entry of opts.registry.listWithOwner()) {
@@ -15897,7 +16310,8 @@ function buildHelpCommand(opts) {
15897
16310
  const header = `/${prefix}${match.cmd.name}`;
15898
16311
  const aliasLine = match.cmd.aliases?.length ? `Aliases: ${match.cmd.aliases.map((a) => `/${prefix}${a}`).join(", ")}
15899
16312
  ` : "";
15900
- 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");
15901
16315
  return {
15902
16316
  message: [
15903
16317
  header,
@@ -18542,7 +18956,7 @@ function errorMessage(err) {
18542
18956
 
18543
18957
  // src/slash-commands/memory.ts
18544
18958
  import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
18545
- import { getSageSurface as getSageSurface3 } from "@wrongstack/sage";
18959
+ import { getSageSurface as getSageSurface4 } from "@wrongstack/sage";
18546
18960
 
18547
18961
  // src/slash-commands/memory-audience.ts
18548
18962
  import { toErrorMessage as toErrorMessage14 } from "@wrongstack/core/utils";
@@ -19412,7 +19826,9 @@ function formatMemoryDiagnostics(diag) {
19412
19826
  lines.push(` with vectors: ${v.vectors}`);
19413
19827
  lines.push(` providers: ${v.providers.join(", ") || "\u2205"}`);
19414
19828
  lines.push(` model: ${v.modelId} (${v.dimensions}-dim)`);
19415
- lines.push(` cache: ${v.cacheEntries} rows \xB7 ${v.cacheProviders} provider(s) \xB7 ${v.totalUseCount} hits`);
19829
+ lines.push(
19830
+ ` cache: ${v.cacheEntries} rows \xB7 ${v.cacheProviders} provider(s) \xB7 ${v.totalUseCount} hits`
19831
+ );
19416
19832
  if (v.oldestLastUsedAt) {
19417
19833
  lines.push(` cache oldest: ${v.oldestLastUsedAt}`);
19418
19834
  }
@@ -19421,7 +19837,9 @@ function formatMemoryDiagnostics(diag) {
19421
19837
  lines.push("Cross-system coverage:");
19422
19838
  lines.push(` vector \u2194 SAGE: ${v.mirroredInSage} mirrored`);
19423
19839
  if (v.standalone > 0) {
19424
- lines.push(` standalone: ${v.standalone} vector-only entries (no SAGE id \u2014 lexical recall misses these)`);
19840
+ lines.push(
19841
+ ` standalone: ${v.standalone} vector-only entries (no SAGE id \u2014 lexical recall misses these)`
19842
+ );
19425
19843
  }
19426
19844
  if (v.mirroredInSage === 0 && diag.sageTotal > 0) {
19427
19845
  lines.push(" \u{1F4A1} Run `wrongstack --vector-sync` to backfill the vector mirror.");
@@ -19522,18 +19940,14 @@ function formatSearchRace(race) {
19522
19940
  if (race.lexicalOnly.length > 0) {
19523
19941
  lines.push("### \u{1F170}\uFE0F Lexical only (vector missed)");
19524
19942
  for (const row of race.lexicalOnly) {
19525
- lines.push(
19526
- `- \`${row.id.slice(0, 12)}\u2026\` L=${pct2(row.lexicalScore ?? 0)} ${row.preview}`
19527
- );
19943
+ lines.push(`- \`${row.id.slice(0, 12)}\u2026\` L=${pct2(row.lexicalScore ?? 0)} ${row.preview}`);
19528
19944
  }
19529
19945
  lines.push("");
19530
19946
  }
19531
19947
  if (race.vectorOnly.length > 0) {
19532
19948
  lines.push("### \u{1F171}\uFE0F Vector only (lexical missed)");
19533
19949
  for (const row of race.vectorOnly) {
19534
- lines.push(
19535
- `- \`${row.id.slice(0, 12)}\u2026\` V=${pct2(row.vectorScore ?? 0)} ${row.preview}`
19536
- );
19950
+ lines.push(`- \`${row.id.slice(0, 12)}\u2026\` V=${pct2(row.vectorScore ?? 0)} ${row.preview}`);
19537
19951
  }
19538
19952
  lines.push("");
19539
19953
  }
@@ -19867,6 +20281,7 @@ import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
19867
20281
  import {
19868
20282
  fileTriageProposals,
19869
20283
  formatTriageReport,
20284
+ getSageSurface as getSageSurface3,
19870
20285
  runTriage
19871
20286
  } from "@wrongstack/sage";
19872
20287
  var DEFAULT_MAX_PHASE3 = 1e3;
@@ -19988,8 +20403,7 @@ Usage: /memory triage [--dry-run|--apply] [--limit N] [--max-phase3 N] [--max-ph
19988
20403
  function getSage(opts) {
19989
20404
  if (!opts.memoryStore) return null;
19990
20405
  try {
19991
- const { getSageSurface: getSageSurface4 } = __require("@wrongstack/sage");
19992
- return getSageSurface4(opts.memoryStore);
20406
+ return getSageSurface3(opts.memoryStore) ?? null;
19993
20407
  } catch {
19994
20408
  return null;
19995
20409
  }
@@ -20082,7 +20496,7 @@ function buildMemoryCommand(opts) {
20082
20496
  async run(args) {
20083
20497
  const store = opts.memoryStore;
20084
20498
  if (!store) return { message: "No memory store configured." };
20085
- const Sage = getSageSurface3(store);
20499
+ const Sage = getSageSurface4(store);
20086
20500
  const { cmd, rest } = parseSubcommand(args);
20087
20501
  const restJoined = rest.join(" ").trim();
20088
20502
  switch (cmd) {
@@ -20295,7 +20709,7 @@ function buildMemoryCommand(opts) {
20295
20709
  };
20296
20710
  }
20297
20711
  try {
20298
- 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 });
20299
20713
  const race = await runSearchRace(restJoined, lexical, vectorStore, { limit: 20 });
20300
20714
  return { message: formatSearchRace(race) };
20301
20715
  } catch (err) {
@@ -20547,9 +20961,7 @@ File size reduced. Audit-logged as \`memory.log_compacted\`.`
20547
20961
  try {
20548
20962
  [sageStats, sageTotal] = await Promise.all([
20549
20963
  Sage.stats(),
20550
- Sage.listSagePage({ limit: 1 }).then(
20551
- (page) => page.total ?? page.memories.length
20552
- )
20964
+ Sage.listSagePage({ limit: 1 }).then((page) => page.total ?? page.memories.length)
20553
20965
  ]);
20554
20966
  } catch (err) {
20555
20967
  return {
@@ -22072,7 +22484,7 @@ function buildPruneCommand(opts) {
22072
22484
  return {
22073
22485
  name: "prune",
22074
22486
  category: "Session",
22075
- 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.",
22076
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.",
22077
22489
  async run(args) {
22078
22490
  const parts = args.split(/\s+/).filter(Boolean);
@@ -23467,7 +23879,11 @@ ${sddHelp()}`
23467
23879
  }
23468
23880
 
23469
23881
  // src/slash-commands/session.ts
23470
- import { extractInterruptedTools, SessionRecovery } from "@wrongstack/core/storage";
23882
+ import {
23883
+ extractInterruptedTools,
23884
+ getSessionRegistry,
23885
+ SessionRecovery
23886
+ } from "@wrongstack/core/storage";
23471
23887
  import { color as color47, isPidAlive, toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
23472
23888
  function statusIcon2(status) {
23473
23889
  switch (status) {
@@ -23499,6 +23915,12 @@ function agentStatusIcon(status) {
23499
23915
  return color47.dim("?");
23500
23916
  }
23501
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
+ }
23502
23924
  function fmtDuration(startedAt) {
23503
23925
  const diff = Date.now() - new Date(startedAt).getTime();
23504
23926
  const min = Math.floor(diff / 6e4);
@@ -23516,8 +23938,7 @@ function fmtAgentLine(agent) {
23516
23938
  }
23517
23939
  function getRegistry() {
23518
23940
  try {
23519
- const mod = __require("@wrongstack/core/storage");
23520
- return mod.getSessionRegistry?.();
23941
+ return getSessionRegistry();
23521
23942
  } catch {
23522
23943
  return void 0;
23523
23944
  }
@@ -23544,7 +23965,7 @@ function buildLoadCommand(opts) {
23544
23965
  name: "sessions",
23545
23966
  category: "Session",
23546
23967
  aliases: ["resume", "load"],
23547
- 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.",
23548
23969
  async run(args) {
23549
23970
  const parts = args.split(/\s+/).filter(Boolean);
23550
23971
  const first = parts[0]?.toLowerCase();
@@ -23593,6 +24014,58 @@ function buildLoadCommand(opts) {
23593
24014
  return { message: color47.red(`Rename failed: ${toErrorMessage21(err)}`) };
23594
24015
  }
23595
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
+ }
23596
24069
  if (first === "delete") {
23597
24070
  const targetId = parts[1];
23598
24071
  if (!targetId) {
@@ -23727,10 +24200,11 @@ function buildLoadCommand(opts) {
23727
24200
  }
23728
24201
  const stat6 = parts2.join(" ");
23729
24202
  const date = color47.dim(s.startedAt.slice(0, 16).replace("T", " "));
24203
+ const archived = s.storageState === "cold" ? color47.dim(" gz") : "";
23730
24204
  const isCurrent = s.id === currentId;
23731
24205
  const marker = isCurrent ? color47.cyan(" (current)") : "";
23732
24206
  const label = s.name ? `${color47.bold(s.id)} ${color47.cyan(`(${s.name})`)}` : color47.bold(s.id);
23733
- return ` ${label}${marker}
24207
+ return ` ${label}${marker}${archived}
23734
24208
  ${date} ${stat6}
23735
24209
  ${color47.dim(s.title)}`;
23736
24210
  });
@@ -24007,7 +24481,7 @@ async function killSession(sessionId, confirm) {
24007
24481
 
24008
24482
  // src/slash-commands/setmodel.ts
24009
24483
  import * as fs15 from "node:fs/promises";
24010
- import { fallbackProfileChain, parseModelRef as parseModelRef3 } from "@wrongstack/core/agent";
24484
+ import { fallbackProfileChain, parseModelRef as parseModelRef4 } from "@wrongstack/core/agent";
24011
24485
  import { AGENT_CATALOG as AGENT_CATALOG2, AGENTS_BY_PHASE as AGENTS_BY_PHASE3 } from "@wrongstack/core/agent-catalog";
24012
24486
  import {
24013
24487
  MATRIX_PHASE_KEYS,
@@ -24405,7 +24879,7 @@ function buildSetModelCommand(opts) {
24405
24879
  const first = chain[0];
24406
24880
  if (!first)
24407
24881
  return { message: `${color48.red("Empty profile")}: ${color48.amber(profile)}` };
24408
- const parsed = parseModelRef3(first);
24882
+ const parsed = parseModelRef4(first);
24409
24883
  const provider2 = parsed.provider ?? config.provider;
24410
24884
  if (!keyed.includes(provider2)) {
24411
24885
  return {
@@ -24694,7 +25168,9 @@ function buildEffortCommand(opts) {
24694
25168
  ` ${color49.bold("effort")} ${color49.bold(current)}${ok ? "" : ` ${color49.amber(`(not advertised by this model \u2014 supported: ${levels.join(", ")})`)}`}`
24695
25169
  );
24696
25170
  } else {
24697
- lines.push(` ${color49.bold("effort")} ${color49.dim("(not set \u2014 auto \xB7 provider default applies)")}`);
25171
+ lines.push(
25172
+ ` ${color49.bold("effort")} ${color49.dim("(not set \u2014 auto \xB7 provider default applies)")}`
25173
+ );
24698
25174
  }
24699
25175
  if (levels) {
24700
25176
  const rendered = REASONING_EFFORT_LEVELS2.filter((l) => levels.includes(l)).map(
@@ -24714,15 +25190,14 @@ function buildEffortCommand(opts) {
24714
25190
  ` ${color49.bold("levels")} ${color49.dim("(unknown \u2014 the resolver drops unsupported values with a warning)")}`
24715
25191
  );
24716
25192
  }
24717
- lines.push(
24718
- "",
24719
- ` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`
24720
- );
25193
+ lines.push("", ` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`);
24721
25194
  return { message: lines.join("\n") };
24722
25195
  }
24723
25196
  if (sub === "clear" || sub === "off-default") {
24724
25197
  if (current === void 0) {
24725
- return { message: `${color49.dim("No session effort set \u2014 provider default already applies.")}` };
25198
+ return {
25199
+ message: `${color49.dim("No session effort set \u2014 provider default already applies.")}`
25200
+ };
24726
25201
  }
24727
25202
  await patchSessionEffort(void 0, opts.paths, config.activeProfile ?? "default");
24728
25203
  opts.configStore.update({
@@ -25203,6 +25678,38 @@ var THEME_META = {
25203
25678
  "gruvbox-dark-hard": {
25204
25679
  name: "Gruvbox Dark Hard",
25205
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"
25206
25713
  }
25207
25714
  };
25208
25715
  var THEME_OPTIONS = THEME_PRESET_IDS.map((id) => ({ id, ...THEME_META[id] }));
@@ -26622,7 +27129,6 @@ function formatDelay(ms) {
26622
27129
  var ALL_SETTINGS_KEYS = [
26623
27130
  "delay",
26624
27131
  "mode",
26625
- "hints",
26626
27132
  "debug-stream",
26627
27133
  "config-scope",
26628
27134
  "fs-access",
@@ -26764,19 +27270,6 @@ async function executeSettingsSubcommand(sub, rest, opts) {
26764
27270
  });
26765
27271
  return { message: `${color54.green("\u2713")} default autonomy \u2192 ${color54.bold(raw)}` };
26766
27272
  }
26767
- if (sub === "hints") {
26768
- const raw = (rest[0] ?? "").toLowerCase();
26769
- if (!["on", "off"].includes(raw)) {
26770
- return { message: `${color54.amber("Usage:")} /settings hints on|off` };
26771
- }
26772
- const on = raw === "on";
26773
- await persistConfigSetting(persistDeps, (cfg) => {
26774
- cfg.hints = on;
26775
- });
26776
- return {
26777
- message: `${color54.green("\u2713")} launch hints \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
26778
- };
26779
- }
26780
27273
  if (sub === "debug-stream") {
26781
27274
  const raw = (rest[0] ?? "").toLowerCase();
26782
27275
  if (!["on", "off"].includes(raw)) {
@@ -27480,7 +27973,6 @@ var SETTINGS_HELP = [
27480
27973
  " /settings stream-fleet off|full Fleet-chat verbosity (on = full)",
27481
27974
  " /settings chime on|off Ring terminal bell when a run completes",
27482
27975
  " /settings confirm-exit on|off Ask for confirmation before interrupt/exit",
27483
- " /settings hints on|off Show or suppress rotating launch hints",
27484
27976
  " /settings debug-stream on|off Raw SSE hex-dump to stderr for debugging",
27485
27977
  " /settings config-scope global|project Save settings globally or per-project",
27486
27978
  " /settings fs-access unrestricted|project File-tool access scope (project = confine to project root)",
@@ -27537,7 +28029,6 @@ function formatSettingsDefaults() {
27537
28029
  "",
27538
28030
  ` auto-proceed delay: ${color55.cyan("45s")} ${color55.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
27539
28031
  ` default autonomy mode: ${color55.cyan("off")}`,
27540
- ` launch hints: ${color55.cyan("on")}`,
27541
28032
  ` iteration timeout: ${color55.cyan("5 min")}`,
27542
28033
  ` session timeout: ${color55.cyan("30 min")}`,
27543
28034
  ` max iterations: ${color55.cyan("100")}`,
@@ -27549,7 +28040,6 @@ function formatCurrentSettingsView(opts) {
27549
28040
  const autonomy = opts.configStore.get().autonomy;
27550
28041
  const delay = autonomy?.autoProceedDelayMs ?? 45e3;
27551
28042
  const mode = autonomy?.defaultMode ?? "off";
27552
- const hints = opts.configStore.get().hints !== false;
27553
28043
  const debugStream = opts.configStore.get().debugStream === true;
27554
28044
  const configScope = opts.configStore.get().configScope ?? "global";
27555
28045
  const fsAccess = opts.configStore.get().tools?.restrictToProjectRoot === true ? "project" : "unrestricted";
@@ -27598,7 +28088,6 @@ function formatCurrentSettingsView(opts) {
27598
28088
  ` fleet chat: ${color55.cyan(resolveFleetChatVerbosity(au))} ${color55.dim("change: /settings stream-fleet off|full")}`,
27599
28089
  ` completion chime: ${au?.chime === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings chime on|off")}`,
27600
28090
  ` confirm before exit: ${au?.confirmExit !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings confirm-exit on|off")}`,
27601
- ` launch hints: ${hints ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hints on|off")}`,
27602
28091
  ` debug stream: ${debugStream ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings debug-stream on|off")}`,
27603
28092
  ` config scope: ${color55.cyan(configScope)} ${color55.dim("change: /settings config-scope global|project")}`,
27604
28093
  ` filesystem access: ${color55.cyan(fsAccess)} ${color55.dim("change: /settings fs-access unrestricted|project")}`,
@@ -28093,67 +28582,68 @@ function buildDirectorCommand(opts) {
28093
28582
  }
28094
28583
 
28095
28584
  // src/slash-commands/statusline.ts
28096
- var ITEM_DESCRIPTIONS = {
28097
- state: "Agent run state / thinking spinner",
28098
- model: "Current provider/model id",
28099
- todos: "Todo items (pending/in-progress/done counts)",
28100
- plan: "Plan board items (open/in-progress/done)",
28101
- tasks: "Task board items (structured work with type/priority)",
28102
- fleet: "Fleet agent status (running/idle/pending/completed)",
28103
- fleet_agents: "Per-agent live detail row",
28104
- git: "Git branch name",
28105
- elapsed: "Session elapsed time",
28106
- context: "Context window usage (input tokens)",
28107
- tokens: "Input/output token counters",
28108
- cache: "Prompt cache hit ratio",
28109
- cost: "Token cost estimate (input/output/total)",
28110
- queue: "Queued prompt count",
28111
- hint: "Transient status hint text",
28112
- index: "Codebase indexing status",
28113
- breaker: "Process breaker countdown",
28114
- working_dir: "Current working directory",
28115
- project: "Project name",
28116
- yolo: "YOLO permission mode",
28117
- autonomy: "Autonomy mode",
28118
- eternal_stage: "Autonomy stage",
28119
- goal: "Active goal summary",
28120
- mode: "Active agent mode label",
28121
- auto_proceed: "Auto-proceed countdown",
28122
- sessions: "Live session count",
28123
- tools: "Registered tool count",
28124
- theme: "Active color theme preset",
28125
- token_saving: "Token-saving mode indicator",
28126
- side_effects: "Side-effect / audit event count",
28127
- processes: "Tracked bash/exec process count",
28128
- version: "WrongStack version + update notice (right-anchored)",
28129
- dropped_tools: "Tools dropped from the provider request (maxTools limit)",
28130
- prompt_variant: "System prompt variant (Lite / Standard / Pro)",
28131
- brain: "Brain arbiter decisions",
28132
- mailbox: "Mailbox unread messages and peers",
28133
- enhance: "Prompt-enhance countdown",
28134
- debug_stream: "Stream debug telemetry",
28135
- next_steps: "Next-step auto-submit countdown",
28136
- memory_context: "Memory context detail (total records + active-in-context)"
28137
- };
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";
28138
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
+ }
28139
28618
  function buildStatuslineCommand(deps) {
28140
28619
  return {
28141
28620
  name: "statusline",
28142
28621
  category: "Config",
28143
28622
  aliases: ["sl"],
28144
- description: "Customize status bar chips: /statusline [item] [on|off|reset]",
28623
+ description: "Customize status bar chips: /statusline [item] [on|off|line N|density D]",
28145
28624
  help: [
28146
- "Usage: /statusline [item] [on|off|reset]",
28147
- " /statusline \u2014 show current config",
28148
- " /statusline <item> \u2014 toggle item on/off",
28149
- " /statusline <item> on \u2014 enable a chip",
28150
- " /statusline <item> off \u2014 disable a chip",
28151
- " /statusline all on \u2014 enable all chips",
28152
- " /statusline all off \u2014 disable all chips",
28153
- " /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`.",
28154
28644
  "",
28155
28645
  "Available items:",
28156
- ...ALL_CONFIG_KEYS.map((k) => ` ${k.padEnd(12)} ${ITEM_DESCRIPTIONS[k]}`),
28646
+ ...ALL_CONFIG_KEYS.map((k) => ` ${k.padEnd(16)} ${CHIP_DESCRIPTIONS[k]}`),
28157
28647
  "",
28158
28648
  "Density mode (minimum/detailed/no-color) is a separate setting \u2014 see /settings.",
28159
28649
  "These toggles set chip eligibility in any mode; some chips only render in detailed mode.",
@@ -28163,8 +28653,8 @@ function buildStatuslineCommand(deps) {
28163
28653
  async run(args) {
28164
28654
  const cfg = await deps.getConfig();
28165
28655
  const trimmed = args.trim();
28166
- const parts = trimmed.split(/\s+/);
28167
- const [item, action] = parts;
28656
+ const parts = trimmed.split(/\s+/).filter(Boolean);
28657
+ const [item, action, value] = parts;
28168
28658
  if (!item && deps.onPanelOpen?.current) {
28169
28659
  const opened = deps.onPanelOpen.current("statuslineOpen");
28170
28660
  if (opened) return { message: "Opened statusline picker." };
@@ -28174,14 +28664,26 @@ function buildStatuslineCommand(deps) {
28174
28664
  for (const k of ALL_CONFIG_KEYS) {
28175
28665
  const val = cfg.chips[k];
28176
28666
  if (val === void 0) continue;
28177
- 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
+ );
28178
28672
  }
28179
28673
  return { message: lines.join("\n") };
28180
28674
  }
28675
+ if (item === "preview") {
28676
+ return { message: ["StatusBar layout:", ...renderLayout(cfg)].join("\n") };
28677
+ }
28181
28678
  if (item === "reset") {
28182
28679
  await deps.setConfig({ ...cfg, chips: { ...DEFAULTS } });
28183
- deps.setHiddenItems([]);
28184
- 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." };
28185
28687
  }
28186
28688
  if (item === "all") {
28187
28689
  const onOff2 = action?.toLowerCase();
@@ -28198,13 +28700,31 @@ function buildStatuslineCommand(deps) {
28198
28700
  message: `statusline all: ${onOff2 === "on" ? "showing all chips" : "hiding all chips"}`
28199
28701
  };
28200
28702
  }
28201
- const validItems = ALL_CONFIG_KEYS;
28202
- if (!validItems.includes(item)) {
28703
+ if (!isConfigKey(item)) {
28203
28704
  return {
28204
28705
  message: `Unknown item "${item}". Run /statusline to see available items.`
28205
28706
  };
28206
28707
  }
28207
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
+ }
28208
28728
  if (!onOff) {
28209
28729
  const currentValue = cfg.chips[item] ?? true;
28210
28730
  const newValue = !currentValue;
@@ -28217,7 +28737,7 @@ function buildStatuslineCommand(deps) {
28217
28737
  return { message: `statusline ${item}: ${newValue ? "on" : "off"}` };
28218
28738
  }
28219
28739
  if (onOff !== "on" && onOff !== "off") {
28220
- return { message: `Usage: /statusline ${item} on|off` };
28740
+ return { message: `Usage: /statusline ${item} on|off|line <1-4>|density <level>` };
28221
28741
  }
28222
28742
  await deps.setConfig({ ...cfg, chips: { ...cfg.chips, [item]: onOff === "on" } });
28223
28743
  if (onOff === "off") {
@@ -29950,7 +30470,7 @@ function buildToolCommand(opts) {
29950
30470
  );
29951
30471
  }
29952
30472
  async function runAutoThinDryRun() {
29953
- const { runBootAutoThin } = await import("./boot-auto-thin-BZ675EVT.js");
30473
+ const { runBootAutoThin } = await import("./boot-auto-thin-MANHOYHE.js");
29954
30474
  const cfg = getAutoThin();
29955
30475
  const result = await runBootAutoThin({
29956
30476
  toolRegistry: opts.toolRegistry,
@@ -30014,7 +30534,7 @@ function buildToolCommand(opts) {
30014
30534
  if (!cfg.enabled) {
30015
30535
  return `${color63.amber("Auto-thinning is off")}. Run ${color63.cyan("/settings autothin on")} first.`;
30016
30536
  }
30017
- const { runBootAutoThin } = await import("./boot-auto-thin-BZ675EVT.js");
30537
+ const { runBootAutoThin } = await import("./boot-auto-thin-MANHOYHE.js");
30018
30538
  const result = await runBootAutoThin({
30019
30539
  toolRegistry: opts.toolRegistry,
30020
30540
  events: opts.events,
@@ -31531,6 +32051,7 @@ function setupCliSlashCommands(params) {
31531
32051
  brainSettings,
31532
32052
  brainRuntime,
31533
32053
  initialBrainLog,
32054
+ brainTierStats,
31534
32055
  coordinatorController,
31535
32056
  statusTracker,
31536
32057
  shadowController,
@@ -31617,6 +32138,7 @@ function setupCliSlashCommands(params) {
31617
32138
  brainSettings,
31618
32139
  brainRuntime,
31619
32140
  getBrainLog: () => initialBrainLog,
32141
+ brainTierStats,
31620
32142
  ...coordinatorController ? { coordinatorController } : {},
31621
32143
  statusTracker,
31622
32144
  shadowController,
@@ -31710,7 +32232,8 @@ function setupCliSlashCommands(params) {
31710
32232
  // src/wiring/command-host-state.ts
31711
32233
  import {
31712
32234
  areSubagentsAllowedForSession as areSubagentsAllowedForSession4,
31713
- FLEET_ROSTER as FLEET_ROSTER5
32235
+ FLEET_ROSTER as FLEET_ROSTER5,
32236
+ mailboxSessionTag as mailboxSessionTag6
31714
32237
  } from "@wrongstack/core/coordination";
31715
32238
  import {
31716
32239
  AgentError as AgentError3,
@@ -31773,8 +32296,7 @@ async function loadStatuslineHiddenItems() {
31773
32296
  for (const k of STATUSLINE_CONFIG_KEYS) {
31774
32297
  chips[k] = !items.includes(k);
31775
32298
  }
31776
- const doc2 = await ensureStatuslineConfig();
31777
- await saveStatuslineConfig({ ...doc2, chips });
32299
+ await saveStatuslineChips(chips);
31778
32300
  };
31779
32301
  return { hiddenItems: hiddenItemsList, setHiddenItems, saveHiddenItems };
31780
32302
  }
@@ -31786,9 +32308,12 @@ async function setupCommandHostState(input) {
31786
32308
  );
31787
32309
  const interruptController = createInterruptController();
31788
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());
31789
32314
  input.hqCommandController.killFleet = () => killFleet2(input.getDirector());
31790
32315
  input.hqCommandController.terminateAgent = (subagentId) => terminateAgent(input.getDirector(), subagentId);
31791
- input.hqCommandController.spawnAgent = (role, task, maxIterations) => spawnAgent2(input.getDirector(), input.sessionRef.current?.id ?? input.session.id, role, task, maxIterations);
32316
+ input.hqCommandController.spawnAgent = (role, task, maxIterations) => spawnAgent2(input.getDirector(), liveSessionId(), role, task, maxIterations);
31792
32317
  const enhanceController = createEnhanceController(input.getConfig());
31793
32318
  const statuslineConfigDeps = createStatuslineConfigDeps();
31794
32319
  const hidden = await loadStatuslineHiddenItems();
@@ -31807,7 +32332,16 @@ async function setupCommandHostState(input) {
31807
32332
  };
31808
32333
  const saveStatuslineLines2 = async (next) => {
31809
32334
  currentLines = { ...next };
31810
- 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 });
31811
32345
  };
31812
32346
  const agentsMonitorController = createAgentsMonitorController();
31813
32347
  const onPanelOpen = { current: null };
@@ -31857,6 +32391,10 @@ async function setupCommandHostState(input) {
31857
32391
  getCurrentStatuslineLines: () => currentLines,
31858
32392
  setStatuslineLines,
31859
32393
  saveStatuslineLines: saveStatuslineLines2,
32394
+ statuslineDensities: { ...statuslineDensities },
32395
+ getCurrentStatuslineDensities: () => currentDensities,
32396
+ setStatuslineDensities,
32397
+ saveStatuslineDensities,
31860
32398
  agentsMonitorController,
31861
32399
  onPanelOpen,
31862
32400
  goalHost,
@@ -32404,7 +32942,7 @@ function setupHqTelemetry(deps) {
32404
32942
  agentMonitor,
32405
32943
  brainMailbox,
32406
32944
  teardownHandlers,
32407
- mailboxSessionTag: mailboxSessionTag7,
32945
+ mailboxSessionTag: mailboxSessionTag8,
32408
32946
  hqPublisherRef,
32409
32947
  mcpRegistry
32410
32948
  } = deps;
@@ -32413,7 +32951,11 @@ function setupHqTelemetry(deps) {
32413
32951
  const hqCommandController = {
32414
32952
  steerMailbox: brainMailbox,
32415
32953
  interruptLeader: () => false,
32416
- 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,
32417
32959
  allowRunCommand: () => flags["hq-allow-exec"] === true
32418
32960
  };
32419
32961
  const hqOnCommand = createHqCommandDispatcher(hqCommandController);
@@ -32577,7 +33119,7 @@ import { NotifierImpl } from "@wrongstack/core/notifications";
32577
33119
  import {
32578
33120
  SlashCommandRegistry
32579
33121
  } from "@wrongstack/core/registry";
32580
- import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
33122
+ import { normalizeTokenSavingTier as normalizeTokenSavingTier4 } from "@wrongstack/core/types";
32581
33123
  import {
32582
33124
  CONTEXT_WINDOW_MODE_PINNED_META_KEY as CONTEXT_WINDOW_MODE_PINNED_META_KEY2,
32583
33125
  resolveContextWindowPolicy as resolveContextWindowPolicy3
@@ -33094,11 +33636,7 @@ async function setupCompaction(params) {
33094
33636
  providerId: config.provider ?? provider.id,
33095
33637
  modelId: config.model ?? context.model
33096
33638
  });
33097
- const initialPolicy = resolveContextWindowPolicy2(
33098
- config.context,
33099
- void 0,
33100
- effectiveMaxContext
33101
- );
33639
+ const initialPolicy = resolveContextWindowPolicy2(config.context, void 0, effectiveMaxContext);
33102
33640
  context.meta ??= {};
33103
33641
  context.meta["contextWindowMode"] = initialPolicy.id;
33104
33642
  context.meta["contextWindowPolicy"] = initialPolicy;
@@ -33632,7 +34170,7 @@ async function setupLifecycleAndPlugins(deps) {
33632
34170
  toolRegistry,
33633
34171
  events,
33634
34172
  log: logger,
33635
- lazyMode: normalizeTokenSavingTier3(config.features.tokenSavingMode) !== "off",
34173
+ lazyMode: normalizeTokenSavingTier4(config.features.tokenSavingMode) !== "off",
33636
34174
  cacheDir: wpaths.cacheDir,
33637
34175
  authorizationProviderFactory: createVaultBackedMcpAuthorizationProviderFactory({
33638
34176
  store: mcpTokenStore
@@ -33661,10 +34199,7 @@ async function setupLifecycleAndPlugins(deps) {
33661
34199
  const getLiveConfig = () => configStore.get();
33662
34200
  const fallbackProfileManager = container.resolve(TOKENS11.FallbackProfileManager);
33663
34201
  const statusTracker = container.resolve(TOKENS11.ProviderModelStatusTracker);
33664
- const buildUtilityProvider = (providerId) => buildProviderForIdRuntimeFn(
33665
- { config: getLiveConfig(), providerRegistry, logger },
33666
- providerId
33667
- );
34202
+ const buildUtilityProvider = (providerId) => buildProviderForIdRuntimeFn({ config: getLiveConfig(), providerRegistry, logger }, providerId);
33668
34203
  const pluginOneShot = new OneShotOrchestrator2({
33669
34204
  buildProvider: buildUtilityProvider,
33670
34205
  getConfig: getLiveConfig,
@@ -34120,7 +34655,10 @@ function setupProviderRuntime(deps) {
34120
34655
  "uiLocale"
34121
34656
  ];
34122
34657
  const activeProfileOf = (c) => typeof c.activeProfile === "string" && c.activeProfile ? c.activeProfile : "default";
34123
- if (process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
34658
+ let reloadProviderConfig = async () => {
34659
+ };
34660
+ const configWatchEnabled = process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1";
34661
+ {
34124
34662
  let activeProfile = activeProfileOf(cfg);
34125
34663
  let configLayers = [];
34126
34664
  const rebuildLayers = () => {
@@ -34211,6 +34749,7 @@ function setupProviderRuntime(deps) {
34211
34749
  );
34212
34750
  }
34213
34751
  };
34752
+ reloadProviderConfig = onAnyConfigChange;
34214
34753
  let watchers = [];
34215
34754
  const openWatchers = () => {
34216
34755
  watchers = configLayers.map(
@@ -34228,20 +34767,22 @@ function setupProviderRuntime(deps) {
34228
34767
  for (const w of watchers) w.close();
34229
34768
  watchers = [];
34230
34769
  };
34231
- openWatchers();
34232
- teardownHandlers.push(
34233
- configStore.watch((next) => {
34234
- const nextProfile = activeProfileOf(next);
34235
- if (nextProfile === activeProfile) return;
34236
- activeProfile = nextProfile;
34237
- closeWatchers();
34238
- rebuildLayers();
34239
- openWatchers();
34240
- previousSnapshotSerialized = void 0;
34241
- void onAnyConfigChange();
34242
- })
34243
- );
34244
- 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
+ }
34245
34786
  }
34246
34787
  return {
34247
34788
  resolveProviderCfg: resolveProviderCfg2,
@@ -34249,7 +34790,8 @@ function setupProviderRuntime(deps) {
34249
34790
  buildProviderForModel,
34250
34791
  refreshMaxContextFor,
34251
34792
  refreshRuntimeModelStateFor,
34252
- switchProviderAndModel
34793
+ switchProviderAndModel,
34794
+ reloadProviderConfig
34253
34795
  };
34254
34796
  }
34255
34797
 
@@ -34470,7 +35012,7 @@ async function setupReplayAndGovernance({
34470
35012
  const replayFlag = flags["replay"];
34471
35013
  const recordFlag = flags["record"];
34472
35014
  if (typeof replayFlag === "string" || recordFlag === true) {
34473
- const { bindReplayToContainer } = await import("./replay-FJ2JBXUA.js");
35015
+ const { bindReplayToContainer } = await import("./replay-Z3FTJEMM.js");
34474
35016
  const mode = recordFlag === true ? "record" : "replay";
34475
35017
  bindReplayToContainer({
34476
35018
  container,
@@ -34658,7 +35200,7 @@ async function prepareRuntimeDispatch(input) {
34658
35200
  // src/wiring/session-establishment.ts
34659
35201
  import * as path31 from "node:path";
34660
35202
  import { TOKENS as TOKENS12 } from "@wrongstack/core/kernel";
34661
- import { getSessionRegistry as getSessionRegistry2 } from "@wrongstack/core/storage";
35203
+ import { getSessionRegistry as getSessionRegistry3 } from "@wrongstack/core/storage";
34662
35204
  import { addFatalSalvageHook } from "@wrongstack/core/utils";
34663
35205
 
34664
35206
  // src/wiring/session.ts
@@ -34695,7 +35237,7 @@ import {
34695
35237
  } from "@wrongstack/tools/session-kanban";
34696
35238
 
34697
35239
  // src/wiring/resume-candidate.ts
34698
- import { getSessionRegistry, SessionRecovery as SessionRecovery2 } from "@wrongstack/core/storage";
35240
+ import { getSessionRegistry as getSessionRegistry2, SessionRecovery as SessionRecovery2 } from "@wrongstack/core/storage";
34699
35241
  var MAX_CANDIDATES = 20;
34700
35242
  async function pickResumeCandidate(options) {
34701
35243
  const live = await liveSessionIds(options.globalRoot);
@@ -34716,7 +35258,7 @@ async function recentCandidates(sessionStore) {
34716
35258
  }
34717
35259
  async function liveSessionIds(globalRoot) {
34718
35260
  try {
34719
- const registry = getSessionRegistry(globalRoot);
35261
+ const registry = getSessionRegistry2(globalRoot);
34720
35262
  const entries = await registry.list();
34721
35263
  return new Set(entries.map((entry) => entry.sessionId));
34722
35264
  } catch {
@@ -35036,7 +35578,7 @@ async function setupSessionEstablishment(args) {
35036
35578
  const sessionStore = container.resolve(TOKENS12.SessionStore);
35037
35579
  const tokenCounter = container.resolve(TOKENS12.TokenCounter);
35038
35580
  tokenCounter.setSessionId?.(() => sessionRef.current?.id);
35039
- const sessionRegistry = getSessionRegistry2(wpaths.globalRoot);
35581
+ const sessionRegistry = getSessionRegistry3(wpaths.globalRoot);
35040
35582
  const sessResult = await setupSession({
35041
35583
  config: { model: config.model, provider: config.provider },
35042
35584
  wpaths,
@@ -35126,11 +35668,11 @@ async function setupSessionRegistry(deps) {
35126
35668
  };
35127
35669
  let ownershipEstablished = false;
35128
35670
  try {
35129
- const [{ getSessionRegistry: getSessionRegistry3 }, { AgentStatusTracker, FleetNotifier }] = await Promise.all([
35671
+ const [{ getSessionRegistry: getSessionRegistry4 }, { AgentStatusTracker, FleetNotifier }] = await Promise.all([
35130
35672
  import("@wrongstack/core/storage"),
35131
35673
  import("@wrongstack/core/coordination")
35132
35674
  ]);
35133
- const registry = getSessionRegistry3(wpaths.globalRoot);
35675
+ const registry = getSessionRegistry4(wpaths.globalRoot);
35134
35676
  const projectSlug = path32.basename(wpaths.projectDir);
35135
35677
  const projectName = path32.basename(projectRoot);
35136
35678
  let gitBranch = await new Promise((resolve8) => {
@@ -35223,7 +35765,9 @@ async function setupSessionRegistry(deps) {
35223
35765
  // src/session-event-wiring.ts
35224
35766
  import {
35225
35767
  createChronicleContext,
35768
+ createChronicleCounterSink,
35226
35769
  createChronicleEventJournal,
35770
+ resolveChronicleDetail,
35227
35771
  startChronicleFileObserver,
35228
35772
  startChronicleHealthMonitor,
35229
35773
  wireDecisionsToChronicle,
@@ -35247,6 +35791,10 @@ function resolveChronicleRetentionDays(config) {
35247
35791
  if (raw <= 0) return 0;
35248
35792
  return Math.max(MIN_CHRONICLE_RETENTION_DAYS, raw);
35249
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
+ }
35250
35798
  function tryCreateChronicleJournal(options) {
35251
35799
  try {
35252
35800
  return createChronicleEventJournal(options);
@@ -35288,11 +35836,18 @@ function wireSessionEvents(deps) {
35288
35836
  let chronicleFileObserver;
35289
35837
  let stopChronicleHealth;
35290
35838
  let stopNetworkTelemetry;
35839
+ let disposeCounterSink;
35291
35840
  if (deps.events && wpaths.projectDir) {
35292
35841
  const retentionDays = resolveChronicleRetentionDays(config);
35293
35842
  chronicleHandle = tryCreateChronicleJournal({
35294
35843
  projectRoot,
35295
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"),
35296
35851
  projectPaths: {
35297
35852
  globalRoot: wpaths.globalRoot,
35298
35853
  projectId: wpaths.projectHash ?? wpaths.projectSlug,
@@ -35302,7 +35857,12 @@ function wireSessionEvents(deps) {
35302
35857
  });
35303
35858
  }
35304
35859
  if (chronicleHandle && deps.events) {
35305
- chronicleJournal = chronicleHandle.journal;
35860
+ const counterSink = createChronicleCounterSink({
35861
+ inner: chronicleHandle.journal,
35862
+ level: resolveChronicleDetail(config)
35863
+ });
35864
+ chronicleJournal = counterSink;
35865
+ disposeCounterSink = () => counterSink.dispose();
35306
35866
  const location = chronicleHandle.identity;
35307
35867
  const chronicleContext = createChronicleContext(
35308
35868
  {
@@ -35628,6 +36188,7 @@ function wireSessionEvents(deps) {
35628
36188
  stopChronicleHealth?.();
35629
36189
  stopNetworkTelemetry?.();
35630
36190
  unsubscribeChronicle?.();
36191
+ await disposeCounterSink?.();
35631
36192
  if (chronicleFileObserver) {
35632
36193
  try {
35633
36194
  await (await chronicleFileObserver).close();
@@ -35914,12 +36475,17 @@ import * as path33 from "node:path";
35914
36475
  import {
35915
36476
  startFirstBootSageSync,
35916
36477
  subscribeVectorMemoryToSage,
36478
+ sweepStaleSageMirrors,
35917
36479
  TransformersEmbeddingProvider,
35918
36480
  VectorMemoryStore,
35919
36481
  wrapMemoryPortWithVectorRecall
35920
36482
  } from "@wrongstack/vector-memory";
36483
+ var DEFAULT_VECTOR_WEIGHT = 0.3;
35921
36484
  async function setupVectorMemory(args) {
35922
- 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
+ }
35923
36489
  let vectorMemoryStore;
35924
36490
  const vectorMemoryModelCacheDir = path33.join(
35925
36491
  projectRoot,
@@ -35950,7 +36516,10 @@ async function setupVectorMemory(args) {
35950
36516
  });
35951
36517
  wrapped = wrapMemoryPortWithVectorRecall(wrapped, {
35952
36518
  store: vectorMemoryStore,
35953
- 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 } : {}
35954
36523
  });
35955
36524
  const mirrorHandle = subscribeVectorMemoryToSage({
35956
36525
  store: vectorMemoryStore,
@@ -35958,6 +36527,11 @@ async function setupVectorMemory(args) {
35958
36527
  logger
35959
36528
  });
35960
36529
  teardownHandlers.push(() => mirrorHandle.dispose());
36530
+ void sweepStaleSageMirrors({
36531
+ store: vectorMemoryStore,
36532
+ memoryStore: wrapped,
36533
+ logger
36534
+ });
35961
36535
  if (flags["vector-sync"] === true) {
35962
36536
  const forced = await startFirstBootSageSync({
35963
36537
  store: vectorMemoryStore,
@@ -36026,7 +36600,8 @@ async function runInteractive(cliCtx) {
36026
36600
  flags,
36027
36601
  logger,
36028
36602
  memoryStore,
36029
- teardownHandlers
36603
+ teardownHandlers,
36604
+ tuning: config.Sage?.vector
36030
36605
  });
36031
36606
  memoryStore = vectorWrappedMemoryStore;
36032
36607
  const skillLoader = container.resolve(TOKENS13.SkillLoader);
@@ -36242,7 +36817,12 @@ async function runInteractive(cliCtx) {
36242
36817
  container.override(TOKENS13.ProviderModelStatusTracker, () => statusTracker);
36243
36818
  bootstrapWrongProxy(config.tools?.wrongProxy);
36244
36819
  await awaitFirstWrongProxyProbe();
36245
- const { buildProviderForId: buildProviderForId2, buildProviderForModel, switchProviderAndModel } = setupProviderRuntime({
36820
+ const {
36821
+ buildProviderForId: buildProviderForId2,
36822
+ buildProviderForModel,
36823
+ switchProviderAndModel,
36824
+ reloadProviderConfig
36825
+ } = setupProviderRuntime({
36246
36826
  config,
36247
36827
  onConfigUpdate: (newConfig) => {
36248
36828
  config = newConfig;
@@ -36315,7 +36895,15 @@ async function runInteractive(cliCtx) {
36315
36895
  events,
36316
36896
  autonomyModeRef
36317
36897
  });
36318
- 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({
36319
36907
  events,
36320
36908
  config,
36321
36909
  vault,
@@ -36334,7 +36922,7 @@ async function runInteractive(cliCtx) {
36334
36922
  cwd,
36335
36923
  wpaths,
36336
36924
  teardownHandlers,
36337
- mailboxSessionTag: mailboxSessionTag6,
36925
+ mailboxSessionTag: mailboxSessionTag7,
36338
36926
  brainMailbox,
36339
36927
  agentMonitor,
36340
36928
  manifestPath,
@@ -36365,7 +36953,7 @@ async function runInteractive(cliCtx) {
36365
36953
  agentMonitor,
36366
36954
  brainMailbox,
36367
36955
  teardownHandlers,
36368
- mailboxSessionTag: mailboxSessionTag6,
36956
+ mailboxSessionTag: mailboxSessionTag7,
36369
36957
  hqPublisherRef,
36370
36958
  mcpRegistry
36371
36959
  });
@@ -36403,6 +36991,9 @@ async function runInteractive(cliCtx) {
36403
36991
  statuslineLines,
36404
36992
  setStatuslineLines,
36405
36993
  saveStatuslineLines: saveStatuslineLines2,
36994
+ statuslineDensities,
36995
+ setStatuslineDensities,
36996
+ saveStatuslineDensities,
36406
36997
  agentsMonitorController,
36407
36998
  onPanelOpen,
36408
36999
  goalHost,
@@ -36471,6 +37062,7 @@ async function runInteractive(cliCtx) {
36471
37062
  brainSettings,
36472
37063
  brainRuntime,
36473
37064
  initialBrainLog: brainLog,
37065
+ brainTierStats,
36474
37066
  coordinatorController,
36475
37067
  statusTracker,
36476
37068
  shadowController,
@@ -36615,6 +37207,7 @@ async function runInteractive(cliCtx) {
36615
37207
  resolvedProvider,
36616
37208
  logger,
36617
37209
  switchProviderAndModel,
37210
+ reloadProviderConfig,
36618
37211
  applyMaxContext,
36619
37212
  renderer,
36620
37213
  reader,
@@ -36642,6 +37235,9 @@ async function runInteractive(cliCtx) {
36642
37235
  statuslineLines,
36643
37236
  setStatuslineLines,
36644
37237
  saveStatuslineLines: saveStatuslineLines2,
37238
+ statuslineDensities,
37239
+ setStatuslineDensities,
37240
+ saveStatuslineDensities,
36645
37241
  setYoloMode,
36646
37242
  autonomyMode,
36647
37243
  setAutonomyMode: (mode) => {
@@ -36683,4 +37279,4 @@ export {
36683
37279
  CLI_VERSION,
36684
37280
  runInteractive
36685
37281
  };
36686
- //# sourceMappingURL=cli-main-72XUFUCL.js.map
37282
+ //# sourceMappingURL=cli-main-TTIVR4DI.js.map