reasonix 0.7.4 → 0.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -7113,11 +7113,11 @@ function formatLogSize(path = defaultUsageLogPath()) {
7113
7113
  // src/cli/commands/chat.tsx
7114
7114
  import { existsSync as existsSync12, statSync as statSync7 } from "fs";
7115
7115
  import { render } from "ink";
7116
- import React25, { useState as useState12 } from "react";
7116
+ import React26, { useState as useState12 } from "react";
7117
7117
 
7118
7118
  // src/cli/ui/App.tsx
7119
- import { Box as Box20, Static, useApp, useStdout as useStdout5 } from "ink";
7120
- import React22, { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo3, useRef as useRef6, useState as useState10 } from "react";
7119
+ import { Box as Box21, Static, useApp, useStdout as useStdout8 } from "ink";
7120
+ import React23, { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo3, useRef as useRef6, useState as useState10 } from "react";
7121
7121
 
7122
7122
  // src/code/pending-edits.ts
7123
7123
  import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync11, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "fs";
@@ -7430,26 +7430,42 @@ function AtMentionSuggestions({
7430
7430
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1, marginTop: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((path, i) => /* @__PURE__ */ React.createElement(FileRow, { key: path, path, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick \xB7 file content inlined on send"));
7431
7431
  }
7432
7432
  function FileRow({ path, isSelected }) {
7433
- const marker = isSelected ? "\u25B8" : " ";
7434
7433
  const slash = path.lastIndexOf("/");
7435
7434
  const dir = slash >= 0 ? `${path.slice(0, slash)}/` : "";
7436
7435
  const base = slash >= 0 ? path.slice(slash + 1) : path;
7437
7436
  if (isSelected) {
7438
- return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "cyan" }, marker, " ", base), /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, dir ? ` ${dir}` : ""));
7437
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { backgroundColor: "#67e8f9", color: "black", bold: true }, ` \u25B8 ${base}${dir ? ` ${dir}` : ""} `));
7439
7438
  }
7440
- return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, marker, " ", base, dir ? ` ${dir}` : ""));
7439
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#94a3b8" }, ` ${base}`), dir ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` ${dir}`) : null);
7441
7440
  }
7442
7441
 
7443
7442
  // src/cli/ui/ChoiceConfirm.tsx
7444
- import { Box as Box3, Text as Text3 } from "ink";
7445
- import React4 from "react";
7443
+ import { Box as Box4 } from "ink";
7444
+ import React5 from "react";
7445
+
7446
+ // src/cli/ui/ModalCard.tsx
7447
+ import { Box as Box2, Text as Text2, useStdout } from "ink";
7448
+ import React2 from "react";
7449
+ function ModalCard({
7450
+ accent,
7451
+ title,
7452
+ subtitle,
7453
+ icon,
7454
+ children
7455
+ }) {
7456
+ const { stdout: stdout2 } = useStdout();
7457
+ const cols = stdout2?.columns ?? 80;
7458
+ const ruleWidth = Math.min(80, Math.max(28, cols - 4));
7459
+ const titleText = icon ? ` ${icon} ${title} ` : ` ${title} `;
7460
+ return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: accent }, "\u2594".repeat(ruleWidth))), /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: accent, color: "black", bold: true }, titleText), subtitle ? /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, ` ${subtitle}`) : null), /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, flexDirection: "column" }, children), /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: accent, dimColor: true }, "\u2581".repeat(ruleWidth))));
7461
+ }
7446
7462
 
7447
7463
  // src/cli/ui/Select.tsx
7448
- import { Box as Box2, Text as Text2 } from "ink";
7449
- import React3, { useState } from "react";
7464
+ import { Box as Box3, Text as Text3 } from "ink";
7465
+ import React4, { useState } from "react";
7450
7466
 
7451
7467
  // src/cli/ui/keystroke-context.tsx
7452
- import React2, { createContext, useContext, useEffect, useRef } from "react";
7468
+ import React3, { createContext, useContext, useEffect, useRef } from "react";
7453
7469
 
7454
7470
  // src/cli/ui/stdin-reader.ts
7455
7471
  import { stdin } from "process";
@@ -7771,7 +7787,7 @@ function KeystrokeProvider({
7771
7787
  unsubscribe();
7772
7788
  };
7773
7789
  }, [providedReader]);
7774
- return /* @__PURE__ */ React2.createElement(KeystrokeContext.Provider, { value: busRef.current }, children);
7790
+ return /* @__PURE__ */ React3.createElement(KeystrokeContext.Provider, { value: busRef.current }, children);
7775
7791
  }
7776
7792
  function useKeystroke(handler, isActive = true) {
7777
7793
  const bus = useContext(KeystrokeContext);
@@ -7809,7 +7825,7 @@ function SingleSelect({
7809
7825
  onCancel();
7810
7826
  }
7811
7827
  });
7812
- return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column" }, items.map((item, i) => /* @__PURE__ */ React3.createElement(
7828
+ return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, items.map((item, i) => /* @__PURE__ */ React4.createElement(
7813
7829
  SelectRow,
7814
7830
  {
7815
7831
  key: item.value,
@@ -7817,7 +7833,7 @@ function SingleSelect({
7817
7833
  active: i === index,
7818
7834
  marker: i === index ? "\u25B8" : " "
7819
7835
  }
7820
- )), footer ? /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text2, { dimColor: true }, footer)) : null);
7836
+ )), footer ? /* @__PURE__ */ React4.createElement(Box3, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(Text3, { dimColor: true }, footer)) : null);
7821
7837
  }
7822
7838
  function MultiSelect({
7823
7839
  items,
@@ -7853,10 +7869,10 @@ function MultiSelect({
7853
7869
  onCancel();
7854
7870
  }
7855
7871
  });
7856
- return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column" }, items.map((item, i) => {
7872
+ return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, items.map((item, i) => {
7857
7873
  const checked = selected.has(item.value);
7858
7874
  const marker = checked ? "[x]" : "[ ]";
7859
- return /* @__PURE__ */ React3.createElement(
7875
+ return /* @__PURE__ */ React4.createElement(
7860
7876
  SelectRow,
7861
7877
  {
7862
7878
  key: item.value,
@@ -7865,7 +7881,7 @@ function MultiSelect({
7865
7881
  marker: `${i === index ? "\u25B8" : " "} ${marker}`
7866
7882
  }
7867
7883
  );
7868
- }), footer ? /* @__PURE__ */ React3.createElement(Box2, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text2, { dimColor: true }, footer)) : null);
7884
+ }), footer ? /* @__PURE__ */ React4.createElement(Box3, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(Text3, { dimColor: true }, footer)) : null);
7869
7885
  }
7870
7886
  function SelectRow({
7871
7887
  item,
@@ -7873,7 +7889,7 @@ function SelectRow({
7873
7889
  marker
7874
7890
  }) {
7875
7891
  const color = item.disabled ? "gray" : active ? "cyan" : void 0;
7876
- return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box2, null, /* @__PURE__ */ React3.createElement(Text2, { color }, marker, " ", item.label)), item.hint ? /* @__PURE__ */ React3.createElement(Box2, { paddingLeft: marker.length + 1 }, /* @__PURE__ */ React3.createElement(Text2, { dimColor: true }, item.hint)) : null);
7892
+ return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box3, null, /* @__PURE__ */ React4.createElement(Text3, { color }, marker, " ", item.label)), item.hint ? /* @__PURE__ */ React4.createElement(Box3, { paddingLeft: marker.length + 1 }, /* @__PURE__ */ React4.createElement(Text3, { dimColor: true }, item.hint)) : null);
7877
7893
  }
7878
7894
  function findNextEnabled(items, from, step) {
7879
7895
  if (items.length === 0) return 0;
@@ -7906,7 +7922,7 @@ function ChoiceConfirmInner({ question, options, allowCustom, onChoose }) {
7906
7922
  label: "Cancel \u2014 drop the question",
7907
7923
  hint: "Model stops and asks what you want instead."
7908
7924
  });
7909
- return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React4.createElement(Box3, null, /* @__PURE__ */ React4.createElement(Text3, { bold: true, color: "magenta" }, "\u{1F500} the model is asking you to pick")), /* @__PURE__ */ React4.createElement(Box3, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(Text3, null, question)), /* @__PURE__ */ React4.createElement(Box3, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(
7925
+ return /* @__PURE__ */ React5.createElement(ModalCard, { accent: "#f0abfc", icon: "\u{1F500}", title: "model wants you to pick", subtitle: question }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(
7910
7926
  SingleSelect,
7911
7927
  {
7912
7928
  initialValue: options[0]?.id,
@@ -7921,11 +7937,11 @@ function ChoiceConfirmInner({ question, options, allowCustom, onChoose }) {
7921
7937
  }
7922
7938
  )));
7923
7939
  }
7924
- var ChoiceConfirm = React4.memo(ChoiceConfirmInner);
7940
+ var ChoiceConfirm = React5.memo(ChoiceConfirmInner);
7925
7941
 
7926
7942
  // src/cli/ui/EditConfirm.tsx
7927
- import { Box as Box4, Text as Text4, useStdout } from "ink";
7928
- import React5, { useMemo, useState as useState2 } from "react";
7943
+ import { Box as Box5, Text as Text4, useStdout as useStdout2 } from "ink";
7944
+ import React6, { useMemo, useState as useState2 } from "react";
7929
7945
 
7930
7946
  // src/code/diff-preview.ts
7931
7947
  function formatEditBlockDiff(block, opts = {}) {
@@ -8000,7 +8016,7 @@ function capLines(lines, maxLines, indent) {
8000
8016
  var MODAL_OVERHEAD_ROWS = 18;
8001
8017
  var MIN_DIFF_ROWS = 8;
8002
8018
  function EditConfirm({ block, onChoose }) {
8003
- const { stdout: stdout2 } = useStdout();
8019
+ const { stdout: stdout2 } = useStdout2();
8004
8020
  const rows = stdout2?.rows ?? 40;
8005
8021
  const budget = Math.max(MIN_DIFF_ROWS, rows - MODAL_OVERHEAD_ROWS);
8006
8022
  const allLines = useMemo(
@@ -8064,57 +8080,75 @@ function EditConfirm({ block, onChoose }) {
8064
8080
  const hiddenBelow = Math.max(0, allLines.length - effectiveScroll - budget);
8065
8081
  const totalLines = allLines.length;
8066
8082
  const showScrollHud = hiddenAbove + hiddenBelow > 0;
8067
- return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text4, { bold: true, color: "yellow" }, "\u25B8 model wants to edit a file")), /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text4, { color: "yellow", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React5.createElement(Box4, { marginTop: 1 }, /* @__PURE__ */ React5.createElement(Text4, null, /* @__PURE__ */ React5.createElement(Text4, { color: isNew ? "green" : "yellow", bold: true }, `[${tag}] `), /* @__PURE__ */ React5.createElement(Text4, { color: "cyan" }, block.path), /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, ` (-${removed} +${added} lines)`), showScrollHud ? /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, ` \xB7 viewing ${effectiveScroll + 1}-${effectiveScroll + visibleLines.length}/${totalLines}`) : null)), hiddenAbove > 0 ? /* @__PURE__ */ React5.createElement(
8068
- Text4,
8083
+ const subtitleParts = [`-${removed} +${added} lines`];
8084
+ if (showScrollHud) {
8085
+ subtitleParts.push(
8086
+ `viewing ${effectiveScroll + 1}-${effectiveScroll + visibleLines.length}/${totalLines}`
8087
+ );
8088
+ }
8089
+ return /* @__PURE__ */ React6.createElement(
8090
+ ModalCard,
8069
8091
  {
8070
- dimColor: true
8092
+ accent: isNew ? "#86efac" : "#fcd34d",
8093
+ icon: isNew ? "\u271A" : "\u270E",
8094
+ title: `${tag} ${block.path}`,
8095
+ subtitle: subtitleParts.join(" \xB7 ")
8071
8096
  },
8072
- ` \u2191 ${hiddenAbove} line${hiddenAbove === 1 ? "" : "s"} above (\u2191/k or PgUp)`
8073
- ) : null, /* @__PURE__ */ React5.createElement(Box4, { marginTop: hiddenAbove > 0 ? 0 : 1, flexDirection: "column" }, visibleLines.map((line, i) => {
8074
- const trimmed = line.trimStart();
8075
- const color = trimmed.startsWith("+") ? "green" : trimmed.startsWith("-") ? "red" : void 0;
8076
- const dim = !color;
8077
- return /* @__PURE__ */ React5.createElement(
8097
+ hiddenAbove > 0 ? /* @__PURE__ */ React6.createElement(
8078
8098
  Text4,
8079
8099
  {
8080
- key: `diff-${effectiveScroll}-${i}`,
8081
- color,
8082
- dimColor: dim
8100
+ dimColor: true
8083
8101
  },
8084
- line
8085
- );
8086
- })), hiddenBelow > 0 ? /* @__PURE__ */ React5.createElement(
8087
- Text4,
8088
- {
8089
- dimColor: true
8090
- },
8091
- ` \u2193 ${hiddenBelow} line${hiddenBelow === 1 ? "" : "s"} below (\u2193/j or Space/PgDn)`
8092
- ) : null, /* @__PURE__ */ React5.createElement(Box4, { marginTop: 1 }, /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, "[", /* @__PURE__ */ React5.createElement(Text4, { color: "cyan", bold: true }, "y"), "/Enter] apply \xB7 [", /* @__PURE__ */ React5.createElement(Text4, { color: "cyan", bold: true }, "n"), "] reject \xB7 [", /* @__PURE__ */ React5.createElement(Text4, { color: "cyan", bold: true }, "a"), "] apply rest \xB7 [", /* @__PURE__ */ React5.createElement(Text4, { color: "cyan", bold: true }, "A"), "] flip AUTO \xB7 [", /* @__PURE__ */ React5.createElement(Text4, { color: "cyan", bold: true }, "\u2191\u2193/Space"), "] scroll \xB7 [Esc] abort")));
8102
+ ` \u2191 ${hiddenAbove} line${hiddenAbove === 1 ? "" : "s"} above (\u2191/k or PgUp)`
8103
+ ) : null,
8104
+ /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column" }, visibleLines.map((line, i) => {
8105
+ const trimmed = line.trimStart();
8106
+ const color = trimmed.startsWith("+") ? "#4ade80" : trimmed.startsWith("-") ? "#f87171" : void 0;
8107
+ const dim = !color;
8108
+ return /* @__PURE__ */ React6.createElement(
8109
+ Text4,
8110
+ {
8111
+ key: `diff-${effectiveScroll}-${i}`,
8112
+ color,
8113
+ dimColor: dim
8114
+ },
8115
+ line
8116
+ );
8117
+ })),
8118
+ hiddenBelow > 0 ? /* @__PURE__ */ React6.createElement(
8119
+ Text4,
8120
+ {
8121
+ dimColor: true
8122
+ },
8123
+ ` \u2193 ${hiddenBelow} line${hiddenBelow === 1 ? "" : "s"} below (\u2193/j or Space/PgDn)`
8124
+ ) : null,
8125
+ /* @__PURE__ */ React6.createElement(Box5, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text4, { dimColor: true }, "[", /* @__PURE__ */ React6.createElement(Text4, { color: "#67e8f9", bold: true }, "y"), "/Enter] apply \xB7 [", /* @__PURE__ */ React6.createElement(Text4, { color: "#67e8f9", bold: true }, "n"), "] reject \xB7 [", /* @__PURE__ */ React6.createElement(Text4, { color: "#67e8f9", bold: true }, "a"), "] apply rest \xB7 [", /* @__PURE__ */ React6.createElement(Text4, { color: "#67e8f9", bold: true }, "A"), "] flip AUTO \xB7 [", /* @__PURE__ */ React6.createElement(Text4, { color: "#67e8f9", bold: true }, "\u2191\u2193/Space"), "] scroll \xB7 [Esc] abort"))
8126
+ );
8093
8127
  }
8094
8128
 
8095
8129
  // src/cli/ui/EventLog.tsx
8096
- import { Box as Box8, Text as Text8, useStdout as useStdout2 } from "ink";
8097
- import React10 from "react";
8130
+ import { Box as Box9, Text as Text8, useStdout as useStdout3 } from "ink";
8131
+ import React11 from "react";
8098
8132
 
8099
8133
  // src/cli/ui/PlanStateBlock.tsx
8100
- import { Box as Box5, Text as Text5 } from "ink";
8101
- import React6 from "react";
8134
+ import { Box as Box6, Text as Text5 } from "ink";
8135
+ import React7 from "react";
8102
8136
  function PlanStateBlock({ planState }) {
8103
8137
  const fields = [];
8104
- if (planState.subgoals.length) fields.push(["subgoals", planState.subgoals, "cyan", false]);
8138
+ if (planState.subgoals.length) fields.push(["subgoals", planState.subgoals, "#67e8f9", false]);
8105
8139
  if (planState.hypotheses.length)
8106
- fields.push(["hypotheses", planState.hypotheses, "green", false]);
8140
+ fields.push(["hypotheses", planState.hypotheses, "#86efac", false]);
8107
8141
  if (planState.uncertainties.length)
8108
- fields.push(["uncertainties", planState.uncertainties, "yellow", false]);
8142
+ fields.push(["uncertainties", planState.uncertainties, "#fcd34d", false]);
8109
8143
  if (planState.rejectedPaths.length)
8110
- fields.push(["rejected", planState.rejectedPaths, "red", true]);
8144
+ fields.push(["rejected", planState.rejectedPaths, "#94a3b8", true]);
8111
8145
  if (fields.length === 0) return null;
8112
- return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color, dim]) => /* @__PURE__ */ React6.createElement(Text5, { key: label }, /* @__PURE__ */ React6.createElement(Text5, { color, bold: true, dimColor: dim }, "\u2039 ", label), /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React6.createElement(Text5, null, `: ${items.join(" \xB7 ")}`))));
8146
+ return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color, dim]) => /* @__PURE__ */ React7.createElement(Box6, { key: label }, /* @__PURE__ */ React7.createElement(Text5, { backgroundColor: color, color: "black", bold: true, dimColor: dim }, ` ${label} ${items.length} `), /* @__PURE__ */ React7.createElement(Text5, null, " "), /* @__PURE__ */ React7.createElement(Text5, { dimColor: dim }, items.join(" \xB7 ")))));
8113
8147
  }
8114
8148
 
8115
8149
  // src/cli/ui/PlanStepList.tsx
8116
- import { Box as Box6, Text as Text6 } from "ink";
8117
- import React7 from "react";
8150
+ import { Box as Box7, Text as Text6 } from "ink";
8151
+ import React8 from "react";
8118
8152
  function riskDots(risk) {
8119
8153
  switch (risk) {
8120
8154
  case "high":
@@ -8127,18 +8161,6 @@ function riskDots(risk) {
8127
8161
  return { dots: " ", color: "gray" };
8128
8162
  }
8129
8163
  }
8130
- function statusGlyph(status2) {
8131
- switch (status2) {
8132
- case "done":
8133
- return { glyph: "\u2713", color: "green" };
8134
- case "running":
8135
- return { glyph: "\u25B6", color: "cyan" };
8136
- case "skipped":
8137
- return { glyph: "\u2014", color: "gray" };
8138
- default:
8139
- return { glyph: " ", color: "yellow" };
8140
- }
8141
- }
8142
8164
  function getStatus(stepId, statuses) {
8143
8165
  if (!statuses) return "pending";
8144
8166
  if (statuses instanceof Map) {
@@ -8153,25 +8175,37 @@ function PlanStepListInner({ steps, statuses, focusStepId }) {
8153
8175
  { length: steps.length },
8154
8176
  (_, i) => getStatus(steps[i].id, statuses)
8155
8177
  ).filter((s) => s === "done").length;
8156
- return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Box6, null, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, `${steps.length} step${steps.length === 1 ? "" : "s"}`, doneCount > 0 ? ` \xB7 ${doneCount} done` : "", hasAnyRisk ? " \xB7 risk: " : ""), hasAnyRisk ? /* @__PURE__ */ React7.createElement(RiskLegend, null) : null), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", marginTop: 1 }, steps.map((step) => {
8178
+ const pct2 = Math.round(doneCount / steps.length * 100);
8179
+ return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, `${steps.length} step${steps.length === 1 ? "" : "s"}`, doneCount > 0 ? ` \xB7 ${doneCount}/${steps.length} done (${pct2}%)` : "", hasAnyRisk ? " \xB7 risk: " : ""), hasAnyRisk ? /* @__PURE__ */ React8.createElement(RiskLegend, null) : null), /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", marginTop: 1 }, steps.map((step) => {
8157
8180
  const status2 = getStatus(step.id, statuses);
8158
8181
  const focus = focusStepId === step.id;
8159
8182
  const risk = riskDots(step.risk);
8160
- const glyph = statusGlyph(status2);
8161
8183
  const titleDim = status2 === "done" || status2 === "skipped";
8162
- return /* @__PURE__ */ React7.createElement(Box6, { key: step.id }, /* @__PURE__ */ React7.createElement(Text6, { color: focus ? "cyan" : "gray", bold: focus }, focus ? "\u203A " : " "), /* @__PURE__ */ React7.createElement(Text6, { color: risk.color, bold: true }, risk.dots), /* @__PURE__ */ React7.createElement(Text6, { color: glyph.color, bold: true }, ` ${glyph.glyph} `), /* @__PURE__ */ React7.createElement(Text6, { dimColor: titleDim }, `${step.id} \xB7 ${step.title}`));
8184
+ return /* @__PURE__ */ React8.createElement(Box7, { key: step.id }, /* @__PURE__ */ React8.createElement(Text6, { color: focus ? "#67e8f9" : "gray", bold: focus }, focus ? "\u25B8 " : " "), /* @__PURE__ */ React8.createElement(Text6, { color: risk.color, bold: true }, risk.dots), /* @__PURE__ */ React8.createElement(Text6, null, " "), /* @__PURE__ */ React8.createElement(StatusBadge, { status: status2 }), /* @__PURE__ */ React8.createElement(Text6, null, " "), /* @__PURE__ */ React8.createElement(Text6, { dimColor: titleDim, bold: focus }, `${step.id} \xB7 ${step.title}`));
8163
8185
  })));
8164
8186
  }
8187
+ function StatusBadge({ status: status2 }) {
8188
+ switch (status2) {
8189
+ case "done":
8190
+ return /* @__PURE__ */ React8.createElement(Text6, { backgroundColor: "#4ade80", color: "black", bold: true }, " \u2713 DONE ");
8191
+ case "running":
8192
+ return /* @__PURE__ */ React8.createElement(Text6, { backgroundColor: "#67e8f9", color: "black", bold: true }, " \u25B6 RUN ");
8193
+ case "skipped":
8194
+ return /* @__PURE__ */ React8.createElement(Text6, { backgroundColor: "#94a3b8", color: "black", bold: true }, " \u2014 SKIP ");
8195
+ default:
8196
+ return /* @__PURE__ */ React8.createElement(Text6, { color: "#94a3b8", dimColor: true }, " \u2610 PEND ");
8197
+ }
8198
+ }
8165
8199
  function RiskLegend() {
8166
- return /* @__PURE__ */ React7.createElement(Box6, null, /* @__PURE__ */ React7.createElement(Text6, { color: "green" }, "\u25CF"), /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, " low "), /* @__PURE__ */ React7.createElement(Text6, { color: "yellow" }, "\u25CF\u25CF"), /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, " med "), /* @__PURE__ */ React7.createElement(Text6, { color: "red" }, "\u25CF\u25CF\u25CF"), /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, " high"));
8200
+ return /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text6, { color: "green" }, "\u25CF"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " low "), /* @__PURE__ */ React8.createElement(Text6, { color: "yellow" }, "\u25CF\u25CF"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " med "), /* @__PURE__ */ React8.createElement(Text6, { color: "red" }, "\u25CF\u25CF\u25CF"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " high"));
8167
8201
  }
