@wrongstack/tui 0.298.2 → 0.299.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.
package/dist/index.js CHANGED
@@ -3827,6 +3827,14 @@ function brainPanelRows(settings) {
3827
3827
  rows.push({ kind: "councilMinRisk" });
3828
3828
  for (let i = 0; i < voters.length; i += 1) rows.push({ kind: "voter", index: i });
3829
3829
  rows.push({ kind: "voterAdd" }, { kind: "judge" });
3830
+ rows.push(
3831
+ { kind: "councilQuorum" },
3832
+ { kind: "councilApproval" },
3833
+ { kind: "councilDistinctness" },
3834
+ { kind: "councilTimeout" },
3835
+ { kind: "councilConcurrency" },
3836
+ { kind: "councilJudgeMaxTokens" }
3837
+ );
3830
3838
  }
3831
3839
  rows.push({ kind: "ledgerToggle" });
3832
3840
  if (settings.ledgerEnabled) rows.push({ kind: "autoDeny" });
@@ -3876,6 +3884,39 @@ var CACHE_TTL_PRESETS = [
3876
3884
  36e5
3877
3885
  ];
3878
3886
  var CACHE_MAX_ENTRIES_PRESETS = [50, 100, 200, 500, 1e3];
3887
+ var COUNCIL_FRACTION_PRESETS = [0.25, 0.5, 0.6, 0.67, 0.75, 1];
3888
+ var COUNCIL_DISTINCTNESS_PRESETS = [
3889
+ "none",
3890
+ "model",
3891
+ "provider"
3892
+ ];
3893
+ var COUNCIL_TIMEOUT_PRESETS = [
3894
+ void 0,
3895
+ 1e4,
3896
+ 15e3,
3897
+ 3e4,
3898
+ 6e4
3899
+ ];
3900
+ var COUNCIL_CONCURRENCY_PRESETS = [
3901
+ void 0,
3902
+ 1,
3903
+ 2,
3904
+ 3,
3905
+ 4,
3906
+ 6,
3907
+ 8
3908
+ ];
3909
+ var COUNCIL_JUDGE_MAX_TOKENS_PRESETS = [
3910
+ void 0,
3911
+ 300,
3912
+ 500,
3913
+ 700,
3914
+ 1200
3915
+ ];
3916
+ function personaLabel(settings, id) {
3917
+ if (!id) return "voter";
3918
+ return settings.personaCatalog?.find((persona) => persona.id === id)?.name ?? id;
3919
+ }
3879
3920
  function cyclePreset(presets, current, delta) {
3880
3921
  const idx = presets.indexOf(current);
3881
3922
  const from = idx >= 0 ? idx : 0;
@@ -7257,6 +7298,50 @@ function useBrainPanel(opts) {
7257
7298
  runBrainMutation(() => host.setCouncilMinRisk(next));
7258
7299
  return;
7259
7300
  }
7301
+ case "councilQuorum":
7302
+ runBrainMutation(
7303
+ () => host.setCouncilQuorum(
7304
+ cyclePreset(COUNCIL_FRACTION_PRESETS, settings.councilQuorum ?? 0.5, delta)
7305
+ )
7306
+ );
7307
+ return;
7308
+ case "councilApproval":
7309
+ runBrainMutation(
7310
+ () => host.setCouncilApproval(
7311
+ cyclePreset(COUNCIL_FRACTION_PRESETS, settings.councilApproval ?? 0.5, delta)
7312
+ )
7313
+ );
7314
+ return;
7315
+ case "councilDistinctness": {
7316
+ const next = cycleEnum(
7317
+ COUNCIL_DISTINCTNESS_PRESETS,
7318
+ settings.councilDistinctness,
7319
+ delta
7320
+ );
7321
+ runBrainMutation(() => host.setCouncilDistinctness(next));
7322
+ return;
7323
+ }
7324
+ case "councilTimeout":
7325
+ runBrainMutation(
7326
+ () => host.setCouncilPerCallTimeout(
7327
+ cyclePreset(COUNCIL_TIMEOUT_PRESETS, settings.councilPerCallTimeoutMs, delta)
7328
+ )
7329
+ );
7330
+ return;
7331
+ case "councilConcurrency":
7332
+ runBrainMutation(
7333
+ () => host.setCouncilMaxConcurrency(
7334
+ cyclePreset(COUNCIL_CONCURRENCY_PRESETS, settings.councilMaxConcurrency, delta)
7335
+ )
7336
+ );
7337
+ return;
7338
+ case "councilJudgeMaxTokens":
7339
+ runBrainMutation(
7340
+ () => host.setCouncilJudgeMaxTokens(
7341
+ cyclePreset(COUNCIL_JUDGE_MAX_TOKENS_PRESETS, settings.councilJudgeMaxTokens, delta)
7342
+ )
7343
+ );
7344
+ return;
7260
7345
  case "ledgerToggle":
7261
7346
  runBrainMutation(() => host.setLedgerEnabled(!settings.ledgerEnabled));
7262
7347
  return;
@@ -14626,7 +14711,8 @@ function reduceSettingsValues(state, action) {
14626
14711
  }
14627
14712
 
14628
14713
  // src/reducers/workspace-panels.ts
14629
- function computeMaxSidebarScroll(state, viewportHeight = 20) {
14714
+ var SIDEBAR_MISSION_MAX_WRAP_LINES = 10;
14715
+ function computeMaxSidebarScroll(state, viewportHeight = 20, effectiveSwarmOnSidebar) {
14630
14716
  let contentHeight = 0;
14631
14717
  contentHeight += 4;
14632
14718
  contentHeight += 3;
@@ -14644,9 +14730,9 @@ function computeMaxSidebarScroll(state, viewportHeight = 20) {
14644
14730
  if (runningSubagents.length > agentCap) contentHeight += 1;
14645
14731
  contentHeight += 1;
14646
14732
  }
14647
- const swarmMode = state.settingsPicker.showAgentSwarmPanel;
14648
- if (swarmMode === "sidebar") {
14649
- contentHeight += 1 + SIDEBAR_MISSION_ROWS + 1 + 1;
14733
+ const swarmOnSidebar = effectiveSwarmOnSidebar ?? state.settingsPicker.showAgentSwarmPanel === "sidebar";
14734
+ if (swarmOnSidebar) {
14735
+ contentHeight += 1 + SIDEBAR_MISSION_ROWS * SIDEBAR_MISSION_MAX_WRAP_LINES + 1 + 1;
14650
14736
  }
14651
14737
  const liveSessionCount = state.sessionsPanel.sessions.length;
14652
14738
  const resumeSessionCount = state.resumePicker.sessions.length;
@@ -14742,9 +14828,11 @@ function reduceWorkspacePanels(state, action) {
14742
14828
  case "toggleSidebarFocus":
14743
14829
  return state.sidebarFocused ? { ...state, sidebarFocused: false, sidebarScrollOffset: 0 } : { ...state, sidebarFocused: true };
14744
14830
  case "sidebarScroll": {
14831
+ const adjustedViewportHeight = (action.viewportHeight ?? 20) - (action.sidebarTwinRowCount ?? 0);
14745
14832
  const maxScroll = computeMaxSidebarScroll(
14746
14833
  state,
14747
- action.viewportHeight
14834
+ Math.max(1, adjustedViewportHeight),
14835
+ action.effectiveSwarmOnSidebar
14748
14836
  );
14749
14837
  return {
14750
14838
  ...state,
@@ -19161,7 +19249,7 @@ import { useEffect as useEffect41 } from "react";
19161
19249
  var MONITOR_INTERVENTION_GRACE_MS = 5e3;
19162
19250
  function useBrainEvents(events, dispatch, getSessionId) {
19163
19251
  useEffect41(() => {
19164
- const isCurrentSession = (sessionId) => {
19252
+ const isCurrentSession2 = (sessionId) => {
19165
19253
  const current = getSessionId?.();
19166
19254
  return !sessionId || !current || sessionId === current;
19167
19255
  };
@@ -19176,8 +19264,21 @@ function useBrainEvents(events, dispatch, getSessionId) {
19176
19264
  return decision.reason;
19177
19265
  }
19178
19266
  };
19267
+ const councilTraces = /* @__PURE__ */ new Map();
19268
+ const councilVotes = /* @__PURE__ */ new Map();
19269
+ const COUNCIL_TRACE_MAX = 100;
19270
+ const capCouncilMap = (map) => {
19271
+ while (map.size > COUNCIL_TRACE_MAX) {
19272
+ const oldest = map.keys().next().value;
19273
+ if (oldest === void 0) break;
19274
+ map.delete(oldest);
19275
+ }
19276
+ };
19179
19277
  const addBrainEntry = (status, payload) => {
19180
19278
  const p = payload;
19279
+ const council = councilTraces.get(p.request.id);
19280
+ councilTraces.delete(p.request.id);
19281
+ councilVotes.delete(p.request.id);
19181
19282
  const decision = decisionSummary(p.decision);
19182
19283
  dispatch({ type: "brainStatus", state: status, source: p.request.source, risk: p.request.risk, summary: decision });
19183
19284
  if (status === "ask_human") {
@@ -19194,7 +19295,7 @@ function useBrainEvents(events, dispatch, getSessionId) {
19194
19295
  dispatch({ type: "brainPromptClear" });
19195
19296
  }
19196
19297
  const rationale = p.decision.type === "deny" ? void 0 : p.decision.rationale;
19197
- dispatch({ type: "addEntry", entry: { kind: "brain", status, source: p.request.source, risk: p.request.risk, question: p.request.question, decision, rationale } });
19298
+ dispatch({ type: "addEntry", entry: { kind: "brain", status, source: p.request.source, risk: p.request.risk, question: p.request.question, decision, rationale, ...council ? { council } : {} } });
19198
19299
  };
19199
19300
  const pendingMonitorAnswers = /* @__PURE__ */ new Map();
19200
19301
  const SHOWN_MONITOR_ANSWERS_MAX = 500;
@@ -19207,11 +19308,11 @@ function useBrainEvents(events, dispatch, getSessionId) {
19207
19308
  }
19208
19309
  };
19209
19310
  const offRequested = events.on("brain.decision_requested", ({ sessionId, request }) => {
19210
- if (!isCurrentSession(sessionId)) return;
19311
+ if (!isCurrentSession2(sessionId)) return;
19211
19312
  dispatch({ type: "brainStatus", state: "deciding", source: request.source, risk: request.risk, summary: requestSummary(request) });
19212
19313
  });
19213
19314
  const offAnswered = events.on("brain.decision_answered", (payload) => {
19214
- if (!isCurrentSession(payload.sessionId)) return;
19315
+ if (!isCurrentSession2(payload.sessionId)) return;
19215
19316
  if (!payload.request.id.startsWith("brainmon-")) {
19216
19317
  addBrainEntry("answered", payload);
19217
19318
  return;
@@ -19220,7 +19321,7 @@ function useBrainEvents(events, dispatch, getSessionId) {
19220
19321
  if (previous) clearTimeout(previous);
19221
19322
  const timer = setTimeout(() => {
19222
19323
  pendingMonitorAnswers.delete(payload.request.id);
19223
- if (isCurrentSession(payload.sessionId)) {
19324
+ if (isCurrentSession2(payload.sessionId)) {
19224
19325
  rememberShownAnswer(payload.request.id);
19225
19326
  addBrainEntry("answered", payload);
19226
19327
  }
@@ -19229,13 +19330,52 @@ function useBrainEvents(events, dispatch, getSessionId) {
19229
19330
  pendingMonitorAnswers.set(payload.request.id, timer);
19230
19331
  });
19231
19332
  const offAskHuman = events.on("brain.decision_ask_human", (payload) => {
19232
- if (isCurrentSession(payload.sessionId)) addBrainEntry("ask_human", payload);
19333
+ if (isCurrentSession2(payload.sessionId)) addBrainEntry("ask_human", payload);
19233
19334
  });
19234
19335
  const offDenied = events.on("brain.decision_denied", (payload) => {
19235
- if (isCurrentSession(payload.sessionId)) addBrainEntry("denied", payload);
19336
+ if (isCurrentSession2(payload.sessionId)) addBrainEntry("denied", payload);
19337
+ });
19338
+ const offCouncilVote = events.on("brain.council_vote", (payload) => {
19339
+ if (!isCurrentSession2(payload.sessionId)) return;
19340
+ const seats = councilVotes.get(payload.requestId) ?? [];
19341
+ seats.push({
19342
+ seatId: payload.seatId,
19343
+ persona: payload.persona,
19344
+ status: payload.status,
19345
+ optionId: payload.optionId,
19346
+ model: payload.model,
19347
+ veto: payload.veto,
19348
+ durationMs: payload.durationMs,
19349
+ error: payload.error
19350
+ });
19351
+ councilVotes.set(payload.requestId, seats);
19352
+ capCouncilMap(councilVotes);
19353
+ dispatch({
19354
+ type: "brainStatus",
19355
+ state: "deciding",
19356
+ source: "council",
19357
+ risk: "high",
19358
+ summary: `council \xB7 ${seats.length} seat${seats.length === 1 ? "" : "s"} voted`
19359
+ });
19360
+ });
19361
+ const offCouncilResolved = events.on("brain.council_resolved", (payload) => {
19362
+ if (!isCurrentSession2(payload.sessionId)) return;
19363
+ councilTraces.set(payload.requestId, {
19364
+ resolution: payload.resolution,
19365
+ configuredSeatCount: payload.configuredSeatCount,
19366
+ validVoteCount: payload.validVoteCount,
19367
+ distinctTargetCount: payload.distinctTargetCount,
19368
+ judgeUsed: payload.judgeUsed,
19369
+ totalTokens: payload.usage?.totalTokens,
19370
+ durationMs: payload.usage?.durationMs,
19371
+ ...payload.warnings?.length ? { warnings: [...payload.warnings] } : {},
19372
+ seats: councilVotes.get(payload.requestId) ?? []
19373
+ });
19374
+ capCouncilMap(councilTraces);
19375
+ councilVotes.delete(payload.requestId);
19236
19376
  });
19237
19377
  const offIntervention = events.on("brain.intervention", (payload) => {
19238
- if (!isCurrentSession(payload.sessionId)) return;
19378
+ if (!isCurrentSession2(payload.sessionId)) return;
19239
19379
  if (shownMonitorAnswers.has(payload.request.id)) return;
19240
19380
  const pending = pendingMonitorAnswers.get(payload.request.id);
19241
19381
  if (pending) {
@@ -19265,9 +19405,13 @@ function useBrainEvents(events, dispatch, getSessionId) {
19265
19405
  offAnswered();
19266
19406
  offAskHuman();
19267
19407
  offDenied();
19408
+ offCouncilVote();
19409
+ offCouncilResolved();
19268
19410
  offIntervention();
19269
19411
  for (const timer of pendingMonitorAnswers.values()) clearTimeout(timer);
19270
19412
  pendingMonitorAnswers.clear();
19413
+ councilTraces.clear();
19414
+ councilVotes.clear();
19271
19415
  };
19272
19416
  }, [events, dispatch, getSessionId]);
19273
19417
  }
@@ -19324,13 +19468,13 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19324
19468
  );
19325
19469
  useEffect42(() => {
19326
19470
  const seen = /* @__PURE__ */ new Set();
19327
- const isCurrentSession = (sessionId) => {
19471
+ const isCurrentSession2 = (sessionId) => {
19328
19472
  const current = getSessionId?.();
19329
19473
  return !sessionId || !current || sessionId === current;
19330
19474
  };
19331
19475
  const mode = () => getChatMode?.() ?? "full";
19332
19476
  const offSpawned = events.on("subagent.spawned", (e) => {
19333
- if (!isCurrentSession(e.sessionId)) return;
19477
+ if (!isCurrentSession2(e.sessionId)) return;
19334
19478
  if (sessionGenerationRef) gate.track(e.subagentId);
19335
19479
  seen.add(e.subagentId);
19336
19480
  const l = lbl(e.subagentId, e.name);
@@ -19358,7 +19502,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19358
19502
  }
19359
19503
  });
19360
19504
  const offStarted = events.on("subagent.task_started", (e) => {
19361
- if (!isCurrentSession(e.sessionId)) return;
19505
+ if (!isCurrentSession2(e.sessionId)) return;
19362
19506
  if (!gate.isLive(e.subagentId)) return;
19363
19507
  seen.add(e.subagentId);
19364
19508
  const l = lbl(e.subagentId);
@@ -19378,7 +19522,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19378
19522
  }
19379
19523
  });
19380
19524
  const offCompleted = events.on("subagent.task_completed", (e) => {
19381
- if (!isCurrentSession(e.sessionId)) return;
19525
+ if (!isCurrentSession2(e.sessionId)) return;
19382
19526
  if (!gate.isLive(e.subagentId)) return;
19383
19527
  seen.add(e.subagentId);
19384
19528
  const l = lbl(e.subagentId);
@@ -19412,7 +19556,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19412
19556
  }
19413
19557
  });
19414
19558
  const offRemoved = events.on("subagent.removed", (e) => {
19415
- if (!isCurrentSession(e.sessionId)) return;
19559
+ if (!isCurrentSession2(e.sessionId)) return;
19416
19560
  seen.delete(e.subagentId);
19417
19561
  labelsRef.current.delete(e.subagentId);
19418
19562
  ctxDispatchRef.current.delete(e.subagentId);
@@ -19425,7 +19569,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19425
19569
  dispatch({ type: "fleetRemove", id: e.subagentId });
19426
19570
  });
19427
19571
  const offBudgetWarning = events.on("subagent.budget_warning", (e) => {
19428
- if (!isCurrentSession(e.sessionId)) return;
19572
+ if (!isCurrentSession2(e.sessionId)) return;
19429
19573
  if (!gate.isLive(e.subagentId)) return;
19430
19574
  seen.add(e.subagentId);
19431
19575
  const l = lbl(e.subagentId);
@@ -19453,7 +19597,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19453
19597
  }
19454
19598
  });
19455
19599
  const offBudgetExtended = events.on("subagent.budget_extended", (e) => {
19456
- if (!isCurrentSession(e.sessionId)) return;
19600
+ if (!isCurrentSession2(e.sessionId)) return;
19457
19601
  if (!gate.isLive(e.subagentId)) return;
19458
19602
  seen.add(e.subagentId);
19459
19603
  const l = lbl(e.subagentId);
@@ -19477,7 +19621,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19477
19621
  }
19478
19622
  });
19479
19623
  const offIterationSummary = events.on("subagent.iteration_summary", (e) => {
19480
- if (!isCurrentSession(e.sessionId)) return;
19624
+ if (!isCurrentSession2(e.sessionId)) return;
19481
19625
  if (!gate.isLive(e.subagentId)) return;
19482
19626
  seen.add(e.subagentId);
19483
19627
  if (mode() !== "full") return;
@@ -19497,7 +19641,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19497
19641
  });
19498
19642
  });
19499
19643
  const offCtxPct = events.on("subagent.ctx_pct", (e) => {
19500
- if (!isCurrentSession(e.sessionId)) return;
19644
+ if (!isCurrentSession2(e.sessionId)) return;
19501
19645
  if (!gate.isLive(e.subagentId)) return;
19502
19646
  seen.add(e.subagentId);
19503
19647
  const emit = () => {
@@ -19538,13 +19682,13 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19538
19682
  });
19539
19683
  const offConcurrencyChanged = events.on("concurrency.changed", (e) => {
19540
19684
  const { n, sessionId } = e;
19541
- if (!isCurrentSession(sessionId)) return;
19685
+ if (!isCurrentSession2(sessionId)) return;
19542
19686
  if (typeof n === "number" && n > 0) {
19543
19687
  dispatch({ type: "fleetConcurrency", n });
19544
19688
  }
19545
19689
  });
19546
19690
  const offLeaderCtxPct = events.on("ctx.pct", (e) => {
19547
- if (!isCurrentSession(e.sessionId)) return;
19691
+ if (!isCurrentSession2(e.sessionId)) return;
19548
19692
  latestLeaderCtxPctRef.current = e;
19549
19693
  const emit = () => {
19550
19694
  const latest = latestLeaderCtxPctRef.current ?? e;
@@ -19581,7 +19725,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19581
19725
  emit();
19582
19726
  });
19583
19727
  const offLeaderMaxContext = events.on("ctx.max_context", (e) => {
19584
- if (!isCurrentSession(e.sessionId)) return;
19728
+ if (!isCurrentSession2(e.sessionId)) return;
19585
19729
  if (e.maxContext > 0) setActiveMaxContext(e.maxContext);
19586
19730
  });
19587
19731
  const offCompactionFired = events.on("compaction.fired", (e) => {
@@ -19589,7 +19733,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
19589
19733
  if (entry) dispatch({ type: "addEntry", entry });
19590
19734
  });
19591
19735
  const offTool = events.on("subagent.tool_executed", (e) => {
19592
- if (!isCurrentSession(e.sessionId)) return;
19736
+ if (!isCurrentSession2(e.sessionId)) return;
19593
19737
  if (!gate.isLive(e.subagentId)) return;
19594
19738
  dispatch({
19595
19739
  type: "fleetTool",
@@ -19648,12 +19792,12 @@ function useTuiEventBridge({
19648
19792
  }
19649
19793
  function useSessionEvents(events, dispatch, onClearHistory, getSessionId) {
19650
19794
  useEffect43(() => {
19651
- const isCurrentSession = (sessionId) => {
19795
+ const isCurrentSession2 = (sessionId) => {
19652
19796
  const current = getSessionId?.();
19653
19797
  return !sessionId || !current || sessionId === current;
19654
19798
  };
19655
19799
  const offCheckpoint = events.on("checkpoint.written", (e) => {
19656
- if (!isCurrentSession(e.sessionId)) return;
19800
+ if (!isCurrentSession2(e.sessionId)) return;
19657
19801
  dispatch({
19658
19802
  type: "checkpointReceived",
19659
19803
  cp: {
@@ -19665,7 +19809,7 @@ function useSessionEvents(events, dispatch, onClearHistory, getSessionId) {
19665
19809
  });
19666
19810
  });
19667
19811
  const offRewound = events.on("session.rewound", (e) => {
19668
- if (!isCurrentSession(e.sessionId)) return;
19812
+ if (!isCurrentSession2(e.sessionId)) return;
19669
19813
  dispatch({ type: "sessionRewound", toPromptIndex: e.toPromptIndex });
19670
19814
  dispatch({ type: "clearHistory" });
19671
19815
  dispatch({ type: "resetContextChip" });
@@ -19680,13 +19824,13 @@ function useSessionEvents(events, dispatch, onClearHistory, getSessionId) {
19680
19824
  function useGoalEvents(subscribeGoal, dispatch, stateRef, getSessionId) {
19681
19825
  useEffect43(() => {
19682
19826
  if (!subscribeGoal) return;
19683
- const isCurrentSession = (sessionId) => {
19827
+ const isCurrentSession2 = (sessionId) => {
19684
19828
  const current = getSessionId?.();
19685
19829
  return !sessionId || !current || sessionId === current;
19686
19830
  };
19687
19831
  const handler = (event, payload) => {
19688
19832
  const sessionId = payload && typeof payload === "object" && "sessionId" in payload ? payload.sessionId : void 0;
19689
- if (!isCurrentSession(sessionId)) return;
19833
+ if (!isCurrentSession2(sessionId)) return;
19690
19834
  switch (event) {
19691
19835
  case "phase.started": {
19692
19836
  const p = payload;
@@ -21216,19 +21360,31 @@ function mergeStatuslineHiddenItems(hookHidden, reducerHidden) {
21216
21360
  function isPickerOverlayOpen(state) {
21217
21361
  return state.modelPicker.open || state.autonomyPicker.open || state.modePicker.open || state.designPicker.open || state.resumePicker.open || state.promptPicker.open || state.settingsPicker.open || state.slashPicker.open || state.statuslinePicker.open || state.pluginPicker.open || state.mcpPicker.open || state.toolsPicker.open || state.brainPanel.open || state.helpPanel.open || state.shadowPanel.open || state.fKeyPicker.open || state.authPanel.open || state.picker.open;
21218
21362
  }
21219
- function resolveSidebarLayout(state, termCols, panelPositionsInput, mailboxPanelOpen) {
21363
+ function resolveSidebarLayout(state, termCols, panelPositionsInput, mailboxPanelOpen, sidebarOpenFlags, legacySwarmOnSidebar) {
21220
21364
  const panelPositions = coercePanelPositionMap(panelPositionsInput);
21221
21365
  const routedToSidebar = (id) => panelPositions[id] === "sidebar";
21222
21366
  const overlayOpen = isPickerOverlayOpen(state) || state.coordinator.monitorOpen && !routedToSidebar("coordinator") || state.auditPanelOpen || state.connectionsPanelOpen && !routedToSidebar("connections") || state.helpOpen || state.agentsMonitorOpen && !routedToSidebar("agents") || state.monitorOpen && !routedToSidebar("fleet") || state.contextPanelOpen || state.processListOpen && !routedToSidebar("processList") || state.todosMonitorOpen && !routedToSidebar("todos") || state.worktreeMonitorOpen && !routedToSidebar("worktree") || state.planPanelOpen && !routedToSidebar("plan") || state.kanbanPanelOpen && !routedToSidebar("kanban") || state.queuePanelOpen && !routedToSidebar("queue") || state.goalPanelOpen && !routedToSidebar("goal") || state.sessionsPanelOpen && !routedToSidebar("sessions") || state.projectPicker.open && !routedToSidebar("projectPicker") || state.goalKanbanPanelOpen || state.cronMonitorOpen || state.rewindOverlay != null || state.shellCommandWarning != null || state.confirmQueue.length > 0 || state.clearConfirm != null || state.exitConfirm != null || state.slashConfirm != null || state.escConfirm != null || state.sendModePicker != null || state.enhance != null || state.enhanceBusy || state.refineCountdown != null || state.refineFailure != null || state.continueConfirm != null || state.brainPrompt != null || mailboxPanelOpen || (state.goalRun?.monitorOpen ?? false) && !routedToSidebar("coordinator") || (state.sddBoard?.monitorOpen ?? false);
21223
21367
  const sidebarWidth = overlayOpen ? 0 : computeSidebarWidth(termCols);
21368
+ const effectiveSwarmOnSidebar = panelPositions.fleet === "sidebar" || (legacySwarmOnSidebar ?? false);
21369
+ let sidebarTwinRowCount = 0;
21370
+ if (sidebarOpenFlags) {
21371
+ for (const id of PANEL_IDS) {
21372
+ if (routedToSidebar(id) && sidebarOpenFlags[id]) {
21373
+ sidebarTwinRowCount += ESTIMATED_TWIN_HEIGHT;
21374
+ }
21375
+ }
21376
+ }
21224
21377
  return {
21225
21378
  panelPositions,
21226
21379
  overlayOpen,
21227
21380
  sidebarWidth,
21228
21381
  sidebarContentWidth: computeSidebarContentWidth(sidebarWidth),
21229
- mainColumnWidth: termCols - sidebarWidth
21382
+ mainColumnWidth: termCols - sidebarWidth,
21383
+ effectiveSwarmOnSidebar,
21384
+ sidebarTwinRowCount
21230
21385
  };
21231
21386
  }
21387
+ var ESTIMATED_TWIN_HEIGHT = 8;
21232
21388
 
21233
21389
  // src/app-view.tsx
21234
21390
  import { expectDefined as expectDefined5 } from "@wrongstack/core/utils";
@@ -26595,10 +26751,11 @@ function rowText(row, s2) {
26595
26751
  return { label: " risk floor", value: s2.councilMinRisk, dim: "council convenes at/above this risk" };
26596
26752
  case "voter": {
26597
26753
  const v = s2.voters[row.index];
26754
+ const lens = personaLabel(s2, v?.persona);
26598
26755
  return {
26599
26756
  label: ` ${row.index + 1}.`,
26600
26757
  value: v?.label ?? "",
26601
- dim: `${v?.persona ?? "voter"}${v?.veto ? " \xB7 VETO" : ""}${v?.weight ? ` \xB7 w=${v.weight}` : ""} (p persona \xB7 v veto \xB7 d remove)`
26758
+ dim: `${lens}${v?.veto ? " \xB7 VETO" : ""}${v?.weight ? ` \xB7 w=${v.weight}` : ""} (p persona \xB7 v veto \xB7 d remove)`
26602
26759
  };
26603
26760
  }
26604
26761
  case "voterAdd":
@@ -26611,6 +26768,42 @@ function rowText(row, s2) {
26611
26768
  dim: "Enter = pick \xB7 d = auto"
26612
26769
  };
26613
26770
  }
26771
+ case "councilQuorum":
26772
+ return {
26773
+ label: " quorum",
26774
+ value: String(s2.councilQuorum ?? 0.5),
26775
+ dim: "fraction of seats that must return a valid vote"
26776
+ };
26777
+ case "councilApproval":
26778
+ return {
26779
+ label: " approval",
26780
+ value: String(s2.councilApproval ?? 0.5),
26781
+ dim: "winning weight must exceed this fraction, else the judge decides"
26782
+ };
26783
+ case "councilDistinctness":
26784
+ return {
26785
+ label: " distinctness",
26786
+ value: s2.councilDistinctness,
26787
+ dim: s2.councilDistinctness === "none" ? "off \u2014 a same-model panel agrees with itself and is never reported" : `warn when seats do not use distinct ${s2.councilDistinctness}s`
26788
+ };
26789
+ case "councilTimeout":
26790
+ return {
26791
+ label: " seat timeout",
26792
+ value: s2.councilPerCallTimeoutMs === void 0 ? "default" : `${s2.councilPerCallTimeoutMs}ms`,
26793
+ dim: "per-seat completion budget (default = the decision timeout)"
26794
+ };
26795
+ case "councilConcurrency":
26796
+ return {
26797
+ label: " concurrency",
26798
+ value: s2.councilMaxConcurrency === void 0 ? "default (3)" : String(s2.councilMaxConcurrency),
26799
+ dim: "seats polled at once, 1..8 \u2014 higher is faster and burstier"
26800
+ };
26801
+ case "councilJudgeMaxTokens":
26802
+ return {
26803
+ label: " judge tokens",
26804
+ value: s2.councilJudgeMaxTokens === void 0 ? "default" : String(s2.councilJudgeMaxTokens),
26805
+ dim: "output budget for the tie-breaker call"
26806
+ };
26614
26807
  case "ledgerToggle":
26615
26808
  return {
26616
26809
  label: "Ledger",
@@ -32853,7 +33046,8 @@ function parseInline(text) {
32853
33046
  let urlEnd = i + 8;
32854
33047
  while (urlEnd < text.length) {
32855
33048
  const c = text[urlEnd];
32856
- if (c !== void 0 && c.match(/[a-zA-Z0-9._~:/?#@!$&+,;=%\-\[\]()'*]/)) {
33049
+ const urlChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._~:/?#@!" + String.fromCharCode(36) + String.fromCharCode(38) + "+,;=-%[]()'*";
33050
+ if (c !== void 0 && urlChars.includes(c)) {
32857
33051
  urlEnd++;
32858
33052
  } else {
32859
33053
  break;
@@ -33475,6 +33669,22 @@ function brainStatusStyle(status) {
33475
33669
  return { icon: "\xD7", color: "red" };
33476
33670
  }
33477
33671
  }
33672
+ function councilHeadline(council) {
33673
+ const parts = [
33674
+ `\u21B3 Council: ${council.resolution}`,
33675
+ `${council.validVoteCount}/${council.configuredSeatCount} seats`,
33676
+ `${council.distinctTargetCount} distinct target${council.distinctTargetCount === 1 ? "" : "s"}`
33677
+ ];
33678
+ if (council.judgeUsed) parts.push("judge used");
33679
+ if (council.durationMs !== void 0) parts.push(`${Math.round(council.durationMs / 100) / 10}s`);
33680
+ if (council.totalTokens) parts.push(`${council.totalTokens} tok`);
33681
+ return parts.join(" \xB7 ");
33682
+ }
33683
+ function councilSeatLine(seat) {
33684
+ const verdict = seat.status === "valid" ? seat.optionId ?? "stance" : seat.error ?? seat.status;
33685
+ const suffix = [seat.model, seat.veto ? "veto" : void 0].filter(Boolean).join(", ");
33686
+ return ` ${seat.status === "valid" ? "\u2022" : "\xD7"} ${seat.persona} \u2192 ${verdict}${suffix ? ` (${suffix})` : ""}`;
33687
+ }
33478
33688
  function memoryLifecycleStyle(action) {
33479
33689
  if (action === "entered" || action === "recovered") return { icon: "\u21B3", color: "green" };
33480
33690
  if (action === "exited") return { icon: "\u21B2", color: "red" };
@@ -34039,7 +34249,12 @@ var Entry = React8.memo(function Entry2({
34039
34249
  entry.outcome ? /* @__PURE__ */ jsx71(Box, { paddingLeft: indentWidth, marginTop: 1, children: /* @__PURE__ */ jsxs68(Text, { children: [
34040
34250
  /* @__PURE__ */ jsx71(Text, { bold: true, color: statusStyle.color, children: "\u2713 Outcome: " }),
34041
34251
  /* @__PURE__ */ jsx71(Text, { color: theme.textPrimary, children: entry.outcome })
34042
- ] }) }) : null
34252
+ ] }) }) : null,
34253
+ entry.council ? /* @__PURE__ */ jsxs68(Box, { flexDirection: "column", paddingLeft: indentWidth, marginTop: 1, children: [
34254
+ /* @__PURE__ */ jsx71(Text, { dimColor: true, children: councilHeadline(entry.council) }),
34255
+ entry.council.seats.map((seat) => /* @__PURE__ */ jsx71(Text, { dimColor: true, children: councilSeatLine(seat) }, seat.seatId)),
34256
+ (entry.council.warnings ?? []).map((warning) => /* @__PURE__ */ jsx71(Text, { color: theme.warn, children: ` \u26A0 ${warning}` }, warning))
34257
+ ] }) : null
34043
34258
  ]
34044
34259
  }
34045
34260
  );
@@ -34943,8 +35158,10 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
34943
35158
  Box,
34944
35159
  {
34945
35160
  flexDirection: "column",
34946
- flexGrow: 1,
35161
+ width: termWidth,
35162
+ flexShrink: 0,
34947
35163
  height: vp,
35164
+ overflowX: "hidden",
34948
35165
  overflowY: "hidden",
34949
35166
  justifyContent: scrolled ? "flex-start" : "flex-end",
34950
35167
  children: /* @__PURE__ */ jsxs71(Box, { flexDirection: "column", flexShrink: 0, marginTop: scrolled && clip2 > 0 ? -clip2 : 0, children: [
@@ -35021,6 +35238,13 @@ function trunc2(s2, max) {
35021
35238
  if (s2.length <= max) return s2;
35022
35239
  return `${s2.slice(0, Math.max(1, max - 1))}\u2026`;
35023
35240
  }
35241
+ function isCurrentSession(rowId, currentSessionId, fallbackIsCurrent) {
35242
+ if (rowId === void 0) return false;
35243
+ if (currentSessionId !== void 0) {
35244
+ return rowId === currentSessionId;
35245
+ }
35246
+ return fallbackIsCurrent === true;
35247
+ }
35024
35248
  function statusGlyph(entry) {
35025
35249
  switch (entry.status) {
35026
35250
  case "running":
@@ -35055,8 +35279,7 @@ function liveSessionColor(status) {
35055
35279
  if (status === "active" || status === "running") return theme.success;
35056
35280
  if (status === "idle") return theme.accent;
35057
35281
  if (status === "error" || status === "stale") return theme.error;
35058
- if (status === "closing") return theme.warn;
35059
- return theme.textMuted;
35282
+ return theme.warn;
35060
35283
  }
35061
35284
  function outcomeBadge(outcome) {
35062
35285
  switch (outcome) {
@@ -35120,7 +35343,7 @@ function Card({
35120
35343
  }
35121
35344
  );
35122
35345
  }
35123
- function buildMissionRows(todos, maxRows, textWidth) {
35346
+ function buildMissionRows(todos, maxRows) {
35124
35347
  const list = todos ?? [];
35125
35348
  const total = list.length;
35126
35349
  const done = list.filter((t) => t.status === "completed").length;
@@ -35131,10 +35354,7 @@ function buildMissionRows(todos, maxRows, textWidth) {
35131
35354
  const rows = shown.map((t) => ({
35132
35355
  id: t.id,
35133
35356
  status: t.status,
35134
- label: trunc2(
35135
- t.status === "in_progress" && t.activeForm ? t.activeForm : t.content,
35136
- textWidth
35137
- )
35357
+ label: t.status === "in_progress" && t.activeForm ? t.activeForm : t.content
35138
35358
  }));
35139
35359
  return { rows, overflow: ordered.length - shown.length, done, total };
35140
35360
  }
@@ -35172,7 +35392,7 @@ function SidebarContent({
35172
35392
  ];
35173
35393
  const hiddenAgentCount = runningSubagents.length - agentCap;
35174
35394
  const running = fleetCounts?.running ?? runningSubagents.length;
35175
- const mission = showSwarmSection ? buildMissionRows(todos, SIDEBAR_MISSION_ROWS, innerWidth - 3) : { rows: [], overflow: 0, done: 0, total: 0 };
35395
+ const mission = showSwarmSection ? buildMissionRows(todos, SIDEBAR_MISSION_ROWS) : { rows: [], overflow: 0, done: 0, total: 0 };
35176
35396
  return /* @__PURE__ */ jsxs72(
35177
35397
  Box,
35178
35398
  {
@@ -35308,29 +35528,29 @@ function SidebarContent({
35308
35528
  ),
35309
35529
  mission.rows.map((m) => {
35310
35530
  if (m.status === "completed") {
35311
- return /* @__PURE__ */ jsxs72(Box, { children: [
35531
+ return /* @__PURE__ */ jsxs72(Box, { width: innerWidth, flexDirection: "row", children: [
35312
35532
  /* @__PURE__ */ jsxs72(Text, { color: theme.success, children: [
35313
35533
  glyphs.success,
35314
35534
  " "
35315
35535
  ] }),
35316
- /* @__PURE__ */ jsx75(Text, { color: theme.textMuted, dimColor: true, strikethrough: true, wrap: "truncate", children: m.label })
35536
+ /* @__PURE__ */ jsx75(Text, { color: theme.textMuted, dimColor: true, strikethrough: true, children: m.label })
35317
35537
  ] }, m.id);
35318
35538
  }
35319
35539
  if (m.status === "in_progress") {
35320
- return /* @__PURE__ */ jsxs72(Box, { children: [
35540
+ return /* @__PURE__ */ jsxs72(Box, { width: innerWidth, flexDirection: "row", children: [
35321
35541
  /* @__PURE__ */ jsxs72(Text, { color: theme.accent, children: [
35322
35542
  glyphs.running,
35323
35543
  " "
35324
35544
  ] }),
35325
- /* @__PURE__ */ jsx75(Text, { color: theme.textPrimary, bold: true, wrap: "truncate", children: m.label })
35545
+ /* @__PURE__ */ jsx75(Text, { color: theme.textPrimary, bold: true, children: m.label })
35326
35546
  ] }, m.id);
35327
35547
  }
35328
- return /* @__PURE__ */ jsxs72(Box, { children: [
35548
+ return /* @__PURE__ */ jsxs72(Box, { width: innerWidth, flexDirection: "row", children: [
35329
35549
  /* @__PURE__ */ jsxs72(Text, { color: theme.textMuted, children: [
35330
35550
  glyphs.pending,
35331
35551
  " "
35332
35552
  ] }),
35333
- /* @__PURE__ */ jsx75(Text, { color: theme.textSecondary, wrap: "truncate", children: m.label })
35553
+ /* @__PURE__ */ jsx75(Text, { color: theme.textSecondary, children: m.label })
35334
35554
  ] }, m.id);
35335
35555
  }),
35336
35556
  mission.overflow > 0 ? /* @__PURE__ */ jsxs72(Text, { color: theme.textMuted, dimColor: true, children: [
@@ -35353,7 +35573,10 @@ function SidebarContent({
35353
35573
  }
35354
35574
  ),
35355
35575
  liveSessions && liveSessions.length > 0 ? /* @__PURE__ */ jsx75(Box, { flexDirection: "column", children: liveSessions.slice(0, 3).map((s2) => {
35356
- const isCurrent = s2.sessionId === currentSessionId;
35576
+ const isCurrent = isCurrentSession(
35577
+ s2.sessionId,
35578
+ currentSessionId
35579
+ );
35357
35580
  const icon = isCurrent ? "\u25CF" : liveSessionIcon(s2.status);
35358
35581
  const color = liveSessionColor(s2.status);
35359
35582
  const name = trunc2(s2.projectName, innerWidth - 6);
@@ -35381,6 +35604,11 @@ function SidebarContent({
35381
35604
  flexDirection: "column",
35382
35605
  marginTop: liveSessions && liveSessions.length > 0 ? 1 : 0,
35383
35606
  children: resumeSessions.slice(0, 3).map((rs) => {
35607
+ const isCurrent = isCurrentSession(
35608
+ rs.id,
35609
+ currentSessionId,
35610
+ rs.isCurrent
35611
+ );
35384
35612
  const badge = outcomeBadge(rs.outcome);
35385
35613
  const title = trunc2(
35386
35614
  rs.title || rs.lastUserMessage || rs.id,
@@ -35395,9 +35623,9 @@ function SidebarContent({
35395
35623
  /* @__PURE__ */ jsx75(
35396
35624
  Text,
35397
35625
  {
35398
- color: rs.isCurrent ? theme.accent : theme.textSecondary,
35626
+ color: isCurrent ? theme.accent : theme.textSecondary,
35399
35627
  wrap: "truncate",
35400
- ...rs.isCurrent ? { bold: true } : {},
35628
+ bold: isCurrent,
35401
35629
  children: title
35402
35630
  }
35403
35631
  ),
@@ -35419,9 +35647,7 @@ function SidebarContent({
35419
35647
  import { useEffect as useEffect68, useState as useState41 } from "react";
35420
35648
  import { jsx as jsx76, jsxs as jsxs73 } from "react/jsx-runtime";
35421
35649
  function trunc3(s2, max) {
35422
- if (max <= 0) return "";
35423
- if (s2.length <= max) return s2;
35424
- return `${s2.slice(0, Math.max(1, max - 1))}\u2026`;
35650
+ return truncateDisplay(s2, max);
35425
35651
  }
35426
35652
  function SidebarSectionHeader({
35427
35653
  glyph: glyph2,
@@ -35469,46 +35695,24 @@ function SidebarPanelFrame({
35469
35695
  kicker,
35470
35696
  right,
35471
35697
  footer,
35472
- children,
35473
- bodyScrollOffset = 0
35698
+ children
35474
35699
  }) {
35475
- const innerWidth = Math.max(8, width - 4);
35476
- const { stdout } = useStdout();
35477
- const sidebarHeight = Math.max(1, (stdout?.rows ?? 32) - 2);
35478
- const bodyHeight = Math.max(1, sidebarHeight - 4);
35479
- return /* @__PURE__ */ jsxs73(
35480
- Box,
35481
- {
35482
- flexDirection: "column",
35483
- width,
35484
- height: sidebarHeight,
35485
- overflowY: "hidden",
35486
- borderStyle: "round",
35487
- borderColor: accent,
35488
- paddingX: 1,
35489
- flexShrink: 0,
35490
- children: [
35491
- /* @__PURE__ */ jsx76(Box, { height: 1, children: /* @__PURE__ */ jsx76(Text, { color: accent, bold: true, wrap: "truncate", children: trunc3(`${icon} ${title}${kicker ? ` / ${kicker}` : ""}`, innerWidth) }) }),
35492
- right ? /* @__PURE__ */ jsx76(Box, { height: 1, children: /* @__PURE__ */ jsx76(Text, { wrap: "truncate", children: right }) }) : null,
35493
- /* @__PURE__ */ jsxs73(Box, { flexDirection: "column", height: bodyHeight, overflowY: "hidden", flexShrink: 0, children: [
35494
- bodyScrollOffset > 0 ? /* @__PURE__ */ jsx76(Box, { children: /* @__PURE__ */ jsxs73(Text, { color: theme.textMuted, dimColor: true, children: [
35495
- "\u2191 ",
35496
- bodyScrollOffset,
35497
- " earlier"
35498
- ] }) }) : null,
35499
- /* @__PURE__ */ jsx76(
35500
- Box,
35501
- {
35502
- flexDirection: "column",
35503
- ...bodyScrollOffset > 0 ? { marginTop: -bodyScrollOffset } : {},
35504
- children
35505
- }
35506
- )
35507
- ] }),
35508
- footer ? /* @__PURE__ */ jsx76(Box, { height: 1, marginTop: 1, children: /* @__PURE__ */ jsx76(Text, { wrap: "truncate", dimColor: true, children: footer }) }) : null
35509
- ]
35510
- }
35511
- );
35700
+ const innerWidth = Math.max(8, width);
35701
+ const showKicker = !!kicker && innerWidth >= 24;
35702
+ return /* @__PURE__ */ jsxs73(Box, { flexDirection: "column", width, flexShrink: 0, children: [
35703
+ /* @__PURE__ */ jsxs73(Box, { height: 1, width: innerWidth, children: [
35704
+ /* @__PURE__ */ jsx76(Text, { color: accent, bold: true, children: "\u258C" }),
35705
+ /* @__PURE__ */ jsx76(Text, { color: accent, bold: true, wrap: "truncate", children: trunc3(` ${icon} ${title}`, Math.max(1, innerWidth - 1)) })
35706
+ ] }),
35707
+ showKicker || right ? /* @__PURE__ */ jsxs73(Box, { height: 1, width: innerWidth, children: [
35708
+ showKicker ? /* @__PURE__ */ jsx76(Text, { color: theme.textMuted, dimColor: true, wrap: "truncate", children: trunc3(kicker, Math.max(1, right ? Math.floor(innerWidth * 0.55) : innerWidth)) }) : null,
35709
+ /* @__PURE__ */ jsx76(Box, { flexGrow: 1 }),
35710
+ right ? /* @__PURE__ */ jsx76(Text, { wrap: "truncate", children: right }) : null
35711
+ ] }) : null,
35712
+ /* @__PURE__ */ jsx76(Text, { color: accent, wrap: "truncate", children: "\u2500".repeat(innerWidth) }),
35713
+ /* @__PURE__ */ jsx76(Box, { flexDirection: "column", children }),
35714
+ footer ? /* @__PURE__ */ jsx76(Box, { height: 1, marginTop: 1, children: /* @__PURE__ */ jsx76(Text, { wrap: "truncate", dimColor: true, children: footer }) }) : null
35715
+ ] });
35512
35716
  }
35513
35717
 
35514
35718
  // src/components/sidebar-panels.tsx
@@ -35575,7 +35779,7 @@ function ProjectPickerSidebar({
35575
35779
  currentProject,
35576
35780
  width
35577
35781
  }) {
35578
- const inner = Math.max(8, width - 4);
35782
+ const inner = Math.max(8, width);
35579
35783
  const projectCount = items.filter((item) => item.kind === "project").length;
35580
35784
  const selectableCount = items.filter((item) => item.key !== "__divider__").length;
35581
35785
  const start = Math.max(0, Math.min(selected - 2, Math.max(0, items.length - 5)));
@@ -35656,7 +35860,7 @@ function FleetPanelSidebar({
35656
35860
  runningCount,
35657
35861
  width
35658
35862
  }) {
35659
- const inner = Math.max(8, width - 4);
35863
+ const inner = Math.max(8, width);
35660
35864
  const all = Object.values(entries);
35661
35865
  const leader = all.find((e) => e.id === "leader");
35662
35866
  const subagents = all.filter((e) => e !== leader && e.status === "running");
@@ -35690,7 +35894,7 @@ function AgentsPanelSidebar({
35690
35894
  nowTick,
35691
35895
  width
35692
35896
  }) {
35693
- const inner = Math.max(8, width - 4);
35897
+ const inner = Math.max(8, width);
35694
35898
  const all = Object.values(entries);
35695
35899
  const running = all.filter((e) => e.status === "running");
35696
35900
  const done = all.filter((e) => e.status === "success");
@@ -35727,13 +35931,10 @@ function AgentsPanelSidebar({
35727
35931
  }
35728
35932
  ),
35729
35933
  /* @__PURE__ */ jsx77(Text, { color: theme.textPrimary, wrap: "truncate", bold: true, children: trunc3(hotAgent.name || hotAgent.id, inner - 4) }),
35730
- /* @__PURE__ */ jsxs74(Text, { color: theme.textMuted, children: [
35731
- "ctx ",
35732
- Math.round((hotAgent.ctxPct ?? 0) * 100),
35733
- "% \xB7",
35734
- " ",
35735
- hotAgent.currentTool?.name ?? "idle"
35736
- ] })
35934
+ /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, wrap: "truncate", children: trunc3(
35935
+ `ctx ${Math.round((hotAgent.ctxPct ?? 0) * 100)}% \xB7 ${hotAgent.currentTool?.name ?? "idle"}`,
35936
+ inner
35937
+ ) })
35737
35938
  ] }) : /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "no live agents" }) }),
35738
35939
  /* @__PURE__ */ jsxs74(SidebarPanelCard, { innerWidth: inner, marginBottom: 0, children: [
35739
35940
  /* @__PURE__ */ jsx77(
@@ -35767,7 +35968,7 @@ function AgentsPanelSidebar({
35767
35968
  function worktreeStatusVisual(status) {
35768
35969
  switch (status) {
35769
35970
  case "active":
35770
- return { glyph: "\u25CF", color: theme.warn };
35971
+ return { glyph: "\u2022", color: theme.warn };
35771
35972
  case "committing":
35772
35973
  return { glyph: "\u25D0", color: theme.accent };
35773
35974
  case "merging":
@@ -35786,7 +35987,7 @@ function WorktreePanelSidebar({
35786
35987
  worktrees,
35787
35988
  width
35788
35989
  }) {
35789
- const inner = Math.max(8, width - 4);
35990
+ const inner = Math.max(8, width);
35790
35991
  const list = Object.values(worktrees);
35791
35992
  const active = list.filter(
35792
35993
  (w) => w.status === "active" || w.status === "committing" || w.status === "merging"
@@ -35803,18 +36004,18 @@ function WorktreePanelSidebar({
35803
36004
  kicker: "isolation",
35804
36005
  right: /* @__PURE__ */ jsxs74(Text, { children: [
35805
36006
  /* @__PURE__ */ jsxs74(Text, { color: theme.warn, children: [
35806
- "\u25B6",
36007
+ "A",
35807
36008
  active
35808
36009
  ] }),
35809
36010
  /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: " " }),
35810
36011
  /* @__PURE__ */ jsxs74(Text, { color: theme.success, children: [
35811
- glyphs.success,
36012
+ "D",
35812
36013
  merged
35813
36014
  ] }),
35814
36015
  failed > 0 ? /* @__PURE__ */ jsxs74(Fragment27, { children: [
35815
36016
  /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: " " }),
35816
36017
  /* @__PURE__ */ jsxs74(Text, { color: theme.error, children: [
35817
- "\u2717",
36018
+ "!",
35818
36019
  failed
35819
36020
  ] })
35820
36021
  ] }) : null
@@ -35822,18 +36023,22 @@ function WorktreePanelSidebar({
35822
36023
  footer: "F4 details",
35823
36024
  children: /* @__PURE__ */ jsx77(SidebarPanelCard, { innerWidth: inner, marginBottom: 0, children: list.length === 0 ? /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "no worktrees" }) : list.slice(0, 10).map((w) => {
35824
36025
  const v = worktreeStatusVisual(w.status);
35825
- const branch = trunc3(w.branch.replace(/^wstack\/ap\//, ""), inner - 16);
36026
+ const diff = `+${w.insertions}/-${w.deletions}`;
36027
+ const showDiff = inner >= 24;
36028
+ const rowChrome = displayWidth(v.glyph) + 1;
36029
+ const diffWidth = showDiff ? displayWidth(diff) + 1 : 0;
36030
+ const branch = trunc3(
36031
+ w.branch.replace(/^wstack\/ap\//, ""),
36032
+ Math.max(4, inner - rowChrome - diffWidth)
36033
+ );
35826
36034
  return /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
35827
36035
  /* @__PURE__ */ jsx77(Text, { color: v.color, children: v.glyph }),
35828
36036
  /* @__PURE__ */ jsx77(Text, { color: theme.textPrimary, children: " " }),
35829
36037
  /* @__PURE__ */ jsx77(Text, { wrap: "truncate", children: branch }),
35830
- /* @__PURE__ */ jsx77(Box, { flexGrow: 1 }),
35831
- /* @__PURE__ */ jsxs74(Text, { color: theme.textMuted, children: [
35832
- "+",
35833
- w.insertions,
35834
- "/-",
35835
- w.deletions
35836
- ] })
36038
+ showDiff ? /* @__PURE__ */ jsxs74(Fragment27, { children: [
36039
+ /* @__PURE__ */ jsx77(Box, { flexGrow: 1 }),
36040
+ /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: diff })
36041
+ ] }) : null
35837
36042
  ] }, w.branch);
35838
36043
  }) })
35839
36044
  }
@@ -35847,7 +36052,7 @@ function PlanPanelSidebar({
35847
36052
  title,
35848
36053
  width
35849
36054
  }) {
35850
- const inner = Math.max(8, width - 4);
36055
+ const inner = Math.max(8, width);
35851
36056
  const total = openCount + inProgressCount + doneCount;
35852
36057
  const ratio = total > 0 ? doneCount / total : 0;
35853
36058
  const ordered = [
@@ -35893,8 +36098,8 @@ function PlanPanelSidebar({
35893
36098
  }
35894
36099
  ),
35895
36100
  /* @__PURE__ */ jsxs74(Box, { children: [
35896
- /* @__PURE__ */ jsx77(Text, { color: ratio === 1 && total > 0 ? theme.success : theme.accent, children: "\u2588".repeat(Math.round(ratio * (inner - 4))) }),
35897
- /* @__PURE__ */ jsx77(Text, { color: theme.borderSubtle, children: "\u2591".repeat(Math.max(0, inner - 4 - Math.round(ratio * (inner - 4)))) })
36101
+ /* @__PURE__ */ jsx77(Text, { color: ratio === 1 && total > 0 ? theme.success : theme.accent, children: "\u2588".repeat(Math.round(ratio * inner)) }),
36102
+ /* @__PURE__ */ jsx77(Text, { color: theme.borderSubtle, children: "\u2591".repeat(Math.max(0, inner - Math.round(ratio * inner))) })
35898
36103
  ] })
35899
36104
  ] }),
35900
36105
  /* @__PURE__ */ jsxs74(SidebarPanelCard, { innerWidth: inner, marginBottom: 0, children: [
@@ -35911,7 +36116,7 @@ function PlanPanelSidebar({
35911
36116
  ordered.length === 0 ? /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "no plan items" }) : ordered.map((item) => {
35912
36117
  const icon = item.status === "done" ? glyphs.success : item.status === "in_progress" ? "\u25D0" : "\u25CB";
35913
36118
  const color = item.status === "done" ? theme.success : item.status === "in_progress" ? theme.warn : theme.textMuted;
35914
- return /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
36119
+ return /* @__PURE__ */ jsxs74(Box, { width: inner, flexDirection: "row", children: [
35915
36120
  /* @__PURE__ */ jsx77(Text, { color, children: icon }),
35916
36121
  /* @__PURE__ */ jsxs74(
35917
36122
  Text,
@@ -35920,7 +36125,7 @@ function PlanPanelSidebar({
35920
36125
  ...item.status === "done" ? { dimColor: true, strikethrough: true } : {},
35921
36126
  children: [
35922
36127
  " ",
35923
- trunc3(item.title, inner - 4)
36128
+ item.title
35924
36129
  ]
35925
36130
  }
35926
36131
  )
@@ -35932,7 +36137,7 @@ function PlanPanelSidebar({
35932
36137
  );
35933
36138
  }
35934
36139
  function TodosPanelSidebar({ todos, width }) {
35935
- const inner = Math.max(8, width - 4);
36140
+ const inner = Math.max(8, width);
35936
36141
  const ordered = [...todos].sort((a, b) => {
35937
36142
  const rank = (t) => t.status === "in_progress" ? 0 : t.status === "pending" ? 1 : 2;
35938
36143
  return rank(a) - rank(b);
@@ -35958,7 +36163,7 @@ function TodosPanelSidebar({ todos, width }) {
35958
36163
  const icon = t.status === "completed" ? glyphs.success : t.status === "in_progress" ? "\u25CF" : "\u25CB";
35959
36164
  const color = t.status === "completed" ? theme.success : t.status === "in_progress" ? theme.accent : theme.textMuted;
35960
36165
  const label = t.status === "in_progress" && t.activeForm ? t.activeForm : t.content;
35961
- return /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
36166
+ return /* @__PURE__ */ jsxs74(Box, { width: inner, flexDirection: "row", children: [
35962
36167
  /* @__PURE__ */ jsx77(Text, { color, children: icon }),
35963
36168
  /* @__PURE__ */ jsxs74(
35964
36169
  Text,
@@ -35967,7 +36172,7 @@ function TodosPanelSidebar({ todos, width }) {
35967
36172
  ...t.status === "completed" ? { dimColor: true, strikethrough: true } : {},
35968
36173
  children: [
35969
36174
  " ",
35970
- trunc3(label, inner - 4)
36175
+ label
35971
36176
  ]
35972
36177
  }
35973
36178
  )
@@ -35977,7 +36182,7 @@ function TodosPanelSidebar({ todos, width }) {
35977
36182
  );
35978
36183
  }
35979
36184
  function QueuePanelSidebar({ items, width }) {
35980
- const inner = Math.max(8, width - 4);
36185
+ const inner = Math.max(8, width);
35981
36186
  return /* @__PURE__ */ jsx77(
35982
36187
  SidebarPanelFrame,
35983
36188
  {
@@ -35988,7 +36193,7 @@ function QueuePanelSidebar({ items, width }) {
35988
36193
  kicker: "queued prompts",
35989
36194
  right: /* @__PURE__ */ jsx77(Text, { color: items.length > 0 ? theme.warn : theme.textMuted, bold: true, children: items.length }),
35990
36195
  footer: "F7 details",
35991
- children: /* @__PURE__ */ jsx77(SidebarPanelCard, { innerWidth: inner, marginBottom: 0, children: items.length === 0 ? /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "queue is empty" }) : items.slice(0, 10).map((item, i) => /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
36196
+ children: /* @__PURE__ */ jsx77(SidebarPanelCard, { innerWidth: inner, marginBottom: 0, children: items.length === 0 ? /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "queue is empty" }) : items.slice(0, 10).map((item, i) => /* @__PURE__ */ jsxs74(Box, { width: inner, flexDirection: "row", children: [
35992
36197
  /* @__PURE__ */ jsxs74(Text, { color: theme.textMuted, children: [
35993
36198
  i + 1,
35994
36199
  "."
@@ -35997,10 +36202,9 @@ function QueuePanelSidebar({ items, width }) {
35997
36202
  Text,
35998
36203
  {
35999
36204
  color: theme.textPrimary,
36000
- wrap: "truncate",
36001
36205
  children: [
36002
36206
  " ",
36003
- trunc3(item.displayText, inner - 6)
36207
+ item.displayText
36004
36208
  ]
36005
36209
  }
36006
36210
  )
@@ -36014,7 +36218,7 @@ function ProcessListPanelSidebar({
36014
36218
  processes,
36015
36219
  width
36016
36220
  }) {
36017
- const inner = Math.max(8, width - 4);
36221
+ const inner = Math.max(8, width);
36018
36222
  return /* @__PURE__ */ jsx77(
36019
36223
  SidebarPanelFrame,
36020
36224
  {
@@ -36046,7 +36250,7 @@ function GoalPanelSidebar({
36046
36250
  coordinatorRunning,
36047
36251
  width
36048
36252
  }) {
36049
- const inner = Math.max(8, width - 4);
36253
+ const inner = Math.max(8, width);
36050
36254
  const displayGoal = goal ? goal.refinedGoal || goal.goal : "";
36051
36255
  const stateIcon = goal?.goalState === "active" ? "\u{1F504}" : goal?.goalState === "paused" ? "\u23F8" : goal?.goalState === "completed" ? "\u2705" : "\u23F9";
36052
36256
  const progress = typeof goal?.progress === "number" ? goal.progress : 0;
@@ -36091,8 +36295,8 @@ function GoalPanelSidebar({
36091
36295
  }
36092
36296
  ),
36093
36297
  /* @__PURE__ */ jsxs74(Box, { children: [
36094
- /* @__PURE__ */ jsx77(Text, { color: theme.success, children: "\u2588".repeat(Math.round(progress / 100 * (inner - 4))) }),
36095
- /* @__PURE__ */ jsx77(Text, { color: theme.borderSubtle, children: "\u2591".repeat(Math.max(0, inner - 4 - Math.round(progress / 100 * (inner - 4)))) })
36298
+ /* @__PURE__ */ jsx77(Text, { color: theme.success, children: "\u2588".repeat(Math.round(progress / 100 * inner)) }),
36299
+ /* @__PURE__ */ jsx77(Text, { color: theme.borderSubtle, children: "\u2591".repeat(Math.max(0, inner - Math.round(progress / 100 * inner))) })
36096
36300
  ] })
36097
36301
  ] }),
36098
36302
  /* @__PURE__ */ jsxs74(SidebarPanelCard, { innerWidth: inner, marginBottom: 0, children: [
@@ -36108,7 +36312,7 @@ function GoalPanelSidebar({
36108
36312
  ),
36109
36313
  deliverables.slice(0, 6).map((d, i) => {
36110
36314
  const done = /^\[[x✓]\]|✅|\(done\)/i.test(d);
36111
- return /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
36315
+ return /* @__PURE__ */ jsxs74(Box, { width: inner, flexDirection: "row", children: [
36112
36316
  /* @__PURE__ */ jsx77(Text, { color: done ? theme.success : theme.textMuted, children: done ? glyphs.success : glyphs.pending }),
36113
36317
  /* @__PURE__ */ jsxs74(
36114
36318
  Text,
@@ -36117,7 +36321,7 @@ function GoalPanelSidebar({
36117
36321
  ...done ? { dimColor: true, strikethrough: true } : {},
36118
36322
  children: [
36119
36323
  " ",
36120
- trunc3(d.replace(/^\[[ x✓]\]\s*/, ""), inner - 4)
36324
+ d.replace(/^\[[ x✓]\]\s*/, "")
36121
36325
  ]
36122
36326
  }
36123
36327
  )
@@ -36134,7 +36338,7 @@ function SessionsPanelSidebar({
36134
36338
  currentSessionId,
36135
36339
  width
36136
36340
  }) {
36137
- const inner = Math.max(8, width - 4);
36341
+ const inner = Math.max(8, width);
36138
36342
  const live = liveSessions?.slice(0, 3) ?? [];
36139
36343
  const resume = resumeSessions?.slice(0, 3) ?? [];
36140
36344
  const total = (liveSessions?.length ?? 0) + (resumeSessions?.length ?? 0);
@@ -36161,7 +36365,10 @@ function SessionsPanelSidebar({
36161
36365
  }
36162
36366
  ),
36163
36367
  live.map((s2) => {
36164
- const isCurrent = s2.sessionId === currentSessionId;
36368
+ const isCurrent = isCurrentSession(
36369
+ s2.sessionId,
36370
+ currentSessionId
36371
+ );
36165
36372
  const icon = isCurrent ? "\u25CF" : liveSessionGlyph(s2.status);
36166
36373
  const color = liveSessionColor2(s2.status);
36167
36374
  return /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
@@ -36194,13 +36401,18 @@ function SessionsPanelSidebar({
36194
36401
  const rel = fmtRelative2(rs.lastActivityAt ?? rs.endedAt);
36195
36402
  const outcomeGlyph = rs.outcome === "completed" ? glyphs.success : rs.outcome === "error" ? glyphs.failure : rs.outcome === "timeout" ? "\u23F1" : "\u2298";
36196
36403
  const outcomeColor = rs.outcome === "completed" ? theme.success : rs.outcome === "error" ? theme.error : rs.outcome === "timeout" ? theme.warn : theme.textMuted;
36404
+ const isCurrent = isCurrentSession(
36405
+ rs.id,
36406
+ currentSessionId,
36407
+ rs.isCurrent
36408
+ );
36197
36409
  return /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
36198
36410
  /* @__PURE__ */ jsx77(Text, { color: outcomeColor, children: outcomeGlyph }),
36199
36411
  /* @__PURE__ */ jsxs74(
36200
36412
  Text,
36201
36413
  {
36202
- color: rs.isCurrent ? theme.accent : theme.textSecondary,
36203
- bold: rs.isCurrent === true,
36414
+ color: isCurrent ? theme.accent : theme.textSecondary,
36415
+ bold: isCurrent,
36204
36416
  wrap: "truncate",
36205
36417
  children: [
36206
36418
  " ",
@@ -36226,7 +36438,7 @@ function CoordinatorPanelSidebar({
36226
36438
  elapsedMs,
36227
36439
  width
36228
36440
  }) {
36229
- const inner = Math.max(8, width - 4);
36441
+ const inner = Math.max(8, width);
36230
36442
  return /* @__PURE__ */ jsxs74(
36231
36443
  SidebarPanelFrame,
36232
36444
  {
@@ -36271,7 +36483,7 @@ function KanbanPanelSidebar({
36271
36483
  activeCardTitles,
36272
36484
  width
36273
36485
  }) {
36274
- const inner = Math.max(8, width - 4);
36486
+ const inner = Math.max(8, width);
36275
36487
  return /* @__PURE__ */ jsxs74(
36276
36488
  SidebarPanelFrame,
36277
36489
  {
@@ -36318,11 +36530,11 @@ function KanbanPanelSidebar({
36318
36530
  innerWidth: inner
36319
36531
  }
36320
36532
  ),
36321
- activeCardTitles.length === 0 ? /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "no active cards" }) : activeCardTitles.slice(0, 6).map((title, i) => /* @__PURE__ */ jsxs74(Box, { flexDirection: "row", children: [
36533
+ activeCardTitles.length === 0 ? /* @__PURE__ */ jsx77(Text, { color: theme.textMuted, children: "no active cards" }) : activeCardTitles.slice(0, 6).map((title, i) => /* @__PURE__ */ jsxs74(Box, { width: inner, flexDirection: "row", children: [
36322
36534
  /* @__PURE__ */ jsx77(Text, { color: theme.warn, children: "\u25CF" }),
36323
- /* @__PURE__ */ jsxs74(Text, { color: theme.textPrimary, wrap: "truncate", children: [
36535
+ /* @__PURE__ */ jsxs74(Text, { color: theme.textPrimary, children: [
36324
36536
  " ",
36325
- trunc3(title, inner - 4)
36537
+ title
36326
36538
  ] })
36327
36539
  ] }, i))
36328
36540
  ] })
@@ -36334,7 +36546,7 @@ function ConnectionsPanelSidebar({
36334
36546
  connections,
36335
36547
  width
36336
36548
  }) {
36337
- const inner = Math.max(8, width - 4);
36549
+ const inner = Math.max(8, width);
36338
36550
  const okCount = connections.filter((c) => c.status === "ok").length;
36339
36551
  const warnCount = connections.filter((c) => c.status === "warn").length;
36340
36552
  const downCount = connections.filter((c) => c.status === "down").length;
@@ -39187,6 +39399,8 @@ function createAppKeyHandler(options) {
39187
39399
  terminalColumns,
39188
39400
  terminalRows,
39189
39401
  mainColumnWidth,
39402
+ effectiveSwarmOnSidebar,
39403
+ sidebarTwinRowCount,
39190
39404
  statusBarWrapRef,
39191
39405
  belowStatusBarRef,
39192
39406
  liveStatuslineMode,
@@ -39389,11 +39603,23 @@ function createAppKeyHandler(options) {
39389
39603
  if (state.sidebarFocused && !overlayOpen) {
39390
39604
  const sidebarViewportHeight = termRows - 2;
39391
39605
  if (key.upArrow) {
39392
- dispatch({ type: "sidebarScroll", delta: -1, viewportHeight: sidebarViewportHeight });
39606
+ dispatch({
39607
+ type: "sidebarScroll",
39608
+ delta: -1,
39609
+ viewportHeight: sidebarViewportHeight,
39610
+ sidebarTwinRowCount,
39611
+ effectiveSwarmOnSidebar
39612
+ });
39393
39613
  return;
39394
39614
  }
39395
39615
  if (key.downArrow) {
39396
- dispatch({ type: "sidebarScroll", delta: 1, viewportHeight: sidebarViewportHeight });
39616
+ dispatch({
39617
+ type: "sidebarScroll",
39618
+ delta: 1,
39619
+ viewportHeight: sidebarViewportHeight,
39620
+ sidebarTwinRowCount,
39621
+ effectiveSwarmOnSidebar
39622
+ });
39397
39623
  return;
39398
39624
  }
39399
39625
  if (key.escape) {
@@ -39442,7 +39668,9 @@ function createAppKeyHandler(options) {
39442
39668
  dispatch({
39443
39669
  type: "sidebarScroll",
39444
39670
  delta: key.mouse.wheel > 0 ? -1 : 1,
39445
- viewportHeight: termRows - 2
39671
+ viewportHeight: termRows - 2,
39672
+ sidebarTwinRowCount,
39673
+ effectiveSwarmOnSidebar
39446
39674
  });
39447
39675
  return;
39448
39676
  }
@@ -39887,11 +40115,33 @@ function App(props) {
39887
40115
  } = useLiveSettingsState({ getSettings, titleController, chime, confirmExit });
39888
40116
  const mailbox = useMailboxViewModel(events);
39889
40117
  const { setMailboxPanelOpen } = mailbox;
40118
+ const sidebarOpenFlags = {
40119
+ projectPicker: state.projectPicker.open,
40120
+ fleet: state.monitorOpen,
40121
+ agents: state.agentsMonitorOpen && (liveSettings?.showAgentSwarmPanel ?? "bottom") !== "off",
40122
+ worktree: state.worktreeMonitorOpen,
40123
+ plan: state.planPanelOpen,
40124
+ todos: state.todosMonitorOpen,
40125
+ queue: state.queuePanelOpen,
40126
+ processList: state.processListOpen,
40127
+ goal: state.goalPanelOpen,
40128
+ sessions: state.sessionsPanelOpen,
40129
+ coordinator: state.coordinator.monitorOpen || (state.goalRun?.monitorOpen ?? false),
40130
+ kanban: state.kanbanPanelOpen,
40131
+ connections: state.connectionsPanelOpen
40132
+ };
39890
40133
  const sidebarLayout = resolveSidebarLayout(
39891
40134
  state,
39892
40135
  stdout?.columns ?? 80,
39893
40136
  liveSettings?.panelPositions,
39894
- mailbox.mailboxPanelOpen
40137
+ mailbox.mailboxPanelOpen,
40138
+ sidebarOpenFlags,
40139
+ // Legacy `showAgentSwarmPanel === 'sidebar'` source from the
40140
+ // persisted config. Mirrors the renderer's read at
40141
+ // `app-view.tsx:897-899` so the scroll-clamp reservation matches
40142
+ // the actual source the renderer uses to decide whether to
40143
+ // render the mission card on the sidebar.
40144
+ (liveSettings?.showAgentSwarmPanel ?? "bottom") === "sidebar"
39895
40145
  );
39896
40146
  useEffect70(() => {
39897
40147
  titleController?.setModel(liveModel);
@@ -40366,6 +40616,8 @@ function App(props) {
40366
40616
  terminalColumns: stdout?.columns ?? 80,
40367
40617
  terminalRows: stdout?.rows ?? 24,
40368
40618
  mainColumnWidth: sidebarLayout.mainColumnWidth,
40619
+ effectiveSwarmOnSidebar: sidebarLayout.effectiveSwarmOnSidebar,
40620
+ sidebarTwinRowCount: sidebarLayout.sidebarTwinRowCount,
40369
40621
  statusBarWrapRef,
40370
40622
  belowStatusBarRef,
40371
40623
  liveStatuslineMode,