reasonix 0.36.0 → 0.36.2

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 (42) hide show
  1. package/README.md +17 -0
  2. package/README.zh-CN.md +17 -0
  3. package/dashboard/dist/app.js +405 -196
  4. package/dashboard/dist/app.js.map +1 -1
  5. package/dist/cli/{chat-RGMYAOY2.js → chat-QSM6JKUA.js} +7 -7
  6. package/dist/cli/{chunk-ZU45XW3P.js → chunk-4D6TT2IB.js} +10 -2
  7. package/dist/cli/chunk-4D6TT2IB.js.map +1 -0
  8. package/dist/cli/{chunk-2MCYGFLK.js → chunk-C5543CRX.js} +17 -16
  9. package/dist/cli/chunk-C5543CRX.js.map +1 -0
  10. package/dist/cli/{chunk-KJQIA4US.js → chunk-K6W64QVE.js} +48 -29
  11. package/dist/cli/chunk-K6W64QVE.js.map +1 -0
  12. package/dist/cli/{chunk-EN4LAZW5.js → chunk-NHV5YGTB.js} +761 -642
  13. package/dist/cli/chunk-NHV5YGTB.js.map +1 -0
  14. package/dist/cli/{chunk-QRUQ2BFT.js → chunk-RNSZYYGB.js} +109 -41
  15. package/dist/cli/chunk-RNSZYYGB.js.map +1 -0
  16. package/dist/cli/{chunk-QPNZWUZF.js → chunk-S4GF3HPO.js} +26 -1
  17. package/dist/cli/chunk-S4GF3HPO.js.map +1 -0
  18. package/dist/cli/{code-KJB3WDU6.js → code-6C5A2CY3.js} +17 -9
  19. package/dist/cli/code-6C5A2CY3.js.map +1 -0
  20. package/dist/cli/index.js +10 -10
  21. package/dist/cli/{prompt-YEKXMNNV.js → prompt-QSEB7HNQ.js} +3 -3
  22. package/dist/cli/{run-FK5UBIIM.js → run-AG4Y45X7.js} +5 -5
  23. package/dist/cli/{server-W4XJK4GX.js → server-GNHR5K3N.js} +4 -4
  24. package/dist/cli/{sessions-YZXWMIWW.js → sessions-MHRF3GU4.js} +5 -5
  25. package/dist/cli/{version-DWD6RLIU.js → version-7AL4JZ63.js} +5 -5
  26. package/dist/index.d.ts +29 -1
  27. package/dist/index.js +146 -45
  28. package/dist/index.js.map +1 -1
  29. package/package.json +1 -1
  30. package/dist/cli/chunk-2MCYGFLK.js.map +0 -1
  31. package/dist/cli/chunk-EN4LAZW5.js.map +0 -1
  32. package/dist/cli/chunk-KJQIA4US.js.map +0 -1
  33. package/dist/cli/chunk-QPNZWUZF.js.map +0 -1
  34. package/dist/cli/chunk-QRUQ2BFT.js.map +0 -1
  35. package/dist/cli/chunk-ZU45XW3P.js.map +0 -1
  36. package/dist/cli/code-KJB3WDU6.js.map +0 -1
  37. /package/dist/cli/{chat-RGMYAOY2.js.map → chat-QSM6JKUA.js.map} +0 -0
  38. /package/dist/cli/{prompt-YEKXMNNV.js.map → prompt-QSEB7HNQ.js.map} +0 -0
  39. /package/dist/cli/{run-FK5UBIIM.js.map → run-AG4Y45X7.js.map} +0 -0
  40. /package/dist/cli/{server-W4XJK4GX.js.map → server-GNHR5K3N.js.map} +0 -0
  41. /package/dist/cli/{sessions-YZXWMIWW.js.map → sessions-MHRF3GU4.js.map} +0 -0
  42. /package/dist/cli/{version-DWD6RLIU.js.map → version-7AL4JZ63.js.map} +0 -0
@@ -34,7 +34,7 @@ import {
34
34
  toWholeFileEditBlock,
35
35
  walkFilesStream,
36
36
  webFetch
37
- } from "./chunk-QRUQ2BFT.js";
37
+ } from "./chunk-RNSZYYGB.js";
38
38
  import {
39
39
  McpClient,
40
40
  SseTransport,
@@ -50,7 +50,7 @@ import {
50
50
  } from "./chunk-XHQIK7B6.js";
51
51
  import {
52
52
  MemoryStore
53
- } from "./chunk-ZU45XW3P.js";
53
+ } from "./chunk-4D6TT2IB.js";
54
54
  import {
55
55
  KeystrokeProvider,
56
56
  SingleSelect,
@@ -101,7 +101,7 @@ import {
101
101
  resolveSlashAlias,
102
102
  savePlanState,
103
103
  suggestSlashCommands
104
- } from "./chunk-2MCYGFLK.js";
104
+ } from "./chunk-C5543CRX.js";
105
105
  import {
106
106
  fetchSmitheryDetail,
107
107
  loadMorePages,
@@ -117,13 +117,13 @@ import {
117
117
  formatCommandResult,
118
118
  pauseGate,
119
119
  runCommand
120
- } from "./chunk-QPNZWUZF.js";
120
+ } from "./chunk-S4GF3HPO.js";
121
121
  import {
122
122
  PROJECT_MEMORY_FILE,
123
123
  SkillStore,
124
124
  memoryEnabled,
125
125
  readProjectMemory
126
- } from "./chunk-KJQIA4US.js";
126
+ } from "./chunk-K6W64QVE.js";
127
127
  import {
128
128
  HOOK_EVENTS,
129
129
  formatHookOutcomeMessage,
@@ -214,7 +214,7 @@ import {
214
214
 
215
215
  // src/cli/commands/chat.tsx
216
216
  import { render } from "ink";
217
- import React63, { useState as useState22 } from "react";
217
+ import React65, { useState as useState22 } from "react";
218
218
 
219
219
  // src/mcp/summary.ts
220
220
  function buildMcpServerSummary(opts) {
@@ -237,8 +237,8 @@ function buildMcpServerSummary(opts) {
237
237
  // src/cli/ui/App.tsx
238
238
  import { statSync } from "fs";
239
239
  import { resolve as resolve2 } from "path";
240
- import { Box as Box49, Text as Text52, useStdout as useStdout15 } from "ink";
241
- import React60, { useCallback as useCallback11, useEffect as useEffect12, useMemo as useMemo9, useRef as useRef9, useState as useState20 } from "react";
240
+ import { Box as Box50, Text as Text53, useStdout as useStdout15 } from "ink";
241
+ import React62, { useCallback as useCallback11, useEffect as useEffect12, useMemo as useMemo9, useRef as useRef9, useState as useState20 } from "react";
242
242
 
243
243
  // src/code/checkpoints.ts
244
244
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
@@ -6552,9 +6552,42 @@ function truncateCells(value, maxCells) {
6552
6552
  return `${value.slice(0, maxCells - 1)}\u2026`;
6553
6553
  }
6554
6554
 
6555
- // src/cli/ui/WelcomeBanner.tsx
6555
+ // src/cli/ui/ThemePicker.tsx
6556
6556
  import { Box as Box24, Text as Text24 } from "ink";
6557
6557
  import React28 from "react";
6558
+ function ThemePicker({
6559
+ currentPreference,
6560
+ activeTheme,
6561
+ onChoose
6562
+ }) {
6563
+ const choices = ["auto", ...listThemeNames()];
6564
+ const items = choices.map((value) => ({
6565
+ value,
6566
+ label: value,
6567
+ hint: describeTheme(value, currentPreference, activeTheme)
6568
+ }));
6569
+ return /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React28.createElement(Text24, { bold: true }, "Theme"), /* @__PURE__ */ React28.createElement(
6570
+ SingleSelect,
6571
+ {
6572
+ items,
6573
+ initialValue: currentPreference,
6574
+ onSubmit: (value) => onChoose({ kind: "select", value }),
6575
+ onCancel: () => onChoose({ kind: "quit" }),
6576
+ footer: "\u2191\u2193 pick \xB7 \u23CE confirm \xB7 esc cancel"
6577
+ }
6578
+ ));
6579
+ }
6580
+ function describeTheme(value, currentPreference, activeTheme) {
6581
+ const tags = [];
6582
+ if (value === currentPreference) tags.push("current preference");
6583
+ if (value === activeTheme) tags.push("active now");
6584
+ if (value === "auto") tags.push("use REASONIX_THEME or default");
6585
+ return tags.join(" \xB7 ");
6586
+ }
6587
+
6588
+ // src/cli/ui/WelcomeBanner.tsx
6589
+ import { Box as Box25, Text as Text25 } from "ink";
6590
+ import React29 from "react";
6558
6591
  var HINTS = ["/help", "/init", "/memory", "/cost"];
6559
6592
  function WelcomeBanner({
6560
6593
  inCodeMode,
@@ -6564,8 +6597,8 @@ function WelcomeBanner({
6564
6597
  const tagline = inCodeMode ? t("ui.taglineCode") : t("ui.taglineChat");
6565
6598
  const taglineSub = t("ui.taglineSub");
6566
6599
  const startTextRaw = t("ui.startSessionHint");
6567
- return /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "column", alignItems: "center", marginY: 1 }, /* @__PURE__ */ React28.createElement(
6568
- Box24,
6600
+ return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", alignItems: "center", marginY: 1 }, /* @__PURE__ */ React29.createElement(
6601
+ Box25,
6569
6602
  {
6570
6603
  flexDirection: "column",
6571
6604
  alignItems: "center",
@@ -6574,9 +6607,9 @@ function WelcomeBanner({
6574
6607
  paddingX: 4,
6575
6608
  paddingY: 1
6576
6609
  },
6577
- /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React28.createElement(Text24, { color: TONE.brand, bold: true }, "REASONIX"), /* @__PURE__ */ React28.createElement(Text24, { color: FG.faint }, "\xD7"), /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React28.createElement(Text24, null, "\u{1F40B}"), /* @__PURE__ */ React28.createElement(Text24, { color: TONE.accent, bold: true }, "DeepSeek"))),
6578
- /* @__PURE__ */ React28.createElement(Box24, { marginTop: 1, flexDirection: "column", alignItems: "center" }, /* @__PURE__ */ React28.createElement(Text24, { color: FG.body }, tagline), /* @__PURE__ */ React28.createElement(Text24, { color: FG.meta }, taglineSub))
6579
- ), /* @__PURE__ */ React28.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React28.createElement(Text24, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ React28.createElement(Box24, { marginTop: 1, flexDirection: "row", gap: 3 }, HINTS.map((cmd) => /* @__PURE__ */ React28.createElement(Text24, { key: cmd, color: FG.meta }, cmd))), inCodeMode && workspaceRoot ? /* @__PURE__ */ React28.createElement(Box24, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React28.createElement(Text24, { color: TONE.brand }, "\u25B8 workspace"), /* @__PURE__ */ React28.createElement(Text24, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React28.createElement(Text24, { color: FG.body }, workspaceRoot), /* @__PURE__ */ React28.createElement(Text24, { color: FG.faint }, " (relaunch with --dir <path> to switch)")) : null, dashboardUrl ? /* @__PURE__ */ React28.createElement(Box24, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React28.createElement(Text24, { color: TONE.brand, bold: true }, "\u25B8 web"), /* @__PURE__ */ React28.createElement(Text24, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React28.createElement(Text24, { color: TONE.accent }, dashboardUrl)) : null);
6610
+ /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React29.createElement(Text25, { color: TONE.brand, bold: true }, "REASONIX"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, "\xD7"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text25, null, "\u{1F40B}"), /* @__PURE__ */ React29.createElement(Text25, { color: TONE.accent, bold: true }, "DeepSeek"))),
6611
+ /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "column", alignItems: "center" }, /* @__PURE__ */ React29.createElement(Text25, { color: FG.body }, tagline), /* @__PURE__ */ React29.createElement(Text25, { color: FG.meta }, taglineSub))
6612
+ ), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "row", gap: 3 }, HINTS.map((cmd) => /* @__PURE__ */ React29.createElement(Text25, { key: cmd, color: FG.meta }, cmd))), inCodeMode && workspaceRoot ? /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: TONE.brand }, "\u25B8 workspace"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.body }, workspaceRoot), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, " (relaunch with --dir <path> to switch)")) : null, dashboardUrl ? /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: TONE.brand, bold: true }, "\u25B8 web"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React29.createElement(Text25, { color: TONE.accent }, dashboardUrl)) : null);
6580
6613
  }
6581
6614
 
6582
6615
  // src/cli/ui/bang.ts
@@ -6774,6 +6807,7 @@ function applySlashResult(result, ctx) {
6774
6807
  return { kind: "consumed" };
6775
6808
  }
6776
6809
  if (result.clear) {
6810
+ ctx.resetPendingModals?.();
6777
6811
  ctx.stdoutWrite("\x1B[2J\x1B[3J\x1B[H");
6778
6812
  ctx.log.reset();
6779
6813
  if (result.info) ctx.log.pushInfo(result.info);
@@ -6879,7 +6913,7 @@ function handleToolStart(ev, ctx) {
6879
6913
  ctx.setOngoingTool({ name: ev.toolName ?? "?", args: ev.toolArgs });
6880
6914
  ctx.setToolProgress(null);
6881
6915
  ctx.toolStartedAtRef.current = Date.now();
6882
- ctx.translator.toolStart(ev.toolName ?? "?", parseJsonOrRaw(ev.toolArgs));
6916
+ ctx.translator.toolStart(ev.toolName ?? "?", parseJsonOrRaw(ev.toolArgs), ev.callId);
6883
6917
  if (!ctx.codeModeOn || !ev.toolArgs) return;
6884
6918
  try {
6885
6919
  const parsed = JSON.parse(ev.toolArgs);
@@ -6894,6 +6928,10 @@ function handleToolStart(ev, ctx) {
6894
6928
  }
6895
6929
  }
6896
6930
  function handleErrorEvent(ev, ctx) {
6931
+ ctx.setOngoingTool(null);
6932
+ ctx.setToolProgress(null);
6933
+ ctx.toolStartedAtRef.current = null;
6934
+ ctx.translator.toolAbort(ev.error ?? ev.content);
6897
6935
  ctx.log.pushError("tool error", ev.error ?? ev.content);
6898
6936
  }
6899
6937
  function handleWarningEvent(ev, ctx) {
@@ -6935,274 +6973,8 @@ function handleToolEvent(ev, ctx) {
6935
6973
  }
6936
6974
  }
6937
6975
 
6938
- // src/cli/ui/hooks/useAgentSession.ts
6939
- import { useMemo as useMemo6 } from "react";
6940
- function useAgentSession({
6941
- sessionId,
6942
- model: model2,
6943
- workspace,
6944
- branch
6945
- }) {
6946
- return useMemo6(
6947
- () => ({
6948
- id: sessionId ?? "default",
6949
- branch: branch ?? "main",
6950
- workspace,
6951
- model: model2
6952
- }),
6953
- [sessionId, branch, workspace, model2]
6954
- );
6955
- }
6956
-
6957
- // src/cli/ui/hooks/useChatScroll.ts
6958
- import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState14 } from "react";
6959
- var SCROLL_PAGE_ROWS = 3;
6960
- var COALESCE_MS = 16;
6961
- function useChatScroll() {
6962
- const [scrollRows, setScrollRows] = useState14(0);
6963
- const [pinned, setPinned] = useState14(true);
6964
- const [maxScroll, setMaxScrollState] = useState14(0);
6965
- const maxScrollRef = useRef2(0);
6966
- const pendingDelta = useRef2(0);
6967
- const flushTimer = useRef2(null);
6968
- const flush = useCallback2(() => {
6969
- flushTimer.current = null;
6970
- const d = pendingDelta.current;
6971
- pendingDelta.current = 0;
6972
- if (d === 0) return;
6973
- if (d < 0) setPinned(false);
6974
- setScrollRows((o) => {
6975
- const next = Math.max(0, Math.min(maxScrollRef.current, o + d));
6976
- if (next >= maxScrollRef.current) setPinned(true);
6977
- return next;
6978
- });
6979
- }, []);
6980
- const schedule = useCallback2(
6981
- (delta) => {
6982
- pendingDelta.current += delta;
6983
- if (flushTimer.current !== null) return;
6984
- flushTimer.current = setTimeout(flush, COALESCE_MS);
6985
- },
6986
- [flush]
6987
- );
6988
- useEffect4(() => {
6989
- return () => {
6990
- if (flushTimer.current !== null) {
6991
- clearTimeout(flushTimer.current);
6992
- flushTimer.current = null;
6993
- }
6994
- };
6995
- }, []);
6996
- useEffect4(() => {
6997
- if (pinned) setScrollRows(maxScroll);
6998
- }, [pinned, maxScroll]);
6999
- useEffect4(() => {
7000
- if (scrollRows > maxScroll) setScrollRows(maxScroll);
7001
- }, [scrollRows, maxScroll]);
7002
- const scrollUp = useCallback2(() => schedule(-SCROLL_PAGE_ROWS), [schedule]);
7003
- const scrollDown = useCallback2(() => schedule(SCROLL_PAGE_ROWS), [schedule]);
7004
- const jumpToBottom = useCallback2(() => {
7005
- pendingDelta.current = 0;
7006
- if (flushTimer.current !== null) {
7007
- clearTimeout(flushTimer.current);
7008
- flushTimer.current = null;
7009
- }
7010
- setPinned(true);
7011
- }, []);
7012
- const setMaxScroll = useCallback2((rows) => {
7013
- maxScrollRef.current = rows;
7014
- setMaxScrollState(rows);
7015
- }, []);
7016
- return { scrollRows, pinned, scrollUp, scrollDown, jumpToBottom, setMaxScroll };
7017
- }
7018
-
7019
- // src/cli/ui/hooks/useCodeMode.ts
7020
- import { useCallback as useCallback3 } from "react";
7021
- function useCodeMode(opts) {
7022
- const { codeMode, pendingEdits, currentRootDir, session, syncPendingCount, recordEdit } = opts;
7023
- const codeApply = useCallback3(
7024
- (indices) => {
7025
- if (!codeMode) return "not in code mode";
7026
- const blocks = pendingEdits.current;
7027
- if (blocks.length === 0) {
7028
- return "nothing pending \u2014 the model hasn't proposed edits since the last /apply or /discard.";
7029
- }
7030
- const useSubset = indices !== void 0 && indices.length > 0;
7031
- const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
7032
- if (selected.length === 0) {
7033
- return "\u25B8 no edits matched those indices \u2014 nothing applied. Use /apply with no args to commit them all.";
7034
- }
7035
- const snaps = snapshotBeforeEdits(selected, currentRootDir);
7036
- const results = applyEditBlocks(selected, currentRootDir);
7037
- const anyApplied = results.some((r) => r.status === "applied" || r.status === "created");
7038
- if (anyApplied) recordEdit("review-apply", selected, results, snaps);
7039
- pendingEdits.current = remaining;
7040
- if (remaining.length === 0) clearPendingEdits(session ?? null);
7041
- else savePendingEdits(session ?? null, remaining);
7042
- syncPendingCount();
7043
- const tail = remaining.length > 0 ? `
7044
- \u25B8 ${remaining.length} edit block(s) still pending \u2014 /apply or /discard to clear them.` : "";
7045
- return formatEditResults(results) + tail;
7046
- },
7047
- [codeMode, currentRootDir, session, syncPendingCount, recordEdit, pendingEdits]
7048
- );
7049
- const codeDiscard = useCallback3(
7050
- (indices) => {
7051
- const blocks = pendingEdits.current;
7052
- if (blocks.length === 0) return "nothing pending to discard.";
7053
- const useSubset = indices !== void 0 && indices.length > 0;
7054
- const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
7055
- if (selected.length === 0) {
7056
- return "\u25B8 no edits matched those indices \u2014 nothing discarded.";
7057
- }
7058
- pendingEdits.current = remaining;
7059
- if (remaining.length === 0) clearPendingEdits(session ?? null);
7060
- else savePendingEdits(session ?? null, remaining);
7061
- syncPendingCount();
7062
- const tail = remaining.length > 0 ? ` (${remaining.length} block(s) still pending)` : ". Nothing was written to disk.";
7063
- return `\u25B8 discarded ${selected.length} pending edit block(s)${tail}`;
7064
- },
7065
- [session, syncPendingCount, pendingEdits]
7066
- );
7067
- return { codeApply, codeDiscard };
7068
- }
7069
-
7070
- // src/cli/ui/hooks/useInputRecall.ts
7071
- import { useCallback as useCallback4, useRef as useRef3 } from "react";
7072
- function useInputRecall(setInput) {
7073
- const promptHistory = useRef3([]);
7074
- const historyCursor = useRef3(-1);
7075
- const recallPrev = useCallback4(() => {
7076
- const hist = promptHistory.current;
7077
- if (hist.length === 0) return;
7078
- const nextCursor = Math.min(historyCursor.current + 1, hist.length - 1);
7079
- historyCursor.current = nextCursor;
7080
- setInput(hist[hist.length - 1 - nextCursor] ?? "");
7081
- }, [setInput]);
7082
- const recallNext = useCallback4(() => {
7083
- if (historyCursor.current < 0) return;
7084
- const hist = promptHistory.current;
7085
- const nextCursor = historyCursor.current - 1;
7086
- historyCursor.current = nextCursor;
7087
- setInput(nextCursor < 0 ? "" : hist[hist.length - 1 - nextCursor] ?? "");
7088
- }, [setInput]);
7089
- const pushHistory = useCallback4((text) => {
7090
- promptHistory.current.push(text);
7091
- }, []);
7092
- const resetCursor = useCallback4(() => {
7093
- historyCursor.current = -1;
7094
- }, []);
7095
- return { recallPrev, recallNext, pushHistory, resetCursor };
7096
- }
7097
-
7098
- // src/cli/ui/hooks/useLoopMode.ts
7099
- import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef4, useState as useState15 } from "react";
7100
- function useLoopMode(opts) {
7101
- const { log, busyRef, handleSubmitRef } = opts;
7102
- const [activeLoop, setActiveLoop] = useState15(null);
7103
- const activeLoopRef = useRef4(null);
7104
- const loopTimerRef = useRef4(null);
7105
- const loopFiringRef = useRef4(false);
7106
- useEffect5(() => {
7107
- activeLoopRef.current = activeLoop;
7108
- }, [activeLoop]);
7109
- const stopLoop = useCallback5(() => {
7110
- if (loopTimerRef.current) {
7111
- clearTimeout(loopTimerRef.current);
7112
- loopTimerRef.current = null;
7113
- }
7114
- const cur = activeLoopRef.current;
7115
- if (!cur) return;
7116
- setActiveLoop(null);
7117
- log.pushInfo(`\u25B8 loop stopped (after ${cur.iter} iter${cur.iter === 1 ? "" : "s"}).`);
7118
- }, [log]);
7119
- const startLoop = useCallback5((intervalMs, prompt) => {
7120
- if (loopTimerRef.current) {
7121
- clearTimeout(loopTimerRef.current);
7122
- loopTimerRef.current = null;
7123
- }
7124
- setActiveLoop({
7125
- prompt,
7126
- intervalMs,
7127
- nextFireAt: Date.now() + intervalMs,
7128
- iter: 0
7129
- });
7130
- }, []);
7131
- const getLoopStatus = useCallback5(() => {
7132
- const cur = activeLoopRef.current;
7133
- if (!cur) return null;
7134
- return {
7135
- prompt: cur.prompt,
7136
- intervalMs: cur.intervalMs,
7137
- iter: cur.iter,
7138
- nextFireMs: Math.max(0, cur.nextFireAt - Date.now())
7139
- };
7140
- }, []);
7141
- const isLoopActive = useCallback5(() => activeLoopRef.current !== null, []);
7142
- const isLoopFiring = useCallback5(() => loopFiringRef.current, []);
7143
- const clearFiringFlag = useCallback5(() => {
7144
- loopFiringRef.current = false;
7145
- }, []);
7146
- useEffect5(() => {
7147
- if (!activeLoop) return;
7148
- const delay = Math.max(0, activeLoop.nextFireAt - Date.now());
7149
- const timer = setTimeout(async () => {
7150
- loopTimerRef.current = null;
7151
- if (busyRef.current) {
7152
- setActiveLoop((cur2) => cur2 ? { ...cur2, nextFireAt: Date.now() + 1e3 } : cur2);
7153
- return;
7154
- }
7155
- const cur = activeLoopRef.current;
7156
- if (!cur) return;
7157
- const nextIter = cur.iter + 1;
7158
- setActiveLoop(
7159
- (c) => c ? { ...c, iter: nextIter, nextFireAt: Date.now() + cur.intervalMs } : c
7160
- );
7161
- log.pushInfo(`\u25B8 /loop iter ${nextIter} \u2192 ${cur.prompt}`);
7162
- loopFiringRef.current = true;
7163
- try {
7164
- await handleSubmitRef.current?.(cur.prompt);
7165
- } catch {
7166
- stopLoop();
7167
- } finally {
7168
- loopFiringRef.current = false;
7169
- }
7170
- }, delay);
7171
- loopTimerRef.current = timer;
7172
- return () => clearTimeout(timer);
7173
- }, [activeLoop, stopLoop, log, busyRef, handleSubmitRef]);
7174
- return {
7175
- startLoop,
7176
- stopLoop,
7177
- getLoopStatus,
7178
- isLoopActive,
7179
- isLoopFiring,
7180
- clearFiringFlag,
7181
- activeLoop
7182
- };
7183
- }
7184
-
7185
- // src/cli/ui/hooks/useQuit.ts
7186
- import { useCallback as useCallback6, useEffect as useEffect6 } from "react";
7187
- function useQuit(transcriptRef) {
7188
- const quitProcess = useCallback6(() => {
7189
- transcriptRef.current?.end();
7190
- process.exit(0);
7191
- }, [transcriptRef]);
7192
- useEffect6(() => {
7193
- process.on("SIGINT", quitProcess);
7194
- return () => {
7195
- process.off("SIGINT", quitProcess);
7196
- };
7197
- }, [quitProcess]);
7198
- return quitProcess;
7199
- }
7200
-
7201
- // src/cli/ui/hooks/useScrollback.ts
7202
- import { useMemo as useMemo7 } from "react";
7203
-
7204
6976
  // src/cli/ui/state/provider.tsx