8168
- var PlanStepList = React7.memo(PlanStepListInner);
8202
+ var PlanStepList = React8.memo(PlanStepListInner);
8169
8203
 
8170
8204
  // src/cli/ui/markdown.tsx
8171
8205
  import { readFileSync as readFileSync13, statSync as statSync6 } from "fs";
8172
8206
  import { isAbsolute as isAbsolute4, join as join11 } from "path";
8173
- import { Box as Box7, Text as Text7 } from "ink";
8174
- import React8 from "react";
8207
+ import { Box as Box8, Text as Text7 } from "ink";
8208
+ import React9 from "react";
8175
8209
  var SUPERSCRIPT = {
8176
8210
  "0": "\u2070",
8177
8211
  "1": "\xB9",
@@ -8367,17 +8401,41 @@ function parseCitationUrl(url) {
8367
8401
  }
8368
8402
  return { path: trimmed };
8369
8403
  }
8404
+ var SIBLING_EXTENSIONS = /* @__PURE__ */ new Map([
8405
+ [".ts", [".tsx", ".mts", ".cts"]],
8406
+ [".tsx", [".ts"]],
8407
+ [".js", [".jsx", ".mjs", ".cjs"]],
8408
+ [".jsx", [".js"]],
8409
+ [".mjs", [".js", ".cjs"]],
8410
+ [".cjs", [".js", ".mjs"]],
8411
+ [".mts", [".ts"]],
8412
+ [".cts", [".ts"]]
8413
+ ]);
8414
+ function extOf(p) {
8415
+ const m = /\.[^./\\]+$/.exec(p);
8416
+ return m ? m[0] : "";
8417
+ }
8370
8418
  function validateCitation(url, projectRoot) {
8371
8419
  const parts = parseCitationUrl(url);
8372
8420
  if (!parts || !parts.path) return { ok: false, reason: "empty path" };
8373
8421
  const normalized = parts.path.replace(/^[/\\]+/, "");
8374
- const fullPath = isAbsolute4(normalized) ? normalized : join11(projectRoot, normalized);
8375
- let stat;
8376
- try {
8377
- stat = statSync6(fullPath);
8378
- } catch {
8379
- return { ok: false, reason: "file not found" };
8422
+ const baseFullPath = isAbsolute4(normalized) ? normalized : join11(projectRoot, normalized);
8423
+ const siblings = SIBLING_EXTENSIONS.get(extOf(baseFullPath)) ?? [];
8424
+ const candidates = [
8425
+ baseFullPath,
8426
+ ...siblings.map((ext) => baseFullPath.replace(/\.[^./\\]+$/, ext))
8427
+ ];
8428
+ let fullPath = baseFullPath;
8429
+ let stat = null;
8430
+ for (const candidate of candidates) {
8431
+ try {
8432
+ stat = statSync6(candidate);
8433
+ fullPath = candidate;
8434
+ break;
8435
+ } catch {
8436
+ }
8380
8437
  }
8438
+ if (!stat) return { ok: false, reason: "file not found" };
8381
8439
  if (!stat.isFile()) return { ok: false, reason: "not a file" };
8382
8440
  if (parts.startLine === void 0) return { ok: true };
8383
8441
  let lineCount;
@@ -8426,67 +8484,67 @@ function InlineMd({
8426
8484
  for (const m of text.matchAll(INLINE_RE)) {
8427
8485
  const start = m.index ?? 0;
8428
8486
  if (start > last) {
8429
- parts.push(/* @__PURE__ */ React8.createElement(Text7, { key: `t${idx++}` }, text.slice(last, start)));
8487
+ parts.push(/* @__PURE__ */ React9.createElement(Text7, { key: `t${idx++}` }, text.slice(last, start)));
8430
8488
  }
8431
8489
  if (m[2] !== void 0 && m[3] !== void 0) {
8432
8490
  const linkText = m[2];
8433
8491
  const url = m[3];
8434
8492
  if (isExternalUrl(url)) {
8435
8493
  parts.push(
8436
- /* @__PURE__ */ React8.createElement(Text7, { key: `l${idx++}`, color: "blue", underline: true }, linkText)
8494
+ /* @__PURE__ */ React9.createElement(Text7, { key: `l${idx++}`, color: "blue", underline: true }, linkText)
8437
8495
  );
8438
8496
  } else {
8439
8497
  const status2 = citations?.get(url);
8440
8498
  if (status2 && !status2.ok) {
8441
8499
  parts.push(
8442
- /* @__PURE__ */ React8.createElement(Text7, { key: `l${idx++}`, color: "red", strikethrough: true }, `${linkText} \u2717`)
8500
+ /* @__PURE__ */ React9.createElement(Text7, { key: `l${idx++}`, color: "red", strikethrough: true }, `${linkText} \u2717`)
8443
8501
  );
8444
8502
  } else {
8445
8503
  parts.push(
8446
- /* @__PURE__ */ React8.createElement(Text7, { key: `l${idx++}`, color: "cyan", underline: true }, linkText)
8504
+ /* @__PURE__ */ React9.createElement(Text7, { key: `l${idx++}`, color: "cyan", underline: true }, linkText)
8447
8505
  );
8448
8506
  }
8449
8507
  }
8450
8508
  } else if (m[4] !== void 0) {
8451
8509
  parts.push(
8452
- /* @__PURE__ */ React8.createElement(Text7, { key: `bi${idx++}`, bold: true, italic: true }, m[4])
8510
+ /* @__PURE__ */ React9.createElement(Text7, { key: `bi${idx++}`, bold: true, italic: true }, m[4])
8453
8511
  );
8454
8512
  } else if (m[5] !== void 0) {
8455
8513
  parts.push(
8456
- /* @__PURE__ */ React8.createElement(Text7, { key: `b${idx++}`, bold: true }, m[5])
8514
+ /* @__PURE__ */ React9.createElement(Text7, { key: `b${idx++}`, bold: true }, m[5])
8457
8515
  );
8458
8516
  } else if (m[6] !== void 0) {
8459
8517
  const stripped = m[6].replace(/^(\w+)\s+/, "");
8460
8518
  parts.push(
8461
- /* @__PURE__ */ React8.createElement(Text7, { key: `c${idx++}`, color: "yellow" }, stripped)
8519
+ /* @__PURE__ */ React9.createElement(Text7, { key: `c${idx++}`, color: "yellow" }, stripped)
8462
8520
  );
8463
8521
  } else if (m[7] !== void 0) {
8464
8522
  parts.push(
8465
- /* @__PURE__ */ React8.createElement(Text7, { key: `c${idx++}`, color: "yellow" }, m[7])
8523
+ /* @__PURE__ */ React9.createElement(Text7, { key: `c${idx++}`, color: "yellow" }, m[7])
8466
8524
  );
8467
8525
  } else if (m[8] !== void 0) {
8468
8526
  parts.push(
8469
- /* @__PURE__ */ React8.createElement(Text7, { key: `s${idx++}`, strikethrough: true, dimColor: true }, m[8])
8527
+ /* @__PURE__ */ React9.createElement(Text7, { key: `s${idx++}`, strikethrough: true, dimColor: true }, m[8])
8470
8528
  );
8471
8529
  } else if (m[9] !== void 0) {
8472
8530
  parts.push(
8473
- /* @__PURE__ */ React8.createElement(Text7, { key: `i${idx++}`, italic: true }, m[9])
8531
+ /* @__PURE__ */ React9.createElement(Text7, { key: `i${idx++}`, italic: true }, m[9])
8474
8532
  );
8475
8533
  } else if (m[10] !== void 0) {
8476
- parts.push(/* @__PURE__ */ React8.createElement(Text7, { key: `esc${idx++}` }, m[10]));
8534
+ parts.push(/* @__PURE__ */ React9.createElement(Text7, { key: `esc${idx++}` }, m[10]));
8477
8535
  }
8478
8536
  last = start + m[0].length;
8479
8537
  }
8480
8538
  if (last < text.length) {
8481
- parts.push(/* @__PURE__ */ React8.createElement(Text7, { key: `t${idx++}` }, text.slice(last)));
8539
+ parts.push(/* @__PURE__ */ React9.createElement(Text7, { key: `t${idx++}` }, text.slice(last)));
8482
8540
  }
8483
8541
  if (padTo !== void 0) {
8484
8542
  const seen = visibleWidth(text);
8485
8543
  if (seen < padTo) {
8486
- parts.push(/* @__PURE__ */ React8.createElement(Text7, { key: `pad${idx++}` }, " ".repeat(padTo - seen)));
8544
+ parts.push(/* @__PURE__ */ React9.createElement(Text7, { key: `pad${idx++}` }, " ".repeat(padTo - seen)));
8487
8545
  }
8488
8546
  }
8489
- return /* @__PURE__ */ React8.createElement(Text7, null, parts);
8547
+ return /* @__PURE__ */ React9.createElement(Text7, null, parts);
8490
8548
  }
8491
8549
  function stripInlineMarkup(s) {
8492
8550
  return s.replace(
@@ -8725,34 +8783,34 @@ function parseBulletItem(raw) {
8725
8783
  function BlockView({ block, citations }) {
8726
8784
  switch (block.kind) {
8727
8785
  case "heading":
8728
- return /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, /* @__PURE__ */ React8.createElement(InlineMd, { text: block.text, citations }));
8786
+ return /* @__PURE__ */ React9.createElement(HeadingView, { level: block.level, text: block.text, citations });
8729
8787
  case "paragraph":
8730
- return /* @__PURE__ */ React8.createElement(ParagraphView, { text: block.text, citations });
8788
+ return /* @__PURE__ */ React9.createElement(ParagraphView, { text: block.text, citations });
8731
8789
  case "bullet":
8732
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column" }, block.items.map((item, i) => /* @__PURE__ */ React8.createElement(Box7, { key: `${i}-${item.text.slice(0, 24)}` }, /* @__PURE__ */ React8.createElement(Text7, { color: item.task === "done" ? "green" : "cyan" }, bulletPrefix(block, i, item)), item.task === "done" ? /* @__PURE__ */ React8.createElement(Text7, { strikethrough: true, dimColor: true }, /* @__PURE__ */ React8.createElement(InlineMd, { text: item.text, citations })) : /* @__PURE__ */ React8.createElement(InlineMd, { text: item.text, citations }))));
8790
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column" }, block.items.map((item, i) => /* @__PURE__ */ React9.createElement(Box8, { key: `${i}-${item.text.slice(0, 24)}` }, /* @__PURE__ */ React9.createElement(Text7, { color: item.task === "done" ? "green" : "cyan" }, bulletPrefix(block, i, item)), item.task === "done" ? /* @__PURE__ */ React9.createElement(Text7, { strikethrough: true, dimColor: true }, /* @__PURE__ */ React9.createElement(InlineMd, { text: item.text, citations })) : /* @__PURE__ */ React9.createElement(InlineMd, { text: item.text, citations }))));
8733
8791
  case "quote":
8734
- return /* @__PURE__ */ React8.createElement(BlockquoteView, { block, citations });
8792
+ return /* @__PURE__ */ React9.createElement(BlockquoteView, { block, citations });
8735
8793
  case "code":
8736
8794
  if (DIAGRAM_LANGS.has(block.lang.toLowerCase())) {
8737
- return /* @__PURE__ */ React8.createElement(DiagramCodeBlock, { lang: block.lang, text: block.text });
8795
+ return /* @__PURE__ */ React9.createElement(DiagramCodeBlock, { lang: block.lang, text: block.text });
8738
8796
  }
8739
- return /* @__PURE__ */ React8.createElement(Box7, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, block.text));
8797
+ return /* @__PURE__ */ React9.createElement(CodeBlockView, { lang: block.lang, text: block.text });
8740
8798
  case "edit-block":
8741
- return /* @__PURE__ */ React8.createElement(EditBlockRow, { block });
8799
+ return /* @__PURE__ */ React9.createElement(EditBlockRow, { block });
8742
8800
  case "table":
8743
- return /* @__PURE__ */ React8.createElement(TableBlockRow, { block, citations });
8801
+ return /* @__PURE__ */ React9.createElement(TableBlockRow, { block, citations });
8744
8802
  case "hr":
8745
- return /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
8803
+ return /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
8746
8804
  }
8747
8805
  }
8748
8806
  function ParagraphView({ text, citations }) {
8749
8807
  if (!text.includes("\n")) {
8750
- return /* @__PURE__ */ React8.createElement(InlineMd, { text, citations });
8808
+ return /* @__PURE__ */ React9.createElement(InlineMd, { text, citations });
8751
8809
  }
8752
8810
  const rows = text.split("\n");
8753
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column" }, rows.map((row2, i) => (
8811
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column" }, rows.map((row2, i) => (
8754
8812
  // biome-ignore lint/suspicious/noArrayIndexKey: hard-break rows are source-ordered and never reorder
8755
- /* @__PURE__ */ React8.createElement(InlineMd, { key: `ln-${i}`, text: row2, citations })
8813
+ /* @__PURE__ */ React9.createElement(InlineMd, { key: `ln-${i}`, text: row2, citations })
8756
8814
  )));
8757
8815
  }
8758
8816
  function bulletPrefix(block, i, item) {
@@ -8765,12 +8823,11 @@ function BlockquoteView({
8765
8823
  block,
8766
8824
  citations
8767
8825
  }) {
8768
- return /* @__PURE__ */ React8.createElement(
8769
- Box7,
8826
+ return /* @__PURE__ */ React9.createElement(
8827
+ Box8,
8770
8828
  {
8771
8829
  borderStyle: "single",
8772
- borderColor: "gray",
8773
- borderDimColor: true,
8830
+ borderColor: "#c4b5fd",
8774
8831
  borderTop: false,
8775
8832
  borderRight: false,
8776
8833
  borderBottom: false,
@@ -8778,7 +8835,7 @@ function BlockquoteView({
8778
8835
  flexDirection: "column",
8779
8836
  gap: 1
8780
8837
  },
8781
- block.children.map((child, i) => /* @__PURE__ */ React8.createElement(BlockView, { key: `q-${i}-${child.kind}`, block: child, citations }))
8838
+ block.children.map((child, i) => /* @__PURE__ */ React9.createElement(BlockView, { key: `q-${i}-${child.kind}`, block: child, citations }))
8782
8839
  );
8783
8840
  }
8784
8841
  function splitTableRow(line) {
@@ -8796,14 +8853,14 @@ function TableBlockRow({ block, citations }) {
8796
8853
  widths.push(Math.min(40, Math.max(3, ...cellLengths)));
8797
8854
  }
8798
8855
  const separator = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u253C\u2500");
8799
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box7, null, block.header.map((cell, ci) => (
8856
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Box8, null, block.header.map((cell, ci) => (
8800
8857
  // biome-ignore lint/suspicious/noArrayIndexKey: table columns never reorder — derived from a static header array
8801
- /* @__PURE__ */ React8.createElement(Text7, { key: `h-${ci}`, bold: true, color: "cyan" }, /* @__PURE__ */ React8.createElement(InlineMd, { text: cell, padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
8802
- ))), /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, separator), block.rows.map((row2, ri) => (
8858
+ /* @__PURE__ */ React9.createElement(Text7, { key: `h-${ci}`, bold: true, color: "cyan" }, /* @__PURE__ */ React9.createElement(InlineMd, { text: cell, padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
8859
+ ))), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, separator), block.rows.map((row2, ri) => (
8803
8860
  // biome-ignore lint/suspicious/noArrayIndexKey: table rows render in source order and don't reorder
8804
- /* @__PURE__ */ React8.createElement(Box7, { key: `r-${ri}` }, Array.from({ length: colCount }).map((_, ci) => (
8861
+ /* @__PURE__ */ React9.createElement(Box8, { key: `r-${ri}` }, Array.from({ length: colCount }).map((_, ci) => (
8805
8862
  // biome-ignore lint/suspicious/noArrayIndexKey: same — column axis is fixed by the table shape
8806
- /* @__PURE__ */ React8.createElement(Text7, { key: `c-${ri}-${ci}` }, /* @__PURE__ */ React8.createElement(InlineMd, { text: row2[ci] ?? "", padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
8863
+ /* @__PURE__ */ React9.createElement(Text7, { key: `c-${ri}-${ci}` }, /* @__PURE__ */ React9.createElement(InlineMd, { text: row2[ci] ?? "", padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
8807
8864
  )))
8808
8865
  )));
8809
8866
  }
@@ -8823,7 +8880,7 @@ function EditBlockRow({ block }) {
8823
8880
  const isNewFile = block.search.length === 0;
8824
8881
  const searchLines = block.search.split("\n");
8825
8882
  const replaceLines = block.replace.split("\n");
8826
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, block.filename), isNewFile ? /* @__PURE__ */ React8.createElement(Text7, { color: "green", bold: true }, " (new file)") : null), isNewFile ? null : /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", marginTop: 1 }, searchLines.map((line, i) => /* @__PURE__ */ React8.createElement(Text7, { key: `s-${i}-${line.length}`, color: "red" }, `- ${line}`))), /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", marginTop: isNewFile ? 1 : 0 }, replaceLines.map((line, i) => /* @__PURE__ */ React8.createElement(Text7, { key: `r-${i}-${line.length}`, color: "green" }, `+ ${line}`))));
8883
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: "cyan" }, block.filename), isNewFile ? /* @__PURE__ */ React9.createElement(Text7, { color: "green", bold: true }, " (new file)") : null), isNewFile ? null : /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", marginTop: 1 }, searchLines.map((line, i) => /* @__PURE__ */ React9.createElement(Text7, { key: `s-${i}-${line.length}`, color: "red" }, `- ${line}`))), /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", marginTop: isNewFile ? 1 : 0 }, replaceLines.map((line, i) => /* @__PURE__ */ React9.createElement(Text7, { key: `r-${i}-${line.length}`, color: "green" }, `+ ${line}`))));
8827
8884
  }
8828
8885
  var DIAGRAM_LANGS = /* @__PURE__ */ new Set([
8829
8886
  "mermaid",
@@ -8843,30 +8900,124 @@ var DIAGRAM_VIEWER_HINT = {
8843
8900
  dot: "\u2192 paste at https://dreampuf.github.io/GraphvizOnline to view",
8844
8901
  graphviz: "\u2192 paste at https://dreampuf.github.io/GraphvizOnline to view"
8845
8902
  };
8903
+ function HeadingView({
8904
+ level,
8905
+ text,
8906
+ citations
8907
+ }) {
8908
+ if (level === 1) {
8909
+ return /* @__PURE__ */ React9.createElement(Box8, { marginY: 1 }, /* @__PURE__ */ React9.createElement(Text7, { backgroundColor: "#67e8f9", color: "black", bold: true }, ` ${text} `));
8910
+ }
8911
+ if (level === 2) {
8912
+ return /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text7, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` ${text} `));
8913
+ }
8914
+ if (level === 3) {
8915
+ return /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text7, { backgroundColor: "#f0abfc", color: "black", bold: true }, ` ${text} `));
8916
+ }
8917
+ return /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: "#f0abfc" }, "\u25B8", " "), /* @__PURE__ */ React9.createElement(Text7, { bold: true }, /* @__PURE__ */ React9.createElement(InlineMd, { text, citations })));
8918
+ }
8919
+ function CodeBlockView({ lang, text }) {
8920
+ const langLabel = lang.trim();
8921
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "#7dd3fc", paddingX: 1 }, langLabel ? /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text7, { backgroundColor: "#7dd3fc", color: "black", bold: true }, ` ${langLabel} `)) : null, /* @__PURE__ */ React9.createElement(Text7, { color: "#fde68a" }, text));
8922
+ }
8846
8923
  function DiagramCodeBlock({ lang, text }) {
8847
8924
  const hint = DIAGRAM_VIEWER_HINT[lang.toLowerCase()] ?? "\u2192 render with the matching viewer to view";
8848
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", borderStyle: "double", borderColor: "magenta", paddingX: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "magenta" }, `\u25C7 ${lang} diagram (source \u2014 terminal can't draw the graph)`), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, text)), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, hint)));
8925
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", borderStyle: "double", borderColor: "magenta", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: "magenta" }, `\u25C7 ${lang} diagram (source \u2014 terminal can't draw the graph)`), /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text7, { color: "yellow" }, text)), /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, hint)));
8849
8926
  }
8850
8927
  function Markdown({ text, projectRoot }) {
8851
8928
  const cleaned = expandAutolinks(expandEmoji(stripMath(text)));
8852
8929
  const root = projectRoot ?? process.cwd();
8853
- const citations = React8.useMemo(() => collectCitations(cleaned, root), [cleaned, root]);
8854
- const blocks = React8.useMemo(() => parseBlocks(cleaned), [cleaned]);
8930
+ const citations = React9.useMemo(() => collectCitations(cleaned, root), [cleaned, root]);
8931
+ const blocks = React9.useMemo(() => parseBlocks(cleaned), [cleaned]);
8855
8932
  const broken = [];
8856
8933
  for (const [url, status2] of citations) {
8857
8934
  if (!status2.ok) broken.push({ url, reason: status2.reason });
8858
8935
  }
8859
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", gap: 1 }, blocks.map((b, i) => /* @__PURE__ */ React8.createElement(BlockView, { key: `${i}-${b.kind}`, block: b, citations })), broken.length > 0 ? /* @__PURE__ */ React8.createElement(BrokenCitationsBlock, { items: broken }) : null);
8936
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", gap: 1 }, blocks.map((b, i) => /* @__PURE__ */ React9.createElement(BlockView, { key: `${i}-${b.kind}`, block: b, citations })), broken.length > 0 ? /* @__PURE__ */ React9.createElement(BrokenCitationsBlock, { items: broken }) : null);
8860
8937
  }
8861
8938
  function BrokenCitationsBlock({ items }) {
8862
- return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red", bold: true }, `\u26A0 ${items.length} broken citation${items.length > 1 ? "s" : ""} \u2014 the model referenced paths or lines that don't exist`), items.map((b, i) => (
8939
+ return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Text7, { color: "red", bold: true }, `\u26A0 ${items.length} broken citation${items.length > 1 ? "s" : ""} \u2014 the model referenced paths or lines that don't exist`), items.map((b, i) => (
8863
8940
  // biome-ignore lint/suspicious/noArrayIndexKey: list is derived from a Map iteration order, stable per render
8864
- /* @__PURE__ */ React8.createElement(Text7, { key: `bc-${i}`, color: "red" }, ` \u2717 ${b.url} \u2192 ${b.reason}`)
8941
+ /* @__PURE__ */ React9.createElement(Text7, { key: `bc-${i}`, color: "red" }, ` \u2717 ${b.url} \u2192 ${b.reason}`)
8865
8942
  )));
8866
8943
  }
8867
8944
 
8945
+ // src/cli/ui/theme.ts
8946
+ var GRADIENT = [
8947
+ "#5eead4",
8948
+ // teal
8949
+ "#67e8f9",
8950
+ // cyan
8951
+ "#7dd3fc",
8952
+ // sky
8953
+ "#93c5fd",
8954
+ // blue
8955
+ "#a5b4fc",
8956
+ // indigo
8957
+ "#c4b5fd",
8958
+ // violet
8959
+ "#d8b4fe",
8960
+ // purple
8961
+ "#f0abfc"
8962
+ // fuchsia
8963
+ ];
8964
+ var COLOR = {
8965
+ primary: "#67e8f9",
8966
+ // cyan-300
8967
+ accent: "#c4b5fd",
8968
+ // violet-300
8969
+ brand: "#5eead4",
8970
+ // teal-300
8971
+ user: "#67e8f9",
8972
+ // user message glyph + bar
8973
+ assistant: "#86efac",
8974
+ // green-300, assistant glyph + bar
8975
+ tool: "#fcd34d",
8976
+ // amber-300, tool ok pill bg
8977
+ toolErr: "#fda4af",
8978
+ // rose-300, tool err pill bg
8979
+ info: "#94a3b8",
8980
+ // slate-400, info / dim
8981
+ warn: "#fbbf24",
8982
+ // amber-400
8983
+ err: "#f87171",
8984
+ // red-400
8985
+ ok: "#4ade80"
8986
+ // green-400
8987
+ };
8988
+ var GLYPH = {
8989
+ brand: "\u25C8",
8990
+ user: "\u25C7",
8991
+ assistant: "\u25C6",
8992
+ toolOk: "\u25A3",
8993
+ toolErr: "\u25A5",
8994
+ warn: "\u25B2",
8995
+ err: "\u2726",
8996
+ arrow: "\u203A",
8997
+ bullet: "\xB7",
8998
+ bar: "\u258E",
8999
+ thinBar: "\u258F",
9000
+ block: "\u2588",
9001
+ shade1: "\u2591",
9002
+ shade2: "\u2592",
9003
+ shade3: "\u2593"
9004
+ };
9005
+ function gradientCells(width, glyph = GLYPH.block) {
9006
+ const cells = [];
9007
+ if (width <= 0) return cells;
9008
+ const last = GRADIENT.length - 1;
9009
+ for (let i = 0; i < width; i++) {
9010
+ const t = width === 1 ? 0 : i * last / (width - 1);
9011
+ const lo = Math.floor(t);
9012
+ const hi = Math.min(last, lo + 1);
9013
+ const color = t - lo < 0.5 ? GRADIENT[lo] : GRADIENT[hi];
9014
+ cells.push({ ch: glyph, color });
9015
+ }
9016
+ return cells;
9017
+ }
9018
+
8868
9019
  // src/cli/ui/ticker.tsx
8869
- import React9, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState3 } from "react";
9020
+ import React10, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState3 } from "react";
8870
9021
  var TICK_MS = 120;
8871
9022
  var TickContext = createContext2(0);
8872
9023
  function TickerProvider({ children, disabled }) {
@@ -8876,7 +9027,7 @@ function TickerProvider({ children, disabled }) {
8876
9027
  const id = setInterval(() => setTick((t) => t + 1), TICK_MS);
8877
9028
  return () => clearInterval(id);
8878
9029
  }, [disabled]);
8879
- return /* @__PURE__ */ React9.createElement(TickContext.Provider, { value: tick }, children);
9030
+ return /* @__PURE__ */ React10.createElement(TickContext.Provider, { value: tick }, children);
8880
9031
  }
8881
9032
  function useTick() {
8882
9033
  return useContext2(TickContext);
@@ -9029,51 +9180,105 @@ function RoleGlyph({
9029
9180
  glyph,
9030
9181
  color
9031
9182
  }) {
9032
- return /* @__PURE__ */ React10.createElement(Text8, { color, bold: true }, glyph);
9183
+ return /* @__PURE__ */ React11.createElement(Text8, { color, bold: true }, glyph);
9184
+ }
9185
+ function ToolPill({ label, status: status2 }) {
9186
+ const bg = status2 === "err" ? "red" : "yellow";
9187
+ const symbol = status2 === "err" ? "\u2717" : "\u2713";
9188
+ return /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: bg, color: "black", bold: true }, ` ${symbol} ${label} `);
9033
9189
  }
9034
9190
  function indentContinuationLines(text) {
9035
9191
  if (!text.includes("\n")) return text;
9036
9192
  return text.split("\n").join("\n ");
9037
9193
  }
9038
- var EventRow = React10.memo(function EventRow2({
9194
+ var EventRow = React11.memo(function EventRow2({
9039
9195
  event,
9040
9196
  projectRoot
9041
9197
  }) {
9042
9198
  if (event.role === "user") {
9043
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, event.leadSeparator ? /* @__PURE__ */ React10.createElement(TurnSeparator, null) : null, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React10.createElement(Text8, null, " ", indentContinuationLines(event.text))));
9199
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column" }, event.leadSeparator ? /* @__PURE__ */ React11.createElement(TurnSeparator, null) : null, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(
9200
+ Box9,
9201
+ {
9202
+ flexDirection: "column",
9203
+ borderStyle: "single",
9204
+ borderTop: false,
9205
+ borderRight: false,
9206
+ borderBottom: false,
9207
+ borderColor: COLOR.user,
9208
+ paddingLeft: 1
9209
+ },
9210
+ /* @__PURE__ */ React11.createElement(Text8, null, indentContinuationLines(event.text))
9211
+ )));
9044
9212
  }
9045
9213
  if (event.role === "assistant") {
9046
- if (event.streaming) return /* @__PURE__ */ React10.createElement(StreamingAssistant, { event });
9047
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(RoleGlyph, { glyph: ROLE_GLYPH.assistant, color: "green" }), event.stats ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${event.stats.model}`) : null), /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", paddingLeft: 2, marginTop: 1 }, event.branch ? /* @__PURE__ */ React10.createElement(BranchBlock, { branch: event.branch }) : null, event.reasoning ? /* @__PURE__ */ React10.createElement(ReasoningBlock, { reasoning: event.reasoning }) : null, !isPlanStateEmpty(event.planState) ? /* @__PURE__ */ React10.createElement(PlanStateBlock, { planState: event.planState }) : null, event.text ? /* @__PURE__ */ React10.createElement(Markdown, { text: event.text, projectRoot }) : /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "(no content)"), event.stats ? /* @__PURE__ */ React10.createElement(StatsLine, { stats: event.stats }) : null, event.repair ? /* @__PURE__ */ React10.createElement(Text8, { color: "magenta" }, event.repair) : null));
9214
+ if (event.streaming) return /* @__PURE__ */ React11.createElement(StreamingAssistant, { event });
9215
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(RoleGlyph, { glyph: ROLE_GLYPH.assistant, color: "green" }), event.stats ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: COLOR.assistant, color: "black", bold: true }, ` ${event.stats.model.replace(/^deepseek-/, "")} `)) : null), /* @__PURE__ */ React11.createElement(
9216
+ Box9,
9217
+ {
9218
+ flexDirection: "column",
9219
+ marginTop: 1,
9220
+ borderStyle: "single",
9221
+ borderTop: false,
9222
+ borderRight: false,
9223
+ borderBottom: false,
9224
+ borderColor: COLOR.assistant,
9225
+ paddingLeft: 1
9226
+ },
9227
+ event.branch ? /* @__PURE__ */ React11.createElement(BranchBlock, { branch: event.branch }) : null,
9228
+ event.reasoning ? /* @__PURE__ */ React11.createElement(ReasoningBlock, { reasoning: event.reasoning }) : null,
9229
+ !isPlanStateEmpty(event.planState) ? /* @__PURE__ */ React11.createElement(PlanStateBlock, { planState: event.planState }) : null,
9230
+ event.text ? /* @__PURE__ */ React11.createElement(Markdown, { text: event.text, projectRoot }) : /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, "(no content)"),
9231
+ event.stats ? /* @__PURE__ */ React11.createElement(StatsLine, { stats: event.stats }) : null,
9232
+ event.repair ? /* @__PURE__ */ React11.createElement(Text8, { color: COLOR.accent }, event.repair) : null
9233
+ ));
9048
9234
  }
9049
9235
  if (event.role === "tool") {
9050
9236
  const isExplicitError = event.text.startsWith("ERROR:");
9051
9237
  const isEditFile = (event.toolName === "edit_file" || event.toolName?.endsWith("_edit_file")) && !isExplicitError;
9052
9238
  if (isEditFile) {
9053
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(RoleGlyph, { glyph: ROLE_GLYPH.toolOk, color: "yellow" }), /* @__PURE__ */ React10.createElement(Text8, { color: "yellow", bold: true }, ` ${event.toolName ?? "?"}`), /* @__PURE__ */ React10.createElement(Text8, { color: "yellow", dimColor: true }, " \u2192")), /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", paddingLeft: 2, marginTop: 1 }, /* @__PURE__ */ React10.createElement(EditFileDiff, { text: event.text })));
9239
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(ToolPill, { label: event.toolName ?? "?", status: "ok" }), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, " diff:")), /* @__PURE__ */ React11.createElement(
9240
+ Box9,
9241
+ {
9242
+ flexDirection: "column",
9243
+ marginTop: 1,
9244
+ borderStyle: "single",
9245
+ borderTop: false,
9246
+ borderRight: false,
9247
+ borderBottom: false,
9248
+ borderColor: COLOR.tool,
9249
+ paddingLeft: 1
9250
+ },
9251
+ /* @__PURE__ */ React11.createElement(EditFileDiff, { text: event.text })
9252
+ ));
9054
9253
  }
9055
9254
  const summary = summarizeToolResult(event.toolName ?? "?", event.text);
9056
- const color = summary.isError ? "red" : "yellow";
9057
- const glyph = summary.isError ? ROLE_GLYPH.toolErr : ROLE_GLYPH.toolOk;
9058
- const marker = summary.isError ? "\u2717" : "\u2192";
9059
- const durationLabel = event.durationMs !== void 0 && event.durationMs >= 100 ? ` (${formatDuration(event.durationMs)})` : "";
9255
+ const status2 = summary.isError ? "err" : "ok";
9256
+ const durationLabel = event.durationMs !== void 0 && event.durationMs >= 100 ? formatDuration(event.durationMs) : "";
9060
9257
  const indexHint = event.toolIndex !== void 0 ? ` /tool ${event.toolIndex}` : "";
9061
- return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(RoleGlyph, { glyph, color }), /* @__PURE__ */ React10.createElement(Text8, { color, bold: true }, ` ${event.toolName ?? "?"}`), durationLabel ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, durationLabel) : null, /* @__PURE__ */ React10.createElement(Text8, { color, dimColor: true }, ` ${marker} `), /* @__PURE__ */ React10.createElement(Text8, { color: summary.isError ? "red" : void 0, dimColor: !summary.isError }, summary.summary), indexHint ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, indexHint) : null);
9258
+ return /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(ToolPill, { label: event.toolName ?? "?", status: status2 }), durationLabel ? /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` ${durationLabel}`) : null, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, " "), /* @__PURE__ */ React11.createElement(Text8, { color: status2 === "err" ? "red" : void 0, dimColor: status2 === "ok" }, summary.summary), indexHint ? /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, indexHint) : null);
9062
9259
  }
9063
9260
  if (event.role === "error") {
9064
- return /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(RoleGlyph, { glyph: ROLE_GLYPH.error, color: "red" }), /* @__PURE__ */ React10.createElement(Text8, { color: "red" }, " ", indentContinuationLines(event.text)));
9261
+ return /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#f87171", color: "black", bold: true }, " \u2726 ERROR "), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#f87171" }, indentContinuationLines(event.text)));
9065
9262
  }
9066
9263
  if (event.role === "info") {
9067
- return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, event.text));
9264
+ const m = event.text.match(/^([▸▶▲⚠✓✗✖↻ⓘ])\s*(.*)$/s);
9265
+ const lead = m?.[1] ?? "\u25B8";
9266
+ const body = m?.[2] ?? event.text;
9267
+ let leadColor = COLOR.info;
9268
+ if (lead === "\u25B2" || lead === "\u26A0") leadColor = COLOR.warn;
9269
+ else if (lead === "\u2713") leadColor = COLOR.ok;
9270
+ else if (lead === "\u2717" || lead === "\u2716") leadColor = COLOR.err;
9271
+ else if (lead === "\u21BB") leadColor = COLOR.primary;
9272
+ return /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { color: leadColor, bold: true }, lead), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, body));
9068
9273
  }
9069
9274
  if (event.role === "plan") {
9070
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { bold: true, color: "cyan" }, "\u{1F4CB} plan proposed \u2014 pick a choice below")), /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Markdown, { text: event.text, projectRoot })));
9275
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { bold: true, color: "cyan" }, "\u{1F4CB} plan proposed \u2014 pick a choice below")), /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Markdown, { text: event.text, projectRoot })));
9071
9276
  }
9072
9277
  if (event.role === "step-progress") {
9073
9278
  const sp = event.stepProgress;
9074
- const counter = sp && sp.total > 0 ? ` (${sp.completed}/${sp.total})` : "";
9279
+ const counter = sp && sp.total > 0 ? `${sp.completed}/${sp.total}` : "";
9075
9280
  const label = sp?.title ? `${sp.stepId} \xB7 ${sp.title}` : sp?.stepId ?? "";
9076
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { color: "green", bold: true }, "\u2713"), /* @__PURE__ */ React10.createElement(Text8, { color: "green" }, ` ${label}`), /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, counter)), event.text ? /* @__PURE__ */ React10.createElement(Box8, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, event.text)) : null, sp?.notes ? /* @__PURE__ */ React10.createElement(Box8, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text8, { color: "yellow", dimColor: true }, `note: ${sp.notes}`)) : null);
9281
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#4ade80", color: "black", bold: true }, " \u2713 STEP "), counter ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#4ade80", bold: true }, counter)) : null, /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#86efac" }, label)), event.text ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, event.text)) : null, sp?.notes ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#fbbf24", dimColor: true }, `note: ${sp.notes}`)) : null);
9077
9282
  }
9078
9283
  if (event.role === "plan-resumed") {
9079
9284
  const rp = event.resumedPlan;
@@ -9088,7 +9293,7 @@ var EventRow = React10.memo(function EventRow2({
9088
9293
  ])
9089
9294
  );
9090
9295
  const nextStep = rp.steps.find((s) => !completedSet.has(s.id));
9091
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { bold: true, color: "cyan" }, "\u25B8 resumed plan"), /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${done}/${total} done \xB7 last touched ${rp.relativeTime}`)), rp.summary ? /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { color: "cyan" }, ` ${rp.summary}`)) : null), /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(PlanStepList, { steps: rp.steps, statuses, focusStepId: nextStep?.id })));
9296
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#67e8f9", color: "black", bold: true }, " \u21BB RESUMED PLAN "), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#67e8f9", bold: true }, `${done}/${total}`), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` done \xB7 last touched ${rp.relativeTime}`)), rp.summary ? /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#67e8f9" }, rp.summary)) : null, /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(PlanStepList, { steps: rp.steps, statuses, focusStepId: nextStep?.id })));
9092
9297
  }
9093
9298
  if (event.role === "plan-replay") {
9094
9299
  const r = event.replayPlan;
@@ -9099,76 +9304,79 @@ var EventRow = React10.memo(function EventRow2({
9099
9304
  const statuses = new Map(
9100
9305
  r.steps.map((s) => [s.id, completedSet.has(s.id) ? "done" : "pending"])
9101
9306
  );
9102
- const navHint = r.total > 1 ? ` \xB7 ${r.index}/${r.total}` : "";
9103
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { bold: true, dimColor: true }, "\u23EA replay"), /* @__PURE__ */ React10.createElement(
9104
- Text8,
9105
- {
9106
- dimColor: true
9107
- },
9108
- ` completed ${r.relativeTime} \xB7 ${done}/${total} done${navHint}`
9109
- )), r.summary ? /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${r.summary}`)) : null, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${r.archiveBasename}`))), r.body ? /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Markdown, { text: r.body, projectRoot })) : null, /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(PlanStepList, { steps: r.steps, statuses })), /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, r.total > 1 ? `(read-only \xB7 /replay ${r.index === 1 ? 2 : 1} for the ${r.index === 1 ? "next" : "newest"} archive)` : "(read-only \xB7 this is an archived plan)")));
9307
+ const navHint = r.total > 1 ? ` \xB7 ${r.index}/${r.total}` : "";
9308
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#94a3b8", color: "black", bold: true }, " \u23EA REPLAY "), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#94a3b8", bold: true }, `${done}/${total}`), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` done \xB7 ${r.relativeTime}${navHint}`)), r.summary ? /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#94a3b8" }, r.summary)) : null, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, r.archiveBasename)), r.body ? /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Markdown, { text: r.body, projectRoot })) : null, /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(PlanStepList, { steps: r.steps, statuses })), /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, r.total > 1 ? `(read-only \xB7 /replay ${r.index === 1 ? 2 : 1} for the ${r.index === 1 ? "next" : "newest"} archive)` : "(read-only \xB7 this is an archived plan)")));
9110
9309
  }
9111
9310
  if (event.role === "warning") {
9112
- return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(RoleGlyph, { glyph: ROLE_GLYPH.warning, color: "yellow" }), /* @__PURE__ */ React10.createElement(Text8, { color: "yellow" }, " ", indentContinuationLines(event.text)));
9311
+ return /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#fbbf24", color: "black", bold: true }, " \u25B2 WARN "), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#fbbf24" }, indentContinuationLines(event.text)));
9113
9312
  }
9114
- return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, null, event.text));
9313
+ return /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, null, event.text));
9115
9314
  });
9116
9315
  function TurnSeparator() {
9117
- const { stdout: stdout2 } = useStdout2();
9316
+ const { stdout: stdout2 } = useStdout3();
9118
9317
  const cols = stdout2?.columns ?? 80;
9119
9318
  const width = Math.max(16, cols - 2);
9120
- const half = Math.floor((width - 3) / 2);
9121
- const left = "\u2500".repeat(half);
9122
- const right = "\u2500".repeat(width - half - 3);
9123
- return /* @__PURE__ */ React10.createElement(Box8, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, left), /* @__PURE__ */ React10.createElement(Text8, { color: "cyan", bold: true }, " \u25C6 "), /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, right));
9319
+ const sideWidth = Math.max(2, Math.floor((width - 5) / 2));
9320
+ const leftCells = gradientCells(sideWidth, "\u2500");
9321
+ const rightCells = gradientCells(sideWidth, "\u2500");
9322
+ return /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1, marginBottom: 1 }, leftCells.map((c, i) => (
9323
+ // biome-ignore lint/suspicious/noArrayIndexKey: fixed-width gradient row
9324
+ /* @__PURE__ */ React11.createElement(Text8, { key: `tsep-l-${i}`, color: c.color }, c.ch)
9325
+ )), /* @__PURE__ */ React11.createElement(Text8, { color: COLOR.brand, bold: true }, " \u25C6 "), rightCells.map((c, i) => (
9326
+ // biome-ignore lint/suspicious/noArrayIndexKey: fixed-width gradient row
9327
+ /* @__PURE__ */ React11.createElement(Text8, { key: `tsep-r-${i}`, color: c.color }, c.ch)
9328
+ )));
9124
9329
  }
9125
9330
  function EditFileDiff({ text }) {
9126
9331
  const lines = text.split(/\r?\n/);
9127
9332
  const [statusHeader, hunkHeader, ...body] = lines;
9128
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${statusHeader ?? ""}`), hunkHeader !== void 0 ? /* @__PURE__ */ React10.createElement(Text8, { color: "cyan", bold: true }, hunkHeader) : null, body.map((line, i) => {
9333
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` ${statusHeader ?? ""}`), hunkHeader !== void 0 ? /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` ${hunkHeader.trim()} `)) : null, body.map((line, i) => {
9129
9334
  const key = `${i}-${line.slice(0, 32)}`;
9130
- if (line.startsWith("- ")) {
9131
- return /* @__PURE__ */ React10.createElement(Text8, { key, color: "red" }, line);
9335
+ const stripped = line.replace(/^ {2}/, "");
9336
+ if (stripped.startsWith("- ")) {
9337
+ return /* @__PURE__ */ React11.createElement(Box9, { key }, /* @__PURE__ */ React11.createElement(Text8, { color: "#f87171", bold: true }, "\u2212 "), /* @__PURE__ */ React11.createElement(Text8, { color: "#fca5a5" }, stripped.slice(2)));
9132
9338
  }
9133
- if (line.startsWith("+ ")) {
9134
- return /* @__PURE__ */ React10.createElement(Text8, { key, color: "green" }, line);
9339
+ if (stripped.startsWith("+ ")) {
9340
+ return /* @__PURE__ */ React11.createElement(Box9, { key }, /* @__PURE__ */ React11.createElement(Text8, { color: "#4ade80", bold: true }, "+ "), /* @__PURE__ */ React11.createElement(Text8, { color: "#86efac" }, stripped.slice(2)));
9135
9341
  }
9136
- return /* @__PURE__ */ React10.createElement(Text8, { key, dimColor: true }, line);
9342
+ return /* @__PURE__ */ React11.createElement(Box9, { key }, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, " "), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, stripped));
9137
9343
  }));
9138
9344
  }
9139
9345
  function BranchBlock({ branch: branch2 }) {
9140
- const per = branch2.uncertainties.map((u, i) => {
9141
- const marker = i === branch2.chosenIndex ? "\u25B8" : " ";
9346
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: "#93c5fd", color: "black", bold: true }, ` \u2387 BRANCH \xD7${branch2.budget} `), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: "#93c5fd" }, "picked "), /* @__PURE__ */ React11.createElement(Text8, { color: "#93c5fd", bold: true }, "#", branch2.chosenIndex)), /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 2, marginTop: 1 }, branch2.uncertainties.map((u, i) => {
9347
+ const chosen = i === branch2.chosenIndex;
9142
9348
  const t = (branch2.temperatures[i] ?? 0).toFixed(1);
9143
- return `${marker} #${i} T=${t} u=${u}`;
9144
- }).join(" ");
9145
- return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { color: "blue" }, "\u2387 branched ", /* @__PURE__ */ React10.createElement(Text8, { bold: true }, branch2.budget), ` samples \u2192 picked #${branch2.chosenIndex} `, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, per)));
9349
+ return (
9350
+ // biome-ignore lint/suspicious/noArrayIndexKey: branch index is positional and stable
9351
+ /* @__PURE__ */ React11.createElement(Text8, { key: `b-${i}` }, /* @__PURE__ */ React11.createElement(Text8, { color: chosen ? "#93c5fd" : "#475569", bold: chosen }, chosen ? "\u25B8 " : " "), /* @__PURE__ */ React11.createElement(Text8, { color: chosen ? "#93c5fd" : "#94a3b8", bold: chosen }, `#${i}`), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` T=${t} u=${u} `))
9352
+ );
9353
+ })));
9146
9354
  }
9147
9355
  function ReasoningBlock({ reasoning }) {
9148
9356
  const max = 260;
9149
9357
  const flat = reasoning.replace(/\s+/g, " ").trim();
9150
9358
  const preview = flat.length <= max ? flat : `\u2026 (+${flat.length - max} earlier chars) ${flat.slice(-max)}`;
9151
- return /* @__PURE__ */ React10.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "\u258F "), /* @__PURE__ */ React10.createElement(Text8, { dimColor: true, italic: true }, "thinking ", preview));
9359
+ return /* @__PURE__ */ React11.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: COLOR.accent, color: "black", bold: true }, " \u22EF thinking "), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { color: COLOR.accent, italic: true, dimColor: true }, preview));
9152
9360
  }
9153
9361
  function Elapsed() {
9154
9362
  const s = useElapsedSeconds();
9155
9363
  const mm = String(Math.floor(s / 60)).padStart(2, "0");
9156
9364
  const ss = String(s % 60).padStart(2, "0");
9157
- return /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, `${mm}:${ss}`);
9365
+ return /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, `${mm}:${ss}`);
9158
9366
  }
9159
9367
  function PulsingAssistantGlyph() {
9160
9368
  const tick = useTick();
9161
9369
  const on = Math.floor(tick / 4) % 2 === 0;
9162
- return /* @__PURE__ */ React10.createElement(Text8, { color: "green", bold: true }, on ? ROLE_GLYPH.assistant : ROLE_GLYPH.assistantPulse);
9370
+ return /* @__PURE__ */ React11.createElement(Text8, { color: "green", bold: true }, on ? ROLE_GLYPH.assistant : ROLE_GLYPH.assistantPulse);
9163
9371
  }