7205
- import React29 from "react";
6977
+ import React30 from "react";
7206
6978
 
7207
6979
  // src/cli/ui/state/reducer.ts
7208
6980
  function reduce(state, event) {
@@ -7536,62 +7308,337 @@ function initialState(session, cards = []) {
7536
7308
  };
7537
7309
  }
7538
7310
 
7539
- // src/cli/ui/state/store.ts
7540
- function createStore(session, initialCards) {
7541
- let state = initialState(session, initialCards);
7542
- const stateListeners = /* @__PURE__ */ new Set();
7543
- const eventListeners = /* @__PURE__ */ new Set();
7544
- return {
7545
- getState() {
7546
- return state;
7547
- },
7548
- dispatch(event) {
7549
- state = reduce(state, event);
7550
- for (const listener of stateListeners) listener();
7551
- for (const listener of eventListeners) listener(event);
7552
- },
7553
- subscribe(listener) {
7554
- stateListeners.add(listener);
7555
- return () => {
7556
- stateListeners.delete(listener);
7557
- };
7558
- },
7559
- onEvent(listener) {
7560
- eventListeners.add(listener);
7561
- return () => {
7562
- eventListeners.delete(listener);
7563
- };
7311
+ // src/cli/ui/state/store.ts
7312
+ function createStore(session, initialCards) {
7313
+ let state = initialState(session, initialCards);
7314
+ const stateListeners = /* @__PURE__ */ new Set();
7315
+ const eventListeners = /* @__PURE__ */ new Set();
7316
+ return {
7317
+ getState() {
7318
+ return state;
7319
+ },
7320
+ dispatch(event) {
7321
+ state = reduce(state, event);
7322
+ for (const listener of stateListeners) listener();
7323
+ for (const listener of eventListeners) listener(event);
7324
+ },
7325
+ subscribe(listener) {
7326
+ stateListeners.add(listener);
7327
+ return () => {
7328
+ stateListeners.delete(listener);
7329
+ };
7330
+ },
7331
+ onEvent(listener) {
7332
+ eventListeners.add(listener);
7333
+ return () => {
7334
+ eventListeners.delete(listener);
7335
+ };
7336
+ }
7337
+ };
7338
+ }
7339
+
7340
+ // src/cli/ui/state/provider.tsx
7341
+ var StoreCtx = React30.createContext(null);
7342
+ function AgentStoreProvider({
7343
+ session,
7344
+ initialCards,
7345
+ children
7346
+ }) {
7347
+ const initialCardsRef = React30.useRef(initialCards);
7348
+ const store = React30.useMemo(() => createStore(session, initialCardsRef.current), [session]);
7349
+ return /* @__PURE__ */ React30.createElement(StoreCtx.Provider, { value: store }, children);
7350
+ }
7351
+ function useAgentStore() {
7352
+ const store = React30.useContext(StoreCtx);
7353
+ if (!store) throw new Error("useAgentStore must be used inside AgentStoreProvider");
7354
+ return store;
7355
+ }
7356
+ function useAgentState(selector) {
7357
+ const store = useAgentStore();
7358
+ const subscribe = React30.useCallback((cb) => store.subscribe(cb), [store]);
7359
+ const getSnapshot = React30.useCallback(() => selector(store.getState()), [store, selector]);
7360
+ return React30.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
7361
+ }
7362
+ function useDispatch() {
7363
+ return useAgentStore().dispatch;
7364
+ }
7365
+
7366
+ // src/cli/ui/hooks/useActivityPhase.ts
7367
+ function deriveActivityLabel(cards) {
7368
+ if (cards.some((c) => c.kind === "reasoning" && c.streaming)) return "thinking\u2026";
7369
+ const last = cards[cards.length - 1];
7370
+ if (!last || last.kind === "user") return "waiting for model\u2026";
7371
+ return "processing\u2026";
7372
+ }
7373
+ function useActivityLabel() {
7374
+ return useAgentState((s) => deriveActivityLabel(s.cards));
7375
+ }
7376
+
7377
+ // src/cli/ui/hooks/useAgentSession.ts
7378
+ import { useMemo as useMemo6 } from "react";
7379
+ function useAgentSession({
7380
+ sessionId,
7381
+ model: model2,
7382
+ workspace,
7383
+ branch
7384
+ }) {
7385
+ return useMemo6(
7386
+ () => ({
7387
+ id: sessionId ?? "default",
7388
+ branch: branch ?? "main",
7389
+ workspace,
7390
+ model: model2
7391
+ }),
7392
+ [sessionId, branch, workspace, model2]
7393
+ );
7394
+ }
7395
+
7396
+ // src/cli/ui/hooks/useChatScroll.ts
7397
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState14 } from "react";
7398
+ var SCROLL_PAGE_ROWS = 3;
7399
+ var COALESCE_MS = 16;
7400
+ function useChatScroll() {
7401
+ const [scrollRows, setScrollRows] = useState14(0);
7402
+ const [pinned, setPinned] = useState14(true);
7403
+ const [maxScroll, setMaxScrollState] = useState14(0);
7404
+ const maxScrollRef = useRef2(0);
7405
+ const pendingDelta = useRef2(0);
7406
+ const flushTimer = useRef2(null);
7407
+ const flush = useCallback2(() => {
7408
+ flushTimer.current = null;
7409
+ const d = pendingDelta.current;
7410
+ pendingDelta.current = 0;
7411
+ if (d === 0) return;
7412
+ if (d < 0) setPinned(false);
7413
+ setScrollRows((o) => {
7414
+ const next = Math.max(0, Math.min(maxScrollRef.current, o + d));
7415
+ if (next >= maxScrollRef.current) setPinned(true);
7416
+ return next;
7417
+ });
7418
+ }, []);
7419
+ const schedule = useCallback2(
7420
+ (delta) => {
7421
+ pendingDelta.current += delta;
7422
+ if (flushTimer.current !== null) return;
7423
+ flushTimer.current = setTimeout(flush, COALESCE_MS);
7424
+ },
7425
+ [flush]
7426
+ );
7427
+ useEffect4(() => {
7428
+ return () => {
7429
+ if (flushTimer.current !== null) {
7430
+ clearTimeout(flushTimer.current);
7431
+ flushTimer.current = null;
7432
+ }
7433
+ };
7434
+ }, []);
7435
+ useEffect4(() => {
7436
+ if (pinned) setScrollRows(maxScroll);
7437
+ }, [pinned, maxScroll]);
7438
+ useEffect4(() => {
7439
+ if (scrollRows > maxScroll) setScrollRows(maxScroll);
7440
+ }, [scrollRows, maxScroll]);
7441
+ const scrollUp = useCallback2(() => schedule(-SCROLL_PAGE_ROWS), [schedule]);
7442
+ const scrollDown = useCallback2(() => schedule(SCROLL_PAGE_ROWS), [schedule]);
7443
+ const jumpToBottom = useCallback2(() => {
7444
+ pendingDelta.current = 0;
7445
+ if (flushTimer.current !== null) {
7446
+ clearTimeout(flushTimer.current);
7447
+ flushTimer.current = null;
7448
+ }
7449
+ setPinned(true);
7450
+ }, []);
7451
+ const setMaxScroll = useCallback2((rows) => {
7452
+ maxScrollRef.current = rows;
7453
+ setMaxScrollState(rows);
7454
+ }, []);
7455
+ return { scrollRows, pinned, scrollUp, scrollDown, jumpToBottom, setMaxScroll };
7456
+ }
7457
+
7458
+ // src/cli/ui/hooks/useCodeMode.ts
7459
+ import { useCallback as useCallback3 } from "react";
7460
+ function useCodeMode(opts) {
7461
+ const { codeMode, pendingEdits, currentRootDir, session, syncPendingCount, recordEdit } = opts;
7462
+ const codeApply = useCallback3(
7463
+ (indices) => {
7464
+ if (!codeMode) return "not in code mode";
7465
+ const blocks = pendingEdits.current;
7466
+ if (blocks.length === 0) {
7467
+ return "nothing pending \u2014 the model hasn't proposed edits since the last /apply or /discard.";
7468
+ }
7469
+ const useSubset = indices !== void 0 && indices.length > 0;
7470
+ const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
7471
+ if (selected.length === 0) {
7472
+ return "\u25B8 no edits matched those indices \u2014 nothing applied. Use /apply with no args to commit them all.";
7473
+ }
7474
+ const snaps = snapshotBeforeEdits(selected, currentRootDir);
7475
+ const results = applyEditBlocks(selected, currentRootDir);
7476
+ const anyApplied = results.some((r) => r.status === "applied" || r.status === "created");
7477
+ if (anyApplied) recordEdit("review-apply", selected, results, snaps);
7478
+ pendingEdits.current = remaining;
7479
+ if (remaining.length === 0) clearPendingEdits(session ?? null);
7480
+ else savePendingEdits(session ?? null, remaining);
7481
+ syncPendingCount();
7482
+ const tail = remaining.length > 0 ? `
7483
+ \u25B8 ${remaining.length} edit block(s) still pending \u2014 /apply or /discard to clear them.` : "";
7484
+ return formatEditResults(results) + tail;
7485
+ },
7486
+ [codeMode, currentRootDir, session, syncPendingCount, recordEdit, pendingEdits]
7487
+ );
7488
+ const codeDiscard = useCallback3(
7489
+ (indices) => {
7490
+ const blocks = pendingEdits.current;
7491
+ if (blocks.length === 0) return "nothing pending to discard.";
7492
+ const useSubset = indices !== void 0 && indices.length > 0;
7493
+ const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
7494
+ if (selected.length === 0) {
7495
+ return "\u25B8 no edits matched those indices \u2014 nothing discarded.";
7496
+ }
7497
+ pendingEdits.current = remaining;
7498
+ if (remaining.length === 0) clearPendingEdits(session ?? null);
7499
+ else savePendingEdits(session ?? null, remaining);
7500
+ syncPendingCount();
7501
+ const tail = remaining.length > 0 ? ` (${remaining.length} block(s) still pending)` : ". Nothing was written to disk.";
7502
+ return `\u25B8 discarded ${selected.length} pending edit block(s)${tail}`;
7503
+ },
7504
+ [session, syncPendingCount, pendingEdits]
7505
+ );
7506
+ return { codeApply, codeDiscard };
7507
+ }
7508
+
7509
+ // src/cli/ui/hooks/useInputRecall.ts
7510
+ import { useCallback as useCallback4, useRef as useRef3 } from "react";
7511
+ function useInputRecall(setInput) {
7512
+ const promptHistory = useRef3([]);
7513
+ const historyCursor = useRef3(-1);
7514
+ const recallPrev = useCallback4(() => {
7515
+ const hist = promptHistory.current;
7516
+ if (hist.length === 0) return;
7517
+ const nextCursor = Math.min(historyCursor.current + 1, hist.length - 1);
7518
+ historyCursor.current = nextCursor;
7519
+ setInput(hist[hist.length - 1 - nextCursor] ?? "");
7520
+ }, [setInput]);
7521
+ const recallNext = useCallback4(() => {
7522
+ if (historyCursor.current < 0) return;
7523
+ const hist = promptHistory.current;
7524
+ const nextCursor = historyCursor.current - 1;
7525
+ historyCursor.current = nextCursor;
7526
+ setInput(nextCursor < 0 ? "" : hist[hist.length - 1 - nextCursor] ?? "");
7527
+ }, [setInput]);
7528
+ const pushHistory = useCallback4((text) => {
7529
+ promptHistory.current.push(text);
7530
+ }, []);
7531
+ const resetCursor = useCallback4(() => {
7532
+ historyCursor.current = -1;
7533
+ }, []);
7534
+ return { recallPrev, recallNext, pushHistory, resetCursor };
7535
+ }
7536
+
7537
+ // src/cli/ui/hooks/useLoopMode.ts
7538
+ import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef4, useState as useState15 } from "react";
7539
+ function useLoopMode(opts) {
7540
+ const { log, busyRef, handleSubmitRef } = opts;
7541
+ const [activeLoop, setActiveLoop] = useState15(null);
7542
+ const activeLoopRef = useRef4(null);
7543
+ const loopTimerRef = useRef4(null);
7544
+ const loopFiringRef = useRef4(false);
7545
+ useEffect5(() => {
7546
+ activeLoopRef.current = activeLoop;
7547
+ }, [activeLoop]);
7548
+ const stopLoop = useCallback5(() => {
7549
+ if (loopTimerRef.current) {
7550
+ clearTimeout(loopTimerRef.current);
7551
+ loopTimerRef.current = null;
7552
+ }
7553
+ const cur = activeLoopRef.current;
7554
+ if (!cur) return;
7555
+ setActiveLoop(null);
7556
+ log.pushInfo(`\u25B8 loop stopped (after ${cur.iter} iter${cur.iter === 1 ? "" : "s"}).`);
7557
+ }, [log]);
7558
+ const startLoop = useCallback5((intervalMs, prompt) => {
7559
+ if (loopTimerRef.current) {
7560
+ clearTimeout(loopTimerRef.current);
7561
+ loopTimerRef.current = null;
7564
7562
  }
7563
+ setActiveLoop({
7564
+ prompt,
7565
+ intervalMs,
7566
+ nextFireAt: Date.now() + intervalMs,
7567
+ iter: 0
7568
+ });
7569
+ }, []);
7570
+ const getLoopStatus = useCallback5(() => {
7571
+ const cur = activeLoopRef.current;
7572
+ if (!cur) return null;
7573
+ return {
7574
+ prompt: cur.prompt,
7575
+ intervalMs: cur.intervalMs,
7576
+ iter: cur.iter,
7577
+ nextFireMs: Math.max(0, cur.nextFireAt - Date.now())
7578
+ };
7579
+ }, []);
7580
+ const isLoopActive = useCallback5(() => activeLoopRef.current !== null, []);
7581
+ const isLoopFiring = useCallback5(() => loopFiringRef.current, []);
7582
+ const clearFiringFlag = useCallback5(() => {
7583
+ loopFiringRef.current = false;
7584
+ }, []);
7585
+ useEffect5(() => {
7586
+ if (!activeLoop) return;
7587
+ const delay = Math.max(0, activeLoop.nextFireAt - Date.now());
7588
+ const timer = setTimeout(async () => {
7589
+ loopTimerRef.current = null;
7590
+ if (busyRef.current) {
7591
+ setActiveLoop((cur2) => cur2 ? { ...cur2, nextFireAt: Date.now() + 1e3 } : cur2);
7592
+ return;
7593
+ }
7594
+ const cur = activeLoopRef.current;
7595
+ if (!cur) return;
7596
+ const nextIter = cur.iter + 1;
7597
+ setActiveLoop(
7598
+ (c) => c ? { ...c, iter: nextIter, nextFireAt: Date.now() + cur.intervalMs } : c
7599
+ );
7600
+ log.pushInfo(`\u25B8 /loop iter ${nextIter} \u2192 ${cur.prompt}`);
7601
+ loopFiringRef.current = true;
7602
+ try {
7603
+ await handleSubmitRef.current?.(cur.prompt);
7604
+ } catch {
7605
+ stopLoop();
7606
+ } finally {
7607
+ loopFiringRef.current = false;
7608
+ }
7609
+ }, delay);
7610
+ loopTimerRef.current = timer;
7611
+ return () => clearTimeout(timer);
7612
+ }, [activeLoop, stopLoop, log, busyRef, handleSubmitRef]);
7613
+ return {
7614
+ startLoop,
7615
+ stopLoop,
7616
+ getLoopStatus,
7617
+ isLoopActive,
7618
+ isLoopFiring,
7619
+ clearFiringFlag,
7620
+ activeLoop
7565
7621
  };
7566
7622
  }
7567
7623
 
7568
- // src/cli/ui/state/provider.tsx
7569
- var StoreCtx = React29.createContext(null);
7570
- function AgentStoreProvider({
7571
- session,
7572
- initialCards,
7573
- children
7574
- }) {
7575
- const initialCardsRef = React29.useRef(initialCards);
7576
- const store = React29.useMemo(() => createStore(session, initialCardsRef.current), [session]);
7577
- return /* @__PURE__ */ React29.createElement(StoreCtx.Provider, { value: store }, children);
7578
- }
7579
- function useAgentStore() {
7580
- const store = React29.useContext(StoreCtx);
7581
- if (!store) throw new Error("useAgentStore must be used inside AgentStoreProvider");
7582
- return store;
7583
- }
7584
- function useAgentState(selector) {
7585
- const store = useAgentStore();
7586
- const subscribe = React29.useCallback((cb) => store.subscribe(cb), [store]);
7587
- const getSnapshot = React29.useCallback(() => selector(store.getState()), [store, selector]);
7588
- return React29.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
7589
- }
7590
- function useDispatch() {
7591
- return useAgentStore().dispatch;
7624
+ // src/cli/ui/hooks/useQuit.ts
7625
+ import { useCallback as useCallback6, useEffect as useEffect6 } from "react";
7626
+ function useQuit(transcriptRef) {
7627
+ const quitProcess = useCallback6(() => {
7628
+ transcriptRef.current?.end();
7629
+ process.exit(0);
7630
+ }, [transcriptRef]);
7631
+ useEffect6(() => {
7632
+ process.on("SIGINT", quitProcess);
7633
+ return () => {
7634
+ process.off("SIGINT", quitProcess);
7635
+ };
7636
+ }, [quitProcess]);
7637
+ return quitProcess;
7592
7638
  }
7593
7639
 
7594
7640
  // src/cli/ui/hooks/useScrollback.ts
7641
+ import { useMemo as useMemo7 } from "react";
7595
7642
  var seq = 0;
7596
7643
  function nextId2(prefix) {
7597
7644
  seq += 1;
@@ -7771,8 +7818,8 @@ ${stack}` : message
7771
7818
  endStreaming(id, aborted) {
7772
7819
  dispatch({ type: "streaming.end", id, aborted });
7773
7820
  },
7774
- startTool(name, args) {
7775
- const id = nextId2("tool");
7821
+ startTool(name, args, presetId) {
7822
+ const id = presetId ?? nextId2("tool");
7776
7823
  dispatch({ type: "tool.start", id, name, args });
7777
7824
  return id;
7778
7825
  },
@@ -7830,21 +7877,21 @@ function useTranscriptWriter(transcriptRef, model2, prefixHash) {
7830
7877
  }
7831
7878
 
7832
7879
  // src/cli/ui/layout/CardStream.tsx
7833
- import { Box as Box44, Text as Text46, useBoxMetrics } from "ink";
7834
- import React53, { useEffect as useEffect7, useRef as useRef5 } from "react";
7880
+ import { Box as Box45, Text as Text47, useBoxMetrics } from "ink";
7881
+ import React55, { useEffect as useEffect7, useRef as useRef5 } from "react";
7835
7882
 
7836
7883
  // src/cli/ui/cards/CardRenderer.tsx
7837
- import { Box as Box43, Text as Text45 } from "ink";
7838
- import React52 from "react";
7884
+ import { Box as Box44, Text as Text46 } from "ink";
7885
+ import React54 from "react";
7839
7886
 
7840
7887
  // src/cli/ui/cards/CtxCard.tsx
7841
- import { Box as Box27, Text as Text26 } from "ink";
7842
- import React32 from "react";
7888
+ import { Box as Box28, Text as Text27 } from "ink";
7889
+ import React33 from "react";
7843
7890
 
7844
7891
  // src/cli/ui/primitives/Card.tsx
7845
- import { Box as Box25 } from "ink";
7846
- import React30, { useContext as useContext3 } from "react";
7847
- var ActiveCardContext = React30.createContext(true);
7892
+ import { Box as Box26 } from "ink";
7893
+ import React31, { useContext as useContext3 } from "react";
7894
+ var ActiveCardContext = React31.createContext(true);
7848
7895
  var STRIPE_BORDER = {
7849
7896
  topLeft: " ",
7850
7897
  top: " ",
@@ -7858,10 +7905,10 @@ var STRIPE_BORDER = {
7858
7905
  function Card({ tone, children }) {
7859
7906
  const active = useContext3(ActiveCardContext);
7860
7907
  if (!active) {
7861
- return /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column" }, children);
7908
+ return /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column" }, children);
7862
7909
  }
7863
- return /* @__PURE__ */ React30.createElement(
7864
- Box25,
7910
+ return /* @__PURE__ */ React31.createElement(
7911
+ Box26,
7865
7912
  {
7866
7913
  flexDirection: "column",
7867
7914
  borderStyle: STRIPE_BORDER,
@@ -7878,8 +7925,8 @@ function Card({ tone, children }) {
7878
7925
  }
7879
7926
 
7880
7927
  // src/cli/ui/primitives/CardHeader.tsx
7881
- import { Box as Box26, Text as Text25 } from "ink";
7882
- import React31, { useContext as useContext4 } from "react";
7928
+ import { Box as Box27, Text as Text26 } from "ink";
7929
+ import React32, { useContext as useContext4 } from "react";
7883
7930
  function CardHeader({
7884
7931
  glyph,
7885
7932
  tone,
@@ -7892,13 +7939,13 @@ function CardHeader({
7892
7939
  }) {
7893
7940
  const active = useContext4(ActiveCardContext);
7894
7941
  const visibleMeta = active ? meta : meta?.filter((item) => typeof item !== "string");
7895
- return /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React31.createElement(Text25, { color: tone }, glyph), titleBg ? /* @__PURE__ */ React31.createElement(Text25, { backgroundColor: titleBg, color: titleColor ?? tone, bold: true }, ` ${title} `) : /* @__PURE__ */ React31.createElement(Text25, { bold: true, color: titleColor ?? tone }, title), subtitle ? /* @__PURE__ */ React31.createElement(Text25, { color: FG.body }, subtitle) : null, visibleMeta?.map((item, i) => {
7942
+ return /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React32.createElement(Text26, { color: tone }, glyph), titleBg ? /* @__PURE__ */ React32.createElement(Text26, { backgroundColor: titleBg, color: titleColor ?? tone, bold: true }, ` ${title} `) : /* @__PURE__ */ React32.createElement(Text26, { bold: true, color: titleColor ?? tone }, title), subtitle ? /* @__PURE__ */ React32.createElement(Text26, { color: FG.body }, subtitle) : null, visibleMeta?.map((item, i) => {
7896
7943
  const isStr = typeof item === "string";
7897
7944
  const text = isStr ? item : item.text;
7898
7945
  const color = isStr ? FG.faint : item.color;
7899
7946
  return (
7900
7947
  // biome-ignore lint/suspicious/noArrayIndexKey: meta items are positional
7901
- /* @__PURE__ */ React31.createElement(React31.Fragment, { key: `m-${i}` }, /* @__PURE__ */ React31.createElement(Text25, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React31.createElement(Text25, { color }, text))
7948
+ /* @__PURE__ */ React32.createElement(React32.Fragment, { key: `m-${i}` }, /* @__PURE__ */ React32.createElement(Text26, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React32.createElement(Text26, { color }, text))
7902
7949
  );
7903
7950
  }), active ? right : null);
7904
7951
  }
@@ -7907,13 +7954,13 @@ function CardHeader({
7907
7954
  var BAR_CELLS = 32;
7908
7955
  function row(label, tokens, ratio, color) {
7909
7956
  const filled = Math.max(0, Math.min(BAR_CELLS, Math.round(ratio * BAR_CELLS)));
7910
- return /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React32.createElement(Text26, { color: FG.sub }, label.padEnd(7)), /* @__PURE__ */ React32.createElement(Text26, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ React32.createElement(Text26, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ React32.createElement(Text26, { bold: true, color: FG.body }, tokens.toLocaleString()), /* @__PURE__ */ React32.createElement(Text26, { color: FG.faint }, `\xB7 ${(ratio * 100).toFixed(1)}%`));
7957
+ return /* @__PURE__ */ React33.createElement(Box28, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React33.createElement(Text27, { color: FG.sub }, label.padEnd(7)), /* @__PURE__ */ React33.createElement(Text27, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ React33.createElement(Text27, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ React33.createElement(Text27, { bold: true, color: FG.body }, tokens.toLocaleString()), /* @__PURE__ */ React33.createElement(Text27, { color: FG.faint }, `\xB7 ${(ratio * 100).toFixed(1)}%`));
7911
7958
  }
7912
7959
  function CtxCard({ card }) {
7913
7960
  const cap = Math.max(1, card.ctxMax);
7914
7961
  const used = card.systemTokens + card.toolsTokens + card.logTokens + card.inputTokens;
7915
7962
  const usedPct = used / cap * 100;
7916
- return /* @__PURE__ */ React32.createElement(Card, { tone: TONE.brand }, /* @__PURE__ */ React32.createElement(
7963
+ return /* @__PURE__ */ React33.createElement(Card, { tone: TONE.brand }, /* @__PURE__ */ React33.createElement(
7917
7964
  CardHeader,
7918
7965
  {
7919
7966
  glyph: "\u2318",
@@ -7921,8 +7968,8 @@ function CtxCard({ card }) {
7921
7968
  title: t("cardTitles.context"),
7922
7969
  meta: [`${used.toLocaleString()} / ${cap.toLocaleString()} (${usedPct.toFixed(1)}%)`]
7923
7970
  }
7924
- ), row(t("cardLabels.system"), card.systemTokens, card.systemTokens / cap, TONE.brand), row(t("cardLabels.tools"), card.toolsTokens, card.toolsTokens / cap, TONE.warn), row(t("cardLabels.log"), card.logTokens, card.logTokens / cap, TONE.ok), row(t("cardLabels.input"), card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(Text26, { color: FG.faint }, `${t("cardLabels.topTools")} \xB7 ${card.toolsCount} ${t("cardLabels.tools")} \xB7 ${card.logMessages} ${t("cardLabels.logMsgs")}`), card.topTools.slice(0, 5).map((tool) => /* @__PURE__ */ React32.createElement(Box27, { key: `${tool.turn}-${tool.name}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React32.createElement(Text26, { color: FG.sub }, tool.name), /* @__PURE__ */ React32.createElement(
7925
- Text26,
7971
+ ), row(t("cardLabels.system"), card.systemTokens, card.systemTokens / cap, TONE.brand), row(t("cardLabels.tools"), card.toolsTokens, card.toolsTokens / cap, TONE.warn), row(t("cardLabels.log"), card.logTokens, card.logTokens / cap, TONE.ok), row(t("cardLabels.input"), card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(Text27, { color: FG.faint }, `${t("cardLabels.topTools")} \xB7 ${card.toolsCount} ${t("cardLabels.tools")} \xB7 ${card.logMessages} ${t("cardLabels.logMsgs")}`), card.topTools.slice(0, 5).map((tool) => /* @__PURE__ */ React33.createElement(Box28, { key: `${tool.turn}-${tool.name}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React33.createElement(Text27, { color: FG.sub }, tool.name), /* @__PURE__ */ React33.createElement(
7972
+ Text27,
7926
7973
  {
7927
7974
  color: FG.faint
7928
7975
  },
@@ -7931,8 +7978,8 @@ function CtxCard({ card }) {
7931
7978
  }
7932
7979
 
7933
7980
  // src/cli/ui/cards/DiffCard.tsx
7934
- import { Box as Box28, Text as Text27 } from "ink";
7935
- import React33 from "react";
7981
+ import { Box as Box29, Text as Text28 } from "ink";
7982
+ import React34 from "react";
7936
7983
  var LINE_COLOR = {
7937
7984
  ctx: FG.sub,
7938
7985
  add: TONE.ok,
@@ -7947,7 +7994,7 @@ var LINE_GLYPH = {
7947
7994
  };
7948
7995
  function DiffCard({ card }) {
7949
7996
  const showFooter = card.hunks.length > 0;
7950
- return /* @__PURE__ */ React33.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React33.createElement(
7997
+ return /* @__PURE__ */ React34.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React34.createElement(
7951
7998
  CardHeader,
7952
7999
  {
7953
8000
  glyph: "\xB1",
@@ -7959,12 +8006,12 @@ function DiffCard({ card }) {
7959
8006
  { text: `-${card.stats.del}`, color: TONE.err }
7960
8007
  ]
7961
8008
  }
7962
- ), card.hunks.map((hunk) => /* @__PURE__ */ React33.createElement(Box28, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ React33.createElement(Text27, { italic: true, color: FG.faint }, hunk.header), hunk.lines.map((line, li) => /* @__PURE__ */ React33.createElement(Box28, { key: `${card.id}:${hunk.header}:${li}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React33.createElement(Text27, { color: LINE_COLOR[line.kind] }, LINE_GLYPH[line.kind]), /* @__PURE__ */ React33.createElement(Text27, { color: LINE_COLOR[line.kind], dimColor: line.kind === "ctx" }, line.text))))), showFooter && /* @__PURE__ */ React33.createElement(Box28, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React33.createElement(Text27, { bold: true, color: TONE.ok }, "[a] apply"), /* @__PURE__ */ React33.createElement(Text27, { color: FG.sub }, "[s] skip"), /* @__PURE__ */ React33.createElement(Text27, { bold: true, color: TONE.err }, "[r] reject")));
8009
+ ), card.hunks.map((hunk) => /* @__PURE__ */ React34.createElement(Box29, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ React34.createElement(Text28, { italic: true, color: FG.faint }, hunk.header), hunk.lines.map((line, li) => /* @__PURE__ */ React34.createElement(Box29, { key: `${card.id}:${hunk.header}:${li}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React34.createElement(Text28, { color: LINE_COLOR[line.kind] }, LINE_GLYPH[line.kind]), /* @__PURE__ */ React34.createElement(Text28, { color: LINE_COLOR[line.kind], dimColor: line.kind === "ctx" }, line.text))))), showFooter && /* @__PURE__ */ React34.createElement(Box29, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React34.createElement(Text28, { bold: true, color: TONE.ok }, "[a] apply"), /* @__PURE__ */ React34.createElement(Text28, { color: FG.sub }, "[s] skip"), /* @__PURE__ */ React34.createElement(Text28, { bold: true, color: TONE.err }, "[r] reject")));
7963
8010
  }
7964
8011
 
7965
8012
  // src/cli/ui/cards/DoctorCard.tsx
7966
- import { Box as Box29, Text as Text28 } from "ink";
7967
- import React34 from "react";
8013
+ import { Box as Box30, Text as Text29 } from "ink";
8014
+ import React35 from "react";
7968
8015
  var LEVEL_GLYPH = {
7969
8016
  ok: "\u2713",
7970
8017
  warn: "\u26A0",
@@ -7987,12 +8034,12 @@ function DoctorCard({ card }) {
7987
8034
  const fail = card.checks.filter((c) => c.level === "fail").length;
7988
8035
  const labelWidth = card.checks.reduce((m, c) => Math.max(m, c.label.length), 0);
7989
8036
  const summary = `${card.checks.length} checks \xB7 ${ok} passed${warn > 0 ? ` \xB7 ${warn} warn` : ""}${fail > 0 ? ` \xB7 ${fail} fail` : ""}`;
7990
- return /* @__PURE__ */ React34.createElement(Card, { tone: CARD.tool.color }, /* @__PURE__ */ React34.createElement(CardHeader, { glyph: "\u2695", tone: CARD.tool.color, title: "doctor", meta: [summary] }), card.checks.map((c) => /* @__PURE__ */ React34.createElement(Box29, { key: c.label, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React34.createElement(Text28, { color: levelColor[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ React34.createElement(Text28, { bold: true, color: fg.body }, c.label.padEnd(labelWidth + 1)), /* @__PURE__ */ React34.createElement(Text28, { color: fg.sub }, c.detail), /* @__PURE__ */ React34.createElement(Text28, { color: levelColor[c.level] }, LEVEL_TAG[c.level]))));
8037
+ return /* @__PURE__ */ React35.createElement(Card, { tone: CARD.tool.color }, /* @__PURE__ */ React35.createElement(CardHeader, { glyph: "\u2695", tone: CARD.tool.color, title: "doctor", meta: [summary] }), card.checks.map((c) => /* @__PURE__ */ React35.createElement(Box30, { key: c.label, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React35.createElement(Text29, { color: levelColor[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ React35.createElement(Text29, { bold: true, color: fg.body }, c.label.padEnd(labelWidth + 1)), /* @__PURE__ */ React35.createElement(Text29, { color: fg.sub }, c.detail), /* @__PURE__ */ React35.createElement(Text29, { color: levelColor[c.level] }, LEVEL_TAG[c.level]))));
7991
8038
  }
7992
8039
 
7993
8040
  // src/cli/ui/cards/ErrorCard.tsx
7994
- import { Box as Box30, Text as Text29 } from "ink";
7995
- import React35 from "react";
8041
+ import { Box as Box31, Text as Text30 } from "ink";
8042
+ import React36 from "react";
7996
8043
  var STACK_TAIL = 5;
7997
8044
  function ErrorCard({ card }) {
7998
8045
  const retryNote = card.retries !== void 0 && card.retries > 0 ? `${card.retries} ${t("cardLabels.retries")}` : null;
@@ -8002,7 +8049,7 @@ function ErrorCard({ card }) {
8002
8049
  const stackHidden = stackTrunc ? stackLines.length - stackVisible.length : 0;
8003
8050
  const hasStack = stackVisible.length > 0;
8004
8051
  const messageLines = card.message.split("\n");
8005
- return /* @__PURE__ */ React35.createElement(Card, { tone: TONE.err }, /* @__PURE__ */ React35.createElement(
8052
+ return /* @__PURE__ */ React36.createElement(Card, { tone: TONE.err }, /* @__PURE__ */ React36.createElement(
8006
8053
  CardHeader,
8007
8054
  {
8008
8055
  glyph: "\u2716",
@@ -8010,19 +8057,19 @@ function ErrorCard({ card }) {
8010
8057
  title: card.title || t("cardTitles.error"),
8011
8058
  meta: retryNote ? [retryNote] : void 0
8012
8059
  }
8013
- ), messageLines.map((line, i) => /* @__PURE__ */ React35.createElement(Text29, { key: `${card.id}:msg:${i}`, color: TONE.err }, line || " ")), hasStack ? /* @__PURE__ */ React35.createElement(Box30, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React35.createElement(Text29, { color: FG.meta }, t("cardLabels.stackTrace")), stackHidden > 0 ? /* @__PURE__ */ React35.createElement(Text29, { color: FG.faint }, t(
8060
+ ), messageLines.map((line, i) => /* @__PURE__ */ React36.createElement(Text30, { key: `${card.id}:msg:${i}`, color: TONE.err }, line || " ")), hasStack ? /* @__PURE__ */ React36.createElement(Box31, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React36.createElement(Text30, { color: FG.meta }, t("cardLabels.stackTrace")), stackHidden > 0 ? /* @__PURE__ */ React36.createElement(Text30, { color: FG.faint }, t(
8014
8061
  stackHidden === 1 ? "cardLabels.earlierStackLine" : "cardLabels.earlierStackLines",
8015
8062
  { count: stackHidden }
8016
- )) : null, stackVisible.map((line, i) => /* @__PURE__ */ React35.createElement(Text29, { key: `${card.id}:stk:${stackHidden + i}`, color: FG.meta }, line || " "))) : null);
8063
+ )) : null, stackVisible.map((line, i) => /* @__PURE__ */ React36.createElement(Text30, { key: `${card.id}:stk:${stackHidden + i}`, color: FG.meta }, line || " "))) : null);
8017
8064
  }
8018
8065
 
8019
8066
  // src/cli/ui/cards/LiveCard.tsx
8020
- import { Box as Box31, Text as Text31 } from "ink";
8021
- import React37 from "react";
8067
+ import { Box as Box32, Text as Text32 } from "ink";
8068
+ import React38 from "react";
8022
8069
 
8023
8070
  // src/cli/ui/primitives/Spinner.tsx
8024
- import { Text as Text30 } from "ink";
8025
- import React36 from "react";
8071
+ import { Text as Text31 } from "ink";
8072
+ import React37 from "react";
8026
8073
  var FRAMES = {
8027
8074
  circle: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
8028
8075
  braille: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827"]
@@ -8031,7 +8078,7 @@ function Spinner({ kind = "circle", color, bold }) {
8031
8078
  const frames = FRAMES[kind];
8032
8079
  const tick = useTick();
8033
8080
  const frame = tick % frames.length;
8034
- return /* @__PURE__ */ React36.createElement(Text30, { bold, color }, frames[frame]);
8081
+ return /* @__PURE__ */ React37.createElement(Text31, { bold, color }, frames[frame]);
8035
8082
  }
8036
8083
 
8037
8084
  // src/cli/ui/cards/LiveCard.tsx
@@ -8058,12 +8105,12 @@ var VARIANT_GLYPH = {
8058
8105
  function LiveCard({ card }) {
8059
8106
  const color = TONE_TO_COLOR[card.tone];
8060
8107
  const glyph = VARIANT_GLYPH[card.variant];
8061
- return /* @__PURE__ */ React37.createElement(Box31, { paddingLeft: 2, flexDirection: "row", gap: 1 }, card.variant === "thinking" ? /* @__PURE__ */ React37.createElement(Spinner, { kind: "circle", color, bold: true }) : /* @__PURE__ */ React37.createElement(Text31, { bold: true, color }, glyph), /* @__PURE__ */ React37.createElement(Text31, { color: FG.body }, card.text), card.meta !== void 0 ? /* @__PURE__ */ React37.createElement(Text31, { color: FG.faint }, `\xB7 ${card.meta}`) : null);
8108
+ return /* @__PURE__ */ React38.createElement(Box32, { paddingLeft: 2, flexDirection: "row", gap: 1 }, card.variant === "thinking" ? /* @__PURE__ */ React38.createElement(Spinner, { kind: "circle", color, bold: true }) : /* @__PURE__ */ React38.createElement(Text32, { bold: true, color }, glyph), /* @__PURE__ */ React38.createElement(Text32, { color: FG.body }, card.text), card.meta !== void 0 ? /* @__PURE__ */ React38.createElement(Text32, { color: FG.faint }, `\xB7 ${card.meta}`) : null);
8062
8109
  }
8063
8110
 
8064
8111
  // src/cli/ui/cards/MemoryCard.tsx
8065
- import { Box as Box32, Text as Text32 } from "ink";
8066
- import React38 from "react";
8112
+ import { Box as Box33, Text as Text33 } from "ink";
8113
+ import React39 from "react";
8067
8114
  var CATEGORY_ORDER = [
8068
8115
  "user",
8069
8116
  "feedback",
@@ -8092,7 +8139,7 @@ function MemoryCard({ card }) {
8092
8139
  const counts = countByCategory(card.entries);
8093
8140
  const summary = CATEGORY_ORDER.filter((c) => counts[c] > 0).map((c) => `${counts[c]} ${c}`).join(" \xB7 ");
8094
8141
  const tokens = card.tokens > 1024 ? `~${(card.tokens / 1024).toFixed(1)}K tok` : `~${card.tokens} tok`;
8095
- return /* @__PURE__ */ React38.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React38.createElement(
8142
+ return /* @__PURE__ */ React39.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React39.createElement(
8096
8143
  CardHeader,
8097
8144
  {
8098
8145
  glyph: "\u2311",
@@ -8105,7 +8152,7 @@ function MemoryCard({ card }) {
8105
8152
  const all = card.entries.filter((e) => e.category === category);
8106
8153
  const shown = all.slice(0, 5);
8107
8154
  const remaining = all.length - shown.length;
8108
- return /* @__PURE__ */ React38.createElement(Box32, { key: category, flexDirection: "column" }, /* @__PURE__ */ React38.createElement(Text32, { color: FG.faint }, `${CATEGORY_LABEL[category]} (${counts[category]})`), shown.map((entry) => /* @__PURE__ */ React38.createElement(Box32, { key: `${category}:${entry.summary}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React38.createElement(Text32, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category]), /* @__PURE__ */ React38.createElement(Text32, { color: FG.sub }, entry.summary))), remaining > 0 ? /* @__PURE__ */ React38.createElement(Text32, { color: FG.faint }, `\u22EE +${remaining} more`) : null);
8155
+ return /* @__PURE__ */ React39.createElement(Box33, { key: category, flexDirection: "column" }, /* @__PURE__ */ React39.createElement(Text33, { color: FG.faint }, `${CATEGORY_LABEL[category]} (${counts[category]})`), shown.map((entry) => /* @__PURE__ */ React39.createElement(Box33, { key: `${category}:${entry.summary}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React39.createElement(Text33, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category]), /* @__PURE__ */ React39.createElement(Text33, { color: FG.sub }, entry.summary))), remaining > 0 ? /* @__PURE__ */ React39.createElement(Text33, { color: FG.faint }, `\u22EE +${remaining} more`) : null);
8109
8156
  }));
8110
8157
  }
8111
8158
  function countByCategory(entries) {
@@ -8120,8 +8167,8 @@ function countByCategory(entries) {
8120
8167
  }
8121
8168
 
8122
8169
  // src/cli/ui/cards/PlanCard.tsx
8123
- import { Box as Box33, Text as Text33 } from "ink";
8124
- import React39 from "react";
8170
+ import { Box as Box34, Text as Text34 } from "ink";
8171
+ import React40 from "react";
8125
8172
  var STATUS_GLYPH = {
8126
8173
  queued: "\u25CB",
8127
8174
  running: "\u25B6",
@@ -8147,11 +8194,11 @@ function PlanCard({ card }) {
8147
8194
  const hasRunning = card.steps.some((s) => s.status === "running");
8148
8195
  const cardTone = hasRunning ? toneActive.accent : tone.accent;
8149
8196
  const window = pickWindow(card.steps);
8150
- return /* @__PURE__ */ React39.createElement(Card, { tone: cardTone }, /* @__PURE__ */ React39.createElement(CardHeader, { glyph: "\u229E", tone: cardTone, title: card.title, meta: [progress] }), window.hiddenBefore > 0 ? /* @__PURE__ */ React39.createElement(Box33, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React39.createElement(Text33, { color: tone.ok }, "\u2713"), /* @__PURE__ */ React39.createElement(Text33, { color: fg.faint }, `\u22EF ${window.hiddenBefore} done`)) : null, window.steps.map((step) => {
8197
+ return /* @__PURE__ */ React40.createElement(Card, { tone: cardTone }, /* @__PURE__ */ React40.createElement(CardHeader, { glyph: "\u229E", tone: cardTone, title: card.title, meta: [progress] }), window.hiddenBefore > 0 ? /* @__PURE__ */ React40.createElement(Box34, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text34, { color: tone.ok }, "\u2713"), /* @__PURE__ */ React40.createElement(Text34, { color: fg.faint }, `\u22EF ${window.hiddenBefore} done`)) : null, window.steps.map((step) => {
8151
8198
  const isActive = step.status === "running";
8152
8199
  const titleColor = isActive ? fg.strong : fg.sub;
8153
- return /* @__PURE__ */ React39.createElement(Box33, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React39.createElement(Text33, { color: statusColor[step.status] }, STATUS_GLYPH[step.status]), /* @__PURE__ */ React39.createElement(Text33, { bold: isActive, color: titleColor }, `${step.indexLabel}. ${step.title}`), isActive ? /* @__PURE__ */ React39.createElement(Text33, { color: toneActive.brand }, "\u2190 in progress") : null);
8154
- }), window.hiddenAfter > 0 ? /* @__PURE__ */ React39.createElement(Box33, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React39.createElement(Text33, { color: fg.faint }, "\u25CB"), /* @__PURE__ */ React39.createElement(Text33, { color: fg.faint }, `\u22EF ${window.hiddenAfter} upcoming`)) : null);
8200
+ return /* @__PURE__ */ React40.createElement(Box34, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text34, { color: statusColor[step.status] }, STATUS_GLYPH[step.status]), /* @__PURE__ */ React40.createElement(Text34, { bold: isActive, color: titleColor }, `${step.indexLabel}. ${step.title}`), isActive ? /* @__PURE__ */ React40.createElement(Text34, { color: toneActive.brand }, "\u2190 in progress") : null);
8201
+ }), window.hiddenAfter > 0 ? /* @__PURE__ */ React40.createElement(Box34, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text34, { color: fg.faint }, "\u25CB"), /* @__PURE__ */ React40.createElement(Text34, { color: fg.faint }, `\u22EF ${window.hiddenAfter} upcoming`)) : null);
8155
8202
  }
8156
8203
  function pickWindow(steps) {
8157
8204
  if (steps.length <= VISIBLE_WINDOW) {
@@ -8179,8 +8226,8 @@ function anchorIndex(steps) {
8179
8226
  }
8180
8227
 
8181
8228
  // src/cli/ui/cards/ReasoningCard.tsx
8182
- import { Box as Box34, Text as Text35, useStdout as useStdout9 } from "ink";
8183
- import React41 from "react";
8229
+ import { Box as Box35, Text as Text36, useStdout as useStdout9 } from "ink";
8230
+ import React42 from "react";
8184
8231
 
8185
8232
  // src/frame/width.ts
8186
8233
  import stringWidthLib from "string-width";
@@ -8231,12 +8278,12 @@ function wrapToCells(s, maxCells) {
8231
8278
  }
8232
8279
 
8233
8280
  // src/cli/ui/primitives/CursorBlock.tsx
8234
- import { Text as Text34 } from "ink";
8235
- import React40 from "react";
8281
+ import { Text as Text35 } from "ink";
8282
+ import React41 from "react";
8236
8283
  function CursorBlock() {
8237
8284
  const tick = useTick();
8238
8285
  const on = Math.floor(tick / 4) % 2 === 0;
8239
- return /* @__PURE__ */ React40.createElement(Text34, { inverse: on, color: CARD.streaming.color }, " ");
8286
+ return /* @__PURE__ */ React41.createElement(Text35, { inverse: on, color: CARD.streaming.color }, " ");
8240
8287
  }
8241
8288
 
8242
8289
  // src/cli/ui/cards/ReasoningCard.tsx
@@ -8252,7 +8299,7 @@ function ReasoningCard({
8252
8299
  const allLines = card.text.length > 0 ? card.text.split("\n") : [];
8253
8300
  const showBody = expanded && (allLines.length > 0 || card.streaming);
8254
8301
  const tone = card.aborted ? TONE.err : card.streaming ? TONE_ACTIVE.accent : TONE.accent;
8255
- return /* @__PURE__ */ React41.createElement(Card, { tone }, /* @__PURE__ */ React41.createElement(ReasoningHeader, { card }), showBody && (card.streaming ? /* @__PURE__ */ React41.createElement(StreamingPreview, { card, allLines, lineCells }) : /* @__PURE__ */ React41.createElement(SettledPreview, { card, allLines, lineCells })));
8302
+ return /* @__PURE__ */ React42.createElement(Card, { tone }, /* @__PURE__ */ React42.createElement(ReasoningHeader, { card }), showBody && (card.streaming ? /* @__PURE__ */ React42.createElement(StreamingPreview, { card, allLines, lineCells }) : /* @__PURE__ */ React42.createElement(SettledPreview, { card, allLines, lineCells })));
8256
8303
  }
8257
8304
  function ReasoningHeader({ card }) {
8258
8305
  const streamingActive = card.streaming && !card.aborted;
@@ -8265,7 +8312,7 @@ function ReasoningHeader({ card }) {
8265
8312
  const duration = headerDuration(card);
8266
8313
  if (duration) meta.push(duration);
8267
8314
  const modelBadge = card.model ? modelBadgeFor(card.model) : null;
8268
- return /* @__PURE__ */ React41.createElement(
8315
+ return /* @__PURE__ */ React42.createElement(
8269
8316
  CardHeader,
8270
8317
  {
8271
8318
  glyph,
@@ -8274,7 +8321,7 @@ function ReasoningHeader({ card }) {
8274
8321
  titleColor: PILL_SECTION.reason.fg,
8275
8322
  titleBg: PILL_SECTION.reason.bg,
8276
8323
  meta: meta.length > 0 ? meta : void 0,
8277
- right: /* @__PURE__ */ React41.createElement(React41.Fragment, null, streamingActive ? /* @__PURE__ */ React41.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.accent }) : null, modelBadge ? /* @__PURE__ */ React41.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null)
8324
+ right: /* @__PURE__ */ React42.createElement(React42.Fragment, null, streamingActive ? /* @__PURE__ */ React42.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.accent }) : null, modelBadge ? /* @__PURE__ */ React42.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null)
8278
8325
  }
8279
8326
  );
8280
8327
  }
@@ -8295,13 +8342,13 @@ function headerDuration(card) {
8295
8342
  function StreamingPreview({ card, allLines, lineCells }) {
8296
8343
  const visualLines = allLines.flatMap((l) => wrapToCells(l, lineCells));
8297
8344
  const visible = visualLines.slice(-STREAMING_PREVIEW_LINES);
8298
- return /* @__PURE__ */ React41.createElement(BodyLines, { card, lines: visible, lineCells, cursorOnLast: true });
8345
+ return /* @__PURE__ */ React42.createElement(BodyLines, { card, lines: visible, lineCells, cursorOnLast: true });
8299
8346
  }
8300
8347
  function SettledPreview({ card, allLines, lineCells }) {
8301
8348
  const visualLines = allLines.flatMap((l) => wrapToCells(l, lineCells));
8302
8349
  const visible = visualLines.slice(-SETTLED_TAIL_LINES);
8303
8350
  const droppedLines = Math.max(0, visualLines.length - visible.length);
8304
- return /* @__PURE__ */ React41.createElement(React41.Fragment, null, droppedLines > 0 ? /* @__PURE__ */ React41.createElement(ElisionHint, { droppedLines, card }) : null, /* @__PURE__ */ React41.createElement(BodyLines, { card, lines: visible, lineCells, indexOffset: droppedLines }));
8351
+ return /* @__PURE__ */ React42.createElement(React42.Fragment, null, droppedLines > 0 ? /* @__PURE__ */ React42.createElement(ElisionHint, { droppedLines, card }) : null, /* @__PURE__ */ React42.createElement(BodyLines, { card, lines: visible, lineCells, indexOffset: droppedLines }));
8305
8352
  }
8306
8353
  function BodyLines({
8307
8354
  card,
@@ -8310,9 +8357,9 @@ function BodyLines({
8310
8357
  cursorOnLast = false,
8311
8358
  indexOffset = 0
8312
8359
  }) {
8313
- return /* @__PURE__ */ React41.createElement(React41.Fragment, null, lines.map((line, i) => {
8360
+ return /* @__PURE__ */ React42.createElement(React42.Fragment, null, lines.map((line, i) => {
8314
8361
  const isLast = i === lines.length - 1;
8315
- return /* @__PURE__ */ React41.createElement(Box34, { key: `${card.id}:b:${indexOffset + i}`, flexDirection: "row" }, /* @__PURE__ */ React41.createElement(Text35, { italic: true, color: FG.meta }, clipToCells(line, lineCells)), isLast && cursorOnLast && /* @__PURE__ */ React41.createElement(CursorBlock, null));
8362
+ return /* @__PURE__ */ React42.createElement(Box35, { key: `${card.id}:b:${indexOffset + i}`, flexDirection: "row" }, /* @__PURE__ */ React42.createElement(Text36, { italic: true, color: FG.meta }, clipToCells(line, lineCells)), isLast && cursorOnLast && /* @__PURE__ */ React42.createElement(CursorBlock, null));
8316
8363
  }));
8317
8364
  }
8318
8365
  function ElisionHint({
@@ -8326,12 +8373,12 @@ function ElisionHint({
8326
8373
  parts.push(`${droppedLines} line${droppedLines === 1 ? "" : "s"}`);
8327
8374
  }
8328
8375
  if (card.tokens > 0) parts.push(`${card.tokens.toLocaleString()} tok`);
8329
- return /* @__PURE__ */ React41.createElement(Text35, { color: FG.faint }, `\u22EF ${parts.join(" \xB7 ")} above \xB7 /reasoning last`);
8376
+ return /* @__PURE__ */ React42.createElement(Text36, { color: FG.faint }, `\u22EF ${parts.join(" \xB7 ")} above \xB7 /reasoning last`);
8330
8377
  }
8331
8378
 
8332
8379
  // src/cli/ui/cards/SearchCard.tsx
8333
- import { Box as Box35, Text as Text36 } from "ink";
8334
- import React42 from "react";
8380
+ import { Box as Box36, Text as Text37 } from "ink";
8381
+ import React43 from "react";
8335
8382
  function SearchCard({ card }) {
8336
8383
  const fileCount = new Set(card.hits.map((h) => h.file)).size;
8337
8384
  const elapsed = `${(card.elapsedMs / 1e3).toFixed(2)}s`;
@@ -8340,7 +8387,7 @@ function SearchCard({ card }) {
8340
8387
  files: fileCount
8341
8388
  });
8342
8389
  const grouped = groupByFile(card.hits.slice(0, 10));
8343
- return /* @__PURE__ */ React42.createElement(Card, { tone: TONE.info }, /* @__PURE__ */ React42.createElement(
8390
+ return /* @__PURE__ */ React43.createElement(Card, { tone: TONE.info }, /* @__PURE__ */ React43.createElement(
8344
8391
  CardHeader,
8345
8392
  {
8346
8393
  glyph: "\u2299",
@@ -8349,7 +8396,7 @@ function SearchCard({ card }) {
8349
8396
  subtitle: `"${card.query}"`,
8350
8397
  meta: [stats2, elapsed]
8351
8398
  }
8352
- ), grouped.map(([file, hits]) => /* @__PURE__ */ React42.createElement(Box35, { key: file, flexDirection: "column" }, /* @__PURE__ */ React42.createElement(Text36, { bold: true, color: FG.strong }, file), hits.map((h, i) => /* @__PURE__ */ React42.createElement(Box35, { key: `${file}:${h.line}:${i}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React42.createElement(Text36, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502`), /* @__PURE__ */ React42.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 ? /* @__PURE__ */ React42.createElement(Text36, { color: FG.faint }, t(
8399
+ ), grouped.map(([file, hits]) => /* @__PURE__ */ React43.createElement(Box36, { key: file, flexDirection: "column" }, /* @__PURE__ */ React43.createElement(Text37, { bold: true, color: FG.strong }, file), hits.map((h, i) => /* @__PURE__ */ React43.createElement(Box36, { key: `${file}:${h.line}:${i}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React43.createElement(Text37, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502`), /* @__PURE__ */ React43.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 ? /* @__PURE__ */ React43.createElement(Text37, { color: FG.faint }, t(
8353
8400
  card.hits.length - 10 === 1 ? "cardLabels.moreHitSingular" : "cardLabels.moreHitsPlural",
8354
8401
  { count: card.hits.length - 10 }
8355
8402
  )) : null);
@@ -8360,9 +8407,9 @@ function HighlightedLine({
8360
8407
  end
8361
8408
  }) {
8362
8409
  if (start < 0 || end <= start || end > text.length) {
8363
- return /* @__PURE__ */ React42.createElement(Text36, { color: FG.sub }, text);
8410
+ return /* @__PURE__ */ React43.createElement(Text37, { color: FG.sub }, text);
8364
8411
  }
8365
- return /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(Text36, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ React42.createElement(Text36, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ React42.createElement(Text36, { color: FG.sub }, text.slice(end)));
8412
+ return /* @__PURE__ */ React43.createElement(React43.Fragment, null, /* @__PURE__ */ React43.createElement(Text37, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ React43.createElement(Text37, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ React43.createElement(Text37, { color: FG.sub }, text.slice(end)));
8366
8413
  }
8367
8414
  function groupByFile(hits) {
8368
8415
  const map = /* @__PURE__ */ new Map();
@@ -8375,8 +8422,8 @@ function groupByFile(hits) {
8375
8422
  }
8376
8423
 
8377
8424
  // src/cli/ui/cards/StreamingCard.tsx
8378
- import { Box as Box37, Text as Text38, useStdout as useStdout11 } from "ink";
8379
- import React44, { useContext as useContext5 } from "react";
8425
+ import { Box as Box38, Text as Text39, useStdout as useStdout11 } from "ink";
8426
+ import React45, { useContext as useContext5 } from "react";
8380
8427
 
8381
8428
  // src/cli/ui/layout/LiveExpandContext.ts
8382
8429
  import { createContext as createContext3 } from "react";
@@ -8384,54 +8431,54 @@ var LiveExpandContext = createContext3(false);
8384
8431
 
8385
8432
  // src/cli/ui/markdown.tsx
8386
8433
  import { highlight, supportsLanguage } from "cli-highlight";
8387
- import { Box as Box36, Text as Text37, useStdout as useStdout10 } from "ink";
8388
- import React43 from "react";
8434
+ import { Box as Box37, Text as Text38, useStdout as useStdout10 } from "ink";
8435
+ import React44 from "react";
8389
8436
  import stringWidth from "string-width";
8390
8437
  var BODY_LEFT_CELLS = 7;
8391
- var MarkdownWidthCtx = React43.createContext(void 0);
8438
+ var MarkdownWidthCtx = React44.createContext(void 0);
8392
8439
  function useWidth() {
8393
- const ctx = React43.useContext(MarkdownWidthCtx);
8440
+ const ctx = React44.useContext(MarkdownWidthCtx);
8394
8441
  if (ctx !== void 0) return ctx;
8395
8442
  return (useStdout10()?.stdout?.columns ?? process.stdout.columns ?? 80) - BODY_LEFT_CELLS;
8396
8443
  }
8397
8444
  marked.setOptions({ gfm: true, breaks: false });
8398
8445
  function Markdown({ text, width }) {
8399
- const tokens = React43.useMemo(() => marked.lexer(text), [text]);
8446
+ const tokens = React44.useMemo(() => marked.lexer(text), [text]);
8400
8447
  const ctxWidth = width !== void 0 ? Math.max(1, width) : void 0;
8401
- return /* @__PURE__ */ React43.createElement(MarkdownWidthCtx.Provider, { value: ctxWidth }, /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ React43.createElement(BlockToken, { key: `${i}-${token.type}`, token }))));
8448
+ return /* @__PURE__ */ React44.createElement(MarkdownWidthCtx.Provider, { value: ctxWidth }, /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ React44.createElement(BlockToken, { key: `${i}-${token.type}`, token }))));
8402
8449
  }
8403
8450
  function BlockToken({ token }) {
8404
8451
  switch (token.type) {
8405
8452
  case "heading":
8406
- return /* @__PURE__ */ React43.createElement(Heading, { token });
8453
+ return /* @__PURE__ */ React44.createElement(Heading, { token });
8407
8454
  case "paragraph":
8408
- return /* @__PURE__ */ React43.createElement(Paragraph, { token });
8455
+ return /* @__PURE__ */ React44.createElement(Paragraph, { token });
8409
8456
  case "list":
8410
- return /* @__PURE__ */ React43.createElement(List, { token, depth: 0 });
8457
+ return /* @__PURE__ */ React44.createElement(List, { token, depth: 0 });
8411
8458
  case "code":
8412
- return /* @__PURE__ */ React43.createElement(CodeBlock2, { token });
8459
+ return /* @__PURE__ */ React44.createElement(CodeBlock2, { token });
8413
8460
  case "blockquote":
8414
- return /* @__PURE__ */ React43.createElement(Blockquote, { token });
8461
+ return /* @__PURE__ */ React44.createElement(Blockquote, { token });
8415
8462
  case "hr":
8416
- return /* @__PURE__ */ React43.createElement(HorizontalRule, null);
8463
+ return /* @__PURE__ */ React44.createElement(HorizontalRule, null);
8417
8464
  case "table":
8418
- return /* @__PURE__ */ React43.createElement(Table, { token });
8465
+ return /* @__PURE__ */ React44.createElement(Table, { token });
8419
8466
  case "html":
8420
- return /* @__PURE__ */ React43.createElement(Text37, { color: FG.body }, token.text);
8467
+ return /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, token.text);
8421
8468
  case "space":
8422
8469
  return null;
8423
8470
  default:
8424
- return /* @__PURE__ */ React43.createElement(Text37, { color: FG.body }, token.raw ?? "");
8471
+ return /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, token.raw ?? "");
8425
8472
  }
8426
8473
  }
8427
8474
  function Heading({ token }) {
8428
- return /* @__PURE__ */ React43.createElement(Box36, null, /* @__PURE__ */ React43.createElement(Text37, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
8475
+ return /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
8429
8476
  }
8430
8477
  function Paragraph({ token }) {
8431
- return /* @__PURE__ */ React43.createElement(Text37, { color: FG.body }, /* @__PURE__ */ React43.createElement(Inline, { tokens: token.tokens ?? [] }));
8478
+ return /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens ?? [] }));
8432
8479
  }
8433
8480
  function List({ token, depth }) {
8434
- return /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ React43.createElement(
8481
+ return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ React44.createElement(
8435
8482
  ListItem,
8436
8483
  {
8437
8484
  key: `${i}-${item.text.slice(0, 24)}`,
@@ -8452,27 +8499,27 @@ function ListItem({
8452
8499
  const markerColor = item.task ? item.checked ? TONE.ok : FG.faint : FG.meta;
8453
8500
  const dim = item.task && item.checked === true;
8454
8501
  const indent = " ".repeat(depth + 1);
8455
- return /* @__PURE__ */ React43.createElement(Box36, null, /* @__PURE__ */ React43.createElement(Text37, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, item.tokens.map((tok, i) => {
8502
+ return /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, item.tokens.map((tok, i) => {
8456
8503
  if (tok.type === "text") {
8457
8504
  const inner = tok.tokens;
8458
8505
  return (
8459
8506
  // biome-ignore lint/suspicious/noArrayIndexKey: list-item children are positional and stable per render
8460
- /* @__PURE__ */ React43.createElement(Text37, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ React43.createElement(Inline, { tokens: inner }) : tok.text)
8507
+ /* @__PURE__ */ React44.createElement(Text38, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ React44.createElement(Inline, { tokens: inner }) : tok.text)
8461
8508
  );
8462
8509
  }
8463
8510
  if (tok.type === "list") {
8464
- return /* @__PURE__ */ React43.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
8511
+ return /* @__PURE__ */ React44.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
8465
8512
  }
8466
- return /* @__PURE__ */ React43.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
8513
+ return /* @__PURE__ */ React44.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
8467
8514
  })));
8468
8515
  }
8469
8516
  function CodeBlock2({ token }) {
8470
8517
  const lang = token.lang?.split(/\s+/)[0] ?? "";
8471
8518
  const colored = highlightCode(token.text, lang);
8472
8519
  const lines = colored.split("\n");
8473
- return /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, lang ? /* @__PURE__ */ React43.createElement(Box36, null, /* @__PURE__ */ React43.createElement(Text37, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, lines.map((line, i) => (
8520
+ return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, lang ? /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, lines.map((line, i) => (
8474
8521
  // biome-ignore lint/suspicious/noArrayIndexKey: code lines are positional and stable per render
8475
- /* @__PURE__ */ React43.createElement(Text37, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
8522
+ /* @__PURE__ */ React44.createElement(Text38, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
8476
8523
  ))));
8477
8524
  }
8478
8525
  function highlightCode(source, lang) {
@@ -8485,7 +8532,7 @@ function highlightCode(source, lang) {
8485
8532
  }
8486
8533
  }
8487
8534
  function Blockquote({ token }) {
8488
- return /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ React43.createElement(Box36, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ React43.createElement(Text37, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ React43.createElement(Text37, { italic: true, color: FG.sub }, /* @__PURE__ */ React43.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ React43.createElement(BlockToken, { token: child })))));
8535
+ return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ React44.createElement(Box37, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ React44.createElement(Text38, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ React44.createElement(Text38, { italic: true, color: FG.sub }, /* @__PURE__ */ React44.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ React44.createElement(BlockToken, { token: child })))));
8489
8536
  }
8490
8537
  function padToCells(text, cells) {
8491
8538
  const w = stringWidth(text);
@@ -8495,7 +8542,7 @@ function padToCells(text, cells) {
8495
8542
  function HorizontalRule() {
8496
8543
  const width = useWidth();
8497
8544
  const rule = "\u2500".repeat(Math.max(width, 1));
8498
- return /* @__PURE__ */ React43.createElement(Text37, { color: FG.faint }, ` ${rule}`);
8545
+ return /* @__PURE__ */ React44.createElement(Text38, { color: FG.faint }, ` ${rule}`);
8499
8546
  }
8500
8547
  function tableLayout(headerCells, bodyCells, availableWidth) {
8501
8548
  const colCount = headerCells.length;
@@ -8523,7 +8570,7 @@ function Table({ token }) {
8523
8570
  const bodyCells = token.rows.map((row2) => row2.map((c) => plainText(c.tokens)));
8524
8571
  const layout = tableLayout(headerCells, bodyCells, width);
8525
8572
  if (!layout.fallback)
8526
- return /* @__PURE__ */ React43.createElement(
8573
+ return /* @__PURE__ */ React44.createElement(
8527
8574
  ColumnarTable,
8528
8575
  {
8529
8576
  headerCells,
@@ -8533,7 +8580,7 @@ function Table({ token }) {
8533
8580
  gap: layout.gap
8534
8581
  }
8535
8582
  );
8536
- return /* @__PURE__ */ React43.createElement(
8583
+ return /* @__PURE__ */ React44.createElement(
8537
8584
  FallbackTable,
8538
8585
  {
8539
8586
  headerCells,
@@ -8551,14 +8598,14 @@ function ColumnarTable({
8551
8598
  gap
8552
8599
  }) {
8553
8600
  const ruleRow = widths.map((w) => "\u2500".repeat(w)).join(gap);
8554
- return /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, /* @__PURE__ */ React43.createElement(Box36, null, /* @__PURE__ */ React43.createElement(Text37, null, " "), headerCells.map((cell, i) => (
8601
+ return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, null, " "), headerCells.map((cell, i) => (
8555
8602
  // biome-ignore lint/suspicious/noArrayIndexKey: header cells positional
8556
- /* @__PURE__ */ React43.createElement(React43.Fragment, { key: `h-${i}` }, /* @__PURE__ */ React43.createElement(Text37, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ React43.createElement(Text37, null, gap) : null)
8557
- ))), /* @__PURE__ */ React43.createElement(Box36, null, /* @__PURE__ */ React43.createElement(Text37, null, " "), /* @__PURE__ */ React43.createElement(Text37, { color: FG.faint }, ruleRow)), bodyCells.map((row2, ri) => (
8603
+ /* @__PURE__ */ React44.createElement(React44.Fragment, { key: `h-${i}` }, /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ React44.createElement(Text38, null, gap) : null)
8604
+ ))), /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, null, " "), /* @__PURE__ */ React44.createElement(Text38, { color: FG.faint }, ruleRow)), bodyCells.map((row2, ri) => (
8558
8605
  // biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
8559
- /* @__PURE__ */ React43.createElement(Box36, { key: `tr-${ri}` }, /* @__PURE__ */ React43.createElement(Text37, null, " "), row2.map((cell, i) => (
8606
+ /* @__PURE__ */ React44.createElement(Box37, { key: `tr-${ri}` }, /* @__PURE__ */ React44.createElement(Text38, null, " "), row2.map((cell, i) => (
8560
8607
  // biome-ignore lint/suspicious/noArrayIndexKey: cells positional
8561
- /* @__PURE__ */ React43.createElement(React43.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ React43.createElement(Text37, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ React43.createElement(Text37, null, gap) : null)
8608
+ /* @__PURE__ */ React44.createElement(React44.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ React44.createElement(Text38, null, gap) : null)
8562
8609
  )))
8563
8610
  )));
8564
8611
  }
@@ -8568,20 +8615,20 @@ function FallbackTable({
8568
8615
  labelPad,
8569
8616
  valueCells
8570
8617
  }) {
8571
- return /* @__PURE__ */ React43.createElement(Box36, { flexDirection: "column" }, bodyCells.map((row2, ri) => (
8618
+ return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, bodyCells.map((row2, ri) => (
8572
8619
  // biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
8573
- /* @__PURE__ */ React43.createElement(Box36, { key: `fr-${ri}`, flexDirection: "column" }, ri > 0 ? /* @__PURE__ */ React43.createElement(Text37, null, " ") : null, headerCells.map((h, ci) => {
8620
+ /* @__PURE__ */ React44.createElement(Box37, { key: `fr-${ri}`, flexDirection: "column" }, ri > 0 ? /* @__PURE__ */ React44.createElement(Text38, null, " ") : null, headerCells.map((h, ci) => {
8574
8621
  const label = `${padToCells(h, labelPad - 2)}: `;
8575
8622
  const lines = wrapToCells(row2[ci] ?? "", valueCells);
8576
8623
  return lines.map((line, li) => (
8577
8624
  // biome-ignore lint/suspicious/noArrayIndexKey: fallback table lines are positional
8578
- /* @__PURE__ */ React43.createElement(Box36, { key: `fc-${ri}-${ci}-${li}` }, li === 0 ? /* @__PURE__ */ React43.createElement(Text37, { bold: true, color: FG.sub }, label) : /* @__PURE__ */ React43.createElement(Text37, null, padToCells("", labelPad)), /* @__PURE__ */ React43.createElement(Text37, { color: FG.body }, line))
8625
+ /* @__PURE__ */ React44.createElement(Box37, { key: `fc-${ri}-${ci}-${li}` }, li === 0 ? /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.sub }, label) : /* @__PURE__ */ React44.createElement(Text38, null, padToCells("", labelPad)), /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, line))
8579
8626
  ));
8580
8627
  }))
8581
8628
  )));
8582
8629
  }
8583
8630
  function Inline({ tokens }) {
8584
- return /* @__PURE__ */ React43.createElement(React43.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ React43.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
8631
+ return /* @__PURE__ */ React44.createElement(React44.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ React44.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
8585
8632
  }
8586
8633
  var FILE_REF_RE2 = /\b([A-Za-z0-9_./@\-]+\.[A-Za-z0-9]{1,6})(?::(\d+)(?:-(\d+))?)?\b/g;
8587
8634
  var MENTION_RE = /(?<![A-Za-z0-9_])@([A-Za-z0-9_./\-]+\.[A-Za-z0-9]{1,6})/g;
@@ -8592,10 +8639,10 @@ function looksLikeFileRef(path, hasLine) {
8592
8639
  return ext.length >= 2;
8593
8640
  }
8594
8641
  function osc8(label, _target, color) {
8595
- return /* @__PURE__ */ React43.createElement(Text37, { color, underline: true }, label);
8642
+ return /* @__PURE__ */ React44.createElement(Text38, { color, underline: true }, label);
8596
8643
  }
8597
8644
  function renderInlineText(raw) {
8598
- if (!raw) return /* @__PURE__ */ React43.createElement(Text37, null, raw);
8645
+ if (!raw) return /* @__PURE__ */ React44.createElement(Text38, null, raw);
8599
8646
  const out = [];
8600
8647
  let cursor = 0;
8601
8648
  const hits = [];
@@ -8606,7 +8653,7 @@ function renderInlineText(raw) {
8606
8653
  hits.push({
8607
8654
  start,
8608
8655
  end,
8609
- node: /* @__PURE__ */ React43.createElement(Text37, { color: TONE.warn, underline: true }, `@${path}`)
8656
+ node: /* @__PURE__ */ React44.createElement(Text38, { color: TONE.warn, underline: true }, `@${path}`)
8610
8657
  });
8611
8658
  }
8612
8659
  for (const m of raw.matchAll(FILE_REF_RE2)) {
@@ -8623,44 +8670,44 @@ function renderInlineText(raw) {
8623
8670
  let key = 0;
8624
8671
  for (const h of hits) {
8625
8672
  if (h.start > cursor) {
8626
- out.push(/* @__PURE__ */ React43.createElement(Text37, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
8673
+ out.push(/* @__PURE__ */ React44.createElement(Text38, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
8627
8674
  }
8628
- out.push(/* @__PURE__ */ React43.createElement(React43.Fragment, { key: `r-${key++}` }, h.node));
8675
+ out.push(/* @__PURE__ */ React44.createElement(React44.Fragment, { key: `r-${key++}` }, h.node));
8629
8676
  cursor = h.end;
8630
8677
  }
8631
- if (cursor < raw.length) out.push(/* @__PURE__ */ React43.createElement(Text37, { key: `t-${key++}` }, raw.slice(cursor)));
8632
- return /* @__PURE__ */ React43.createElement(React43.Fragment, null, out);
8678
+ if (cursor < raw.length) out.push(/* @__PURE__ */ React44.createElement(Text38, { key: `t-${key++}` }, raw.slice(cursor)));
8679
+ return /* @__PURE__ */ React44.createElement(React44.Fragment, null, out);
8633
8680
  }
8634
8681
  function InlineToken({ token }) {
8635
8682
  switch (token.type) {
8636
8683
  case "text": {
8637
8684
  const t2 = token;
8638
- return t2.tokens ? /* @__PURE__ */ React43.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
8685
+ return t2.tokens ? /* @__PURE__ */ React44.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
8639
8686
  }
8640
8687
  case "strong":
8641
- return /* @__PURE__ */ React43.createElement(Text37, { bold: true, color: FG.strong }, /* @__PURE__ */ React43.createElement(Inline, { tokens: token.tokens }));
8688
+ return /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.strong }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens }));
8642
8689
  case "em":
8643
- return /* @__PURE__ */ React43.createElement(Text37, { italic: true }, /* @__PURE__ */ React43.createElement(Inline, { tokens: token.tokens }));
8690
+ return /* @__PURE__ */ React44.createElement(Text38, { italic: true }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens }));
8644
8691
  case "codespan":
8645
- return /* @__PURE__ */ React43.createElement(Text37, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${token.text} `);
8692
+ return /* @__PURE__ */ React44.createElement(Text38, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${token.text} `);
8646
8693
  case "del":
8647
- return /* @__PURE__ */ React43.createElement(Text37, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ React43.createElement(Inline, { tokens: token.tokens }));
8694
+ return /* @__PURE__ */ React44.createElement(Text38, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens }));
8648
8695
  case "link": {
8649
8696
  const l = token;
8650
- return /* @__PURE__ */ React43.createElement(Text37, { color: TONE.brand, underline: true }, /* @__PURE__ */ React43.createElement(Inline, { tokens: l.tokens }));
8697
+ return /* @__PURE__ */ React44.createElement(Text38, { color: TONE.brand, underline: true }, /* @__PURE__ */ React44.createElement(Inline, { tokens: l.tokens }));
8651
8698
  }
8652
8699
  case "image": {
8653
8700
  const im = token;
8654
- return /* @__PURE__ */ React43.createElement(Text37, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
8701
+ return /* @__PURE__ */ React44.createElement(Text38, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
8655
8702
  }
8656
8703
  case "br":
8657
- return /* @__PURE__ */ React43.createElement(Text37, null, "\n");
8704
+ return /* @__PURE__ */ React44.createElement(Text38, null, "\n");
8658
8705
  case "escape":
8659
- return /* @__PURE__ */ React43.createElement(Text37, null, token.text);
8706
+ return /* @__PURE__ */ React44.createElement(Text38, null, token.text);
8660
8707
  case "html":
8661
- return /* @__PURE__ */ React43.createElement(Text37, null, token.text);
8708
+ return /* @__PURE__ */ React44.createElement(Text38, null, token.text);
8662
8709
  default:
8663
- return /* @__PURE__ */ React43.createElement(Text37, null, token.raw ?? "");
8710
+ return /* @__PURE__ */ React44.createElement(Text38, null, token.raw ?? "");
8664
8711
  }
8665
8712
  }
8666
8713
  function plainText(tokens) {
@@ -8723,19 +8770,19 @@ function StreamingCard({ card }) {
8723
8770
  });
8724
8771
  useSlowTick();
8725
8772
  const modelBadge = card.model ? modelBadgeFor(card.model) : null;
8726
- const modelPill = modelBadge ? /* @__PURE__ */ React44.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null;
8773
+ const modelPill = modelBadge ? /* @__PURE__ */ React45.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null;
8727
8774
  if (card.done && !card.aborted) {
8728
8775
  const { tokens, tps } = tokenRate(card.text, card.ts, card.endedAt ?? Date.now());
8729
- const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */ React44.createElement(Pill, { label: `${formatTokenCount(tokens)} tok \xB7 ${tps} t/s`, ...PILL_RATE, bold: false }) : null;
8730
- return /* @__PURE__ */ React44.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React44.createElement(
8776
+ const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */ React45.createElement(Pill, { label: `${formatTokenCount(tokens)} tok \xB7 ${tps} t/s`, ...PILL_RATE, bold: false }) : null;
8777
+ return /* @__PURE__ */ React45.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React45.createElement(
8731
8778
  CardHeader,
8732
8779
  {
8733
8780
  glyph: "\u2039",
8734
8781
  tone: TONE.ok,
8735
8782
  title: t("cardTitles.reply"),
8736
- right: /* @__PURE__ */ React44.createElement(React44.Fragment, null, ratePill, modelPill)
8783
+ right: /* @__PURE__ */ React45.createElement(React45.Fragment, null, ratePill, modelPill)
8737
8784
  }
8738
- ), /* @__PURE__ */ React44.createElement(Markdown, { text: card.text }));
8785
+ ), /* @__PURE__ */ React45.createElement(Markdown, { text: card.text }));
8739
8786
  }
8740
8787
  const lineCells = Math.max(20, cols - 4);
8741
8788
  const allLines = card.text.length > 0 ? card.text.split("\n") : [""];
@@ -8748,24 +8795,24 @@ function StreamingCard({ card }) {
8748
8795
  const glyph = aborted ? "\u2039" : "\u25C8";
8749
8796
  const headLabel = aborted ? t("cardLabels.aborted") : t("cardLabels.writing");
8750
8797
  const { tokens: liveTokens, tps: liveTps } = tokenRate(card.text, card.ts, Date.now());
8751
- const liveRatePill = !aborted && liveTokens >= MIN_TOKENS_FOR_RATE && liveTps !== null ? /* @__PURE__ */ React44.createElement(Pill, { label: `${liveTps} t/s`, ...PILL_RATE, bold: false }) : null;
8752
- const expandPill = !aborted ? /* @__PURE__ */ React44.createElement(Pill, { label: expanded ? "expanded \u2303o" : "preview \u2303o", ...PILL_RATE, bold: false }) : null;
8753
- return /* @__PURE__ */ React44.createElement(Card, { tone: headColor }, /* @__PURE__ */ React44.createElement(
8798
+ const liveRatePill = !aborted && liveTokens >= MIN_TOKENS_FOR_RATE && liveTps !== null ? /* @__PURE__ */ React45.createElement(Pill, { label: `${liveTps} t/s`, ...PILL_RATE, bold: false }) : null;
8799
+ const expandPill = !aborted ? /* @__PURE__ */ React45.createElement(Pill, { label: expanded ? "expanded \u2303o" : "preview \u2303o", ...PILL_RATE, bold: false }) : null;
8800
+ return /* @__PURE__ */ React45.createElement(Card, { tone: headColor }, /* @__PURE__ */ React45.createElement(
8754
8801
  CardHeader,
8755
8802
  {
8756
8803
  glyph,
8757
8804
  tone: headColor,
8758
8805
  title: headLabel,
8759
- right: /* @__PURE__ */ React44.createElement(React44.Fragment, null, liveRatePill, expandPill, aborted ? null : /* @__PURE__ */ React44.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand }), modelPill)
8806
+ right: /* @__PURE__ */ React45.createElement(React45.Fragment, null, liveRatePill, expandPill, aborted ? null : /* @__PURE__ */ React45.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand }), modelPill)
8760
8807
  }
8761
- ), expanded && droppedAbove > 0 ? /* @__PURE__ */ React44.createElement(Text38, { color: FG.faint }, t(droppedAbove === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
8808
+ ), expanded && droppedAbove > 0 ? /* @__PURE__ */ React45.createElement(Text39, { color: FG.faint }, t(droppedAbove === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
8762
8809
  count: droppedAbove
8763
- })) : null, visible.map((line, i) => /* @__PURE__ */ React44.createElement(Box37, { key: `${card.id}:${visualLines.length - visible.length + i}`, flexDirection: "row" }, /* @__PURE__ */ React44.createElement(Text38, { color: aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)))), aborted ? /* @__PURE__ */ React44.createElement(Text38, { color: FG.faint }, t("cardLabels.truncatedByEsc")) : null);
8810
+ })) : null, visible.map((line, i) => /* @__PURE__ */ React45.createElement(Box38, { key: `${card.id}:${visualLines.length - visible.length + i}`, flexDirection: "row" }, /* @__PURE__ */ React45.createElement(Text39, { color: aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)))), aborted ? /* @__PURE__ */ React45.createElement(Text39, { color: FG.faint }, t("cardLabels.truncatedByEsc")) : null);
8764
8811
  }
8765
8812
 
8766
8813
  // src/cli/ui/cards/SubAgentCard.tsx
8767
- import { Box as Box38, Text as Text39 } from "ink";
8768
- import React45, { useContext as useContext6 } from "react";
8814
+ import { Box as Box39, Text as Text40 } from "ink";
8815
+ import React46, { useContext as useContext6 } from "react";
8769
8816
  function SubAgentCard({ card }) {
8770
8817
  const { fg, tone, toneActive } = useThemeTokens();
8771
8818
  const statusColor = {
@@ -8779,7 +8826,7 @@ function SubAgentCard({ card }) {
8779
8826
  const isRunning = card.status === "running";
8780
8827
  const inLive = useContext6(ActiveCardContext);
8781
8828
  const headerMeta2 = isRunning ? runningChildren > 0 ? [`${runningChildren} ${t("cardLabels.runningLabel")}`] : [t("cardLabels.workingLabel")] : [{ text: card.status, color: headColor }];
8782
- return /* @__PURE__ */ React45.createElement(Card, { tone: headColor }, /* @__PURE__ */ React45.createElement(
8829
+ return /* @__PURE__ */ React46.createElement(Card, { tone: headColor }, /* @__PURE__ */ React46.createElement(
8783
8830
  CardHeader,
8784
8831
  {
8785
8832
  glyph: headGlyph,
@@ -8789,7 +8836,7 @@ function SubAgentCard({ card }) {
8789
8836
  subtitle: card.task,
8790
8837
  meta: headerMeta2
8791
8838
  }
8792
- ), card.name ? /* @__PURE__ */ React45.createElement(Text39, { color: fg.faint }, `${t("cardLabels.agent")} \xB7 ${card.name}`) : null, card.tools && card.tools.length > 0 && /* @__PURE__ */ React45.createElement(Text39, { color: fg.faint }, `${t("cardLabels.tools")} \xB7 ${card.tools.join(", ")}`), card.children.map((child) => /* @__PURE__ */ React45.createElement(Box38, { key: child.id, flexDirection: "row", gap: 1 }, inLive ? null : /* @__PURE__ */ React45.createElement(Text39, { color: tone.violet }, "\u258E"), /* @__PURE__ */ React45.createElement(ChildRow, { card: child }))));
8839
+ ), card.name ? /* @__PURE__ */ React46.createElement(Text40, { color: fg.faint }, `${t("cardLabels.agent")} \xB7 ${card.name}`) : null, card.tools && card.tools.length > 0 && /* @__PURE__ */ React46.createElement(Text40, { color: fg.faint }, `${t("cardLabels.tools")} \xB7 ${card.tools.join(", ")}`), card.children.map((child) => /* @__PURE__ */ React46.createElement(Box39, { key: child.id, flexDirection: "row", gap: 1 }, inLive ? null : /* @__PURE__ */ React46.createElement(Text40, { color: tone.violet }, "\u258E"), /* @__PURE__ */ React46.createElement(ChildRow, { card: child }))));
8793
8840
  }
8794
8841
  function isChildDone(card) {
8795
8842
  switch (card.kind) {
@@ -8806,16 +8853,16 @@ function ChildRow({ card }) {
8806
8853
  const { fg, tone } = useThemeTokens();
8807
8854
  const v = childVisual(card, tone.ok, tone.err, fg.faint);
8808
8855
  const isDone = isChildDone(card);
8809
- return /* @__PURE__ */ React45.createElement(React45.Fragment, null, v.statusGlyph, /* @__PURE__ */ React45.createElement(Text39, { color: v.kindColor }, v.kindGlyph), /* @__PURE__ */ React45.createElement(Text39, { dimColor: isDone, color: fg.body }, v.text));
8856
+ return /* @__PURE__ */ React46.createElement(React46.Fragment, null, v.statusGlyph, /* @__PURE__ */ React46.createElement(Text40, { color: v.kindColor }, v.kindGlyph), /* @__PURE__ */ React46.createElement(Text40, { dimColor: isDone, color: fg.body }, v.text));
8810
8857
  }
8811
8858
  function runningGlyph(color) {
8812
- return /* @__PURE__ */ React45.createElement(Spinner, { kind: "circle", color });
8859
+ return /* @__PURE__ */ React46.createElement(Spinner, { kind: "circle", color });
8813
8860
  }
8814
8861
  function doneGlyph(color) {
8815
- return /* @__PURE__ */ React45.createElement(Text39, { color }, "\u2713");
8862
+ return /* @__PURE__ */ React46.createElement(Text40, { color }, "\u2713");
8816
8863
  }
8817
8864
  function failedGlyph(color) {
8818
- return /* @__PURE__ */ React45.createElement(Text39, { color }, "\u2716");
8865
+ return /* @__PURE__ */ React46.createElement(Text40, { color }, "\u2716");
8819
8866
  }
8820
8867
  function childVisual(card, doneColor, failedColor, fallbackColor) {
8821
8868
  switch (card.kind) {
@@ -8860,7 +8907,7 @@ function childVisual(card, doneColor, failedColor, fallbackColor) {
8860
8907
  };
8861
8908
  default:
8862
8909
  return {
8863
- statusGlyph: /* @__PURE__ */ React45.createElement(Text39, { color: fallbackColor }, "\xB7"),
8910
+ statusGlyph: /* @__PURE__ */ React46.createElement(Text40, { color: fallbackColor }, "\xB7"),
8864
8911
  kindGlyph: "\xB7",
8865
8912
  kindColor: fallbackColor,
8866
8913
  text: card.kind
@@ -8869,8 +8916,8 @@ function childVisual(card, doneColor, failedColor, fallbackColor) {
8869
8916
  }
8870
8917
 
8871
8918
  // src/cli/ui/cards/TaskCard.tsx
8872
- import { Box as Box39, Text as Text40 } from "ink";
8873
- import React46 from "react";
8919
+ import { Box as Box40, Text as Text41 } from "ink";
8920
+ import React47 from "react";
8874
8921
  var STEP_GLYPH = {
8875
8922
  queued: "\u25CB",
8876
8923
  running: "\u25B6",
@@ -8896,7 +8943,7 @@ function TaskCard({ card }) {
8896
8943
  failed: tone.err
8897
8944
  };
8898
8945
  const elapsed = `${(card.elapsedMs / 1e3).toFixed(1)}s`;
8899
- return /* @__PURE__ */ React46.createElement(Card, { tone: taskColor[card.status] }, /* @__PURE__ */ React46.createElement(
8946
+ return /* @__PURE__ */ React47.createElement(Card, { tone: taskColor[card.status] }, /* @__PURE__ */ React47.createElement(
8900
8947
  CardHeader,
8901
8948
  {
8902
8949
  glyph: TASK_GLYPH[card.status],
@@ -8905,12 +8952,12 @@ function TaskCard({ card }) {
8905
8952
  subtitle: card.title,
8906
8953
  meta: [elapsed, card.status]
8907
8954
  }
8908
- ), card.steps.map((step) => /* @__PURE__ */ React46.createElement(Box39, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React46.createElement(Text40, { color: stepColor[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ React46.createElement(Text40, { bold: true, color: fg.body }, (step.toolName ?? "step").padEnd(7)), /* @__PURE__ */ React46.createElement(Text40, { color: fg.sub }, step.title), step.detail ? /* @__PURE__ */ React46.createElement(Text40, { color: fg.faint }, step.detail) : null, step.elapsedMs !== void 0 ? /* @__PURE__ */ React46.createElement(Text40, { color: fg.faint }, `${(step.elapsedMs / 1e3).toFixed(2)}s`) : null)));
8955
+ ), card.steps.map((step) => /* @__PURE__ */ React47.createElement(Box40, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React47.createElement(Text41, { color: stepColor[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ React47.createElement(Text41, { bold: true, color: fg.body }, (step.toolName ?? "step").padEnd(7)), /* @__PURE__ */ React47.createElement(Text41, { color: fg.sub }, step.title), step.detail ? /* @__PURE__ */ React47.createElement(Text41, { color: fg.faint }, step.detail) : null, step.elapsedMs !== void 0 ? /* @__PURE__ */ React47.createElement(Text41, { color: fg.faint }, `${(step.elapsedMs / 1e3).toFixed(2)}s`) : null)));
8909
8956
  }
8910
8957
 
8911
8958
  // src/cli/ui/cards/TipCard.tsx
8912
- import { Box as Box40, Text as Text41 } from "ink";
8913
- import React47 from "react";
8959
+ import { Box as Box41, Text as Text42 } from "ink";
8960
+ import React48 from "react";
8914
8961
  import stringWidth2 from "string-width";
8915
8962
  var KEY_GUTTER = 4;
8916
8963
  function TipCard({ card }) {
@@ -8918,7 +8965,7 @@ function TipCard({ card }) {
8918
8965
  (max, sec) => sec.rows.reduce((m, r) => Math.max(m, stringWidth2(r.key)), max),
8919
8966
  0
8920
8967
  );
8921
- return /* @__PURE__ */ React47.createElement(Box40, { flexDirection: "column", paddingLeft: 2, marginY: 1 }, /* @__PURE__ */ React47.createElement(Box40, { flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React47.createElement(Box40, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React47.createElement(Text41, { color: TONE.accent, bold: true }, "\u24D8"), /* @__PURE__ */ React47.createElement(Text41, { color: FG.body, bold: true }, card.topic)), card.oneTime ? /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, t("ui.tipShownOnce")) : null), card.sections.map((section, i) => /* @__PURE__ */ React47.createElement(Box40, { key: section.title ?? `section-${i}`, flexDirection: "column", marginTop: 1 }, section.title ? /* @__PURE__ */ React47.createElement(Box40, { marginBottom: 0 }, /* @__PURE__ */ React47.createElement(Text41, { color: FG.sub }, section.title)) : null, section.rows.map((row2) => /* @__PURE__ */ React47.createElement(
8968
+ return /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "column", paddingLeft: 2, marginY: 1 }, /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React48.createElement(Text42, { color: TONE.accent, bold: true }, "\u24D8"), /* @__PURE__ */ React48.createElement(Text42, { color: FG.body, bold: true }, card.topic)), card.oneTime ? /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, t("ui.tipShownOnce")) : null), card.sections.map((section, i) => /* @__PURE__ */ React48.createElement(Box41, { key: section.title ?? `section-${i}`, flexDirection: "column", marginTop: 1 }, section.title ? /* @__PURE__ */ React48.createElement(Box41, { marginBottom: 0 }, /* @__PURE__ */ React48.createElement(Text42, { color: FG.sub }, section.title)) : null, section.rows.map((row2) => /* @__PURE__ */ React48.createElement(
8922
8969
  TipRowRender,
8923
8970
  {
8924
8971
  key: row2.key,
@@ -8926,7 +8973,7 @@ function TipCard({ card }) {
8926
8973
  keyWidth,
8927
8974
  indent: section.title ? 2 : 0
8928
8975
  }
8929
- )))), card.footer ? /* @__PURE__ */ React47.createElement(Box40, { marginTop: 1 }, /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, card.footer)) : null);
8976
+ )))), card.footer ? /* @__PURE__ */ React48.createElement(Box41, { marginTop: 1 }, /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, card.footer)) : null);
8930
8977
  }
8931
8978
  function TipRowRender({
8932
8979
  row: row2,
@@ -8935,12 +8982,34 @@ function TipRowRender({
8935
8982
  }) {
8936
8983
  const pad = " ".repeat(Math.max(0, keyWidth - stringWidth2(row2.key) + KEY_GUTTER));
8937
8984
  const lead = indent > 0 ? " ".repeat(indent) : "";
8938
- return /* @__PURE__ */ React47.createElement(Box40, { flexDirection: "row" }, lead ? /* @__PURE__ */ React47.createElement(Text41, null, lead) : null, /* @__PURE__ */ React47.createElement(Text41, { color: TONE.accent }, row2.key), /* @__PURE__ */ React47.createElement(Text41, null, pad), /* @__PURE__ */ React47.createElement(Text41, { color: FG.body }, row2.text));
8985
+ return /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "row" }, lead ? /* @__PURE__ */ React48.createElement(Text42, null, lead) : null, /* @__PURE__ */ React48.createElement(Text42, { color: TONE.accent }, row2.key), /* @__PURE__ */ React48.createElement(Text42, null, pad), /* @__PURE__ */ React48.createElement(Text42, { color: FG.body }, row2.text));
8939
8986
  }
8940
8987
 
8941
8988
  // src/cli/ui/cards/ToolCard.tsx
8942
- import { Text as Text42, useStdout as useStdout12 } from "ink";
8943
- import React48 from "react";
8989
+ import { Text as Text43, useStdout as useStdout12 } from "ink";
8990
+ import React50 from "react";
8991
+
8992
+ // src/cli/ui/state/inflight-context.tsx
8993
+ import React49, { createContext as createContext4, useContext as useContext7, useSyncExternalStore } from "react";
8994
+ var Ctx = createContext4(null);
8995
+ function InflightProvider({
8996
+ inflight,
8997
+ children
8998
+ }) {
8999
+ return /* @__PURE__ */ React49.createElement(Ctx.Provider, { value: inflight }, children);
9000
+ }
9001
+ function useIsInflight(id) {
9002
+ const inflight = useContext7(Ctx);
9003
+ return useSyncExternalStore(
9004
+ (cb) => inflight ? inflight.subscribe(cb) : noop,
9005
+ () => inflight ? inflight.has(id) : false,
9006
+ () => false
9007
+ );
9008
+ }
9009
+ var noop = () => {
9010
+ };
9011
+
9012
+ // src/cli/ui/cards/ToolCard.tsx
8944
9013
  var READ_TAIL = 2;
8945
9014
  var OTHER_TAIL = 5;
8946
9015
  function tailLinesFor(name) {
@@ -8958,7 +9027,8 @@ function ToolCard({ card }) {
8958
9027
  const truncated = allLines.length > tail;
8959
9028
  const visible = truncated ? allLines.slice(-tail) : allLines;
8960
9029
  const hidden = truncated ? allLines.length - visible.length : 0;
8961
- const status2 = toolStatus(card);
9030
+ const isInflight = useIsInflight(card.id);
9031
+ const status2 = toolStatus(card, isInflight);
8962
9032
  const headColor = headerColorFor(status2);
8963
9033
  const errColor = card.exitCode && card.exitCode !== 0 ? TONE.err : FG.sub;
8964
9034
  const showBody = !card.rejected && (subagentMarkdown !== null || visible.length > 0);
@@ -8970,7 +9040,7 @@ function ToolCard({ card }) {
8970
9040
  meta.push({ text: t("cardLabels.rejected"), color: TONE.err });
8971
9041
  }
8972
9042
  for (const part of metaTrail(card)) meta.push(part);
8973
- return /* @__PURE__ */ React48.createElement(Card, { tone: headColor }, /* @__PURE__ */ React48.createElement(
9043
+ return /* @__PURE__ */ React50.createElement(Card, { tone: headColor }, /* @__PURE__ */ React50.createElement(
8974
9044
  CardHeader,
8975
9045
  {
8976
9046
  glyph: statusGlyph2(status2),
@@ -8978,12 +9048,12 @@ function ToolCard({ card }) {
8978
9048
  title: card.name,
8979
9049
  subtitle: argsLabel || void 0,
8980
9050
  meta: meta.length > 0 ? meta : void 0,
8981
- right: status2 === "running" ? /* @__PURE__ */ React48.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand, bold: true }) : void 0
9051
+ right: status2 === "running" ? /* @__PURE__ */ React50.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand, bold: true }) : void 0
8982
9052
  }
8983
- ), showBody && (subagentMarkdown !== null ? /* @__PURE__ */ React48.createElement(Markdown, { text: subagentMarkdown, width: lineCells }) : /* @__PURE__ */ React48.createElement(React48.Fragment, null, hidden > 0 ? /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, t(hidden === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
9053
+ ), showBody && (subagentMarkdown !== null ? /* @__PURE__ */ React50.createElement(Markdown, { text: subagentMarkdown, width: lineCells }) : /* @__PURE__ */ React50.createElement(React50.Fragment, null, hidden > 0 ? /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, t(hidden === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
8984
9054
  count: hidden
8985
- })) : null, visible.map((line, i) => /* @__PURE__ */ React48.createElement(
8986
- Text42,
9055
+ })) : null, visible.map((line, i) => /* @__PURE__ */ React50.createElement(
9056
+ Text43,
8987
9057
  {
8988
9058
  key: `${card.id}:${hidden + i}`,
8989
9059
  color: errColor,
@@ -9006,10 +9076,10 @@ function unwrapSubagentMarkdown(card) {
9006
9076
  return null;
9007
9077
  }
9008
9078
  }
9009
- function toolStatus(card) {
9079
+ function toolStatus(card, isInflight) {
9080
+ if (isInflight) return "running";
9010
9081
  if (card.rejected) return "rejected";
9011
9082
  if (card.aborted) return "aborted";
9012
- if (!card.done) return "running";
9013
9083
  if (card.exitCode !== void 0 && card.exitCode !== 0) return "error";
9014
9084
  return "ok";
9015
9085
  }
@@ -9084,8 +9154,8 @@ function formatBytes(n) {
9084
9154
  }
9085
9155
 
9086
9156
  // src/cli/ui/cards/UsageCard.tsx
9087
- import { Box as Box42, Text as Text43 } from "ink";
9088
- import React49 from "react";
9157
+ import { Box as Box43, Text as Text44 } from "ink";
9158
+ import React51 from "react";
9089
9159
  var BAR_CELLS2 = 30;
9090
9160
  function compactNum(n) {
9091
9161
  if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
@@ -9095,10 +9165,10 @@ function compactNum(n) {
9095
9165
  function bar(ratio, color) {
9096
9166
  const filled = Math.max(0, Math.min(BAR_CELLS2, Math.round(ratio * BAR_CELLS2)));
9097
9167
  const empty = BAR_CELLS2 - filled;
9098
- return /* @__PURE__ */ React49.createElement(React49.Fragment, null, /* @__PURE__ */ React49.createElement(Text43, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, "\u2591".repeat(empty)));
9168
+ return /* @__PURE__ */ React51.createElement(React51.Fragment, null, /* @__PURE__ */ React51.createElement(Text44, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, "\u2591".repeat(empty)));
9099
9169
  }
9100
9170
  function UsageCard({ card }) {
9101
- if (card.compact) return /* @__PURE__ */ React49.createElement(CompactUsageRow, { card });
9171
+ if (card.compact) return /* @__PURE__ */ React51.createElement(CompactUsageRow, { card });
9102
9172
  const cap = Math.max(1, card.tokens.promptCap);
9103
9173
  const promptRatio = card.tokens.prompt / cap;
9104
9174
  const reasonRatio = card.tokens.reason / cap;
@@ -9108,15 +9178,15 @@ function UsageCard({ card }) {
9108
9178
  formatCost(card.cost, card.balanceCurrency)
9109
9179
  ];
9110
9180
  if (card.elapsedMs !== void 0) headerMeta2.push(`${(card.elapsedMs / 1e3).toFixed(1)}s`);
9111
- return /* @__PURE__ */ React49.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React49.createElement(CardHeader, { glyph: "\u03A3", tone: FG.meta, title: t("cardTitles.usage"), meta: headerMeta2 }), /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, t("cardLabels.prompt")), bar(promptRatio, TONE.brand), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: FG.body }, card.tokens.prompt.toLocaleString()), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, `/ 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, t("cardLabels.reason")), bar(reasonRatio, TONE.accent), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: FG.body }, card.tokens.reason.toLocaleString())), /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, t("cardLabels.output")), bar(outputRatio, TONE.brand), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: FG.body }, card.tokens.output.toLocaleString())), /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, t("cardLabels.cache"), " "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: TONE.ok }, `${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, t("cardLabels.session")), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: FG.body }, `\u26C1 ${formatCost(card.sessionCost, card.balanceCurrency, 3)}`), card.balance !== void 0 ? /* @__PURE__ */ React49.createElement(React49.Fragment, null, /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, `\xB7 ${t("cardLabels.balance")}`), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: TONE.brand }, formatBalance(card.balance, card.balanceCurrency))) : null));
9181
+ return /* @__PURE__ */ React51.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React51.createElement(CardHeader, { glyph: "\u03A3", tone: FG.meta, title: t("cardTitles.usage"), meta: headerMeta2 }), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.prompt")), bar(promptRatio, TONE.brand), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, card.tokens.prompt.toLocaleString()), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `/ 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.reason")), bar(reasonRatio, TONE.accent), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, card.tokens.reason.toLocaleString())), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.output")), bar(outputRatio, TONE.brand), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, card.tokens.output.toLocaleString())), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.cache"), " "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: TONE.ok }, `${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, t("cardLabels.session")), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, `\u26C1 ${formatCost(card.sessionCost, card.balanceCurrency, 3)}`), card.balance !== void 0 ? /* @__PURE__ */ React51.createElement(React51.Fragment, null, /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `\xB7 ${t("cardLabels.balance")}`), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: TONE.brand }, formatBalance(card.balance, card.balanceCurrency))) : null));
9112
9182
  }