9164
9372
  function StreamingAssistant({ event }) {
9165
9373
  if (event.branchProgress) {
9166
9374
  const p = event.branchProgress;
9167
9375
  if (p.completed === 0) {
9168
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React10.createElement(Text8, { color: "blue" }, " \u2387 launching ", p.total, " parallel samples (R1 thinking in parallel)\u2026 "), /* @__PURE__ */ React10.createElement(Elapsed, null)), /* @__PURE__ */ React10.createElement(Text8, { color: "yellow" }, " ", "spread across T=0.0/0.5/1.0 \xB7 reasoner typically takes 30-90s \u2014 this is normal"));
9376
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React11.createElement(Text8, { color: "blue" }, " \u2387 launching ", p.total, " parallel samples (R1 thinking in parallel)\u2026 "), /* @__PURE__ */ React11.createElement(Elapsed, null)), /* @__PURE__ */ React11.createElement(Text8, { color: "yellow" }, " ", "spread across T=0.0/0.5/1.0 \xB7 reasoner typically takes 30-90s \u2014 this is normal"));
9169
9377
  }
9170
9378
  const pct2 = Math.round(p.completed / p.total * 100);
9171
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React10.createElement(Text8, { color: "blue" }, " \u2387 branching ", p.completed, "/", p.total, " (", pct2, "%) "), /* @__PURE__ */ React10.createElement(Elapsed, null)), /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, " latest #", p.latestIndex, " T=", p.latestTemperature.toFixed(1), " u=", p.latestUncertainties, p.completed < p.total ? " \xB7 waiting for other samples\u2026" : " \xB7 selecting winner\u2026"));
9379
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React11.createElement(Text8, { color: "blue" }, " \u2387 branching ", p.completed, "/", p.total, " (", pct2, "%) "), /* @__PURE__ */ React11.createElement(Elapsed, null)), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, " latest #", p.latestIndex, " T=", p.latestTemperature.toFixed(1), " u=", p.latestUncertainties, p.completed < p.total ? " \xB7 waiting for other samples\u2026" : " \xB7 selecting winner\u2026"));
9172
9380
  }
9173
9381
  const tail = lastLine(event.text, 140);
9174
9382
  const reasoningTail = event.reasoning ? lastLine(event.reasoning, 120) : "";
@@ -9176,38 +9384,43 @@ function StreamingAssistant({ event }) {
9176
9384
  const preFirstByte = !event.text && !event.reasoning && !toolCallBuild;
9177
9385
  const reasoningOnly = !event.text && !!event.reasoning && !toolCallBuild;
9178
9386
  const toolCallOnly = !event.text && !event.reasoning && !!toolCallBuild;
9387
+ let pillBg;
9388
+ let pillText;
9179
9389
  let label;
9180
- let labelColor;
9181
9390
  if (preFirstByte) {
9391
+ pillBg = "#fbbf24";
9392
+ pillText = "WAITING";
9182
9393
  label = "request sent \xB7 waiting for server";
9183
- labelColor = "yellow";
9184
9394
  } else if (reasoningOnly) {
9185
- label = `R1 reasoning \xB7 ${event.reasoning?.length ?? 0} chars of thought`;
9186
- labelColor = "cyan";
9395
+ pillBg = "#c4b5fd";
9396
+ pillText = "THINKING";
9397
+ label = `${event.reasoning?.length ?? 0} chars of thought`;
9187
9398
  } else if (toolCallOnly) {
9188
- label = `assembling tool call${formatToolCallIndex(toolCallBuild)} <${toolCallBuild.name}> \xB7 ${toolCallBuild.chars} chars of arguments${formatReadyTail(toolCallBuild)}`;
9189
- labelColor = "magenta";
9399
+ pillBg = "#f0abfc";
9400
+ pillText = "DISPATCH";
9401
+ label = `assembling${formatToolCallIndex(toolCallBuild)} <${toolCallBuild.name}> \xB7 ${toolCallBuild.chars} chars${formatReadyTail(toolCallBuild)}`;
9190
9402
  } else {
9191
- const parts = [`writing response \xB7 ${event.text.length} chars`];
9192
- if (event.reasoning) parts.push(`after ${event.reasoning.length} chars of reasoning`);
9403
+ pillBg = "#86efac";
9404
+ pillText = "WRITING";
9405
+ const parts = [`${event.text.length} chars`];
9406
+ if (event.reasoning) parts.push(`after ${event.reasoning.length} reasoning`);
9193
9407
  if (toolCallBuild) {
9194
9408
  parts.push(
9195
- `building tool call${formatToolCallIndex(toolCallBuild)} <${toolCallBuild.name}> \xB7 ${toolCallBuild.chars} chars${formatReadyTail(toolCallBuild)}`
9409
+ `tool${formatToolCallIndex(toolCallBuild)} <${toolCallBuild.name}> ${toolCallBuild.chars}c${formatReadyTail(toolCallBuild)}`
9196
9410
  );
9197
9411
  }
9198
9412
  label = parts.join(" \xB7 ");
9199
- labelColor = "green";
9200
9413
  }
9201
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React10.createElement(Text8, null, " "), /* @__PURE__ */ React10.createElement(Pulse, null), /* @__PURE__ */ React10.createElement(Text8, { color: labelColor }, ` ${label} `), /* @__PURE__ */ React10.createElement(Elapsed, null)), reasoningTail ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true, italic: true }, "\u21B3 thinking: ", reasoningTail) : null, tail ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "\u25B8 ", tail) : preFirstByte ? (
9202
- // Non-dim yellow: first-time users misread the dim version as
9414
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Pulse, null), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: pillBg, color: "black", bold: true }, ` ${pillText} `), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` ${label} `), /* @__PURE__ */ React11.createElement(Elapsed, null)), reasoningTail ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#c4b5fd", italic: true, dimColor: true }, "\u21B3 ", reasoningTail)) : null, tail ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, "\u25B8 ", tail)) : preFirstByte ? (
9415
+ // Non-dim amber: first-time users misread the dim version as
9203
9416
  // "app frozen". The reassurance has to be VISIBLE to do its job.
9204
- /* @__PURE__ */ React10.createElement(Text8, { color: "yellow", italic: true }, " waiting for first byte \u2014 this is normal, typically 5-60s depending on model + load")
9205
- ) : reasoningOnly ? /* @__PURE__ */ React10.createElement(Text8, { color: "yellow", italic: true }, " R1 is thinking before it speaks \u2014 body text arrives when reasoning finishes (typically 20-90s, this is normal)") : toolCallOnly ? /* @__PURE__ */ React10.createElement(Text8, { color: "magenta", italic: true }, " tool-call arguments streaming \u2014 the model is about to dispatch a tool") : event.reasoning ? /* @__PURE__ */ React10.createElement(Text8, { color: "yellow", italic: true }, " R1 still reasoning \u2014 body text or tool call arrives when thinking finishes") : null);
9417
+ /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#fbbf24", italic: true }, "waiting for first byte \u2014 typical 5\u201360s depending on model + load"))
9418
+ ) : reasoningOnly ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#c4b5fd", italic: true }, "R1 thinks before it speaks \u2014 body text arrives when reasoning finishes (20\u201390s)")) : toolCallOnly ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#f0abfc", italic: true }, "tool-call arguments streaming \u2014 about to dispatch")) : event.reasoning ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#fbbf24", italic: true }, "R1 still reasoning \u2014 body text or tool call arrives when thinking finishes")) : null);
9206
9419
  }
9207
9420
  function Pulse() {
9208
9421
  const tick = useTick();
9209
9422
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
9210
- return /* @__PURE__ */ React10.createElement(Text8, { color: "cyan" }, frames[Math.floor(tick / 4) % frames.length]);
9423
+ return /* @__PURE__ */ React11.createElement(Text8, { color: "cyan" }, frames[Math.floor(tick / 4) % frames.length]);
9211
9424
  }
9212
9425
  function formatToolCallIndex(tb) {
9213
9426
  if (!tb || tb.index === void 0) return "";
@@ -9226,17 +9439,18 @@ function lastLine(s, maxChars) {
9226
9439
  }
9227
9440
  function StatsLine({ stats: stats2 }) {
9228
9441
  const hit = (stats2.cacheHitRatio * 100).toFixed(1);
9229
- return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "\u258F "), /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "cache ", hit, "% \xB7 tokens ", stats2.usage.promptTokens, " \u2192 ", stats2.usage.completionTokens, " \xB7 $", stats2.cost.toFixed(6)));
9442
+ const hitColor = stats2.cacheHitRatio >= 0.7 ? "#4ade80" : stats2.cacheHitRatio >= 0.4 ? "#fcd34d" : "#f87171";
9443
+ return /* @__PURE__ */ React11.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text8, { color: hitColor, bold: true }, `\u232C ${hit}%`), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React11.createElement(Text8, { color: "#94a3b8" }, "in ", /* @__PURE__ */ React11.createElement(Text8, { color: "#67e8f9", bold: true }, stats2.usage.promptTokens), " \u2192 out ", /* @__PURE__ */ React11.createElement(Text8, { color: "#c4b5fd", bold: true }, stats2.usage.completionTokens)), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React11.createElement(Text8, { color: "#86efac", bold: true }, `$${stats2.cost.toFixed(6)}`));
9230
9444
  }
9231
9445
 
9232
9446
  // src/cli/ui/LiveRows.tsx
9233
- import { Box as Box9, Text as Text9 } from "ink";
9234
- import React11 from "react";
9447
+ import { Box as Box10, Text as Text9, useStdout as useStdout4 } from "ink";
9448
+ import React12 from "react";
9235
9449
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
9236
9450
  function StatusRow({ text }) {
9237
9451
  const tick = useTick();
9238
9452
  const elapsed = useElapsedSeconds();
9239
- return /* @__PURE__ */ React11.createElement(Box9, { marginY: 1 }, /* @__PURE__ */ React11.createElement(Text9, { color: "magenta" }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React11.createElement(Text9, { color: "magenta" }, ` ${text}`), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, ` ${elapsed}s`));
9453
+ return /* @__PURE__ */ React12.createElement(Box10, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text9, { color: "#c4b5fd", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React12.createElement(Text9, null, " "), /* @__PURE__ */ React12.createElement(Text9, { color: "#c4b5fd" }, text), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, ` \xB7 ${elapsed}s`));
9240
9454
  }
9241
9455
  function ModeStatusBar({
9242
9456
  editMode,
@@ -9248,14 +9462,28 @@ function ModeStatusBar({
9248
9462
  }) {
9249
9463
  useTick();
9250
9464
  const running = jobs2?.runningCount() ?? 0;
9251
- const jobsTag = running > 0 ? /* @__PURE__ */ React11.createElement(Text9, { color: "yellow", bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
9465
+ const jobsTag = running > 0 ? /* @__PURE__ */ React12.createElement(Text9, { color: "yellow", bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
9252
9466
  if (planMode) {
9253
- return /* @__PURE__ */ React11.createElement(Box9, { paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text9, { color: "red", bold: true, inverse: flash }, "plan mode"), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, " writes gated \xB7 /plan off to leave"), jobsTag);
9467
+ return /* @__PURE__ */ React12.createElement(ModeBarFrame, null, /* @__PURE__ */ React12.createElement(ModePill, { label: "PLAN MODE", bg: "red", flash }), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, " writes gated \xB7 /plan off to leave"), jobsTag);
9254
9468
  }
9255
- const label = editMode === "auto" ? "auto" : "review";
9256
- const labelColor = editMode === "auto" ? "magenta" : "cyan";
9257
- const mid = 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";
9258
- return /* @__PURE__ */ React11.createElement(Box9, { paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text9, { color: labelColor, bold: true, inverse: flash }, label), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
9469
+ const isAuto = editMode === "auto";
9470
+ const label = isAuto ? "AUTO" : "REVIEW";
9471
+ const bg = isAuto ? "magenta" : "cyan";
9472
+ const mid = isAuto ? "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";
9473
+ return /* @__PURE__ */ React12.createElement(ModeBarFrame, null, /* @__PURE__ */ React12.createElement(ModePill, { label, bg, flash }), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
9474
+ }
9475
+ function ModeBarFrame({ children }) {
9476
+ const { stdout: stdout2 } = useStdout4();
9477
+ const cols = stdout2?.columns ?? 80;
9478
+ const ruleWidth = Math.max(20, cols - 2);
9479
+ return /* @__PURE__ */ React12.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Box10, { paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text9, { color: "#475569", dimColor: true }, "\u254C".repeat(ruleWidth))), /* @__PURE__ */ React12.createElement(Box10, { paddingX: 1 }, children));
9480
+ }
9481
+ function ModePill({
9482
+ label,
9483
+ bg,
9484
+ flash
9485
+ }) {
9486
+ return /* @__PURE__ */ React12.createElement(Text9, { backgroundColor: bg, color: "white", bold: true, inverse: flash }, ` ${label} `);
9259
9487
  }
9260
9488
  function UndoBanner({
9261
9489
  banner
@@ -9265,14 +9493,15 @@ function UndoBanner({
9265
9493
  const remainingSec = Math.ceil(remainingMs / 1e3);
9266
9494
  const ok = banner.results.filter((r) => r.status === "applied" || r.status === "created").length;
9267
9495
  const total = banner.results.length;
9268
- return /* @__PURE__ */ React11.createElement(Box9, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text9, { color: "magenta", bold: true }, "\u2713 auto-applied "), /* @__PURE__ */ React11.createElement(Text9, { color: "magenta" }, `${ok}/${total} edit${total === 1 ? "" : "s"}`), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, " \xB7 press "), /* @__PURE__ */ React11.createElement(Text9, { color: "magenta", bold: true }, "u"), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, " to undo ("), /* @__PURE__ */ React11.createElement(Text9, { color: remainingSec <= 1 ? "red" : "magenta" }, `${remainingSec}s`), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, ")"));
9496
+ const urgent = remainingSec <= 1;
9497
+ return /* @__PURE__ */ React12.createElement(Box10, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text9, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, " press "), /* @__PURE__ */ React12.createElement(Text9, { backgroundColor: "#67e8f9", color: "black", bold: true }, " u "), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, " to undo "), /* @__PURE__ */ React12.createElement(Text9, { color: urgent ? "#f87171" : "#c4b5fd", bold: urgent }, `${remainingSec}s`));
9269
9498
  }
9270
9499
  function SubagentRow({
9271
9500
  activity
9272
9501
  }) {
9273
9502
  const tick = useTick();
9274
9503
  const seconds = (activity.elapsedMs / 1e3).toFixed(1);
9275
- return /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text9, { color: "magenta" }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React11.createElement(Text9, { color: "magenta" }, ` \u232C subagent: ${activity.task}`), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, ` \xB7 iter ${activity.iter} \xB7 ${seconds}s`));
9504
+ return /* @__PURE__ */ React12.createElement(Box10, { paddingLeft: 3 }, /* @__PURE__ */ React12.createElement(Text9, { color: "#c4b5fd", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React12.createElement(Text9, null, " "), /* @__PURE__ */ React12.createElement(Text9, { backgroundColor: "#c4b5fd", color: "black", bold: true }, " \u232C subagent "), /* @__PURE__ */ React12.createElement(Text9, { color: "#c4b5fd" }, ` ${activity.task}`), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, ` iter ${activity.iter} \xB7 ${seconds}s`));
9276
9505
  }
9277
9506
  function OngoingToolRow({
9278
9507
  tool: tool2,
@@ -9281,7 +9510,7 @@ function OngoingToolRow({
9281
9510
  const tick = useTick();
9282
9511
  const elapsed = useElapsedSeconds();
9283
9512
  const summary = summarizeToolArgs(tool2.name, tool2.args);
9284
- return /* @__PURE__ */ React11.createElement(Box9, { marginY: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text9, { color: "cyan" }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React11.createElement(Text9, { color: "yellow" }, ` tool<${tool2.name}> running\u2026`), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, ` ${elapsed}s`)), progress ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text9, { color: "cyan" }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, summary)) : null);
9513
+ return /* @__PURE__ */ React12.createElement(Box10, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React12.createElement(Box10, null, /* @__PURE__ */ React12.createElement(Text9, { color: "#fcd34d", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React12.createElement(Text9, null, " "), /* @__PURE__ */ React12.createElement(Text9, { backgroundColor: "#fcd34d", color: "black", bold: true }, ` \u23F5 ${tool2.name} `), /* @__PURE__ */ React12.createElement(Text9, { color: "#fcd34d" }, " running"), /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, ` \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React12.createElement(Box10, { paddingLeft: 3 }, /* @__PURE__ */ React12.createElement(Text9, { color: "#67e8f9" }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React12.createElement(Box10, { paddingLeft: 3 }, /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, summary)) : null);
9285
9514
  }
9286
9515
  function renderProgressLine(p) {
9287
9516
  const msg = p.message ? ` ${p.message}` : "";
@@ -9337,8 +9566,8 @@ function summarizeToolArgs(name, args) {
9337
9566
  }
9338
9567
 
9339
9568
  // src/cli/ui/PlanCheckpointConfirm.tsx
9340
- import { Box as Box10, Text as Text10 } from "ink";
9341
- import React12 from "react";
9569
+ import { Box as Box11 } from "ink";
9570
+ import React13 from "react";
9342
9571
  function PlanCheckpointConfirmInner({
9343
9572
  stepId,
9344
9573
  title,
@@ -9349,10 +9578,11 @@ function PlanCheckpointConfirmInner({
9349
9578
  onChoose
9350
9579
  }) {
9351
9580
  const label = title ? `${stepId} \xB7 ${title}` : stepId;
9352
- const counter = total > 0 ? ` (${completed}/${total})` : "";
9581
+ const counter = total > 0 ? `${completed}/${total}` : "";
9353
9582
  const isLast = total > 0 && completed >= total;
9354
9583
  const statuses = buildStatusMap(steps, completedStepIds, stepId, isLast);
9355
- return /* @__PURE__ */ React12.createElement(Box10, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React12.createElement(Box10, null, /* @__PURE__ */ React12.createElement(Text10, { bold: true, color: "green" }, "\u25B8 checkpoint \u2014 step done"), /* @__PURE__ */ React12.createElement(Text10, { dimColor: true }, ` ${label}${counter}`)), steps && steps.length > 0 ? /* @__PURE__ */ React12.createElement(Box10, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React12.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
9584
+ const subtitle = counter ? `${counter} \xB7 ${label}` : label;
9585
+ return /* @__PURE__ */ React13.createElement(ModalCard, { accent: "#86efac", icon: "\u2713", title: "checkpoint \u2014 step done", subtitle }, steps && steps.length > 0 ? /* @__PURE__ */ React13.createElement(Box11, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React13.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React13.createElement(
9356
9586
  SingleSelect,
9357
9587
  {
9358
9588
  initialValue: isLast ? "stop" : "continue",
@@ -9377,9 +9607,9 @@ function PlanCheckpointConfirmInner({
9377
9607
  onCancel: () => onChoose("stop"),
9378
9608
  footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] stop"
9379
9609
  }
9380
- )));
9610
+ ));
9381
9611
  }
9382
- var PlanCheckpointConfirm = React12.memo(PlanCheckpointConfirmInner);
9612
+ var PlanCheckpointConfirm = React13.memo(PlanCheckpointConfirmInner);
9383
9613
  function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
9384
9614
  const map = /* @__PURE__ */ new Map();
9385
9615
  if (!steps) return map;
@@ -9396,42 +9626,53 @@ function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
9396
9626
  }
9397
9627
 
9398
9628
  // src/cli/ui/PlanConfirm.tsx
9399
- import { Box as Box11, Text as Text11 } from "ink";
9400
- import React13 from "react";
9629
+ import { Box as Box12, Text as Text10 } from "ink";
9630
+ import React14 from "react";
9401
9631
  function PlanConfirmInner({ plan: plan2, steps, summary, onChoose }) {
9402
9632
  const hasOpenQuestions = /^#{1,6}\s*(open[-\s]?questions?|risks?|unknowns?|assumptions?|unclear)/im.test(plan2) || /^#{1,6}\s*(待确认|开放问题|风险|未知|假设|不确定)/im.test(plan2);
9403
- return /* @__PURE__ */ React13.createElement(Box11, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React13.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React13.createElement(Box11, null, /* @__PURE__ */ React13.createElement(Text11, { bold: true, color: "cyan" }, "\u25B8 plan proposed (full text above) \u2014 approve / refine / cancel")), summary ? /* @__PURE__ */ React13.createElement(Box11, null, /* @__PURE__ */ React13.createElement(Text11, { color: "cyan" }, ` ${summary}`)) : null), hasOpenQuestions ? /* @__PURE__ */ React13.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(Text11, { color: "yellow" }, "\u25B2 the plan flags open questions or risks \u2014 pick", " ", /* @__PURE__ */ React13.createElement(Text11, { bold: true }, "Refine / answer questions"), " to write concrete answers before the model moves on.")) : null, steps && steps.length > 0 ? /* @__PURE__ */ React13.createElement(Box11, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React13.createElement(PlanStepList, { steps })) : null, /* @__PURE__ */ React13.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(
9404
- SingleSelect,
9633
+ return /* @__PURE__ */ React14.createElement(
9634
+ ModalCard,
9405
9635
  {
9406
- initialValue: hasOpenQuestions ? "refine" : "approve",
9407
- items: [
9408
- {
9409
- value: "approve",
9410
- label: "Approve and implement",
9411
- hint: "Exit plan mode. The model starts executing. You'll get a text input to add any last instructions (or just press Enter to skip)."
9412
- },
9413
- {
9414
- value: "refine",
9415
- label: "Refine / answer questions",
9416
- hint: "Stay in plan mode. Write answers, modifications, or critiques; the model revises and re-submits."
9417
- },
9418
- {
9419
- value: "cancel",
9420
- label: "Cancel",
9421
- hint: "Exit plan mode. Drop the plan; the model won't implement it."
9422
- }
9423
- ],
9424
- onSubmit: (v) => onChoose(v),
9425
- onCancel: () => onChoose("cancel"),
9426
- footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] cancel"
9427
- }
9428
- )));
9636
+ accent: "#67e8f9",
9637
+ icon: "\u{1F4CB}",
9638
+ title: "plan proposed",
9639
+ subtitle: summary ?? "approve / refine / cancel"
9640
+ },
9641
+ hasOpenQuestions ? /* @__PURE__ */ React14.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text10, { color: "#fbbf24" }, "\u25B2 the plan flags open questions or risks \u2014 pick", " ", /* @__PURE__ */ React14.createElement(Text10, { bold: true }, "Refine / answer questions"), " to write concrete answers before the model moves on.")) : null,
9642
+ steps && steps.length > 0 ? /* @__PURE__ */ React14.createElement(Box12, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(PlanStepList, { steps })) : null,
9643
+ /* @__PURE__ */ React14.createElement(
9644
+ SingleSelect,
9645
+ {
9646
+ initialValue: hasOpenQuestions ? "refine" : "approve",
9647
+ items: [
9648
+ {
9649
+ value: "approve",
9650
+ label: "Approve and implement",
9651
+ hint: "Exit plan mode. The model starts executing. You'll get a text input to add any last instructions (or just press Enter to skip)."
9652
+ },
9653
+ {
9654
+ value: "refine",
9655
+ label: "Refine / answer questions",
9656
+ hint: "Stay in plan mode. Write answers, modifications, or critiques; the model revises and re-submits."
9657
+ },
9658
+ {
9659
+ value: "cancel",
9660
+ label: "Cancel",
9661
+ hint: "Exit plan mode. Drop the plan; the model won't implement it."
9662
+ }
9663
+ ],
9664
+ onSubmit: (v) => onChoose(v),
9665
+ onCancel: () => onChoose("cancel"),
9666
+ footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] cancel"
9667
+ }
9668
+ )
9669
+ );
9429
9670
  }
9430
- var PlanConfirm = React13.memo(PlanConfirmInner);
9671
+ var PlanConfirm = React14.memo(PlanConfirmInner);
9431
9672
 
9432
9673
  // src/cli/ui/PlanRefineInput.tsx
9433
- import { Box as Box12, Text as Text12 } from "ink";
9434
- import React14, { useState as useState4 } from "react";
9674
+ import { Box as Box13, Text as Text11 } from "ink";
9675
+ import React15, { useState as useState4 } from "react";
9435
9676
  function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
9436
9677
  const [value, setValue] = useState4("");
9437
9678
  useKeystroke((ev) => {
@@ -9455,15 +9696,33 @@ function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
9455
9696
  setValue((v) => v + ev.input);
9456
9697
  }
9457
9698
  });
9458
- const title = mode2 === "approve" ? "\u25B8 approving \u2014 any last instructions or answers to open questions?" : mode2 === "checkpoint-revise" ? "\u25B8 revising \u2014 what should change before the next step?" : mode2 === "choice-custom" ? "\u25B8 custom answer \u2014 type whatever fits" : "\u25B8 refining \u2014 what should the model change?";
9459
- const hint = mode2 === "approve" ? "Answer questions the plan raised, add constraints, or just press Enter to approve as-is." : mode2 === "checkpoint-revise" ? "Scope change, skip steps, alternative approach \u2014 the model will adjust the remaining plan based on this." : mode2 === "choice-custom" ? "Free-form reply. The model reads it verbatim and proceeds \u2014 no need to match the listed options." : "Describe what's wrong or missing, or answer questions the plan raised.";
9699
+ const tick = useTick();
9700
+ const cursorOn = Math.floor(tick / 4) % 2 === 0;
9701
+ const meta = mode2 === "approve" ? {
9702
+ title: "approving \u2014 any last instructions?",
9703
+ icon: "\u{1F4CB}",
9704
+ accent: "#67e8f9"
9705
+ } : mode2 === "checkpoint-revise" ? {
9706
+ title: "revising \u2014 what should change before the next step?",
9707
+ icon: "\u270F",
9708
+ accent: "#fbbf24"
9709
+ } : mode2 === "choice-custom" ? {
9710
+ title: "custom answer \u2014 type whatever fits",
9711
+ icon: "\u{1F500}",
9712
+ accent: "#f0abfc"
9713
+ } : {
9714
+ title: "refining \u2014 what should the model change?",
9715
+ icon: "\u270F",
9716
+ accent: "#fbbf24"
9717
+ };
9718
+ const hint = mode2 === "approve" ? "Answer questions the plan raised, add constraints, or just press Enter to approve as-is." : mode2 === "checkpoint-revise" ? "Scope change, skip steps, alternative approach \u2014 the model adjusts the remaining plan." : mode2 === "choice-custom" ? "Free-form reply. The model reads it verbatim and proceeds \u2014 no need to match the listed options." : "Describe what's wrong or missing, or answer questions the plan raised.";
9460
9719
  const blankHint = mode2 === "approve" ? " (Enter with blank = approve without extra instructions.)" : mode2 === "checkpoint-revise" ? " (Enter with blank = continue with the current plan.)" : mode2 === "choice-custom" ? " (Enter with blank = ask the model what you actually want.)" : " (Enter with blank = ask the model to list concrete questions.)";
9461
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text12, { bold: true, color: "yellow" }, title)), /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text12, { dimColor: true }, hint, " Enter to send \xB7 Esc to return to the picker.", value === "" ? blankHint : "")), /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text12, null, /* @__PURE__ */ React14.createElement(Text12, { color: "yellow" }, "\u203A "), /* @__PURE__ */ React14.createElement(Text12, null, value || " "), /* @__PURE__ */ React14.createElement(Text12, { color: "yellow" }, "\u258D"))));
9720
+ return /* @__PURE__ */ React15.createElement(ModalCard, { accent: meta.accent, icon: meta.icon, title: meta.title }, /* @__PURE__ */ React15.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text11, { dimColor: true }, hint, " Enter to send \xB7 Esc to return to the picker.", value === "" ? blankHint : "")), /* @__PURE__ */ React15.createElement(Box13, null, /* @__PURE__ */ React15.createElement(Text11, { color: meta.accent, bold: true }, "\u203A "), /* @__PURE__ */ React15.createElement(Text11, null, value), /* @__PURE__ */ React15.createElement(Text11, { color: meta.accent, bold: true }, cursorOn ? "\u258D" : " ")));
9462
9721
  }
9463
9722
 
9464
9723
  // src/cli/ui/PlanReviseConfirm.tsx
9465
- import { Box as Box13, Text as Text13 } from "ink";
9466
- import React15 from "react";
9724
+ import { Box as Box14, Text as Text12 } from "ink";
9725
+ import React16 from "react";
9467
9726
  function computeDiff(oldSteps, newSteps) {
9468
9727
  const oldIds = new Set(oldSteps.map((s) => s.id));
9469
9728
  const newIds = new Set(newSteps.map((s) => s.id));
@@ -9479,13 +9738,13 @@ function computeDiff(oldSteps, newSteps) {
9479
9738
  function riskDots2(risk) {
9480
9739
  switch (risk) {
9481
9740
  case "high":
9482
- return { dots: "\u25CF\u25CF\u25CF", color: "red" };
9741
+ return { dots: "\u25CF\u25CF\u25CF", color: "#f87171" };
9483
9742
  case "med":
9484
- return { dots: "\u25CF\u25CF ", color: "yellow" };
9743
+ return { dots: "\u25CF\u25CF ", color: "#fbbf24" };
9485
9744
  case "low":
9486
- return { dots: "\u25CF ", color: "green" };
9745
+ return { dots: "\u25CF ", color: "#4ade80" };
9487
9746
  default:
9488
- return { dots: " ", color: "gray" };
9747
+ return { dots: " ", color: "#94a3b8" };
9489
9748
  }
9490
9749
  }
9491
9750
  function PlanReviseConfirmInner({
@@ -9499,40 +9758,52 @@ function PlanReviseConfirmInner({
9499
9758
  const removedCount = rows.filter((r) => r.kind === "removed").length;
9500
9759
  const addedCount = rows.filter((r) => r.kind === "added").length;
9501
9760
  const keptCount = rows.filter((r) => r.kind === "kept").length;
9502
- return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React15.createElement(Box13, null, /* @__PURE__ */ React15.createElement(Text13, { bold: true, color: "yellow" }, "\u270F plan revision proposed"), /* @__PURE__ */ React15.createElement(Text13, { dimColor: true }, ` \u2212${removedCount} +${addedCount} (${keptCount} kept)`)), /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, null, reason)), summary ? /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, { dimColor: true }, `updated summary: ${summary}`)) : null, /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1, flexDirection: "column" }, rows.map((row2) => {
9503
- const risk = riskDots2(row2.step.risk);
9504
- const prefix = row2.kind === "removed" ? "\u2212" : row2.kind === "added" ? "+" : " ";
9505
- const prefixColor = row2.kind === "removed" ? "red" : row2.kind === "added" ? "green" : "gray";
9506
- const dim = row2.kind === "kept";
9507
- const strike = row2.kind === "removed";
9508
- return /* @__PURE__ */ React15.createElement(Box13, { key: `${row2.kind}-${row2.step.id}` }, /* @__PURE__ */ React15.createElement(Text13, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React15.createElement(Text13, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React15.createElement(Text13, { dimColor: dim, strikethrough: strike }, ` ${row2.step.id} \xB7 ${row2.step.title}`));
9509
- })), /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(
9510
- SingleSelect,
9761
+ return /* @__PURE__ */ React16.createElement(
9762
+ ModalCard,
9511
9763
  {
9512
- initialValue: "accept",
9513
- items: [
9514
- {
9515
- value: "accept",
9516
- label: "Accept revision \u2014 apply the new step list",
9517
- hint: "Replaces the remaining plan with the proposed steps. Done steps are untouched."
9518
- },
9519
- {
9520
- value: "reject",
9521
- label: "Reject \u2014 keep the original plan",
9522
- hint: "Drops the proposal. Model continues with the original remaining steps."
9523
- }
9524
- ],
9525
- onSubmit: (v) => onChoose(v),
9526
- onCancel: () => onChoose("reject"),
9527
- footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] reject"
9528
- }
9529
- )));
9764
+ accent: "#fbbf24",
9765
+ icon: "\u270F",
9766
+ title: "plan revision proposed",
9767
+ subtitle: `\u2212${removedCount} +${addedCount} \xB7 ${keptCount} kept`
9768
+ },
9769
+ /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text12, null, reason)),
9770
+ summary ? /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text12, { dimColor: true }, `updated summary: ${summary}`)) : null,
9771
+ /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1, flexDirection: "column" }, rows.map((row2) => {
9772
+ const risk = riskDots2(row2.step.risk);
9773
+ const prefix = row2.kind === "removed" ? "\u2212" : row2.kind === "added" ? "+" : " ";
9774
+ const prefixColor = row2.kind === "removed" ? "#f87171" : row2.kind === "added" ? "#4ade80" : "#94a3b8";
9775
+ const dim = row2.kind === "kept";
9776
+ const strike = row2.kind === "removed";
9777
+ return /* @__PURE__ */ React16.createElement(Box14, { key: `${row2.kind}-${row2.step.id}` }, /* @__PURE__ */ React16.createElement(Text12, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React16.createElement(Text12, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React16.createElement(Text12, { dimColor: dim, strikethrough: strike }, ` ${row2.step.id} \xB7 ${row2.step.title}`));
9778
+ })),
9779
+ /* @__PURE__ */ React16.createElement(
9780
+ SingleSelect,
9781
+ {
9782
+ initialValue: "accept",
9783
+ items: [
9784
+ {
9785
+ value: "accept",
9786
+ label: "Accept revision \u2014 apply the new step list",
9787
+ hint: "Replaces the remaining plan with the proposed steps. Done steps are untouched."
9788
+ },
9789
+ {
9790
+ value: "reject",
9791
+ label: "Reject \u2014 keep the original plan",
9792
+ hint: "Drops the proposal. Model continues with the original remaining steps."
9793
+ }
9794
+ ],
9795
+ onSubmit: (v) => onChoose(v),
9796
+ onCancel: () => onChoose("reject"),
9797
+ footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] reject"
9798
+ }
9799
+ )
9800
+ );
9530
9801
  }
9531
- var PlanReviseConfirm = React15.memo(PlanReviseConfirmInner);
9802
+ var PlanReviseConfirm = React16.memo(PlanReviseConfirmInner);
9532
9803
 
9533
9804
  // src/cli/ui/PromptInput.tsx
9534
- import { Box as Box14, Text as Text14, useStdout as useStdout3 } from "ink";
9535
- import React16, { useRef as useRef2, useState as useState5 } from "react";
9805
+ import { Box as Box15, Text as Text13, useStdout as useStdout5 } from "ink";
9806
+ import React17, { useRef as useRef2, useState as useState5 } from "react";
9536
9807
 
9537
9808
  // src/cli/ui/key-normalize.ts
9538
9809
  var CSI_TAIL_TO_FLAGS = [
@@ -9593,8 +9864,11 @@ function processMultilineKey(value, cursor, keyIn) {
9593
9864
  if (key.pageDown) {
9594
9865
  return cursor === value.length ? NOOP : { next: null, cursor: value.length, submit: false };
9595
9866
  }
9596
- if (value.length === 0 && (key.upArrow || key.downArrow)) {
9597
- return { ...NOOP, historyHandoff: key.upArrow ? "prev" : "next" };
9867
+ if (key.ctrl && key.input === "p") {
9868
+ return { ...NOOP, historyHandoff: "prev" };
9869
+ }
9870
+ if (key.ctrl && key.input === "n") {
9871
+ return { ...NOOP, historyHandoff: "next" };
9598
9872
  }
9599
9873
  if (key.leftArrow) {
9600
9874
  return { next: null, cursor: Math.max(0, cursor - 1), submit: false };
@@ -9604,13 +9878,11 @@ function processMultilineKey(value, cursor, keyIn) {
9604
9878
  }
9605
9879
  if (key.upArrow) {
9606
9880
  const moved = moveCursorUp(value, cursor);
9607
- if (moved === cursor) return { ...NOOP, historyHandoff: "prev" };
9608
- return { next: null, cursor: moved, submit: false };
9881
+ return moved === cursor ? NOOP : { next: null, cursor: moved, submit: false };
9609
9882
  }
9610
9883
  if (key.downArrow) {
9611
9884
  const moved = moveCursorDown(value, cursor);
9612
- if (moved === cursor) return { ...NOOP, historyHandoff: "next" };
9613
- return { next: null, cursor: moved, submit: false };
9885
+ return moved === cursor ? NOOP : { next: null, cursor: moved, submit: false };
9614
9886
  }
9615
9887
  if (key.ctrl && key.input === "a") {
9616
9888
  return { next: null, cursor: startOfLine(value, cursor), submit: false };
@@ -10003,7 +10275,7 @@ function PromptInput({
10003
10275
  if (action.historyHandoff === "prev") onHistoryPrev?.();
10004
10276
  if (action.historyHandoff === "next") onHistoryNext?.();
10005
10277
  }, !disabled);
10006
- const { stdout: stdout2 } = useStdout3();
10278
+ const { stdout: stdout2 } = useStdout5();
10007
10279
  const cols = stdout2?.columns ?? 80;
10008
10280
  const narrow = cols <= 90;
10009
10281
  const promptBody = narrow ? "\u203A " : "you \u203A ";
@@ -10011,18 +10283,20 @@ function PromptInput({
10011
10283
  const continuationIndent = BAR + " ".repeat(promptBody.length);
10012
10284
  const prefixCells = promptPrefix.length;
10013
10285
  const visibleCells = Math.max(8, cols - prefixCells - 3);
10014
- const placeholderActive = narrow ? "type a message, or /command" : "type a message, or /command \xB7 [Ctrl+J] newline (Shift+Enter where supported)";
10286
+ const placeholderActive = narrow ? "type a message, or /command" : "type a message, or /command \xB7 [Ctrl+J] newline \xB7 [Ctrl+P/N] history";
10015
10287
  const effectivePlaceholder = disabled ? placeholder ?? "\u2026waiting for response\u2026" : placeholder ?? placeholderActive;
10016
10288
  const lines = value.length > 0 ? value.split("\n") : [""];
10017
10289
  const accentColor = disabled ? "gray" : "cyan";
10290
+ const barColorAt = (rowIdx) => disabled ? "gray" : GRADIENT[(rowIdx % GRADIENT.length + GRADIENT.length) % GRADIENT.length];
10291
+ const cursorVisible = true;
10018
10292
  const { line: cursorLine, col: cursorCol } = lineAndColumn(value, cursor);
10019
10293
  const renderItems = collapseLinesForDisplay(lines, cursorLine);
10020
10294
  const showHugeBufferHints = lines.length > 20;
10021
- return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", paddingX: 1 }, renderItems.map((item, renderIdx) => {
10295
+ return /* @__PURE__ */ React17.createElement(Box15, { flexDirection: "column", paddingX: 1 }, renderItems.map((item, renderIdx) => {
10022
10296
  if (item.kind === "skip") {
10023
10297
  return (
10024
10298
  // biome-ignore lint/suspicious/noArrayIndexKey: stable — collapse markers derive from a fixed sliding window
10025
- /* @__PURE__ */ React16.createElement(Box14, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, BAR), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
10299
+ /* @__PURE__ */ React17.createElement(Box15, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React17.createElement(Text13, { color: barColorAt(renderIdx) }, BAR), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
10026
10300
  );
10027
10301
  }
10028
10302
  const i = item.originalIndex;
@@ -10030,7 +10304,7 @@ function PromptInput({
10030
10304
  const isFirst = i === 0;
10031
10305
  const isCursorLine = i === cursorLine;
10032
10306
  const showPlaceholder = isFirst && value.length === 0;
10033
- return /* @__PURE__ */ React16.createElement(
10307
+ return /* @__PURE__ */ React17.createElement(
10034
10308
  PromptLine,
10035
10309
  {
10036
10310
  key: `ln-${i}`,
@@ -10038,29 +10312,33 @@ function PromptInput({
10038
10312
  isFirst,
10039
10313
  isCursorLine: isCursorLine && !disabled,
10040
10314
  cursorCol: isCursorLine ? cursorCol : null,
10315
+ cursorVisible,
10041
10316
  showPlaceholder,
10042
10317
  placeholderText: effectivePlaceholder,
10043
10318
  promptPrefix,
10044
10319
  continuationIndent,
10045
10320
  visibleCells,
10046
10321
  accentColor,
10322
+ barColor: barColorAt(i),
10047
10323
  pastes: pastesRef.current,
10048
10324
  disabled: disabled === true
10049
10325
  }
10050
10326
  );
10051
- }), showHugeBufferHints && !disabled ? /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, BAR), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, `[${lines.length} lines \xB7 PageUp/PageDown jump to top/bottom \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled && !narrow && value.length > 0 && !value.includes("\n") ? /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, BAR), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, "[Ctrl+J] newline \xB7 [Enter] submit \xB7 ends with \\ for line continuation")) : null, disabled ? /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, BAR), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, "[Esc] to stop")) : null);
10327
+ }), showHugeBufferHints && !disabled ? /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text13, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, `[${lines.length} lines \xB7 PageUp/PageDown jump to top/bottom \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled && !narrow && value.length > 0 && !value.includes("\n") ? /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text13, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, "[Ctrl+J] newline \xB7 [Enter] submit \xB7 ends with \\ for line continuation")) : null, disabled ? /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text13, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, "[Esc] to stop")) : null);
10052
10328
  }
10053
10329
  function PromptLine({
10054
10330
  line,
10055
10331
  isFirst,
10056
10332
  isCursorLine,
10057
10333
  cursorCol,
10334
+ cursorVisible,
10058
10335
  showPlaceholder,
10059
10336
  placeholderText,
10060
10337
  promptPrefix,
10061
10338
  continuationIndent,
10062
10339
  visibleCells,
10063
10340
  accentColor,
10341
+ barColor,
10064
10342
  pastes,
10065
10343
  disabled
10066
10344
  }) {
@@ -10068,25 +10346,27 @@ function PromptLine({
10068
10346
  const bodyPrefix = promptPrefix.slice(BAR.length);
10069
10347
  const bodyContinuation = continuationIndent.slice(BAR.length);
10070
10348
  if (showPlaceholder) {
10071
- return /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, barText), /* @__PURE__ */ React16.createElement(Text14, { bold: true, color: accentColor }, bodyPrefix), !disabled ? /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, "\u258C") : null, /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, placeholderText));
10349
+ return /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text13, { color: barColor }, barText), /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: accentColor }, bodyPrefix), !disabled ? /* @__PURE__ */ React17.createElement(Text13, { color: accentColor }, cursorVisible ? "\u258C" : " ") : null, /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, placeholderText));
10072
10350
  }
10073
10351
  const viewport = buildViewport(line, isCursorLine ? cursorCol : null, visibleCells, pastes);
10074
- return /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Text14, { color: accentColor }, barText), isFirst ? /* @__PURE__ */ React16.createElement(Text14, { bold: true, color: accentColor }, bodyPrefix) : /* @__PURE__ */ React16.createElement(Text14, { dimColor: true }, bodyContinuation), viewport.hiddenLeft ? /* @__PURE__ */ React16.createElement(Text14, { color: "gray", dimColor: true }, "\u2039") : null, /* @__PURE__ */ React16.createElement(
10352
+ return /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text13, { color: barColor }, barText), isFirst ? /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: accentColor }, bodyPrefix) : /* @__PURE__ */ React17.createElement(Text13, { dimColor: true }, bodyContinuation), viewport.hiddenLeft ? /* @__PURE__ */ React17.createElement(Text13, { color: "gray", dimColor: true }, "\u2039") : null, /* @__PURE__ */ React17.createElement(
10075
10353
  ViewportContent,
10076
10354
  {
10077
10355
  segments: viewport.segments,
10078
10356
  cursorCell: isCursorLine ? viewport.cursorCell : null,
10079
- accentColor
10357
+ accentColor,
10358
+ cursorVisible
10080
10359
  }
10081
- ), viewport.hiddenRight ? /* @__PURE__ */ React16.createElement(Text14, { color: "gray", dimColor: true }, "\u203A") : null);
10360
+ ), viewport.hiddenRight ? /* @__PURE__ */ React17.createElement(Text13, { color: "gray", dimColor: true }, "\u203A") : null);
10082
10361
  }
10083
10362
  function ViewportContent({
10084
10363
  segments,
10085
10364
  cursorCell,
10086
- accentColor
10365
+ accentColor,
10366
+ cursorVisible
10087
10367
  }) {
10088
10368
  if (cursorCell === null) {
10089
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
10369
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
10090
10370
  }
10091
10371
  const out = [];
10092
10372
  let cells = 0;
@@ -10105,7 +10385,7 @@ function ViewportContent({
10105
10385
  }
10106
10386
  if (seg.kind === "paste") {
10107
10387
  out.push(
10108
- /* @__PURE__ */ React16.createElement(Text14, { key: `p-${i}-cursor`, color: "magenta", bold: true, inverse: true }, seg.label)
10388
+ /* @__PURE__ */ React17.createElement(Text13, { key: `p-${i}-cursor`, color: "magenta", bold: true, inverse: cursorVisible }, seg.label)
10109
10389
  );
10110
10390
  placed = true;
10111
10391
  cells += segCells;
@@ -10114,29 +10394,29 @@ function ViewportContent({
10114
10394
  const offsetIntoSeg = cursorCell - cells;
10115
10395
  const split = splitTextByCells(seg.text, offsetIntoSeg);
10116
10396
  if (split.before.length > 0) {
10117
- out.push(/* @__PURE__ */ React16.createElement(Text14, { key: `t-${i}-b` }, split.before));
10397
+ out.push(/* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-b` }, split.before));
10118
10398
  }
10119
10399
  if (split.atCursor.length > 0) {
10120
10400
  out.push(
10121
- /* @__PURE__ */ React16.createElement(Text14, { key: `t-${i}-c`, inverse: true, color: accentColor }, split.atCursor)
10401
+ /* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-c`, inverse: cursorVisible, color: accentColor }, split.atCursor)
10122
10402
  );
10123
10403
  } else {
10124
10404
  out.push(
10125
- /* @__PURE__ */ React16.createElement(Text14, { key: `t-${i}-c-eol`, color: accentColor }, "\u258C")
10405
+ /* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-c-eol`, color: accentColor }, cursorVisible ? "\u258C" : " ")
10126
10406
  );
10127
10407
  }
10128
10408
  if (split.after.length > 0) {
10129
- out.push(/* @__PURE__ */ React16.createElement(Text14, { key: `t-${i}-a` }, split.after));
10409
+ out.push(/* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-a` }, split.after));
10130
10410
  }
10131
10411
  placed = true;
10132
10412
  cells += segCells;
10133
10413
  }
10134
10414
  if (!placed) {
10135
10415
  out.push(
10136
- /* @__PURE__ */ React16.createElement(Text14, { key: "cursor-eol", color: accentColor }, "\u258C")
10416
+ /* @__PURE__ */ React17.createElement(Text13, { key: "cursor-eol", color: accentColor }, cursorVisible ? "\u258C" : " ")
10137
10417
  );
10138
10418
  }
10139
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, out);
10419
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, out);
10140
10420
  }