9113
9183
  function CompactUsageRow({ card }) {
9114
9184
  const elapsed = card.elapsedMs !== void 0 ? ` \xB7 ${(card.elapsedMs / 1e3).toFixed(1)}s` : "";
9115
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ React49.createElement(Text43, { color: FG.meta }, "\u03A3"), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, `${t("cardLabels.turn")} ${card.turn}`), /* @__PURE__ */ React49.createElement(Text43, { color: FG.meta }, `\xB7 ${compactNum(card.tokens.prompt)} ${t("cardLabels.prompt")} \xB7 ${compactNum(card.tokens.output)} ${t("cardLabels.output")}`), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, `\xB7 ${t("cardLabels.cache")}`), /* @__PURE__ */ React49.createElement(Text43, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, `\xB7 ${formatCost(card.cost, card.balanceCurrency)}${elapsed}`), card.balance !== void 0 ? /* @__PURE__ */ React49.createElement(Text43, { color: TONE.brand }, `\xB7 ${formatBalance(card.balance, card.balanceCurrency)}`) : null);
9185
+ return /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.meta }, "\u03A3"), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `${t("cardLabels.turn")} ${card.turn}`), /* @__PURE__ */ React51.createElement(Text44, { color: FG.meta }, `\xB7 ${compactNum(card.tokens.prompt)} ${t("cardLabels.prompt")} \xB7 ${compactNum(card.tokens.output)} ${t("cardLabels.output")}`), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `\xB7 ${t("cardLabels.cache")}`), /* @__PURE__ */ React51.createElement(Text44, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `\xB7 ${formatCost(card.cost, card.balanceCurrency)}${elapsed}`), card.balance !== void 0 ? /* @__PURE__ */ React51.createElement(Text44, { color: TONE.brand }, `\xB7 ${formatBalance(card.balance, card.balanceCurrency)}`) : null);
9116
9186
  }