10141
10421
  function segmentCells(seg) {
10142
10422
  if (seg.kind === "paste") return seg.label.length;
@@ -10176,9 +10456,9 @@ function charCellsForText(ch) {
10176
10456
  }
10177
10457
  function renderSegment(seg, key, _inverse) {
10178
10458
  if (seg.kind === "text") {
10179
- return /* @__PURE__ */ React16.createElement(Text14, { key: `s-${key}` }, seg.text);
10459
+ return /* @__PURE__ */ React17.createElement(Text13, { key: `s-${key}` }, seg.text);
10180
10460
  }
10181
- return /* @__PURE__ */ React16.createElement(Text14, { key: `s-${key}`, color: "magenta", bold: true }, seg.label);
10461
+ return /* @__PURE__ */ React17.createElement(Text13, { key: `s-${key}`, backgroundColor: "#f0abfc", color: "black", bold: true }, seg.label);
10182
10462
  }
10183
10463
  var COLLAPSE_THRESHOLD = 20;
10184
10464
  var COLLAPSE_HEAD_LINES = 3;
@@ -10205,36 +10485,47 @@ function collapseLinesForDisplay(lines, cursorLine) {
10205
10485
  }
10206
10486
 
10207
10487
  // src/cli/ui/ShellConfirm.tsx
10208
- import { Box as Box15, Text as Text15 } from "ink";
10209
- import React17 from "react";
10488
+ import { Box as Box16, Text as Text14 } from "ink";
10489
+ import React18 from "react";
10210
10490
  function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
10211
10491
  const isBackground = kind === "run_background";
10212
- return /* @__PURE__ */ React17.createElement(Box15, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text15, { bold: true, color: "red" }, isBackground ? "\u25B8 model wants to start a BACKGROUND process" : "\u25B8 model wants to run a shell command")), isBackground ? /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, " (long-running: dev server / watcher; keeps running after approval, /kill to stop)")) : null, /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text15, { color: "red", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React17.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text15, null, /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, "$ "), /* @__PURE__ */ React17.createElement(Text15, { color: "cyan" }, command))), /* @__PURE__ */ React17.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(
10213
- SingleSelect,
10492
+ const subtitle = isBackground ? "long-running process \u2014 keeps running after approval, /kill to stop" : "model wants to run a shell command";
10493
+ return /* @__PURE__ */ React18.createElement(
10494
+ ModalCard,
10214
10495
  {
10215
- initialValue: "run_once",
10216
- items: [
10217
- {
10218
- value: "run_once",
10219
- label: "Run once",
10220
- hint: "Execute this command, don't remember it."
10221
- },
10222
- {
10223
- value: "always_allow",
10224
- label: `Always allow "${allowPrefix}" in this project`,
10225
- hint: "Save the prefix to ~/.reasonix/config.json; future matches auto-run."
10226
- },
10227
- {
10228
- value: "deny",
10229
- label: "Deny",
10230
- hint: "Tell the model the user refused; it will continue without this command."
10231
- }
10232
- ],
10233
- onSubmit: (v) => onChoose(v),
10234
- onCancel: () => onChoose("deny"),
10235
- footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] deny"
10236
- }
10237
- )));
10496
+ accent: "#f87171",
10497
+ icon: isBackground ? "\u23F1" : "\u26A1",
10498
+ title: isBackground ? "background process" : "shell command",
10499
+ subtitle
10500
+ },
10501
+ /* @__PURE__ */ React18.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text14, { dimColor: true }, "$ "), /* @__PURE__ */ React18.createElement(Text14, { color: "#67e8f9", bold: true }, command)),
10502
+ /* @__PURE__ */ React18.createElement(
10503
+ SingleSelect,
10504
+ {
10505
+ initialValue: "run_once",
10506
+ items: [
10507
+ {
10508
+ value: "run_once",
10509
+ label: "Run once",
10510
+ hint: "Execute this command, don't remember it."
10511
+ },
10512
+ {
10513
+ value: "always_allow",
10514
+ label: `Always allow "${allowPrefix}" in this project`,
10515
+ hint: "Save the prefix to ~/.reasonix/config.json; future matches auto-run."
10516
+ },
10517
+ {
10518
+ value: "deny",
10519
+ label: "Deny",
10520
+ hint: "Tell the model the user refused; it will continue without this command."
10521
+ }
10522
+ ],
10523
+ onSubmit: (v) => onChoose(v),
10524
+ onCancel: () => onChoose("deny"),
10525
+ footer: "[\u2191\u2193] navigate \xB7 [Enter] select \xB7 [Esc] deny"
10526
+ }
10527
+ )
10528
+ );
10238
10529
  }
10239
10530
  function derivePrefix(command) {
10240
10531
  const tokens = command.trim().split(/\s+/).filter(Boolean);
@@ -10266,8 +10557,8 @@ function derivePrefix(command) {
10266
10557
  }
10267
10558
 
10268
10559
  // src/cli/ui/SlashArgPicker.tsx
10269
- import { Box as Box16, Text as Text16 } from "ink";
10270
- import React18 from "react";
10560
+ import { Box as Box17, Text as Text15 } from "ink";
10561
+ import React19 from "react";
10271
10562
  function SlashArgPicker({
10272
10563
  matches,
10273
10564
  selectedIndex,
@@ -10276,11 +10567,11 @@ function SlashArgPicker({
10276
10567
  partial
10277
10568
  }) {
10278
10569
  if (kind === "hint") {
10279
- return /* @__PURE__ */ React18.createElement(Box16, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary));
10570
+ return /* @__PURE__ */ React19.createElement(Box17, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, " ", /* @__PURE__ */ React19.createElement(Text15, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary));
10280
10571
  }
10281
10572
  if (matches === null) return null;
10282
10573
  if (matches.length === 0) {
10283
- return /* @__PURE__ */ React18.createElement(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), /* @__PURE__ */ React18.createElement(Text16, { color: "yellow" }, ' no match for "', partial, '" \u2014 keep typing, or Backspace to edit'));
10574
+ return /* @__PURE__ */ React19.createElement(Box17, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, " ", /* @__PURE__ */ React19.createElement(Text15, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), /* @__PURE__ */ React19.createElement(Text15, { color: "yellow" }, ' no match for "', partial, '" \u2014 keep typing, or Backspace to edit'));
10284
10575
  }
10285
10576
  const MAX = 8;
10286
10577
  const total = matches.length;
@@ -10288,26 +10579,26 @@ function SlashArgPicker({
10288
10579
  const shown = matches.slice(windowStart, windowStart + MAX);
10289
10580
  const hiddenAbove = windowStart;
10290
10581
  const hiddenBelow = total - windowStart - shown.length;
10291
- return /* @__PURE__ */ React18.createElement(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), hiddenAbove > 0 ? /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((value, i) => /* @__PURE__ */ React18.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
10582
+ return /* @__PURE__ */ React19.createElement(Box17, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, " ", /* @__PURE__ */ React19.createElement(Text15, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), hiddenAbove > 0 ? /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((value, i) => /* @__PURE__ */ React19.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
10292
10583
  }
10293
10584
  function ArgRow({ value, isSelected }) {
10294
10585
  const marker = isSelected ? "\u25B8" : " ";
10295
10586
  if (isSelected) {
10296
- return /* @__PURE__ */ React18.createElement(Box16, null, /* @__PURE__ */ React18.createElement(Text16, { bold: true, color: "cyan" }, marker, " ", value));
10587
+ return /* @__PURE__ */ React19.createElement(Box17, null, /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: "cyan" }, marker, " ", value));
10297
10588
  }
10298
- return /* @__PURE__ */ React18.createElement(Box16, null, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, marker, " ", value));
10589
+ return /* @__PURE__ */ React19.createElement(Box17, null, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, marker, " ", value));
10299
10590
  }
10300
10591
 
10301
10592
  // src/cli/ui/SlashSuggestions.tsx
10302
- import { Box as Box17, Text as Text17 } from "ink";
10303
- import React19 from "react";
10593
+ import { Box as Box18, Text as Text16 } from "ink";
10594
+ import React20 from "react";
10304
10595
  function SlashSuggestions({
10305
10596
  matches,
10306
10597
  selectedIndex
10307
10598
  }) {
10308
10599
  if (matches === null) return null;
10309
10600
  if (matches.length === 0) {
10310
- return /* @__PURE__ */ React19.createElement(Box17, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text17, { color: "yellow" }, "no slash command matches that prefix"), /* @__PURE__ */ React19.createElement(Text17, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
10601
+ return /* @__PURE__ */ React20.createElement(Box18, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: "yellow" }, "no slash command matches that prefix"), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
10311
10602
  }
10312
10603
  const MAX = 8;
10313
10604
  const total = matches.length;
@@ -10315,47 +10606,26 @@ function SlashSuggestions({
10315
10606
  const shown = matches.slice(windowStart, windowStart + MAX);
10316
10607
  const hiddenAbove = windowStart;
10317
10608
  const hiddenBelow = total - windowStart - shown.length;
10318
- return /* @__PURE__ */ React19.createElement(Box17, { flexDirection: "column", paddingX: 1, marginTop: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React19.createElement(Text17, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((spec, i) => /* @__PURE__ */ React19.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React19.createElement(Text17, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React19.createElement(Text17, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
10609
+ return /* @__PURE__ */ React20.createElement(Box18, { flexDirection: "column", paddingX: 1, marginTop: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((spec, i) => /* @__PURE__ */ React20.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
10319
10610
  }
10320
10611
  function SuggestionRow({ spec, isSelected }) {
10321
- const marker = isSelected ? "\u25B8" : " ";
10322
10612
  const name = `/${spec.cmd}`;
10323
10613
  const argsSuffix = spec.argsHint ? ` ${spec.argsHint}` : "";
10324
10614
  if (isSelected) {
10325
- return /* @__PURE__ */ React19.createElement(Box17, null, /* @__PURE__ */ React19.createElement(Text17, { bold: true, color: "cyan" }, marker, " ", name.padEnd(12), argsSuffix.padEnd(16)), /* @__PURE__ */ React19.createElement(Text17, { color: "cyan" }, " ", spec.summary));
10615
+ return /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { backgroundColor: "#67e8f9", color: "black", bold: true }, ` \u25B8 ${name.padEnd(12)}${argsSuffix.padEnd(16)} ${spec.summary} `));
10326
10616
  }
10327
- return /* @__PURE__ */ React19.createElement(Box17, null, /* @__PURE__ */ React19.createElement(Text17, { dimColor: true }, marker, " ", name.padEnd(12), argsSuffix.padEnd(16), " ", spec.summary));
10617
+ return /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: "#94a3b8" }, ` ${name.padEnd(12)}${argsSuffix.padEnd(16)} ${spec.summary}`));
10328
10618
  }
10329
10619
 
10330
10620
  // src/cli/ui/StatsPanel.tsx
10331
- import { Box as Box18, Text as Text18, useStdout as useStdout4 } from "ink";
10332
- import React20 from "react";
10333
- var WORDMARK_STYLES = [
10334
- { ch: "\u25C8", color: "#5eead4", isLogo: true },
10335
- // teal — brand mark
10336
- { ch: " ", color: "#5eead4", isLogo: false },
10337
- { ch: "R", color: "#67e8f9", isLogo: false },
10338
- // cyan
10339
- { ch: "E", color: "#7dd3fc", isLogo: false },
10340
- // sky
10341
- { ch: "A", color: "#93c5fd", isLogo: false },
10342
- // blue
10343
- { ch: "S", color: "#a5b4fc", isLogo: false },
10344
- // indigo
10345
- { ch: "O", color: "#c4b5fd", isLogo: false },
10346
- // violet
10347
- { ch: "N", color: "#d8b4fe", isLogo: false },
10348
- // purple
10349
- { ch: "I", color: "#f0abfc", isLogo: false },
10350
- // fuchsia
10351
- { ch: "X", color: "#f0abfc", isLogo: false }
10352
- // fuchsia
10353
- ];
10354
- function Wordmark({ busy }) {
10355
- const tick = useTick();
10356
- const period = busy ? 5 : 12;
10357
- const bright = Math.floor(tick / period) % 2 === 0;
10358
- return /* @__PURE__ */ React20.createElement(Text18, null, WORDMARK_STYLES.map((c) => /* @__PURE__ */ React20.createElement(Text18, { key: `${c.ch}-${c.color}`, color: c.color, bold: c.isLogo ? bright : true }, c.ch)));
10621
+ import { Box as Box19, Text as Text17, useStdout as useStdout6 } from "ink";
10622
+ import React21 from "react";
10623
+ var WORDMARK_LETTERS = ["R", "E", "A", "S", "O", "N", "I", "X"];
10624
+ function Wordmark({
10625
+ busy: _busy,
10626
+ animate: _animate
10627
+ }) {
10628
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: GRADIENT[0], bold: true }, "\u25C8"), /* @__PURE__ */ React21.createElement(Text17, null, " "), WORDMARK_LETTERS.map((letter, i) => /* @__PURE__ */ React21.createElement(Text17, { key: letter, color: GRADIENT[i % GRADIENT.length], bold: true }, letter)));
10359
10629
  }
10360
10630
  var NARROW_BREAKPOINT = 120;
10361
10631
  var COLD_START_TURNS = 3;
@@ -10377,57 +10647,48 @@ function StatsPanel({
10377
10647
  const branchOn = (branchBudget ?? 1) > 1;
10378
10648
  const ctxMax = DEEPSEEK_CONTEXT_TOKENS[model2] ?? DEFAULT_CONTEXT_TOKENS;
10379
10649
  const ctxRatio = summary.lastPromptTokens / ctxMax;
10380
- const { stdout: stdout2 } = useStdout4();
10650
+ const { stdout: stdout2 } = useStdout6();
10381
10651
  const columns = stdout2?.columns ?? 80;
10382
10652
  const narrow = columns < NARROW_BREAKPOINT;
10383
10653
  const coldStart = summary.turns <= COLD_START_TURNS;
10384
- const ruleWidth = Math.max(20, columns - 2);
10385
- return (
10386
- // Borderless layout: no `borderStyle`, no rounded box, no `width={cols}`
10387
- // pinning. Bordered Boxes were the most visible amplifier of Ink's
10388
- // eraseLines miscount on Windows terminals — every miscounted render
10389
- // pushed a top-border frame into scrollback. Without a border there
10390
- // is nothing visually obvious to duplicate; visual structure comes
10391
- // from the gradient wordmark + colored pills + a top/bottom margin
10392
- // + a thin dim rule that closes the panel cleanly under the metrics.
10393
- /* @__PURE__ */ React20.createElement(Box18, { flexDirection: "column", paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React20.createElement(
10394
- Header,
10395
- {
10396
- model: model2,
10397
- prefixHash,
10398
- harvestOn,
10399
- branchOn,
10400
- branchBudget: branchBudget ?? 1,
10401
- reasoningEffort,
10402
- planMode,
10403
- editMode,
10404
- turns: summary.turns,
10405
- updateAvailable,
10406
- narrow,
10407
- busy: busy ?? false,
10408
- proArmed: proArmed ?? false,
10409
- escalated: escalated ?? false
10410
- }
10411
- ), narrow ? /* @__PURE__ */ React20.createElement(
10412
- StackedMetrics,
10413
- {
10414
- summary,
10415
- ctxRatio,
10416
- ctxMax,
10417
- balance,
10418
- coldStart
10419
- }
10420
- ) : /* @__PURE__ */ React20.createElement(
10421
- InlineMetrics,
10422
- {
10423
- summary,
10424
- ctxRatio,
10425
- ctxMax,
10426
- balance,
10427
- coldStart
10428
- }
10429
- ), /* @__PURE__ */ React20.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "\u2500".repeat(ruleWidth))))
10430
- );
10654
+ return /* @__PURE__ */ React21.createElement(Box19, { flexDirection: "column", paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React21.createElement(
10655
+ Header,
10656
+ {
10657
+ model: model2,
10658
+ prefixHash,
10659
+ harvestOn,
10660
+ branchOn,
10661
+ branchBudget: branchBudget ?? 1,
10662
+ reasoningEffort,
10663
+ planMode,
10664
+ editMode,
10665
+ turns: summary.turns,
10666
+ updateAvailable,
10667
+ narrow,
10668
+ busy: busy ?? false,
10669
+ proArmed: proArmed ?? false,
10670
+ escalated: escalated ?? false,
10671
+ animate: false
10672
+ }
10673
+ ), narrow ? /* @__PURE__ */ React21.createElement(
10674
+ StackedMetrics,
10675
+ {
10676
+ summary,
10677
+ ctxRatio,
10678
+ ctxMax,
10679
+ balance,
10680
+ coldStart
10681
+ }
10682
+ ) : /* @__PURE__ */ React21.createElement(
10683
+ InlineMetrics,
10684
+ {
10685
+ summary,
10686
+ ctxRatio,
10687
+ ctxMax,
10688
+ balance,
10689
+ coldStart
10690
+ }
10691
+ ));
10431
10692
  }
10432
10693
  function Header({
10433
10694
  model: model2,
@@ -10443,14 +10704,16 @@ function Header({
10443
10704
  narrow,
10444
10705
  busy,
10445
10706
  proArmed,
10446
- escalated
10707
+ escalated,
10708
+ animate
10447
10709
  }) {
10448
10710
  const modePill = planMode ? { label: "PLAN", bg: "red" } : editMode === "auto" ? { label: "AUTO", bg: "magenta" } : editMode === "review" ? { label: "REVIEW", bg: "cyan" } : null;
10449
10711
  const proPill = escalated ? { label: "\u21E7 PRO", bg: "red" } : proArmed ? { label: "\u21E7 PRO", bg: "yellow" } : null;
10450
- return /* @__PURE__ */ React20.createElement(Box18, { justifyContent: "space-between" }, /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Wordmark, { busy }), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, ` ${VERSION}`), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, " "), /* @__PURE__ */ React20.createElement(Text18, { color: "yellow", bold: true }, model2.replace(/^deepseek-/, "")), modePill ? /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Text18, null, " "), /* @__PURE__ */ React20.createElement(Pill, { label: modePill.label, bg: modePill.bg })) : null, proPill ? /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Text18, null, " "), /* @__PURE__ */ React20.createElement(Pill, { label: proPill.label, bg: proPill.bg })) : null, harvestOn ? /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, /* @__PURE__ */ React20.createElement(Text18, null, " "), /* @__PURE__ */ React20.createElement(Text18, { color: "magenta" }, "harvest")) : null, branchOn ? /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, /* @__PURE__ */ React20.createElement(Text18, null, " "), /* @__PURE__ */ React20.createElement(Text18, { color: "blue" }, `branch\xD7${branchBudget}`)) : null, reasoningEffort === "max" ? /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Text18, null, " "), /* @__PURE__ */ React20.createElement(Text18, { color: "green", dimColor: true }, "max")) : null, reasoningEffort === "high" ? /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Text18, null, " "), /* @__PURE__ */ React20.createElement(Text18, { color: "yellow", dimColor: true }, "high")) : null), /* @__PURE__ */ React20.createElement(Text18, null, updateAvailable ? /* @__PURE__ */ React20.createElement(Text18, { color: "yellow", bold: true }, `\u2191 ${updateAvailable} `) : null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, narrow ? `t${turns}` : `turn ${turns} \xB7 /help`)));
10712
+ const showSecondary = animate && !narrow;
10713
+ return /* @__PURE__ */ React21.createElement(Box19, { justifyContent: "space-between" }, /* @__PURE__ */ React21.createElement(Box19, null, /* @__PURE__ */ React21.createElement(Wordmark, { busy, animate }), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` ${VERSION}`), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " "), /* @__PURE__ */ React21.createElement(Text17, { color: "yellow", bold: true }, model2.replace(/^deepseek-/, "")), modePill ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Pill, { label: modePill.label, bg: modePill.bg })) : null, proPill ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Pill, { label: proPill.label, bg: proPill.bg })) : null, showSecondary && harvestOn ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: "magenta" }, "harvest")) : null, showSecondary && branchOn ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: "blue" }, `branch\xD7${branchBudget}`)) : null, showSecondary && reasoningEffort === "max" ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: "green", dimColor: true }, "max")) : null, showSecondary && reasoningEffort === "high" ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: "yellow", dimColor: true }, "high")) : null), /* @__PURE__ */ React21.createElement(Text17, null, updateAvailable ? /* @__PURE__ */ React21.createElement(Text17, { color: "yellow", bold: true }, `\u2191 ${updateAvailable} `) : null, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, narrow ? `t${turns}` : `turn ${turns} \xB7 /help`)));
10451
10714
  }
10452
10715
  function Pill({ label, bg }) {
10453
- return /* @__PURE__ */ React20.createElement(Text18, { backgroundColor: bg, color: "white", bold: true }, ` ${label} `);
10716
+ return /* @__PURE__ */ React21.createElement(Text17, { backgroundColor: bg, color: "white", bold: true }, ` ${label} `);
10454
10717
  }
10455
10718
  function InlineMetrics({
10456
10719
  summary,
@@ -10459,7 +10722,7 @@ function InlineMetrics({
10459
10722
  balance,
10460
10723
  coldStart
10461
10724
  }) {
10462
- return /* @__PURE__ */ React20.createElement(Box18, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React20.createElement(ContextCell, { ratio: ctxRatio, promptTokens: summary.lastPromptTokens, ctxMax }), /* @__PURE__ */ React20.createElement(CacheCell, { hitRatio: summary.cacheHitRatio, coldStart, turns: summary.turns }), /* @__PURE__ */ React20.createElement(CostCell, { summary, coldStart }), balance ? /* @__PURE__ */ React20.createElement(BalanceCell, { balance }) : null);
10725
+ return /* @__PURE__ */ React21.createElement(Box19, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React21.createElement(ContextCell, { ratio: ctxRatio, promptTokens: summary.lastPromptTokens, ctxMax }), /* @__PURE__ */ React21.createElement(CacheCell, { hitRatio: summary.cacheHitRatio, coldStart, turns: summary.turns }), /* @__PURE__ */ React21.createElement(CostCell, { summary, coldStart }), balance ? /* @__PURE__ */ React21.createElement(BalanceCell, { balance }) : null);
10463
10726
  }
10464
10727
  function StackedMetrics({
10465
10728
  summary,
@@ -10468,7 +10731,7 @@ function StackedMetrics({
10468
10731
  balance,
10469
10732
  coldStart
10470
10733
  }) {
10471
- return /* @__PURE__ */ React20.createElement(Box18, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React20.createElement(
10734
+ return /* @__PURE__ */ React21.createElement(Box19, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React21.createElement(
10472
10735
  ContextCell,
10473
10736
  {
10474
10737
  ratio: ctxRatio,
@@ -10476,7 +10739,7 @@ function StackedMetrics({
10476
10739
  ctxMax,
10477
10740
  showBar: true
10478
10741
  }
10479
- ), balance ? /* @__PURE__ */ React20.createElement(BalanceCell, { balance }) : null, /* @__PURE__ */ React20.createElement(CacheCell, { hitRatio: summary.cacheHitRatio, coldStart, turns: summary.turns }), /* @__PURE__ */ React20.createElement(CostCell, { summary, coldStart }));
10742
+ ), balance ? /* @__PURE__ */ React21.createElement(BalanceCell, { balance }) : null, /* @__PURE__ */ React21.createElement(CacheCell, { hitRatio: summary.cacheHitRatio, coldStart, turns: summary.turns }), /* @__PURE__ */ React21.createElement(CostCell, { summary, coldStart }));
10480
10743
  }
10481
10744
  function ContextCell({
10482
10745
  ratio,
@@ -10485,11 +10748,11 @@ function ContextCell({
10485
10748
  showBar
10486
10749
  }) {
10487
10750
  if (promptTokens === 0) {
10488
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "ctx "), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "\u2014 (no turns yet)"));
10751
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info, dimColor: true }, "\u25A3 ctx "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u2014 (no turns yet)"));
10489
10752
  }
10490
- const color = ratio >= 0.8 ? "red" : ratio >= 0.6 ? "yellow" : "green";
10753
+ const color = ratio >= 0.8 ? COLOR.err : ratio >= 0.6 ? COLOR.warn : COLOR.ok;
10491
10754
  const pct2 = Math.round(ratio * 100);
10492
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "ctx "), showBar ? /* @__PURE__ */ React20.createElement(Bar, { ratio, color }) : null, showBar ? /* @__PURE__ */ React20.createElement(Text18, null, " ") : null, /* @__PURE__ */ React20.createElement(Text18, { color, bold: true }, formatTokens(promptTokens), "/", formatTokens(ctxMax)), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, " (", pct2, "%)"), ratio >= 0.8 ? /* @__PURE__ */ React20.createElement(Text18, { color: "red", bold: true }, " \xB7 /compact") : null);
10755
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25A3 ctx "), /* @__PURE__ */ React21.createElement(Bar, { ratio, color, cells: showBar ? 14 : 10 }), /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color, bold: true }, formatTokens(promptTokens), "/", formatTokens(ctxMax)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " (", pct2, "%)"), ratio >= 0.8 ? /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.err, bold: true }, " \xB7 /compact") : null);
10493
10756
  }
10494
10757
  function CacheCell({
10495
10758
  hitRatio,
@@ -10498,46 +10761,48 @@ function CacheCell({
10498
10761
  }) {
10499
10762
  const pct2 = (hitRatio * 100).toFixed(1);
10500
10763
  if (turns === 0) {
10501
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "cache "), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "\u2014"));
10764
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info, dimColor: true }, "\u232C cache "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u2014"));
10502
10765
  }
10503
10766
  if (coldStart) {
10504
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "cache "), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, pct2, "% "), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true, italic: true }, "(cold start)"));
10767
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info, dimColor: true }, "\u232C cache "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, pct2, "% "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true, italic: true }, "(cold start)"));
10505
10768
  }
10506
- const color = hitRatio >= 0.7 ? "green" : hitRatio >= 0.4 ? "yellow" : "red";
10507
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "cache "), /* @__PURE__ */ React20.createElement(Text18, { color, bold: true }, pct2, "%"));
10769
+ const color = hitRatio >= 0.7 ? COLOR.ok : hitRatio >= 0.4 ? COLOR.warn : COLOR.err;
10770
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u232C cache "), /* @__PURE__ */ React21.createElement(Text17, { color, bold: true }, pct2, "%"));
10508
10771
  }
10509
10772
  function turnCostColor(cost) {
10510
10773
  if (cost <= 0) return void 0;
10511
- if (cost >= 0.2) return "red";
10512
- if (cost >= 0.05) return "yellow";
10513
- return "green";
10774
+ if (cost >= 0.2) return COLOR.err;
10775
+ if (cost >= 0.05) return COLOR.warn;
10776
+ return COLOR.ok;
10514
10777
  }
10515
10778
  function sessionCostColor(cost) {
10516
10779
  if (cost <= 0) return void 0;
10517
- if (cost >= 5) return "red";
10518
- if (cost >= 0.5) return "yellow";
10519
- return "green";
10780
+ if (cost >= 5) return COLOR.err;
10781
+ if (cost >= 0.5) return COLOR.warn;
10782
+ return COLOR.ok;
10520
10783
  }
10521
10784
  function CostCell({
10522
10785
  summary,
10523
10786
  coldStart
10524
10787
  }) {
10525
10788
  if (summary.turns === 0) {
10526
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "cost "), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "\u2014"));
10789
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info, dimColor: true }, "\u25F4 cost "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u2014"));
10527
10790
  }
10528
10791
  const turnColor = coldStart ? void 0 : turnCostColor(summary.lastTurnCostUsd);
10529
10792
  const sessionColor = coldStart ? void 0 : sessionCostColor(summary.totalCostUsd);
10530
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "turn "), /* @__PURE__ */ React20.createElement(Text18, { color: turnColor, bold: !coldStart, dimColor: coldStart }, "$", summary.lastTurnCostUsd.toFixed(4)), /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, " \xB7 session "), /* @__PURE__ */ React20.createElement(Text18, { color: sessionColor, bold: !coldStart, dimColor: coldStart }, "$", summary.totalCostUsd.toFixed(4)));
10793
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25F4 turn "), /* @__PURE__ */ React21.createElement(Text17, { color: turnColor, bold: !coldStart, dimColor: coldStart }, "$", summary.lastTurnCostUsd.toFixed(4)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " \xB7 session "), /* @__PURE__ */ React21.createElement(Text17, { color: sessionColor, bold: !coldStart, dimColor: coldStart }, "$", summary.totalCostUsd.toFixed(4)));
10531
10794
  }
10532
10795
  function BalanceCell({ balance }) {
10533
- const color = balance.total < 1 ? "red" : balance.total < 5 ? "yellow" : "green";
10534
- return /* @__PURE__ */ React20.createElement(Text18, null, /* @__PURE__ */ React20.createElement(Text18, { dimColor: true }, "balance "), /* @__PURE__ */ React20.createElement(Text18, { color, bold: true }, balance.currency === "USD" ? "$" : "", balance.total.toFixed(2), balance.currency !== "USD" ? ` ${balance.currency}` : ""));
10796
+ const color = balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok;
10797
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25D0 balance "), /* @__PURE__ */ React21.createElement(Text17, { color, bold: true }, balance.currency === "USD" ? "$" : "", balance.total.toFixed(2), balance.currency !== "USD" ? ` ${balance.currency}` : ""));
10535
10798
  }
10536
- function Bar({ ratio, color }) {
10537
- const cells = 10;
10799
+ function Bar({
10800
+ ratio,
10801
+ color,
10802
+ cells = 14
10803
+ }) {
10538
10804
  const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
10539
- const bar = "\u2588".repeat(filled) + "\u2591".repeat(cells - filled);
10540
- return /* @__PURE__ */ React20.createElement(Text18, { color }, bar);
10805
+ return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color }, "\u25B0".repeat(filled)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u25B1".repeat(cells - filled)));
10541
10806
  }
10542
10807
  function formatTokens(n) {
10543
10808
  if (n < 1024) return String(n);
@@ -10546,13 +10811,26 @@ function formatTokens(n) {
10546
10811
  }
10547
10812
 
10548
10813
  // src/cli/ui/WelcomeBanner.tsx
10549
- import { Box as Box19, Text as Text19 } from "ink";
10550
- import React21 from "react";
10814
+ import { Box as Box20, Text as Text18, useStdout as useStdout7 } from "ink";
10815
+ import React22 from "react";
10551
10816
  function WelcomeBanner({ inCodeMode }) {
10552
- return /* @__PURE__ */ React21.createElement(Box19, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React21.createElement(Box19, null, /* @__PURE__ */ React21.createElement(Text19, { bold: true, color: "cyan" }, "Hi"), /* @__PURE__ */ React21.createElement(Text19, null, " \u2014 type a message to start, or try:")), /* @__PURE__ */ React21.createElement(Box19, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Hint, { cmd: "/help", desc: "every command + keyboard shortcut" }), /* @__PURE__ */ React21.createElement(Hint, { cmd: "/skill", desc: "invoke a stored playbook" }), inCodeMode ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(Hint, { cmd: "@path", desc: "inline a file in your message" }), /* @__PURE__ */ React21.createElement(Hint, { cmd: "!cmd", desc: "run a shell command, output goes to context" })) : null, /* @__PURE__ */ React21.createElement(Hint, { cmd: "/exit", desc: "quit" })));
10817
+ const { stdout: stdout2 } = useStdout7();
10818
+ const cols = stdout2?.columns ?? 80;
10819
+ const ruleWidth = Math.min(60, Math.max(28, cols - 4));
10820
+ return /* @__PURE__ */ React22.createElement(Box20, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React22.createElement(GradientRule, { width: ruleWidth }), /* @__PURE__ */ React22.createElement(BarRow, null, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: COLOR.brand }, "\u25C8 welcome"), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " \xB7 type a message to start")), /* @__PURE__ */ React22.createElement(BarRow, null), /* @__PURE__ */ React22.createElement(BarRow, null, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: COLOR.primary }, "quick start")), /* @__PURE__ */ React22.createElement(Hint, { cmd: "/help", desc: "every command + keyboard shortcut" }), /* @__PURE__ */ React22.createElement(Hint, { cmd: "/skill", desc: "invoke a stored playbook" }), inCodeMode ? /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(Hint, { cmd: "@path", desc: "inline a file in your message" }), /* @__PURE__ */ React22.createElement(Hint, { cmd: "!cmd", desc: "run a shell command, output goes to context" })) : null, /* @__PURE__ */ React22.createElement(Hint, { cmd: "/exit", desc: "quit (Ctrl+C also works)" }), /* @__PURE__ */ React22.createElement(BarRow, null), /* @__PURE__ */ React22.createElement(BarRow, null, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true, italic: true }, "tip:"), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " Ctrl+J inserts a newline \xB7 trailing \\ also continues")), /* @__PURE__ */ React22.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(GradientRule, { width: ruleWidth, thin: true })));
10821
+ }
10822
+ function GradientRule({ width, thin }) {
10823
+ const cells = gradientCells(width, thin ? "\u2581" : "\u2584");
10824
+ return /* @__PURE__ */ React22.createElement(Box20, null, cells.map((c, i) => (
10825
+ // biome-ignore lint/suspicious/noArrayIndexKey: fixed-width gradient row, never reordered
10826
+ /* @__PURE__ */ React22.createElement(Text18, { key: `wrule-${i}`, color: c.color }, c.ch)
10827
+ )));
10828
+ }
10829
+ function BarRow({ children }) {
10830
+ return /* @__PURE__ */ React22.createElement(Box20, null, /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.brand, bold: true }, "\u258E"), /* @__PURE__ */ React22.createElement(Text18, null, " "), children);
10553
10831
  }
10554
10832
  function Hint({ cmd, desc }) {
10555
- return /* @__PURE__ */ React21.createElement(Box19, null, /* @__PURE__ */ React21.createElement(Text19, { dimColor: true }, " "), /* @__PURE__ */ React21.createElement(Text19, { bold: true, color: "magenta" }, cmd.padEnd(8)), /* @__PURE__ */ React21.createElement(Text19, { dimColor: true }, ` ${desc}`));
10833
+ return /* @__PURE__ */ React22.createElement(BarRow, null, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: COLOR.accent }, cmd.padEnd(8)), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` ${desc}`));
10556
10834
  }
10557
10835
 
10558
10836
  // src/cli/ui/bang.ts
@@ -12894,7 +13172,7 @@ function App({
12894
13172
  const abortedThisTurn = useRef6(false);
12895
13173
  const [ongoingTool, setOngoingTool] = useState10(null);
12896
13174
  const [toolProgress, setToolProgress] = useState10(null);
12897
- const { stdout: stdout2 } = useStdout5();
13175
+ const { stdout: stdout2 } = useStdout8();
12898
13176
  useEffect6(() => {
12899
13177
  if (!stdout2 || !stdout2.isTTY) return;
12900
13178
  stdout2.write("\x1B[?2004h");
@@ -12904,6 +13182,24 @@ function App({
12904
13182
  stdout2.write("\x1B[>4m");
12905
13183
  };
12906
13184
  }, [stdout2]);
13185
+ const [isResizing, setIsResizing] = useState10(false);
13186
+ useEffect6(() => {
13187
+ if (!stdout2 || !stdout2.isTTY) return;
13188
+ let timer = null;
13189
+ const onResize = () => {
13190
+ setIsResizing(true);
13191
+ if (timer) clearTimeout(timer);
13192
+ timer = setTimeout(() => {
13193
+ setIsResizing(false);
13194
+ timer = null;
13195
+ }, 400);
13196
+ };
13197
+ stdout2.on("resize", onResize);
13198
+ return () => {
13199
+ stdout2.off("resize", onResize);
13200
+ if (timer) clearTimeout(timer);
13201
+ };
13202
+ }, [stdout2]);
12907
13203
  const { activity: subagentActivity, sinkRef: subagentSinkRef } = useSubagent({
12908
13204
  session,
12909
13205
  setHistorical
@@ -14477,12 +14773,12 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14477
14773
  async (choice) => handleReviseConfirmRef.current(choice),
14478
14774
  []
14479
14775
  );
14480
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(
14776
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(
14481
14777
  TickerProvider,
14482
14778
  {
14483
- disabled: PLAIN_UI || !!pendingPlan || !!pendingShell || !!pendingEditReview || !!pendingCheckpoint || !!stagedCheckpointRevise || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision
14779
+ disabled: PLAIN_UI || isResizing || !!pendingPlan || !!pendingShell || !!pendingEditReview || !!pendingCheckpoint || !!stagedCheckpointRevise || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision
14484
14780
  },
14485
- /* @__PURE__ */ React22.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(
14781
+ /* @__PURE__ */ React23.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React23.createElement(
14486
14782
  StatsPanel,
14487
14783
  {
14488
14784
  summary,
@@ -14499,28 +14795,28 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14499
14795
  proArmed,
14500
14796
  escalated: turnOnPro
14501
14797
  }
14502
- ), /* @__PURE__ */ React22.createElement(Static, { items: historical }, (item) => /* @__PURE__ */ React22.createElement(EventRow, { key: item.id, event: item, projectRoot: hookCwd })), !historical.some((e) => e.role === "user" || e.role === "assistant") && !busy && !streaming ? /* @__PURE__ */ React22.createElement(WelcomeBanner, { inCodeMode: !!codeMode }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && streaming ? /* @__PURE__ */ React22.createElement(Box20, { marginY: 1 }, /* @__PURE__ */ React22.createElement(EventRow, { event: streaming, projectRoot: hookCwd })) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && ongoingTool ? /* @__PURE__ */ React22.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && subagentActivity ? /* @__PURE__ */ React22.createElement(SubagentRow, { activity: subagentActivity }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !ongoingTool && statusLine ? /* @__PURE__ */ React22.createElement(StatusRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision ? /* @__PURE__ */ React22.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && busy && !streaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React22.createElement(StatusRow, { text: "processing\u2026" }) : null, stagedInput ? /* @__PURE__ */ React22.createElement(
14798
+ ), /* @__PURE__ */ React23.createElement(Static, { items: historical }, (item) => /* @__PURE__ */ React23.createElement(EventRow, { key: item.id, event: item, projectRoot: hookCwd })), !historical.some((e) => e.role === "user" || e.role === "assistant") && !busy && !streaming ? /* @__PURE__ */ React23.createElement(WelcomeBanner, { inCodeMode: !!codeMode }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && streaming ? /* @__PURE__ */ React23.createElement(Box21, { marginY: 1 }, /* @__PURE__ */ React23.createElement(EventRow, { event: streaming, projectRoot: hookCwd })) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && ongoingTool ? /* @__PURE__ */ React23.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && subagentActivity ? /* @__PURE__ */ React23.createElement(SubagentRow, { activity: subagentActivity }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !ongoingTool && statusLine ? /* @__PURE__ */ React23.createElement(StatusRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision ? /* @__PURE__ */ React23.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && busy && !streaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React23.createElement(StatusRow, { text: "processing\u2026" }) : null, stagedInput ? /* @__PURE__ */ React23.createElement(
14503
14799
  PlanRefineInput,
14504
14800
  {
14505
14801
  mode: stagedInput.mode,
14506
14802
  onSubmit: handleStagedInputSubmit,
14507
14803
  onCancel: handleStagedInputCancel
14508
14804
  }
14509
- ) : stagedCheckpointRevise ? /* @__PURE__ */ React22.createElement(
14805
+ ) : stagedCheckpointRevise ? /* @__PURE__ */ React23.createElement(
14510
14806
  PlanRefineInput,
14511
14807
  {
14512
14808
  mode: "checkpoint-revise",
14513
14809
  onSubmit: handleCheckpointReviseSubmit,
14514
14810
  onCancel: handleCheckpointReviseCancel
14515
14811
  }
14516
- ) : stagedChoiceCustom ? /* @__PURE__ */ React22.createElement(
14812
+ ) : stagedChoiceCustom ? /* @__PURE__ */ React23.createElement(
14517
14813
  PlanRefineInput,
14518
14814
  {
14519
14815
  mode: "choice-custom",
14520
14816
  onSubmit: handleChoiceCustomSubmit,
14521
14817
  onCancel: handleChoiceCustomCancel
14522
14818
  }
14523
- ) : pendingChoice ? /* @__PURE__ */ React22.createElement(
14819
+ ) : pendingChoice ? /* @__PURE__ */ React23.createElement(
14524
14820
  ChoiceConfirm,
14525
14821
  {
14526
14822
  question: pendingChoice.question,
@@ -14528,7 +14824,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14528
14824
  allowCustom: pendingChoice.allowCustom,
14529
14825
  onChoose: stableHandleChoiceConfirm
14530
14826
  }
14531
- ) : pendingRevision ? /* @__PURE__ */ React22.createElement(
14827
+ ) : pendingRevision ? /* @__PURE__ */ React23.createElement(
14532
14828
  PlanReviseConfirm,
14533
14829
  {
14534
14830
  reason: pendingRevision.reason,
@@ -14539,7 +14835,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14539
14835
  summary: pendingRevision.summary,
14540
14836
  onChoose: stableHandleReviseConfirm
14541
14837
  }
14542
- ) : pendingCheckpoint ? /* @__PURE__ */ React22.createElement(
14838
+ ) : pendingCheckpoint ? /* @__PURE__ */ React23.createElement(
14543
14839
  PlanCheckpointConfirm,
14544
14840
  {
14545
14841
  stepId: pendingCheckpoint.stepId,
@@ -14550,7 +14846,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14550
14846
  completedStepIds: completedStepIdsRef.current,
14551
14847
  onChoose: stableHandleCheckpointConfirm
14552
14848
  }
14553
- ) : pendingPlan ? /* @__PURE__ */ React22.createElement(
14849
+ ) : pendingPlan ? /* @__PURE__ */ React23.createElement(
14554
14850
  PlanConfirm,
14555
14851
  {
14556
14852
  plan: pendingPlan,
@@ -14559,7 +14855,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14559
14855
  onChoose: stableHandlePlanConfirm,
14560
14856
  projectRoot: hookCwd
14561
14857
  }
14562
- ) : pendingShell ? /* @__PURE__ */ React22.createElement(
14858
+ ) : pendingShell ? /* @__PURE__ */ React23.createElement(
14563
14859
  ShellConfirm,
14564
14860
  {
14565
14861
  command: pendingShell.command,
@@ -14567,7 +14863,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14567
14863
  kind: pendingShell.kind,
14568
14864
  onChoose: handleShellConfirm
14569
14865
  }
14570
- ) : pendingEditReview ? /* @__PURE__ */ React22.createElement(
14866
+ ) : pendingEditReview ? /* @__PURE__ */ React23.createElement(
14571
14867
  EditConfirm,
14572
14868
  {
14573
14869
  block: pendingEditReview,
@@ -14579,7 +14875,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14579
14875
  }
14580
14876
  }
14581
14877
  }
14582
- ) : /* @__PURE__ */ React22.createElement(React22.Fragment, null, codeMode ? /* @__PURE__ */ React22.createElement(
14878
+ ) : /* @__PURE__ */ React23.createElement(React23.Fragment, null, codeMode ? /* @__PURE__ */ React23.createElement(
14583
14879
  ModeStatusBar,
14584
14880
  {
14585
14881
  editMode,
@@ -14589,7 +14885,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14589
14885
  undoArmed: !!undoBanner || hasUndoable(),
14590
14886
  jobs: codeMode.jobs
14591
14887
  }
14592
- ) : null, /* @__PURE__ */ React22.createElement(
14888
+ ) : null, /* @__PURE__ */ React23.createElement(
14593
14889
  PromptInput,
14594
14890
  {
14595
14891
  value: input,
@@ -14599,14 +14895,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14599
14895
  onHistoryPrev: recallPrev,
14600
14896
  onHistoryNext: recallNext
14601
14897
  }
14602
- ), /* @__PURE__ */ React22.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }), /* @__PURE__ */ React22.createElement(
14898
+ ), /* @__PURE__ */ React23.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }), /* @__PURE__ */ React23.createElement(
14603
14899
  AtMentionSuggestions,
14604
14900
  {
14605
14901
  matches: atMatches,
14606
14902
  selectedIndex: atSelected,
14607
14903
  query: atPicker?.query ?? ""
14608
14904
  }
14609
- ), slashArgContext ? /* @__PURE__ */ React22.createElement(
14905
+ ), slashArgContext ? /* @__PURE__ */ React23.createElement(
14610
14906
  SlashArgPicker,
14611
14907
  {
14612
14908
  matches: slashArgMatches,
@@ -14620,15 +14916,15 @@ Continue executing from the next pending step. Call mark_step_complete after eac
14620
14916
  }
14621
14917
 
14622
14918
  // src/cli/ui/SessionPicker.tsx
14623
- import { Box as Box21, Text as Text20 } from "ink";
14624
- import React23 from "react";
14919
+ import { Box as Box22, Text as Text19 } from "ink";
14920
+ import React24 from "react";
14625
14921
  function SessionPicker({
14626
14922
  sessionName,
14627
14923
  messageCount,
14628
14924
  lastActive,
14629
14925
  onChoose
14630
14926
  }) {
14631
- return /* @__PURE__ */ React23.createElement(Box21, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React23.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text20, { bold: true, color: "cyan" }, `Session "${sessionName}" has ${messageCount} prior message${messageCount === 1 ? "" : "s"}`), /* @__PURE__ */ React23.createElement(Text20, { dimColor: true }, ` \xB7 last active ${relativeTime2(lastActive)}`)), /* @__PURE__ */ React23.createElement(
14927
+ return /* @__PURE__ */ React24.createElement(Box22, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React24.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: "cyan" }, `Session "${sessionName}" has ${messageCount} prior message${messageCount === 1 ? "" : "s"}`), /* @__PURE__ */ React24.createElement(Text19, { dimColor: true }, ` \xB7 last active ${relativeTime2(lastActive)}`)), /* @__PURE__ */ React24.createElement(
14632
14928
  SingleSelect,
14633
14929
  {
14634
14930
  initialValue: "new",
@@ -14651,7 +14947,7 @@ function SessionPicker({
14651
14947
  ],
14652
14948
  onSubmit: (v) => onChoose(v)
14653
14949
  }
14654
- ), /* @__PURE__ */ React23.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text20, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] select")));
14950
+ ), /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] select")));
14655
14951
  }
14656
14952
  function relativeTime2(date) {
14657
14953
  const ms = Date.now() - date.getTime();
@@ -14667,9 +14963,9 @@ function relativeTime2(date) {
14667
14963
  }
14668
14964
 
14669
14965
  // src/cli/ui/Setup.tsx
14670
- import { Box as Box22, Text as Text21, useApp as useApp2 } from "ink";
14966
+ import { Box as Box23, Text as Text20, useApp as useApp2 } from "ink";
14671
14967
  import TextInput from "ink-text-input";
14672
- import React24, { useState as useState11 } from "react";
14968
+ import React25, { useState as useState11 } from "react";
14673
14969
  function Setup({ onReady }) {
14674
14970
  const [value, setValue] = useState11("");
14675
14971
  const [error, setError] = useState11(null);
@@ -14693,7 +14989,7 @@ function Setup({ onReady }) {
14693
14989
  }
14694
14990
  onReady(trimmed);
14695
14991
  };
14696
- return /* @__PURE__ */ React24.createElement(Box22, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React24.createElement(
14992
+ return /* @__PURE__ */ React25.createElement(Box23, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React25.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React25.createElement(Text20, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React25.createElement(Text20, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React25.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React25.createElement(
14697
14993
  TextInput,
14698
14994
  {
14699
14995
  value,
@@ -14702,7 +14998,7 @@ function Setup({ onReady }) {
14702
14998
  mask: "\u2022",
14703
14999
  placeholder: "sk-..."
14704
15000
  }
14705
- )), error ? /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, { color: "red" }, error)) : value ? /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "preview: ", redactKey(value))) : null, /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "(Type /exit to abort.)")));
15001
+ )), error ? /* @__PURE__ */ React25.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: "red" }, error)) : value ? /* @__PURE__ */ React25.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { dimColor: true }, "preview: ", redactKey(value))) : null, /* @__PURE__ */ React25.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { dimColor: true }, "(Type /exit to abort.)")));
14706
15002
  }
14707
15003
 
14708
15004
  // src/cli/commands/chat.tsx