9117
9187
 
9118
9188
  // src/cli/ui/cards/UserCard.tsx
9119
- import React50 from "react";
9189
+ import React52 from "react";
9120
9190
 
9121
9191
  // src/cli/ui/cards/time.ts
9122
9192
  function formatRelativeTime(ts, now = Date.now()) {
@@ -9133,7 +9203,7 @@ function formatRelativeTime(ts, now = Date.now()) {
9133
9203
 
9134
9204
  // src/cli/ui/cards/UserCard.tsx
9135
9205
  function UserCard({ card }) {
9136
- return /* @__PURE__ */ React50.createElement(Card, { tone: TONE.accent }, /* @__PURE__ */ React50.createElement(
9206
+ return /* @__PURE__ */ React52.createElement(Card, { tone: TONE.accent }, /* @__PURE__ */ React52.createElement(
9137
9207
  CardHeader,
9138
9208
  {
9139
9209
  glyph: "\u203A",
@@ -9142,15 +9212,15 @@ function UserCard({ card }) {
9142
9212
  titleColor: FG.sub,
9143
9213
  meta: [formatRelativeTime(card.ts)]
9144
9214
  }
9145
- ), /* @__PURE__ */ React50.createElement(Markdown, { text: card.text }));
9215
+ ), /* @__PURE__ */ React52.createElement(Markdown, { text: card.text }));
9146
9216
  }
9147
9217
 
9148
9218
  // src/cli/ui/cards/WarnCard.tsx
9149
- import { Text as Text44 } from "ink";
9150
- import React51 from "react";
9219
+ import { Text as Text45 } from "ink";
9220
+ import React53 from "react";
9151
9221
  function WarnCard({ card }) {
9152
9222
  const messageLines = card.message.length > 0 ? card.message.split("\n") : [];
9153
- return /* @__PURE__ */ React51.createElement(Card, { tone: TONE.warn }, /* @__PURE__ */ React51.createElement(
9223
+ return /* @__PURE__ */ React53.createElement(Card, { tone: TONE.warn }, /* @__PURE__ */ React53.createElement(
9154
9224
  CardHeader,
9155
9225
  {
9156
9226
  glyph: "\u26A0",
@@ -9158,57 +9228,57 @@ function WarnCard({ card }) {
9158
9228
  title: card.title,
9159
9229
  meta: card.detail ? [card.detail] : void 0
9160
9230
  }
9161
- ), messageLines.map((line, i) => /* @__PURE__ */ React51.createElement(Text44, { key: `${card.id}:${i}`, color: FG.body }, line || " ")));
9231
+ ), messageLines.map((line, i) => /* @__PURE__ */ React53.createElement(Text45, { key: `${card.id}:${i}`, color: FG.body }, line || " ")));
9162
9232
  }
9163
9233
 
9164
9234
  // src/cli/ui/cards/CardRenderer.tsx
9165
- var CardRenderer = React52.memo(function CardRenderer2({
9235
+ var CardRenderer = React54.memo(function CardRenderer2({
9166
9236
  card
9167
9237
  }) {
9168
- return /* @__PURE__ */ React52.createElement(Box43, { flexDirection: "column" }, renderCard(card));
9238
+ return /* @__PURE__ */ React54.createElement(Box44, { flexDirection: "column" }, renderCard(card));
9169
9239
  });
9170
9240
  function renderCard(card) {
9171
9241
  switch (card.kind) {
9172
9242
  case "user":
9173
- return /* @__PURE__ */ React52.createElement(UserCard, { card });
9243
+ return /* @__PURE__ */ React54.createElement(UserCard, { card });
9174
9244
  case "reasoning":
9175
- return /* @__PURE__ */ React52.createElement(ReasoningCard, { card, expanded: true });
9245
+ return /* @__PURE__ */ React54.createElement(ReasoningCard, { card, expanded: true });
9176
9246
  case "streaming":
9177
- return /* @__PURE__ */ React52.createElement(StreamingCard, { card });
9247
+ return /* @__PURE__ */ React54.createElement(StreamingCard, { card });
9178
9248
  case "tool":
9179
- return /* @__PURE__ */ React52.createElement(ToolCard, { card });
9249
+ return /* @__PURE__ */ React54.createElement(ToolCard, { card });
9180
9250
  case "task":
9181
- return /* @__PURE__ */ React52.createElement(TaskCard, { card });
9251
+ return /* @__PURE__ */ React54.createElement(TaskCard, { card });
9182
9252
  case "plan":
9183
- return /* @__PURE__ */ React52.createElement(PlanCard, { card });
9253
+ return /* @__PURE__ */ React54.createElement(PlanCard, { card });
9184
9254
  case "diff":
9185
- return /* @__PURE__ */ React52.createElement(DiffCard, { card });
9255
+ return /* @__PURE__ */ React54.createElement(DiffCard, { card });
9186
9256
  case "error":
9187
- return /* @__PURE__ */ React52.createElement(ErrorCard, { card });
9257
+ return /* @__PURE__ */ React54.createElement(ErrorCard, { card });
9188
9258
  case "warn":
9189
- return /* @__PURE__ */ React52.createElement(WarnCard, { card });
9259
+ return /* @__PURE__ */ React54.createElement(WarnCard, { card });
9190
9260
  case "usage":
9191
- return /* @__PURE__ */ React52.createElement(UsageCard, { card });
9261
+ return /* @__PURE__ */ React54.createElement(UsageCard, { card });
9192
9262
  case "memory":
9193
- return /* @__PURE__ */ React52.createElement(MemoryCard, { card });
9263
+ return /* @__PURE__ */ React54.createElement(MemoryCard, { card });
9194
9264
  case "subagent":
9195
- return /* @__PURE__ */ React52.createElement(SubAgentCard, { card });
9265
+ return /* @__PURE__ */ React54.createElement(SubAgentCard, { card });
9196
9266
  case "search":
9197
- return /* @__PURE__ */ React52.createElement(SearchCard, { card });
9267
+ return /* @__PURE__ */ React54.createElement(SearchCard, { card });
9198
9268
  case "live":
9199
- return /* @__PURE__ */ React52.createElement(LiveCard, { card });
9269
+ return /* @__PURE__ */ React54.createElement(LiveCard, { card });
9200
9270
  case "tip":
9201
- return /* @__PURE__ */ React52.createElement(TipCard, { card });
9271
+ return /* @__PURE__ */ React54.createElement(TipCard, { card });
9202
9272
  case "ctx":
9203
- return /* @__PURE__ */ React52.createElement(CtxCard, { card });
9273
+ return /* @__PURE__ */ React54.createElement(CtxCard, { card });
9204
9274
  case "doctor":
9205
- return /* @__PURE__ */ React52.createElement(DoctorCard, { card });
9275
+ return /* @__PURE__ */ React54.createElement(DoctorCard, { card });
9206
9276
  default:
9207
- return /* @__PURE__ */ React52.createElement(FallbackCard, { card });
9277
+ return /* @__PURE__ */ React54.createElement(FallbackCard, { card });
9208
9278
  }
9209
9279
  }
9210
9280
  function FallbackCard({ card }) {
9211
- return /* @__PURE__ */ React52.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React52.createElement(Text45, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
9281
+ return /* @__PURE__ */ React54.createElement(Box44, { flexDirection: "row" }, /* @__PURE__ */ React54.createElement(Text46, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
9212
9282
  }
9213
9283
 
9214
9284
  // src/cli/ui/layout/CardStream.tsx
@@ -9230,7 +9300,7 @@ function CardStream({
9230
9300
  if (suppressLive && cards.length > 0 && !isFullySettled(cards[cards.length - 1])) {
9231
9301
  visible = cards.slice(0, -1);
9232
9302
  }
9233
- return /* @__PURE__ */ React53.createElement(React53.Fragment, null, scrollRows > 0 ? /* @__PURE__ */ React53.createElement(Text46, { color: FG.faint }, " \u2191 earlier \u2014 PgUp / wheel / \u2191") : null, /* @__PURE__ */ React53.createElement(Box44, { ref: outerRef, flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ React53.createElement(Box44, { ref: innerRef, flexDirection: "column", marginTop: -scrollRows, flexShrink: 0 }, visible.map((card) => /* @__PURE__ */ React53.createElement(CardRenderer, { key: card.id, card })))));
9303
+ return /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Box45, { height: 1, flexShrink: 0 }, scrollRows > 0 ? /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, " \u2191 earlier \u2014 PgUp / wheel / \u2191") : null), /* @__PURE__ */ React55.createElement(Box45, { ref: outerRef, flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ React55.createElement(Box45, { ref: innerRef, flexDirection: "column", marginTop: -scrollRows, flexShrink: 0 }, visible.map((card) => /* @__PURE__ */ React55.createElement(CardRenderer, { key: card.id, card })))));
9234
9304
  }
9235
9305
  function isFullySettled(card) {
9236
9306
  switch (card.kind) {
@@ -9250,13 +9320,13 @@ function isFullySettled(card) {
9250
9320
  }
9251
9321
 
9252
9322
  // src/cli/ui/layout/LiveRows.tsx
9253
- import { Box as Box45, Text as Text47 } from "ink";
9254
- import React54 from "react";
9323
+ import { Box as Box46, Text as Text48 } from "ink";
9324
+ import React56 from "react";
9255
9325
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
9256
9326
  function ThinkingRow({ text }) {
9257
9327
  const elapsed = useElapsedSeconds();
9258
9328
  const { fg, tone } = useThemeTokens();
9259
- return /* @__PURE__ */ React54.createElement(Box45, { marginY: 1, paddingX: 1, gap: 1 }, /* @__PURE__ */ React54.createElement(Spinner, { kind: "circle", color: TONE.accent }), /* @__PURE__ */ React54.createElement(Text47, { italic: true, color: FG.sub }, text), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, `${elapsed}s`));
9329
+ return /* @__PURE__ */ React56.createElement(Box46, { marginY: 1, paddingX: 1, gap: 1 }, /* @__PURE__ */ React56.createElement(Spinner, { kind: "circle", color: TONE.accent }), /* @__PURE__ */ React56.createElement(Text48, { italic: true, color: FG.sub }, text), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, `${elapsed}s`));
9260
9330
  }
9261
9331
  function ModeStatusBar({
9262
9332
  editMode,
@@ -9268,24 +9338,24 @@ function ModeStatusBar({
9268
9338
  }) {
9269
9339
  useSlowTick();
9270
9340
  const running = jobs2?.runningCount() ?? 0;
9271
- const jobsTag = running > 0 ? /* @__PURE__ */ React54.createElement(Text47, { color: TONE.warn, bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
9341
+ const jobsTag = running > 0 ? /* @__PURE__ */ React56.createElement(Text48, { color: TONE.warn, bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
9272
9342
  if (planMode) {
9273
- return /* @__PURE__ */ React54.createElement(ModeBarFrame, null, /* @__PURE__ */ React54.createElement(ModePill, { label: "PLAN MODE", color: TONE.err, flash }), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, " writes gated \xB7 /plan off to leave"), jobsTag);
9343
+ return /* @__PURE__ */ React56.createElement(ModeBarFrame, null, /* @__PURE__ */ React56.createElement(ModePill, { label: "PLAN MODE", color: TONE.err, flash }), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, " writes gated \xB7 /plan off to leave"), jobsTag);
9274
9344
  }
9275
9345
  const label = editMode === "yolo" ? "YOLO" : editMode === "auto" ? "AUTO" : "REVIEW";
9276
9346
  const pillColor = editMode === "yolo" ? TONE.err : editMode === "auto" ? TONE.accent : TONE.brand;
9277
9347
  const mid = editMode === "yolo" ? "edits + shell auto \xB7 /undo to roll back" : editMode === "auto" ? "edits land now \xB7 u to undo" : pendingCount > 0 ? `${pendingCount} queued \xB7 y apply \xB7 n discard` : "edits queued \xB7 y apply \xB7 n discard";
9278
- return /* @__PURE__ */ React54.createElement(ModeBarFrame, null, /* @__PURE__ */ React54.createElement(ModePill, { label, color: pillColor, flash }), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
9348
+ return /* @__PURE__ */ React56.createElement(ModeBarFrame, null, /* @__PURE__ */ React56.createElement(ModePill, { label, color: pillColor, flash }), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
9279
9349
  }
9280
9350
  function ModeBarFrame({ children }) {
9281
- return /* @__PURE__ */ React54.createElement(Box45, { paddingX: 1 }, children);
9351
+ return /* @__PURE__ */ React56.createElement(Box46, { paddingX: 1 }, children);
9282
9352
  }
9283
9353
  function ModePill({
9284
9354
  label,
9285
9355
  color,
9286
9356
  flash
9287
9357
  }) {
9288
- return /* @__PURE__ */ React54.createElement(Text47, { color, bold: true, inverse: flash }, `[${label}]`);
9358
+ return /* @__PURE__ */ React56.createElement(Text48, { color, bold: true, inverse: flash }, `[${label}]`);
9289
9359
  }
9290
9360
  function UndoBanner({
9291
9361
  banner
@@ -9300,7 +9370,7 @@ function UndoBanner({
9300
9370
  const urgent = !paused && remainingSec <= 1;
9301
9371
  const pct = remainingMs / totalMs * 100;
9302
9372
  const tone = paused ? TONE.warn : urgent ? TONE.err : TONE.accent;
9303
- return /* @__PURE__ */ React54.createElement(Box45, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React54.createElement(Text47, { backgroundColor: TONE.accent, color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, " press "), /* @__PURE__ */ React54.createElement(Text47, { backgroundColor: TONE.brand, color: "black", bold: true }, " u "), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, paused ? " to undo \xB7 " : " to undo \xB7 "), /* @__PURE__ */ React54.createElement(Text47, { backgroundColor: paused ? TONE.warn : FG.faint, color: "black", bold: true }, " space "), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, paused ? " to resume " : " to pause "), /* @__PURE__ */ React54.createElement(CharBar, { pct, width: 20, color: tone, showLabel: false }), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, " "), /* @__PURE__ */ React54.createElement(Text47, { color: tone, bold: urgent || paused }, paused ? `${remainingSec}s \xB7 paused` : `${remainingSec}s`));
9373
+ return /* @__PURE__ */ React56.createElement(Box46, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React56.createElement(Text48, { backgroundColor: TONE.accent, color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, " press "), /* @__PURE__ */ React56.createElement(Text48, { backgroundColor: TONE.brand, color: "black", bold: true }, " u "), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, paused ? " to undo \xB7 " : " to undo \xB7 "), /* @__PURE__ */ React56.createElement(Text48, { backgroundColor: paused ? TONE.warn : FG.faint, color: "black", bold: true }, " space "), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, paused ? " to resume " : " to pause "), /* @__PURE__ */ React56.createElement(CharBar, { pct, width: 20, color: tone, showLabel: false }), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, " "), /* @__PURE__ */ React56.createElement(Text48, { color: tone, bold: urgent || paused }, paused ? `${remainingSec}s \xB7 paused` : `${remainingSec}s`));
9304
9374
  }
9305
9375
  function subagentPhaseLabel(phase, iter, elapsedMs) {
9306
9376
  if (phase === "summarising") return "summarising findings\u2026";
@@ -9315,7 +9385,7 @@ function SubagentRow({ activity }) {
9315
9385
  const last = activity.lastInner;
9316
9386
  const subtitle = activity.skillName ?? truncate2(activity.task, 48);
9317
9387
  const modelBadge = activity.model ? modelBadgeFor(activity.model) : null;
9318
- return /* @__PURE__ */ React54.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React54.createElement(
9388
+ return /* @__PURE__ */ React56.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React56.createElement(
9319
9389
  CardHeader,
9320
9390
  {
9321
9391
  glyph: "\u232C",
@@ -9325,9 +9395,9 @@ function SubagentRow({ activity }) {
9325
9395
  titleBg: PILL_SECTION.plan.bg,
9326
9396
  subtitle,
9327
9397
  meta: [`iter ${activity.iter}`, `${seconds}s`],
9328
- right: /* @__PURE__ */ React54.createElement(React54.Fragment, null, modelBadge ? /* @__PURE__ */ React54.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null, /* @__PURE__ */ React54.createElement(Spinner, { kind: "braille", color: CARD.subagent.color }))
9398
+ right: /* @__PURE__ */ React56.createElement(React56.Fragment, null, modelBadge ? /* @__PURE__ */ React56.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null, /* @__PURE__ */ React56.createElement(Spinner, { kind: "braille", color: CARD.subagent.color }))
9329
9399
  }
9330
- ), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, "task ", /* @__PURE__ */ React54.createElement(Text47, { color: FG.sub }, activity.task)), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, "last ", last ? /* @__PURE__ */ React54.createElement(React54.Fragment, null, /* @__PURE__ */ React54.createElement(Text47, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React54.createElement(Text47, { color: FG.body }, last.label), last.meta ? /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, "queued\u2026")), /* @__PURE__ */ React54.createElement(Text47, { color: TONE.brand }, "\u25B6 ", phase));
9400
+ ), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "task ", /* @__PURE__ */ React56.createElement(Text48, { color: FG.sub }, activity.task)), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "last ", last ? /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Text48, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.body }, last.label), last.meta ? /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "queued\u2026")), /* @__PURE__ */ React56.createElement(Text48, { color: TONE.brand }, "\u25B6 ", phase));
9331
9401
  }
9332
9402
  function SubagentLiveStack({
9333
9403
  activities,
@@ -9335,13 +9405,13 @@ function SubagentLiveStack({
9335
9405
  }) {
9336
9406
  const tick = useTick();
9337
9407
  if (activities.length === 0) return null;
9338
- if (activities.length === 1) return /* @__PURE__ */ React54.createElement(SubagentRow, { activity: activities[0] });
9408
+ if (activities.length === 1) return /* @__PURE__ */ React56.createElement(SubagentRow, { activity: activities[0] });
9339
9409
  const visible = activities.slice(0, max);
9340
9410
  const overflow = activities.length - visible.length;
9341
9411
  const summarising = activities.filter((a) => a.phase === "summarising").length;
9342
9412
  const metaParts = [`${activities.length} running`];
9343
9413
  if (summarising > 0) metaParts.push(`${summarising} summarising`);
9344
- return /* @__PURE__ */ React54.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React54.createElement(
9414
+ return /* @__PURE__ */ React56.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React56.createElement(
9345
9415
  CardHeader,
9346
9416
  {
9347
9417
  glyph: "\u232C",
@@ -9350,9 +9420,9 @@ function SubagentLiveStack({
9350
9420
  titleColor: PILL_SECTION.plan.fg,
9351
9421
  titleBg: PILL_SECTION.plan.bg,
9352
9422
  subtitle: metaParts.join(" \xB7 "),
9353
- right: /* @__PURE__ */ React54.createElement(Spinner, { kind: "braille", color: CARD.subagent.color })
9423
+ right: /* @__PURE__ */ React56.createElement(Spinner, { kind: "braille", color: CARD.subagent.color })
9354
9424
  }
9355
- ), visible.map((a, i) => /* @__PURE__ */ React54.createElement(CompactSubagentLine, { key: a.runId, activity: a, tick, index: i })), overflow > 0 ? /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, ` +${overflow} more running\u2026`) : null);
9425
+ ), visible.map((a, i) => /* @__PURE__ */ React56.createElement(CompactSubagentLine, { key: a.runId, activity: a, tick, index: i })), overflow > 0 ? /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` +${overflow} more running\u2026`) : null);
9356
9426
  }
9357
9427
  function CompactSubagentLine({
9358
9428
  activity,
@@ -9367,7 +9437,7 @@ function CompactSubagentLine({
9367
9437
  const title = activity.skillName ?? truncate2(activity.task, 28);
9368
9438
  const titlePadded = title.padEnd(28);
9369
9439
  const last = activity.lastInner;
9370
- return /* @__PURE__ */ React54.createElement(Box45, { flexDirection: "row" }, /* @__PURE__ */ React54.createElement(Text47, { color: glyphColor, bold: true }, ` ${glyph} `), /* @__PURE__ */ React54.createElement(Text47, { color: FG.body }, titlePadded), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, ` iter ${String(activity.iter).padStart(2)} \xB7 ${seconds}s \xB7 `), last ? /* @__PURE__ */ React54.createElement(React54.Fragment, null, /* @__PURE__ */ React54.createElement(Text47, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React54.createElement(Text47, { color: FG.body }, truncate2(last.label, 18)), last.meta ? /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, "queued\u2026"));
9440
+ return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React56.createElement(Text48, { color: glyphColor, bold: true }, ` ${glyph} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.body }, titlePadded), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` iter ${String(activity.iter).padStart(2)} \xB7 ${seconds}s \xB7 `), last ? /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Text48, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.body }, truncate2(last.label, 18)), last.meta ? /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "queued\u2026"));
9371
9441
  }
9372
9442
  function truncate2(text, max) {
9373
9443
  return text.length > max ? `${text.slice(0, max)}\u2026` : text;
@@ -9379,7 +9449,7 @@ function OngoingToolRow({
9379
9449
  const tick = useTick();
9380
9450
  const elapsed = useElapsedSeconds();
9381
9451
  const summary = summarizeToolArgs(tool.name, tool.args);
9382
- return /* @__PURE__ */ React54.createElement(Box45, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React54.createElement(Box45, null, /* @__PURE__ */ React54.createElement(Text47, { color: CARD.tool.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React54.createElement(Text47, null, " "), /* @__PURE__ */ React54.createElement(Text47, { color: CARD.tool.color, bold: true }, `\u25A3 ${tool.name}`), /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React54.createElement(Box45, { paddingLeft: 3 }, /* @__PURE__ */ React54.createElement(Text47, { color: TONE.brand }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React54.createElement(Box45, { paddingLeft: 3 }, /* @__PURE__ */ React54.createElement(Text47, { color: FG.faint }, summary)) : null);
9452
+ return /* @__PURE__ */ React56.createElement(Box46, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React56.createElement(Box46, null, /* @__PURE__ */ React56.createElement(Text48, { color: CARD.tool.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React56.createElement(Text48, null, " "), /* @__PURE__ */ React56.createElement(Text48, { color: CARD.tool.color, bold: true }, `\u25A3 ${tool.name}`), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React56.createElement(Box46, { paddingLeft: 3 }, /* @__PURE__ */ React56.createElement(Text48, { color: TONE.brand }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React56.createElement(Box46, { paddingLeft: 3 }, /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, summary)) : null);
9383
9453
  }
9384
9454
  function renderProgressLine(p) {
9385
9455
  const msg = p.message ? ` ${p.message}` : "";
@@ -9435,16 +9505,16 @@ function summarizeToolArgs(name, args) {
9435
9505
  }
9436
9506
 
9437
9507
  // src/cli/ui/layout/StatusRow.tsx
9438
- import { Box as Box46, Text as Text49, useStdout as useStdout13 } from "ink";
9439
- import React56 from "react";
9508
+ import { Box as Box47, Text as Text50, useStdout as useStdout13 } from "ink";
9509
+ import React58 from "react";
9440
9510
 
9441
9511
  // src/cli/ui/primitives/Countdown.tsx
9442
- import { Text as Text48 } from "ink";
9443
- import React55 from "react";
9512
+ import { Text as Text49 } from "ink";
9513
+ import React57 from "react";
9444
9514
  function Countdown({ endsAt, color = TONE.brand }) {
9445
9515
  useSlowTick();
9446
9516
  const remainingSec = Math.max(0, Math.ceil((endsAt - Date.now()) / 1e3));
9447
- return /* @__PURE__ */ React55.createElement(Text48, { bold: true, color }, String(remainingSec));
9517
+ return /* @__PURE__ */ React57.createElement(Text49, { bold: true, color }, String(remainingSec));
9448
9518
  }
9449
9519
 
9450
9520
  // src/cli/ui/layout/StatusRow.tsx
@@ -9463,21 +9533,21 @@ function StatusRow() {
9463
9533
  const hasSession = status2.sessionCost > 0;
9464
9534
  const hasBalance = typeof status2.balance === "number";
9465
9535
  const showWallet = cols >= WALLET_MIN_COLS && (hasSession || hasBalance);
9466
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Box46, { height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, null, " "), /* @__PURE__ */ React56.createElement(Text49, { color: FG.faint, wrap: "truncate" }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, minHeight: 1, flexWrap: "nowrap", flexShrink: 0 }, /* @__PURE__ */ React56.createElement(Text49, { wrap: "truncate" }, " "), status2.recording ? /* @__PURE__ */ React56.createElement(RecordingPill, { rec: status2.recording }) : status2.countdownSeconds !== void 0 ? /* @__PURE__ */ React56.createElement(CountdownRow, { mode: status2.mode, secondsLeft: status2.countdownSeconds }) : /* @__PURE__ */ React56.createElement(ModePill2, { mode: status2.mode, network: status2.network, detail: status2.networkDetail }), /* @__PURE__ */ React56.createElement(Sep, null), /* @__PURE__ */ React56.createElement(Text49, { color: FG.sub, wrap: "truncate" }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Sep, null), /* @__PURE__ */ React56.createElement(Text49, { bold: true, color: TONE.brand, wrap: "truncate" }, "\u25B8 "), /* @__PURE__ */ React56.createElement(Text49, { bold: true, color: FG.body, wrap: "truncate" }, `${formatCost(status2.cost, status2.balanceCurrency)} turn`)), /* @__PURE__ */ React56.createElement(Sep, null), /* @__PURE__ */ React56.createElement(
9467
- Text49,
9536
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Box47, { height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, null, " "), /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, minHeight: 1, flexWrap: "nowrap", flexShrink: 0 }, /* @__PURE__ */ React58.createElement(Text50, { wrap: "truncate" }, " "), status2.recording ? /* @__PURE__ */ React58.createElement(RecordingPill, { rec: status2.recording }) : status2.countdownSeconds !== void 0 ? /* @__PURE__ */ React58.createElement(CountdownRow, { mode: status2.mode, secondsLeft: status2.countdownSeconds }) : /* @__PURE__ */ React58.createElement(ModePill2, { mode: status2.mode, network: status2.network, detail: status2.networkDetail }), /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: TONE.brand, wrap: "truncate" }, "\u25B8 "), /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: FG.body, wrap: "truncate" }, `${formatCost(status2.cost, status2.balanceCurrency)} turn`)), /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(
9537
+ Text50,
9468
9538
  {
9469
9539
  color: TONE.accent,
9470
9540
  wrap: "truncate"
9471
9541
  },
9472
9542
  `cache ${Math.round(status2.cacheHit * 100)}%`
9473
- ), showWallet && /* @__PURE__ */ React56.createElement(
9543
+ ), showWallet && /* @__PURE__ */ React58.createElement(
9474
9544
  WalletPill,
9475
9545
  {
9476
9546
  sessionCostUsd: status2.sessionCost,
9477
9547
  balance: status2.balance,
9478
9548
  currency: status2.balanceCurrency
9479
9549
  }
9480
- ), cols >= VERSION_MIN_COLS && /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Sep, null), /* @__PURE__ */ React56.createElement(Text49, { color: FG.faint, wrap: "truncate" }, `v${VERSION}`), cols >= FEEDBACK_HINT_MIN_COLS && /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Text49, { color: FG.faint, wrap: "truncate" }, " \xB7 "), /* @__PURE__ */ React56.createElement(Text49, { color: FG.meta, wrap: "truncate" }, "\u2691 "), /* @__PURE__ */ React56.createElement(Text49, { color: FG.sub, wrap: "truncate" }, "/feedback")))));
9550
+ ), cols >= VERSION_MIN_COLS && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, `v${VERSION}`), cols >= FEEDBACK_HINT_MIN_COLS && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, " \xB7 "), /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, "\u2691 "), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, "/feedback")))));
9481
9551
  }
9482
9552
  function WalletPill({
9483
9553
  sessionCostUsd,
@@ -9486,14 +9556,14 @@ function WalletPill({
9486
9556
  }) {
9487
9557
  const showSpent = sessionCostUsd > 0;
9488
9558
  const showBalance = typeof balance === "number";
9489
- return /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Sep, null), /* @__PURE__ */ React56.createElement(Text49, { color: FG.meta, wrap: "truncate" }, "\u26C1 "), showSpent && /* @__PURE__ */ React56.createElement(
9490
- Text49,
9559
+ return /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, "\u26C1 "), showSpent && /* @__PURE__ */ React58.createElement(
9560
+ Text50,
9491
9561
  {
9492
9562
  color: FG.body,
9493
9563
  wrap: "truncate"
9494
9564
  },
9495
9565
  `${formatCost(sessionCostUsd, currency, 2)} spent`
9496
- ), showSpent && showBalance && /* @__PURE__ */ React56.createElement(Text49, { color: FG.meta, wrap: "truncate" }, " / "), showBalance && /* @__PURE__ */ React56.createElement(Text49, { bold: true, color: balanceColor(balance, currency), wrap: "truncate" }, formatBalance(balance, currency, { fractionDigits: 2 })), showBalance && /* @__PURE__ */ React56.createElement(Text49, { color: FG.faint, wrap: "truncate" }, " left"));
9566
+ ), showSpent && showBalance && /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, " / "), showBalance && /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: balanceColor(balance, currency), wrap: "truncate" }, formatBalance(balance, currency, { fractionDigits: 2 })), showBalance && /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, " left"));
9497
9567
  }
9498
9568
  function ModePill2({
9499
9569
  mode: mode2,
@@ -9502,18 +9572,18 @@ function ModePill2({
9502
9572
  }) {
9503
9573
  if (network === "online") {
9504
9574
  const pill = modeGlyph(mode2);
9505
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, { color: pill.color, wrap: "truncate" }, pill.glyph), /* @__PURE__ */ React56.createElement(Text49, { color: FG.sub, wrap: "truncate" }, ` ${mode2}`));
9575
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: pill.color, wrap: "truncate" }, pill.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, ` ${mode2}`));
9506
9576
  }
9507
9577
  const dot = networkDot(network);
9508
9578
  if (network === "slow") {
9509
9579
  const tail = detail ? ` \xB7 ${detail}` : "";
9510
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React56.createElement(Text49, { color: dot.color, wrap: "truncate" }, ` ${mode2} \xB7 slow${tail}`));
9580
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, ` ${mode2} \xB7 slow${tail}`));
9511
9581
  }
9512
9582
  if (network === "disconnected") {
9513
9583
  const tail = detail ? ` \xB7 ${detail}` : "";
9514
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React56.createElement(Text49, { color: dot.color, wrap: "truncate" }, ` disconnect${tail}`));
9584
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, ` disconnect${tail}`));
9515
9585
  }
9516
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React56.createElement(Text49, { color: dot.color, wrap: "truncate" }, " reconnecting\u2026"));
9586
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, " reconnecting\u2026"));
9517
9587
  }
9518
9588
  function CountdownRow({
9519
9589
  mode: mode2,
@@ -9521,14 +9591,14 @@ function CountdownRow({
9521
9591
  }) {
9522
9592
  const pill = modeGlyph(mode2);
9523
9593
  const endsAt = Date.now() + secondsLeft * 1e3;
9524
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, { color: pill.color, wrap: "truncate" }, pill.glyph), /* @__PURE__ */ React56.createElement(Text49, { color: FG.sub, wrap: "truncate" }, ` ${mode2} \xB7 `), /* @__PURE__ */ React56.createElement(Text49, { color: TONE.warn, wrap: "truncate" }, "approving in "), /* @__PURE__ */ React56.createElement(Countdown, { endsAt }), /* @__PURE__ */ React56.createElement(Text49, { color: TONE.warn, wrap: "truncate" }, "s \xB7 esc to interrupt"));
9594
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: pill.color, wrap: "truncate" }, pill.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, ` ${mode2} \xB7 `), /* @__PURE__ */ React58.createElement(Text50, { color: TONE.warn, wrap: "truncate" }, "approving in "), /* @__PURE__ */ React58.createElement(Countdown, { endsAt }), /* @__PURE__ */ React58.createElement(Text50, { color: TONE.warn, wrap: "truncate" }, "s \xB7 esc to interrupt"));
9525
9595
  }
9526
9596
  function RecordingPill({ rec }) {
9527
9597
  const sizeMb = (rec.sizeBytes / (1024 * 1024)).toFixed(1);
9528
- return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React56.createElement(Text49, { bold: true, color: TONE.err, wrap: "truncate" }, "\u25CFREC"), /* @__PURE__ */ React56.createElement(Text49, { color: TONE.err, wrap: "truncate" }, ` ${sizeMb} MB \xB7 ${rec.events} evt`));
9598
+ return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: TONE.err, wrap: "truncate" }, "\u25CFREC"), /* @__PURE__ */ React58.createElement(Text50, { color: TONE.err, wrap: "truncate" }, ` ${sizeMb} MB \xB7 ${rec.events} evt`));
9529
9599
  }
9530
9600
  function Sep() {
9531
- return /* @__PURE__ */ React56.createElement(Text49, { color: FG.meta, wrap: "truncate" }, " \xB7 ");
9601
+ return /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, " \xB7 ");
9532
9602
  }
9533
9603
  function modeGlyph(mode2) {
9534
9604
  switch (mode2) {
@@ -9556,8 +9626,8 @@ function networkDot(state) {
9556
9626
  }
9557
9627
 
9558
9628
  // src/cli/ui/layout/ToastRail.tsx
9559
- import { Box as Box47, Text as Text50, useStdout as useStdout14 } from "ink";
9560
- import React57, { useEffect as useEffect8 } from "react";
9629
+ import { Box as Box48, Text as Text51, useStdout as useStdout14 } from "ink";
9630
+ import React59, { useEffect as useEffect8 } from "react";
9561
9631
  var TONE_COLOR = {
9562
9632
  ok: TONE.ok,
9563
9633
  info: TONE.brand,
@@ -9595,17 +9665,17 @@ function ToastRail() {
9595
9665
  }, [toasts, dispatch]);
9596
9666
  const visible = toasts.filter((t2) => now - t2.bornAt < t2.ttlMs);
9597
9667
  if (visible.length === 0) return null;
9598
- return /* @__PURE__ */ React57.createElement(Box47, { flexDirection: "column" }, visible.map((t2) => {
9668
+ return /* @__PURE__ */ React59.createElement(Box48, { flexDirection: "column" }, visible.map((t2) => {
9599
9669
  const color = TONE_COLOR[t2.tone];
9600
9670
  const glyph = TONE_GLYPH[t2.tone];
9601
9671
  const body = bodyColor(t2, now);
9602
9672
  const remainingSec = Math.max(0, Math.ceil((t2.ttlMs - (now - t2.bornAt)) / 1e3));
9603
- return /* @__PURE__ */ React57.createElement(Box47, { key: t2.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React57.createElement(Text50, { color }, rule), /* @__PURE__ */ React57.createElement(Box47, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text50, { color }, glyph), /* @__PURE__ */ React57.createElement(Text50, { bold: true, color: body }, ` ${t2.title}`), t2.detail !== void 0 && /* @__PURE__ */ React57.createElement(Text50, { color: FG.sub }, ` \xB7 ${t2.detail}`), /* @__PURE__ */ React57.createElement(Box47, { flexGrow: 1 }), /* @__PURE__ */ React57.createElement(Text50, { color: FG.faint }, `${remainingSec}s`)));
9673
+ return /* @__PURE__ */ React59.createElement(Box48, { key: t2.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React59.createElement(Text51, { color }, rule), /* @__PURE__ */ React59.createElement(Box48, { flexDirection: "row" }, /* @__PURE__ */ React59.createElement(Text51, { color }, glyph), /* @__PURE__ */ React59.createElement(Text51, { bold: true, color: body }, ` ${t2.title}`), t2.detail !== void 0 && /* @__PURE__ */ React59.createElement(Text51, { color: FG.sub }, ` \xB7 ${t2.detail}`), /* @__PURE__ */ React59.createElement(Box48, { flexGrow: 1 }), /* @__PURE__ */ React59.createElement(Text51, { color: FG.faint }, `${remainingSec}s`)));
9604
9674
  }));
9605
9675
  }
9606
9676
 
9607
9677
  // src/cli/ui/layout/plan-live-row.tsx
9608
- import React58 from "react";
9678
+ import React60 from "react";
9609
9679
  function isActivePlanInFlight(card) {
9610
9680
  if (card.kind !== "plan") return false;
9611
9681
  if (card.variant !== "active") return false;
@@ -9620,7 +9690,7 @@ function PlanLiveRow() {
9620
9690
  return null;
9621
9691
  });
9622
9692
  if (!planCard) return null;
9623
- return /* @__PURE__ */ React58.createElement(PlanCard, { card: planCard });
9693
+ return /* @__PURE__ */ React60.createElement(PlanCard, { card: planCard });
9624
9694
  }
9625
9695
 
9626
9696
  // src/cli/ui/loop.ts
@@ -11109,8 +11179,8 @@ function writeClipboard(text) {
11109
11179
  }
11110
11180
 
11111
11181
  // src/cli/ui/ctx-breakdown.tsx
11112
- import { Box as Box48, Text as Text51 } from "ink";
11113
- import React59 from "react";
11182
+ import { Box as Box49, Text as Text52 } from "ink";
11183
+ import React61 from "react";
11114
11184
  function computeCtxBreakdown(loop2) {
11115
11185
  const systemTokens = countTokens(loop2.prefix.system);
11116
11186
  const toolsTokens = countTokens(JSON.stringify(loop2.prefix.toolSpecs));
@@ -11765,23 +11835,12 @@ var handlers15 = {
11765
11835
 
11766
11836
  // src/cli/ui/slash/handlers/theme.ts
11767
11837
  var themeChoices = ["auto", ...listThemeNames()];
11768
- function formatThemeStatus() {
11769
- const configured = loadTheme();
11770
- const active = resolveThemePreference(configured, process.env.REASONIX_THEME);
11771
- const source = configured && configured !== "auto" ? "config" : "env/default";
11772
- return [
11773
- `theme: ${active} (${source})`,
11774
- `configured: ${configured ?? "unset"}`,
11775
- `available: ${themeChoices.join(", ")}`,
11776
- "usage: /theme <name|auto>"
11777
- ].join("\n");
11778
- }
11779
11838
  function isThemeChoice(value) {
11780
11839
  return value === "auto" || isThemeName(value);
11781
11840
  }
11782
11841
  var theme = (args) => {
11783
11842
  const next = args[0];
11784
- if (!next) return { info: formatThemeStatus() };
11843
+ if (!next) return { openThemePicker: true };
11785
11844
  if (!isThemeChoice(next)) {
11786
11845
  return { info: `unknown theme: ${next}
11787
11846
  available: ${themeChoices.join(", ")}` };
@@ -11908,9 +11967,9 @@ var TurnTranslator = class {
11908
11967
  this.log.appendStreaming(this.streamingCardId, contentChunk);
11909
11968
  }
11910
11969
  }
11911
- toolStart(name, args) {
11970
+ toolStart(name, args, callId) {
11912
11971
  this.toolStartedAt = Date.now();
11913
- this.toolCardId = this.log.startTool(name, args);
11972
+ this.toolCardId = this.log.startTool(name, args, callId);
11914
11973
  }
11915
11974
  toolEnd(output) {
11916
11975
  if (this.toolCardId) {
@@ -11921,6 +11980,16 @@ var TurnTranslator = class {
11921
11980
  this.toolCardId = null;
11922
11981
  }
11923
11982
  }
11983
+ toolAbort(output) {
11984
+ if (this.toolCardId) {
11985
+ this.log.endTool(this.toolCardId, {
11986
+ output,
11987
+ elapsedMs: Date.now() - this.toolStartedAt,
11988
+ aborted: true
11989
+ });
11990
+ this.toolCardId = null;
11991
+ }
11992
+ }
11924
11993
  toolRetry(attempt, max) {
11925
11994
  if (this.toolCardId) this.log.retryTool(this.toolCardId, attempt, max);
11926
11995
  }
@@ -12814,13 +12883,13 @@ var PLAIN_UI = process.env.REASONIX_UI === "plain";
12814
12883
  function LoopStatusRow({
12815
12884
  loop: loop2
12816
12885
  }) {
12817
- const [, setTick] = React60.useState(0);
12818
- React60.useEffect(() => {
12886
+ const [, setTick] = React62.useState(0);
12887
+ React62.useEffect(() => {
12819
12888
  const id = setInterval(() => setTick((t2) => t2 + 1), 1e3);
12820
12889
  return () => clearInterval(id);
12821
12890
  }, []);
12822
12891
  const nextFireMs = Math.max(0, loop2.nextFireAt - Date.now());
12823
- return /* @__PURE__ */ React60.createElement(Box49, null, /* @__PURE__ */ React60.createElement(Text52, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
12892
+ return /* @__PURE__ */ React62.createElement(Box50, null, /* @__PURE__ */ React62.createElement(Text53, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
12824
12893
  }
12825
12894
  function App(props) {
12826
12895
  markPhase("app_render_start");
@@ -12829,12 +12898,14 @@ function App(props) {
12829
12898
  model: props.model,
12830
12899
  workspace: props.codeMode?.rootDir ?? process.cwd()
12831
12900
  });
12832
- const initialCards = React60.useMemo(
12901
+ const initialCards = React62.useMemo(
12833
12902
  () => props.session ? hydrateCardsFromMessages(loadSessionMessages(props.session)) : [],
12834
12903
  [props.session]
12835
12904
  );
12836
- const themeName = resolveThemePreference(loadTheme(), process.env.REASONIX_THEME);
12837
- return /* @__PURE__ */ React60.createElement(ThemeProvider, { name: themeName }, /* @__PURE__ */ React60.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ React60.createElement(AppInner, { ...props })));
12905
+ const [themeName, setThemeName] = React62.useState(
12906
+ () => resolveThemePreference(loadTheme(), process.env.REASONIX_THEME)
12907
+ );
12908
+ return /* @__PURE__ */ React62.createElement(ThemeProvider, { name: themeName }, /* @__PURE__ */ React62.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ React62.createElement(AppInner, { ...props, themeName, setThemeName })));
12838
12909
  }
12839
12910
  function AppInner({
12840
12911
  model: model2,
@@ -12850,7 +12921,9 @@ function AppInner({
12850
12921
  codeMode,
12851
12922
  noDashboard,
12852
12923
  onSwitchSession,
12853
- mouse = true
12924
+ mouse = true,
12925
+ themeName,
12926
+ setThemeName
12854
12927
  }) {
12855
12928
  markPhase("app_inner_start");
12856
12929
  const log = useScrollback();
@@ -12859,6 +12932,7 @@ function AppInner({
12859
12932
  (s) => s.cards.some((c) => c.kind === "user" || c.kind === "streaming")
12860
12933
  );
12861
12934
  const isStreaming = useAgentState((s) => s.cards.some((c) => c.kind === "streaming" && !c.done));
12935
+ const activityLabel = useActivityLabel();
12862
12936
  const chatScroll = useChatScroll();
12863
12937
  const [input, setInput] = useState20("");
12864
12938
  const [busy, setBusy] = useState20(false);
@@ -12965,13 +13039,14 @@ function AppInner({
12965
13039
  const [checkpointPickerList, setCheckpointPickerList] = useState20([]);
12966
13040
  const [pendingMcpHub, setPendingMcpHub] = useState20(null);
12967
13041
  const [pendingModelPicker, setPendingModelPicker] = useState20(false);
13042
+ const [pendingThemePicker, setPendingThemePicker] = useState20(false);
12968
13043
  const [stagedInput, setStagedInput] = useState20(null);
12969
13044
  const [pendingCheckpoint, setPendingCheckpoint] = useState20(null);
12970
13045
  const [stagedCheckpointRevise, setStagedCheckpointRevise] = useState20(null);
12971
13046
  const [pendingRevision, setPendingRevision] = useState20(null);
12972
13047
  const [pendingChoice, setPendingChoice] = useState20(null);
12973
13048
  const [stagedChoiceCustom, setStagedChoiceCustom] = useState20(null);
12974
- const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingCheckpointPicker || !!pendingMcpHub || pendingModelPicker || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
13049
+ const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingCheckpointPicker || !!pendingMcpHub || pendingModelPicker || pendingThemePicker || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
12975
13050
  const [planMode, setPlanMode] = useState20(false);
12976
13051
  const [proArmed, setProArmed] = useState20(false);
12977
13052
  const [turnOnPro, setTurnOnPro] = useState20(false);
@@ -13382,12 +13457,7 @@ function AppInner({
13382
13457
  if (key.escape && busy) {
13383
13458
  if (abortedThisTurn.current) return;
13384
13459
  abortedThisTurn.current = true;
13385
- const resolve3 = editReviewResolveRef.current;
13386
- if (resolve3) {
13387
- editReviewResolveRef.current = null;
13388
- setPendingEditReview(null);
13389
- resolve3({ choice: "reject" });
13390
- }
13460
+ resetPendingModals();
13391
13461
  if (isLoopActive()) stopLoop();
13392
13462
  loop2.abort();
13393
13463
  return;
@@ -13582,7 +13652,7 @@ function AppInner({
13582
13652
  if (dashboardRef.current) return dashboardRef.current.url;
13583
13653
  if (dashboardStartingRef.current) return dashboardStartingRef.current;
13584
13654
  const startup = (async () => {
13585
- const { startDashboardServer } = await import("./server-W4XJK4GX.js");
13655
+ const { startDashboardServer } = await import("./server-GNHR5K3N.js");
13586
13656
  const handle = await startDashboardServer({
13587
13657
  mode: "attached",
13588
13658
  configPath: defaultConfigPath(),
@@ -13906,7 +13976,7 @@ function AppInner({
13906
13976
  }
13907
13977
  if (text.startsWith("/") && !text.includes(" ")) {
13908
13978
  const typed = text.slice(1).toLowerCase();
13909
- const matches = suggestSlashCommands(typed, !!codeMode);
13979
+ const matches = suggestSlashCommands(typed, !!codeMode, slashUsage);
13910
13980
  const exact = matches.find((m) => m.cmd === typed);
13911
13981
  if (!exact && matches.length > 0) {
13912
13982
  const chosen = matches[slashSelected] ?? matches[0];
@@ -14103,6 +14173,11 @@ function AppInner({
14103
14173
  pushHistory(text);
14104
14174
  return;
14105
14175
  }
14176
+ if (result.openThemePicker) {
14177
+ setPendingThemePicker(true);
14178
+ pushHistory(text);
14179
+ return;
14180
+ }
14106
14181
  if (result.openArgPickerFor) {
14107
14182
  pushHistory(text);
14108
14183
  setInput(`/${result.openArgPickerFor} `);
@@ -14135,6 +14210,7 @@ function AppInner({
14135
14210
  stopLoop,
14136
14211
  quitProcess,
14137
14212
  pushHistory,
14213
+ resetPendingModals,
14138
14214
  text
14139
14215
  });
14140
14216
  if (outcome.kind === "resubmit") {
@@ -14346,7 +14422,13 @@ function AppInner({
14346
14422
  codeModeOn: !!codeMode
14347
14423
  });
14348
14424
  } else if (ev.role === "error") {
14349
- handleErrorEvent(ev, { log });
14425
+ handleErrorEvent(ev, {
14426
+ log,
14427
+ setOngoingTool,
14428
+ setToolProgress,
14429
+ toolStartedAtRef,
14430
+ translator
14431
+ });
14350
14432
  } else if (ev.role === "warning") {
14351
14433
  handleWarningEvent(ev, { log, setTurnOnPro });
14352
14434
  }
@@ -14400,6 +14482,7 @@ function AppInner({
14400
14482
  planMode,
14401
14483
  session,
14402
14484
  slashSelected,
14485
+ slashUsage,
14403
14486
  atState,
14404
14487
  atSelected,
14405
14488
  pickAtMention,
@@ -14469,6 +14552,24 @@ function AppInner({
14469
14552
  [pendingShell, codeMode, currentRootDir, log]
14470
14553
  );
14471
14554
  const pendingGateIdRef = useRef9(null);
14555
+ const resetPendingModals = useCallback11(() => {
14556
+ const editResolve = editReviewResolveRef.current;
14557
+ if (editResolve) {
14558
+ editReviewResolveRef.current = null;
14559
+ setPendingEditReview(null);
14560
+ editResolve({ choice: "reject" });
14561
+ }
14562
+ setPendingShell(null);
14563
+ setPendingPlan(null);
14564
+ setPendingCheckpoint(null);
14565
+ setPendingRevision(null);
14566
+ setPendingChoice(null);
14567
+ setStagedInput(null);
14568
+ setStagedChoiceCustom(null);
14569
+ setStagedCheckpointRevise(null);
14570
+ pendingGateIdRef.current = null;
14571
+ pauseGate.cancelAll();
14572
+ }, []);
14472
14573
  useEffect12(() => {
14473
14574
  if (!busy && queuedSubmit !== null) {
14474
14575
  const text = queuedSubmit;
@@ -14844,14 +14945,14 @@ function AppInner({
14844
14945
  []
14845
14946
  );
14846
14947
  const tickerSuspended = PLAIN_UI || modalOpen || !busy && !isStreaming;
14847
- return /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(TickerProvider, { disabled: tickerSuspended }, /* @__PURE__ */ React60.createElement(ViewportBudgetProvider, null, /* @__PURE__ */ React60.createElement(Box49, { flexDirection: "row", height: stdout?.rows ?? 24 }, /* @__PURE__ */ React60.createElement(Box49, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React60.createElement(Box49, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React60.createElement(LiveExpandContext.Provider, { value: liveExpand }, /* @__PURE__ */ React60.createElement(
14948
+ return /* @__PURE__ */ React62.createElement(React62.Fragment, null, /* @__PURE__ */ React62.createElement(TickerProvider, { disabled: tickerSuspended }, /* @__PURE__ */ React62.createElement(ViewportBudgetProvider, null, /* @__PURE__ */ React62.createElement(InflightProvider, { inflight: loop2.inflight }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "row", height: stdout?.rows ?? 24 }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React62.createElement(LiveExpandContext.Provider, { value: liveExpand }, /* @__PURE__ */ React62.createElement(
14848
14949
  CardStream,
14849
14950
  {
14850
14951
  suppressLive: modalOpen,
14851
14952
  scrollRows: chatScroll.scrollRows,
14852
14953
  onMaxScrollChange: chatScroll.setMaxScroll
14853
14954
  }
14854
- )), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */ React60.createElement(
14955
+ )), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */ React62.createElement(
14855
14956
  WelcomeBanner,
14856
14957
  {
14857
14958
  inCodeMode: !!codeMode,
@@ -14859,7 +14960,7 @@ function AppInner({
14859
14960
  dashboardUrl,
14860
14961
  languageVersion
14861
14962
  }
14862
- ) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && ongoingTool ? /* @__PURE__ */ React60.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && subagentActivities.length > 0 ? /* @__PURE__ */ React60.createElement(SubagentLiveStack, { activities: subagentActivities, max: 3 }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !ongoingTool && statusLine ? /* @__PURE__ */ React60.createElement(ThinkingRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !pendingChoice && !stagedChoiceCustom && !pendingRevision && !stagedCheckpointRevise && !pendingCheckpoint ? /* @__PURE__ */ React60.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && busy && !isStreaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React60.createElement(ThinkingRow, { text: "processing\u2026" }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview ? /* @__PURE__ */ React60.createElement(PlanLiveRow, null) : null, /* @__PURE__ */ React60.createElement(ToastRail, null)), stagedInput ? /* @__PURE__ */ React60.createElement(
14963
+ ) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && ongoingTool ? /* @__PURE__ */ React62.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && subagentActivities.length > 0 ? /* @__PURE__ */ React62.createElement(SubagentLiveStack, { activities: subagentActivities, max: 3 }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !ongoingTool && statusLine ? /* @__PURE__ */ React62.createElement(ThinkingRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !pendingChoice && !stagedChoiceCustom && !pendingRevision && !stagedCheckpointRevise && !pendingCheckpoint ? /* @__PURE__ */ React62.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && busy && !isStreaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React62.createElement(ThinkingRow, { text: activityLabel }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview ? /* @__PURE__ */ React62.createElement(PlanLiveRow, null) : null, /* @__PURE__ */ React62.createElement(ToastRail, null)), stagedInput ? /* @__PURE__ */ React62.createElement(
14863
14964
  PlanRefineInput,
14864
14965
  {
14865
14966
  mode: stagedInput.mode,
@@ -14867,21 +14968,21 @@ function AppInner({
14867
14968
  onSubmit: handleStagedInputSubmit,
14868
14969
  onCancel: handleStagedInputCancel
14869
14970
  }
14870
- ) : stagedChoiceCustom ? /* @__PURE__ */ React60.createElement(
14971
+ ) : stagedChoiceCustom ? /* @__PURE__ */ React62.createElement(
14871
14972
  PlanRefineInput,
14872
14973
  {
14873
14974
  mode: "choice-custom",
14874
14975
  onSubmit: handleChoiceCustomSubmit,
14875
14976
  onCancel: handleChoiceCustomCancel
14876
14977
  }
14877
- ) : stagedCheckpointRevise ? /* @__PURE__ */ React60.createElement(
14978
+ ) : stagedCheckpointRevise ? /* @__PURE__ */ React62.createElement(
14878
14979
  PlanRefineInput,
14879
14980
  {
14880
14981
  mode: "checkpoint-revise",
14881
14982
  onSubmit: (text) => handleCheckpointReviseSubmit(text, stagedCheckpointRevise),
14882
14983
  onCancel: handleCheckpointReviseCancel
14883
14984
  }
14884
- ) : pendingChoice ? /* @__PURE__ */ React60.createElement(
14985
+ ) : pendingChoice ? /* @__PURE__ */ React62.createElement(
14885
14986
  ChoiceConfirm,
14886
14987
  {
14887
14988
  question: pendingChoice.question,
@@ -14889,7 +14990,7 @@ function AppInner({
14889
14990
  allowCustom: pendingChoice.allowCustom,
14890
14991
  onChoose: stableHandleChoiceConfirm
14891
14992
  }
14892
- ) : pendingRevision ? /* @__PURE__ */ React60.createElement(
14993
+ ) : pendingRevision ? /* @__PURE__ */ React62.createElement(
14893
14994
  PlanReviseConfirm,
14894
14995
  {
14895
14996
  reason: pendingRevision.reason,
@@ -14900,7 +15001,7 @@ function AppInner({
14900
15001
  summary: pendingRevision.summary,
14901
15002
  onChoose: stableHandleReviseConfirm
14902
15003
  }
14903
- ) : pendingCheckpoint ? /* @__PURE__ */ React60.createElement(
15004
+ ) : pendingCheckpoint ? /* @__PURE__ */ React62.createElement(
14904
15005
  PlanCheckpointConfirm,
14905
15006
  {
14906
15007
  stepId: pendingCheckpoint.stepId,
@@ -14911,7 +15012,7 @@ function AppInner({
14911
15012
  completedStepIds: completedStepIdsRef.current,
14912
15013
  onChoose: stableHandleCheckpointConfirm
14913
15014
  }
14914
- ) : pendingCheckpointPicker ? /* @__PURE__ */ React60.createElement(
15015
+ ) : pendingCheckpointPicker ? /* @__PURE__ */ React62.createElement(
14915
15016
  CheckpointPicker,
14916
15017
  {
14917
15018
  checkpoints: checkpointPickerList,
@@ -14956,7 +15057,7 @@ function AppInner({
14956
15057
  }
14957
15058
  }
14958
15059
  }
14959
- ) : pendingSessionsPicker ? /* @__PURE__ */ React60.createElement(
15060
+ ) : pendingSessionsPicker ? /* @__PURE__ */ React62.createElement(
14960
15061
  SessionPicker,
14961
15062
  {
14962
15063
  sessions: sessionsPickerList,
@@ -15001,7 +15102,25 @@ function AppInner({
15001
15102
  }
15002
15103
  }
15003
15104
  }
15004
- ) : pendingModelPicker ? /* @__PURE__ */ React60.createElement(
15105
+ ) : pendingThemePicker ? /* @__PURE__ */ React62.createElement(
15106
+ ThemePicker,
15107
+ {
15108
+ currentPreference: loadTheme() ?? "auto",
15109
+ activeTheme: themeName,
15110
+ onChoose: (outcome) => {
15111
+ setPendingThemePicker(false);
15112
+ if (outcome.kind === "quit") return;
15113
+ saveTheme(outcome.value);
15114
+ const active = resolveThemePreference(
15115
+ outcome.value,
15116
+ process.env.REASONIX_THEME
15117
+ );
15118
+ setThemeName(active);
15119
+ log.pushInfo(`\u25B8 theme saved: ${outcome.value}
15120
+ active now: ${active}`);
15121
+ }
15122
+ }
15123
+ ) : pendingModelPicker ? /* @__PURE__ */ React62.createElement(
15005
15124
  ModelPicker,
15006
15125
  {
15007
15126
  models,
@@ -15033,7 +15152,7 @@ function AppInner({
15033
15152
  }
15034
15153
  }
15035
15154
  }
15036
- ) : pendingMcpHub ? /* @__PURE__ */ React60.createElement(
15155
+ ) : pendingMcpHub ? /* @__PURE__ */ React62.createElement(
15037
15156
  McpHub,
15038
15157
  {
15039
15158
  initialTab: pendingMcpHub.tab,
@@ -15053,7 +15172,7 @@ function AppInner({
15053
15172
  return r;
15054
15173
  } : void 0
15055
15174
  }
15056
- ) : pendingPlan ? /* @__PURE__ */ React60.createElement(
15175
+ ) : pendingPlan ? /* @__PURE__ */ React62.createElement(
15057
15176
  PlanConfirm,
15058
15177
  {
15059
15178
  plan: pendingPlan,
@@ -15062,7 +15181,7 @@ function AppInner({
15062
15181
  onChoose: stableHandlePlanConfirm,
15063
15182
  projectRoot: currentRootDir
15064
15183
  }
15065
- ) : pendingReviseEditor ? /* @__PURE__ */ React60.createElement(
15184
+ ) : pendingReviseEditor ? /* @__PURE__ */ React62.createElement(
15066
15185
  PlanReviseEditor,
15067
15186
  {
15068
15187
  steps: planStepsRef.current ?? [],
@@ -15081,7 +15200,7 @@ function AppInner({
15081
15200
  setPendingPlan(planText);
15082
15201
  }
15083
15202
  }
15084
- ) : pendingShell ? /* @__PURE__ */ React60.createElement(
15203
+ ) : pendingShell ? /* @__PURE__ */ React62.createElement(
15085
15204
  ShellConfirm,
15086
15205
  {
15087
15206
  command: pendingShell.command,
@@ -15089,7 +15208,7 @@ function AppInner({
15089
15208
  kind: pendingShell.kind,
15090
15209
  onChoose: handleShellConfirm
15091
15210
  }
15092
- ) : pendingEditReview ? /* @__PURE__ */ React60.createElement(
15211
+ ) : pendingEditReview ? /* @__PURE__ */ React62.createElement(
15093
15212
  EditConfirm,
15094
15213
  {
15095
15214
  block: pendingEditReview,
@@ -15101,14 +15220,14 @@ function AppInner({
15101
15220
  }
15102
15221
  }
15103
15222
  }
15104
- ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React60.createElement(
15223
+ ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React62.createElement(
15105
15224
  EditConfirm,
15106
15225
  {
15107
15226
  key: `walk-${pendingTick}`,
15108
15227
  block: pendingEdits.current[0],
15109
15228
  onChoose: handleWalkChoice
15110
15229
  }
15111
- ) : !chatScroll.pinned ? /* @__PURE__ */ React60.createElement(Text52, { color: FG.faint }, " \u{1F4D6} reading history \u2014 End / PgDn to return \xB7 \u2193 to advance one line") : /* @__PURE__ */ React60.createElement(Box49, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, /* @__PURE__ */ React60.createElement(Box49, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, codeMode ? /* @__PURE__ */ React60.createElement(
15230
+ ) : !chatScroll.pinned ? /* @__PURE__ */ React62.createElement(Text53, { color: FG.faint }, " \u{1F4D6} reading history \u2014 End / PgDn to return \xB7 \u2193 to advance one line") : /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, codeMode ? /* @__PURE__ */ React62.createElement(
15112
15231
  ModeStatusBar,
15113
15232
  {
15114
15233
  editMode,
@@ -15118,7 +15237,7 @@ function AppInner({
15118
15237
  undoArmed: !!undoBanner || hasUndoable(),
15119
15238
  jobs: codeMode.jobs
15120
15239
  }
15121
- ) : null, activeLoop ? /* @__PURE__ */ React60.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React60.createElement(StatusRow, null), /* @__PURE__ */ React60.createElement(
15240
+ ) : null, activeLoop ? /* @__PURE__ */ React62.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React62.createElement(StatusRow, null), /* @__PURE__ */ React62.createElement(
15122
15241
  PromptInput,
15123
15242
  {
15124
15243
  value: input,
@@ -15128,7 +15247,7 @@ function AppInner({
15128
15247
  onHistoryPrev: recallPrev,
15129
15248
  onHistoryNext: recallNext
15130
15249
  }
15131
- )), /* @__PURE__ */ React60.createElement(Box49, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, slashMatches !== null ? /* @__PURE__ */ React60.createElement(
15250
+ )), /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, slashMatches !== null ? /* @__PURE__ */ React62.createElement(
15132
15251
  SlashSuggestions,
15133
15252
  {
15134
15253
  key: `slash-suggestions:${slashGroupMode ? "group" : "search"}`,
@@ -15137,7 +15256,7 @@ function AppInner({
15137
15256
  groupMode: slashGroupMode,
15138
15257
  advancedHidden: slashAdvancedHidden
15139
15258
  }
15140
- ) : null, atState !== null ? /* @__PURE__ */ React60.createElement(AtMentionSuggestions, { state: atState, selectedIndex: atSelected }) : null), slashArgContext ? /* @__PURE__ */ React60.createElement(
15259
+ ) : null, atState !== null ? /* @__PURE__ */ React62.createElement(AtMentionSuggestions, { state: atState, selectedIndex: atSelected }) : null), slashArgContext ? /* @__PURE__ */ React62.createElement(
15141
15260
  SlashArgPicker,
15142
15261
  {
15143
15262
  matches: slashArgMatches,
@@ -15146,16 +15265,16 @@ function AppInner({
15146
15265
  kind: slashArgContext.kind,
15147
15266
  partial: slashArgContext.partial
15148
15267
  }
15149
- ) : null))))));
15268
+ ) : null)))))));
15150
15269
  }
15151
15270
 
15152
15271
  // src/cli/ui/Setup.tsx
15153
- import { Box as Box50, Text as Text54, useApp } from "ink";
15154
- import React62, { useState as useState21 } from "react";
15272
+ import { Box as Box51, Text as Text55, useApp } from "ink";
15273
+ import React64, { useState as useState21 } from "react";
15155
15274
 
15156
15275
  // src/cli/ui/MaskedInput.tsx
15157
- import { Text as Text53, useInput } from "ink";
15158
- import React61, { useRef as useRef10 } from "react";
15276
+ import { Text as Text54, useInput } from "ink";
15277
+ import React63, { useRef as useRef10 } from "react";
15159
15278
  function stripPasteMarkers(s) {
15160
15279
  return s.replace(/\u001b?\[20[01]~/g, "").replace(/\u001b/g, "");
15161
15280
  }
@@ -15190,11 +15309,11 @@ function MaskedInput({
15190
15309
  });
15191
15310
  if (value.length === 0) {
15192
15311
  if (placeholder.length === 0) {
15193
- return /* @__PURE__ */ React61.createElement(Text53, { inverse: true }, " ");
15312
+ return /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, " ");
15194
15313
  }
15195
- return /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, { inverse: true }, placeholder[0]), /* @__PURE__ */ React61.createElement(Text53, { color: FG.faint }, placeholder.slice(1)));
15314
+ return /* @__PURE__ */ React63.createElement(React63.Fragment, null, /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, placeholder[0]), /* @__PURE__ */ React63.createElement(Text54, { color: FG.faint }, placeholder.slice(1)));
15196
15315
  }
15197
- return /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, null, mask.repeat(value.length)), /* @__PURE__ */ React61.createElement(Text53, { inverse: true }, " "));
15316
+ return /* @__PURE__ */ React63.createElement(React63.Fragment, null, /* @__PURE__ */ React63.createElement(Text54, null, mask.repeat(value.length)), /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, " "));
15198
15317
  }
15199
15318
 
15200
15319
  // src/cli/ui/Setup.tsx
@@ -15221,7 +15340,7 @@ function Setup({ onReady }) {
15221
15340
  }
15222
15341
  onReady(trimmed);
15223
15342
  };
15224
- return /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React62.createElement(Box50, null, /* @__PURE__ */ React62.createElement(Text54, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React62.createElement(Text54, null, " "), /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "Welcome to "), /* @__PURE__ */ React62.createElement(Text54, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React62.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React62.createElement(Text54, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React62.createElement(Box50, null, /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, " sign up at \xB7 "), /* @__PURE__ */ React62.createElement(Text54, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React62.createElement(Box50, null, /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, " saved to "), /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React62.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React62.createElement(Text54, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React62.createElement(Text54, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React62.createElement(
15343
+ return /* @__PURE__ */ React64.createElement(Box51, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React64.createElement(Box51, null, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React64.createElement(Text55, null, " "), /* @__PURE__ */ React64.createElement(Text55, { bold: true }, "Welcome to "), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React64.createElement(Box51, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " sign up at \xB7 "), /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React64.createElement(Box51, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " saved to "), /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React64.createElement(
15225
15344
  MaskedInput,
15226
15345
  {
15227
15346
  value,
@@ -15230,7 +15349,7 @@ function Setup({ onReady }) {
15230
15349
  mask: "\u2022",
15231
15350
  placeholder: "sk-..."
15232
15351
  }
15233
- )), error ? /* @__PURE__ */ React62.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React62.createElement(Text54, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React62.createElement(Text54, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React62.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React62.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, " /exit to abort")));
15352
+ )), error ? /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " /exit to abort")));
15234
15353
  }
15235
15354
 
15236
15355
  // src/cli/ui/drain-tty.ts
@@ -15441,7 +15560,7 @@ function Root({
15441
15560
  const workspaceRoot = appProps.codeMode?.rootDir ?? process.cwd();
15442
15561
  const [sessions2, setSessions] = useState22(() => listSessionsForWorkspace(workspaceRoot));
15443
15562
  if (!key) {
15444
- return /* @__PURE__ */ React63.createElement(
15563
+ return /* @__PURE__ */ React65.createElement(
15445
15564
  Setup,
15446
15565
  {
15447
15566
  onReady: (k) => {
@@ -15453,7 +15572,7 @@ function Root({
15453
15572
  }
15454
15573
  process.env.DEEPSEEK_API_KEY = key;
15455
15574
  if (pickerOpen) {
15456
- return /* @__PURE__ */ React63.createElement(KeystrokeProvider, null, /* @__PURE__ */ React63.createElement(
15575
+ return /* @__PURE__ */ React65.createElement(KeystrokeProvider, null, /* @__PURE__ */ React65.createElement(
15457
15576
  SessionPicker,
15458
15577
  {
15459
15578
  sessions: sessions2,
@@ -15486,7 +15605,7 @@ function Root({
15486
15605
  }
15487
15606
  ));
15488
15607
  }
15489
- return /* @__PURE__ */ React63.createElement(KeystrokeProvider, null, /* @__PURE__ */ React63.createElement(
15608
+ return /* @__PURE__ */ React65.createElement(KeystrokeProvider, null, /* @__PURE__ */ React65.createElement(
15490
15609
  App,
15491
15610
  {
15492
15611
  key: activeSession ?? "__new__",
@@ -15559,7 +15678,7 @@ async function chatCommand(opts) {
15559
15678
  const showPicker = !opts.session && !opts.forceResume && listSessionsForWorkspace(launchWorkspace).length > 0;
15560
15679
  markPhase("ink_render_call");
15561
15680
  const { waitUntilExit } = render(
15562
- /* @__PURE__ */ React63.createElement(
15681
+ /* @__PURE__ */ React65.createElement(
15563
15682
  Root,
15564
15683
  {
15565
15684
  initialKey,
@@ -15600,4 +15719,4 @@ async function chatCommand(opts) {
15600
15719
  export {
15601
15720
  chatCommand
15602
15721
  };
15603
- //# sourceMappingURL=chunk-EN4LAZW5.js.map
15722
+ //# sourceMappingURL=chunk-NHV5YGTB.js.map