@@ -14718,7 +15014,7 @@ function Root({
14718
15014
  const [key, setKey] = useState12(initialKey);
14719
15015
  const [pending, setPending] = useState12(sessionPreview);
14720
15016
  if (!key) {
14721
- return /* @__PURE__ */ React25.createElement(
15017
+ return /* @__PURE__ */ React26.createElement(
14722
15018
  Setup,
14723
15019
  {
14724
15020
  onReady: (k) => {
@@ -14730,7 +15026,7 @@ function Root({
14730
15026
  }
14731
15027
  process.env.DEEPSEEK_API_KEY = key;
14732
15028
  if (pending && appProps.session) {
14733
- return /* @__PURE__ */ React25.createElement(KeystrokeProvider, null, /* @__PURE__ */ React25.createElement(
15029
+ return /* @__PURE__ */ React26.createElement(KeystrokeProvider, null, /* @__PURE__ */ React26.createElement(
14734
15030
  SessionPicker,
14735
15031
  {
14736
15032
  sessionName: appProps.session,
@@ -14745,7 +15041,7 @@ function Root({
14745
15041
  }
14746
15042
  ));
14747
15043
  }
14748
- return /* @__PURE__ */ React25.createElement(KeystrokeProvider, null, /* @__PURE__ */ React25.createElement(
15044
+ return /* @__PURE__ */ React26.createElement(KeystrokeProvider, null, /* @__PURE__ */ React26.createElement(
14749
15045
  App,
14750
15046
  {
14751
15047
  model: appProps.model,
@@ -14850,7 +15146,7 @@ async function chatCommand(opts) {
14850
15146
  rewriteSession(opts.session, []);
14851
15147
  }
14852
15148
  const { waitUntilExit } = render(
14853
- /* @__PURE__ */ React25.createElement(
15149
+ /* @__PURE__ */ React26.createElement(
14854
15150
  Root,
14855
15151
  {
14856
15152
  initialKey,
@@ -14919,35 +15215,35 @@ async function codeCommand(opts = {}) {
14919
15215
  import { writeFileSync as writeFileSync7 } from "fs";
14920
15216
  import { basename as basename3 } from "path";
14921
15217
  import { render as render2 } from "ink";
14922
- import React28 from "react";
15218
+ import React29 from "react";
14923
15219
 
14924
15220
  // src/cli/ui/DiffApp.tsx
14925
- import { Box as Box24, Static as Static2, Text as Text23, useApp as useApp3, useInput } from "ink";
14926
- import React27, { useState as useState13 } from "react";
15221
+ import { Box as Box25, Static as Static2, Text as Text22, useApp as useApp3, useInput } from "ink";
15222
+ import React28, { useState as useState13 } from "react";
14927
15223
 
14928
15224
  // src/cli/ui/RecordView.tsx
14929
- import { Box as Box23, Text as Text22 } from "ink";
14930
- import React26 from "react";
15225
+ import { Box as Box24, Text as Text21 } from "ink";
15226
+ import React27 from "react";
14931
15227
  function RecordView({ rec, compact: compact2 = false }) {
14932
15228
  const toolArgsMax = compact2 ? 120 : 200;
14933
15229
  const toolContentMax = compact2 ? 200 : 400;
14934
15230
  if (rec.role === "user") {
14935
15231
  const content = rec.content.includes("\n") ? rec.content.split("\n").join("\n ") : rec.content;
14936
- return /* @__PURE__ */ React26.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React26.createElement(Text22, null, content));
15232
+ return /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text21, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React27.createElement(Text21, null, content));
14937
15233
  }
14938
15234
  if (rec.role === "assistant_final") {
14939
- return /* @__PURE__ */ React26.createElement(Box23, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React26.createElement(Box23, null, /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React26.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React26.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React26.createElement(Text22, null, rec.content) : /* @__PURE__ */ React26.createElement(Text22, { dimColor: true, italic: true }, "(tool-call response only)"));
15235
+ return /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React27.createElement(Box24, null, /* @__PURE__ */ React27.createElement(Text21, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React27.createElement(Text21, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React27.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React27.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React27.createElement(Text21, null, rec.content) : /* @__PURE__ */ React27.createElement(Text21, { dimColor: true, italic: true }, "(tool-call response only)"));
14940
15236
  }
14941
15237
  if (rec.role === "tool") {
14942
- return /* @__PURE__ */ React26.createElement(Box23, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React26.createElement(Text22, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, " args: ", truncate2(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, " \u2192 ", truncate2(rec.content, toolContentMax)));
15238
+ return /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text21, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React27.createElement(Text21, { dimColor: true }, " args: ", truncate2(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React27.createElement(Text21, { dimColor: true }, " \u2192 ", truncate2(rec.content, toolContentMax)));
14943
15239
  }
14944
15240
  if (rec.role === "error") {
14945
- return /* @__PURE__ */ React26.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React26.createElement(Text22, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React26.createElement(Text22, { color: "red" }, rec.error ?? rec.content));
15241
+ return /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text21, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React27.createElement(Text21, { color: "red" }, rec.error ?? rec.content));
14946
15242
  }
14947
15243
  if (rec.role === "done" || rec.role === "assistant_delta") {
14948
15244
  return null;
14949
15245
  }
14950
- return /* @__PURE__ */ React26.createElement(Box23, null, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, "[", rec.role, "] ", rec.content));
15246
+ return /* @__PURE__ */ React27.createElement(Box24, null, /* @__PURE__ */ React27.createElement(Text21, { dimColor: true }, "[", rec.role, "] ", rec.content));
14951
15247
  }
14952
15248
  function CacheBadge({ usage }) {
14953
15249
  const hit = usage.prompt_cache_hit_tokens ?? 0;
@@ -14956,7 +15252,7 @@ function CacheBadge({ usage }) {
14956
15252
  if (total === 0) return null;
14957
15253
  const pct2 = hit / total * 100;
14958
15254
  const color = pct2 >= 70 ? "green" : pct2 >= 40 ? "yellow" : "red";
14959
- return /* @__PURE__ */ React26.createElement(Text22, null, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React26.createElement(Text22, { color }, pct2.toFixed(1), "%"));
15255
+ return /* @__PURE__ */ React27.createElement(Text21, null, /* @__PURE__ */ React27.createElement(Text21, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React27.createElement(Text21, { color }, pct2.toFixed(1), "%"));
14960
15256
  }
14961
15257
  function truncate2(s, max) {
14962
15258
  return s.length <= max ? s : `${s.slice(0, max)}\u2026 (+${s.length - max} chars)`;
@@ -14990,7 +15286,7 @@ function DiffApp({ report }) {
14990
15286
  }
14991
15287
  });
14992
15288
  const pair = report.pairs[idx];
14993
- return /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(DiffHeader, { report }), /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React27.createElement(Text23, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React27.createElement(Text23, null, pair ? /* @__PURE__ */ React27.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React27.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React27.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React27.createElement(Text23, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React27.createElement(Text23, null, pair.divergenceNote)) : null, /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "j"), "/", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "k"), "/", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "N"), "/", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "g"), "/", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React27.createElement(Text23, { bold: true }, "q"), " ", "quit")));
15289
+ return /* @__PURE__ */ React28.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React28.createElement(DiffHeader, { report }), /* @__PURE__ */ React28.createElement(Box25, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React28.createElement(Text22, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React28.createElement(Text22, null, pair ? /* @__PURE__ */ React28.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React28.createElement(Box25, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React28.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React28.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React28.createElement(Box25, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React28.createElement(Text22, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React28.createElement(Text22, null, pair.divergenceNote)) : null, /* @__PURE__ */ React28.createElement(Box25, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "j"), "/", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "k"), "/", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "N"), "/", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "g"), "/", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React28.createElement(Text22, { bold: true }, "q"), " ", "quit")));
14994
15290
  }
14995
15291
  function DiffHeader({ report }) {
14996
15292
  const a = report.a;
@@ -15008,15 +15304,15 @@ function DiffHeader({ report }) {
15008
15304
  } else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {
15009
15305
  prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}\u2026 \u2014 cache delta attributable to log stability, not prompt change.`;
15010
15306
  }
15011
- return /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React27.createElement(Box24, { justifyContent: "space-between" }, /* @__PURE__ */ React27.createElement(Text23, null, /* @__PURE__ */ React27.createElement(Text23, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React27.createElement(Text23, { color: "blue" }, a.label), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, " vs B="), /* @__PURE__ */ React27.createElement(Text23, { color: "magenta" }, b.label)), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React27.createElement(Text23, null, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "cache "), /* @__PURE__ */ React27.createElement(Text23, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React27.createElement(Text23, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React27.createElement(Text23, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React27.createElement(Text23, null, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "cost "), /* @__PURE__ */ React27.createElement(Text23, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React27.createElement(Text23, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React27.createElement(Text23, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React27.createElement(Text23, null, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "model calls "), /* @__PURE__ */ React27.createElement(Text23, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true, italic: true }, prefixLine)) : null);
15307
+ return /* @__PURE__ */ React28.createElement(Box25, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React28.createElement(Box25, { justifyContent: "space-between" }, /* @__PURE__ */ React28.createElement(Text22, null, /* @__PURE__ */ React28.createElement(Text22, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React28.createElement(Text22, { color: "blue" }, a.label), /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, " vs B="), /* @__PURE__ */ React28.createElement(Text22, { color: "magenta" }, b.label)), /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React28.createElement(Box25, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React28.createElement(Text22, null, /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, "cache "), /* @__PURE__ */ React28.createElement(Text22, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React28.createElement(Text22, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React28.createElement(Text22, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React28.createElement(Text22, null, /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, "cost "), /* @__PURE__ */ React28.createElement(Text22, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React28.createElement(Text22, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React28.createElement(Text22, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React28.createElement(Text22, null, /* @__PURE__ */ React28.createElement(Text22, { dimColor: true }, "model calls "), /* @__PURE__ */ React28.createElement(Text22, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React28.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React28.createElement(Text22, { dimColor: true, italic: true }, prefixLine)) : null);
15012
15308
  }
15013
15309
  function Pane({
15014
15310
  label,
15015
15311
  headerColor,
15016
15312
  records
15017
15313
  }) {
15018
- return /* @__PURE__ */ React27.createElement(
15019
- Box24,
15314
+ return /* @__PURE__ */ React28.createElement(
15315
+ Box25,
15020
15316
  {
15021
15317
  flexDirection: "column",
15022
15318
  flexGrow: 1,
@@ -15024,21 +15320,21 @@ function Pane({
15024
15320
  borderStyle: "single",
15025
15321
  borderColor: headerColor
15026
15322
  },
15027
- /* @__PURE__ */ React27.createElement(Text23, { color: headerColor, bold: true }, label),
15028
- records.length === 0 ? /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React27.createElement(Static2, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React27.createElement(RecordView, { key, rec, compact: true }))
15323
+ /* @__PURE__ */ React28.createElement(Text22, { color: headerColor, bold: true }, label),
15324
+ records.length === 0 ? /* @__PURE__ */ React28.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React28.createElement(Text22, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React28.createElement(Static2, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React28.createElement(RecordView, { key, rec, compact: true }))
15029
15325
  );
15030
15326
  }
15031
15327
  function KindBadge({ kind }) {
15032
15328
  if (kind === "match") {
15033
- return /* @__PURE__ */ React27.createElement(Text23, { color: "green" }, "\u2713 match");
15329
+ return /* @__PURE__ */ React28.createElement(Text22, { color: "green" }, "\u2713 match");
15034
15330
  }
15035
15331
  if (kind === "diverge") {
15036
- return /* @__PURE__ */ React27.createElement(Text23, { color: "yellow" }, "\u2605 diverge");
15332
+ return /* @__PURE__ */ React28.createElement(Text22, { color: "yellow" }, "\u2605 diverge");
15037
15333
  }
15038
15334
  if (kind === "only_in_a") {
15039
- return /* @__PURE__ */ React27.createElement(Text23, { color: "blue" }, "\u2190 only in A");
15335
+ return /* @__PURE__ */ React28.createElement(Text22, { color: "blue" }, "\u2190 only in A");
15040
15336
  }
15041
- return /* @__PURE__ */ React27.createElement(Text23, { color: "magenta" }, "\u2192 only in B");
15337
+ return /* @__PURE__ */ React28.createElement(Text22, { color: "magenta" }, "\u2192 only in B");
15042
15338
  }
15043
15339
  function paneRecords(pair, side) {
15044
15340
  if (!pair) return [];
@@ -15069,7 +15365,7 @@ markdown report written to ${opts.mdPath}`);
15069
15365
  return;
15070
15366
  }
15071
15367
  if (wantTui) {
15072
- const { waitUntilExit } = render2(React28.createElement(DiffApp, { report }), {
15368
+ const { waitUntilExit } = render2(React29.createElement(DiffApp, { report }), {
15073
15369
  exitOnCtrlC: true,
15074
15370
  patchConsole: false
15075
15371
  });
@@ -15210,11 +15506,11 @@ function pad2(s, width) {
15210
15506
 
15211
15507
  // src/cli/commands/replay.ts
15212
15508
  import { render as render3 } from "ink";
15213
- import React30 from "react";
15509
+ import React31 from "react";
15214
15510
 
15215
15511
  // src/cli/ui/ReplayApp.tsx
15216
- import { Box as Box25, Static as Static3, Text as Text24, useApp as useApp4, useInput as useInput2 } from "ink";
15217
- import React29, { useMemo as useMemo4, useState as useState14 } from "react";
15512
+ import { Box as Box26, Static as Static3, Text as Text23, useApp as useApp4, useInput as useInput2 } from "ink";
15513
+ import React30, { useMemo as useMemo4, useState as useState14 } from "react";
15218
15514
  function ReplayApp({ meta, pages }) {
15219
15515
  const { exit: exit2 } = useApp4();
15220
15516
  const maxIdx = Math.max(0, pages.length - 1);
@@ -15254,14 +15550,14 @@ function ReplayApp({ meta, pages }) {
15254
15550
  const prefixHash = cumStats.prefixHashes.length === 1 ? cumStats.prefixHashes[0].slice(0, 16) : cumStats.prefixHashes.length === 0 ? "(untracked)" : `(churned \xD7${cumStats.prefixHashes.length})`;
15255
15551
  const currentPage = pages[idx];
15256
15552
  const progressLabel = pages.length === 0 ? "empty transcript" : `turn ${idx + 1} / ${pages.length}`;
15257
- return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(
15553
+ return /* @__PURE__ */ React30.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(
15258
15554
  StatsPanel,
15259
15555
  {
15260
15556
  summary,
15261
15557
  model: cumStats.models[0] ?? meta?.model ?? "?",
15262
15558
  prefixHash
15263
15559
  }
15264
- ), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React29.createElement(Box25, { justifyContent: "space-between" }, /* @__PURE__ */ React29.createElement(Text24, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React29.createElement(Static3, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React29.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React29.createElement(Text24, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "j"), "/", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "k"), "/", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "q"), " quit")));
15560
+ ), /* @__PURE__ */ React30.createElement(Box26, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React30.createElement(Box26, { justifyContent: "space-between" }, /* @__PURE__ */ React30.createElement(Text23, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React30.createElement(Text23, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React30.createElement(Static3, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React30.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React30.createElement(Text23, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React30.createElement(Box26, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React30.createElement(Text23, { dimColor: true }, /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "j"), "/", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "k"), "/", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React30.createElement(Text23, { bold: true }, "q"), " quit")));
15265
15561
  }
15266
15562
 
15267
15563
  // src/cli/commands/replay.ts
@@ -15273,7 +15569,7 @@ async function replayCommand(opts) {
15273
15569
  }
15274
15570
  const { parsed } = replayFromFile(opts.path);
15275
15571
  const pages = groupRecordsByTurn(parsed.records);
15276
- const { waitUntilExit } = render3(React30.createElement(ReplayApp, { meta: parsed.meta, pages }), {
15572
+ const { waitUntilExit } = render3(React31.createElement(ReplayApp, { meta: parsed.meta, pages }), {
15277
15573
  exitOnCtrlC: true,
15278
15574
  patchConsole: false
15279
15575
  });
@@ -15578,12 +15874,12 @@ function truncate3(s, max) {
15578
15874
 
15579
15875
  // src/cli/commands/setup.tsx
15580
15876
  import { render as render4 } from "ink";
15581
- import React32 from "react";
15877
+ import React33 from "react";
15582
15878
 
15583
15879
  // src/cli/ui/Wizard.tsx
15584
- import { Box as Box26, Text as Text25, useApp as useApp5, useInput as useInput3 } from "ink";
15880
+ import { Box as Box27, Text as Text24, useApp as useApp5, useInput as useInput3 } from "ink";
15585
15881
  import TextInput2 from "ink-text-input";
15586
- import React31, { useState as useState15 } from "react";
15882
+ import React32, { useState as useState15 } from "react";
15587
15883
 
15588
15884
  // src/cli/ui/presets.ts
15589
15885
  var PRESETS = {
@@ -15631,7 +15927,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15631
15927
  if (key.escape && step !== "saved" && onCancel) onCancel();
15632
15928
  });
15633
15929
  if (step === "apiKey") {
15634
- return /* @__PURE__ */ React31.createElement(
15930
+ return /* @__PURE__ */ React32.createElement(
15635
15931
  ApiKeyStep,
15636
15932
  {
15637
15933
  onSubmit: (key) => {
@@ -15645,7 +15941,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15645
15941
  );
15646
15942
  }
15647
15943
  if (step === "preset") {
15648
- return /* @__PURE__ */ React31.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React31.createElement(
15944
+ return /* @__PURE__ */ React32.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React32.createElement(
15649
15945
  SingleSelect,
15650
15946
  {
15651
15947
  items: presetItems(),
@@ -15655,10 +15951,10 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15655
15951
  setStep("mcp");
15656
15952
  }
15657
15953
  }
15658
- ), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
15954
+ ), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
15659
15955
  }
15660
15956
  if (step === "mcp") {
15661
- return /* @__PURE__ */ React31.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React31.createElement(
15957
+ return /* @__PURE__ */ React32.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React32.createElement(
15662
15958
  MultiSelect,
15663
15959
  {
15664
15960
  items: mcpItems(),
@@ -15683,7 +15979,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15683
15979
  }
15684
15980
  const currentName = pending[0];
15685
15981
  const entry = CATALOG_BY_NAME.get(currentName);
15686
- return /* @__PURE__ */ React31.createElement(
15982
+ return /* @__PURE__ */ React32.createElement(
15687
15983
  McpArgsStep,
15688
15984
  {
15689
15985
  entry,
@@ -15701,7 +15997,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15701
15997
  }
15702
15998
  if (step === "review") {
15703
15999
  const specs = data.selectedCatalog.map((name) => buildSpec(name, data.catalogArgs));
15704
- return /* @__PURE__ */ React31.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React31.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React31.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React31.createElement(
16000
+ return /* @__PURE__ */ React32.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "column" }, /* @__PURE__ */ React32.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React32.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React32.createElement(
15705
16001
  SummaryLine,
15706
16002
  {
15707
16003
  label: "MCP",
@@ -15709,8 +16005,8 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15709
16005
  }
15710
16006
  ), specs.map((spec, i) => (
15711
16007
  // biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
15712
- /* @__PURE__ */ React31.createElement(Box26, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "\xB7 ", spec))
15713
- )), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { color: "red" }, error)) : null, /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React31.createElement(
16008
+ /* @__PURE__ */ React32.createElement(Box27, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "\xB7 ", spec))
16009
+ )), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { color: "red" }, error)) : null, /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React32.createElement(
15714
16010
  ReviewConfirm,
15715
16011
  {
15716
16012
  onConfirm: () => {
@@ -15736,7 +16032,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15736
16032
  }
15737
16033
  ));
15738
16034
  }
15739
- return /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React31.createElement(Text25, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React31.createElement(ExitOnEnter, { onExit: exit2 }));
16035
+ return /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React32.createElement(Text24, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React32.createElement(ExitOnEnter, { onExit: exit2 }));
15740
16036
  }
15741
16037
  function ApiKeyStep({
15742
16038
  onSubmit,
@@ -15744,7 +16040,7 @@ function ApiKeyStep({
15744
16040
  onError
15745
16041
  }) {
15746
16042
  const [value, setValue] = useState15("");
15747
- return /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React31.createElement(Text25, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React31.createElement(
16043
+ return /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React32.createElement(Text24, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React32.createElement(
15748
16044
  TextInput2,
15749
16045
  {
15750
16046
  value,
@@ -15761,7 +16057,7 @@ function ApiKeyStep({
15761
16057
  mask: "\u2022",
15762
16058
  placeholder: "sk-..."
15763
16059
  }
15764
- )), error ? /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { color: "red" }, error)) : value ? /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "preview: ", redactKey(value))) : null);
16060
+ )), error ? /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { color: "red" }, error)) : value ? /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "preview: ", redactKey(value))) : null);
15765
16061
  }
15766
16062
  function McpArgsStep({
15767
16063
  entry,
@@ -15770,7 +16066,7 @@ function McpArgsStep({
15770
16066
  onError
15771
16067
  }) {
15772
16068
  const [value, setValue] = useState15("");
15773
- return /* @__PURE__ */ React31.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React31.createElement(Text25, null, entry.summary), entry.note ? /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, null, "Required parameter: "), /* @__PURE__ */ React31.createElement(Text25, { bold: true }, entry.userArgs)), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React31.createElement(
16069
+ return /* @__PURE__ */ React32.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "column" }, /* @__PURE__ */ React32.createElement(Text24, null, entry.summary), entry.note ? /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, null, "Required parameter: "), /* @__PURE__ */ React32.createElement(Text24, { bold: true }, entry.userArgs)), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React32.createElement(
15774
16070
  TextInput2,
15775
16071
  {
15776
16072
  value,
@@ -15786,7 +16082,7 @@ function McpArgsStep({
15786
16082
  },
15787
16083
  placeholder: placeholderFor(entry)
15788
16084
  }
15789
- )), error ? /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text25, { color: "red" }, error)) : null));
16085
+ )), error ? /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text24, { color: "red" }, error)) : null));
15790
16086
  }
15791
16087
  function ReviewConfirm({ onConfirm }) {
15792
16088
  useInput3((_i, key) => {
@@ -15806,10 +16102,10 @@ function StepFrame({
15806
16102
  total,
15807
16103
  children
15808
16104
  }) {
15809
- return /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React31.createElement(Box26, null, /* @__PURE__ */ React31.createElement(Text25, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React31.createElement(Text25, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React31.createElement(Box26, { marginTop: 1, flexDirection: "column" }, children));
16105
+ return /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React32.createElement(Box27, null, /* @__PURE__ */ React32.createElement(Text24, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React32.createElement(Text24, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React32.createElement(Box27, { marginTop: 1, flexDirection: "column" }, children));
15810
16106
  }
15811
16107
  function SummaryLine({ label, value }) {
15812
- return /* @__PURE__ */ React31.createElement(Box26, null, /* @__PURE__ */ React31.createElement(Text25, null, label.padEnd(12)), /* @__PURE__ */ React31.createElement(Text25, { bold: true }, value));
16108
+ return /* @__PURE__ */ React32.createElement(Box27, null, /* @__PURE__ */ React32.createElement(Text24, null, label.padEnd(12)), /* @__PURE__ */ React32.createElement(Text24, { bold: true }, value));
15813
16109
  }
15814
16110
  function presetItems() {
15815
16111
  return ["fast", "smart", "max"].map((name) => ({
@@ -15865,7 +16161,7 @@ async function setupCommand(_opts = {}) {
15865
16161
  const existingKey = loadApiKey();
15866
16162
  const existing = readConfig();
15867
16163
  const { waitUntilExit, unmount } = render4(
15868
- /* @__PURE__ */ React32.createElement(
16164
+ /* @__PURE__ */ React33.createElement(
15869
16165
  Wizard,
15870
16166
  {
15871
16167
  existingApiKey: existingKey,