reasonix 0.13.5 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -2788,6 +2788,7 @@ var CacheFirstLoop = class {
2788
2788
  if (signal.aborted) {
2789
2789
  this.autoCompactToolResultsOnTurnEnd();
2790
2790
  yield { turn: this._turn, role: "done", content: "" };
2791
+ this._turnAbort = new AbortController();
2791
2792
  return;
2792
2793
  }
2793
2794
  yield {
@@ -7767,12 +7768,12 @@ function formatLogSize(path5 = defaultUsageLogPath()) {
7767
7768
  // src/cli/commands/chat.tsx
7768
7769
  import { existsSync as existsSync23, statSync as statSync13 } from "fs";
7769
7770
  import { render } from "ink";
7770
- import React31, { useState as useState12 } from "react";
7771
+ import React34, { useState as useState12 } from "react";
7771
7772
 
7772
7773
  // src/cli/ui/App.tsx
7773
7774
  import * as pathMod7 from "path";
7774
- import { Box as Box26, Text as Text24, useStdout as useStdout9 } from "ink";
7775
- import React28, { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo3, useRef as useRef6, useState as useState10 } from "react";
7775
+ import { Box as Box28, Text as Text27, useStdout as useStdout11 } from "ink";
7776
+ import React31, { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo4, useRef as useRef6, useState as useState10 } from "react";
7776
7777
 
7777
7778
  // src/code/pending-edits.ts
7778
7779
  import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync11, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "fs";
@@ -7986,6 +7987,263 @@ function relativeTime(updatedAt, now = Date.now()) {
7986
7987
  return updatedAt.slice(0, 10);
7987
7988
  }
7988
7989
 
7990
+ // src/frame/width.ts
7991
+ import stringWidthLib from "string-width";
7992
+ var segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
7993
+ function graphemes(s) {
7994
+ return Array.from(segmenter.segment(s), (seg) => seg.segment);
7995
+ }
7996
+ function graphemeWidth(g) {
7997
+ if (g.length === 0) return 0;
7998
+ const w = stringWidthLib(g);
7999
+ if (w <= 0) return 0;
8000
+ if (w >= 2) return 2;
8001
+ return 1;
8002
+ }
8003
+
8004
+ // src/frame/frame.ts
8005
+ var SPACE = { char: " ", width: 1 };
8006
+ var TAIL = { char: "", width: 1, tail: true };
8007
+ function empty(width = 0) {
8008
+ return { width, rows: [] };
8009
+ }
8010
+ function text(s, opts) {
8011
+ const { width, fg, bg, bold, dim, italic, underline, inverse, href } = opts;
8012
+ if (width <= 0) return empty(0);
8013
+ const styleOf = (g, w) => {
8014
+ const base = { char: g, width: w };
8015
+ if (fg !== void 0) base.fg = fg;
8016
+ if (bg !== void 0) base.bg = bg;
8017
+ if (bold) base.bold = true;
8018
+ if (dim) base.dim = true;
8019
+ if (italic) base.italic = true;
8020
+ if (underline) base.underline = true;
8021
+ if (inverse) base.inverse = true;
8022
+ if (href !== void 0) base.href = href;
8023
+ return base;
8024
+ };
8025
+ const rows = [];
8026
+ const lines = s.split("\n");
8027
+ for (const line of lines) {
8028
+ if (line.length === 0) {
8029
+ rows.push(padRowRight([], width));
8030
+ continue;
8031
+ }
8032
+ let buf = [];
8033
+ let bufWidth = 0;
8034
+ for (const g of graphemes(line)) {
8035
+ const w = graphemeWidth(g);
8036
+ if (w === 0) continue;
8037
+ if (bufWidth + w > width) {
8038
+ rows.push(padRowRight(buf, width - bufWidth));
8039
+ buf = [];
8040
+ bufWidth = 0;
8041
+ }
8042
+ buf.push(styleOf(g, w));
8043
+ if (w === 2) buf.push(TAIL);
8044
+ bufWidth += w;
8045
+ }
8046
+ rows.push(padRowRight(buf, width - bufWidth));
8047
+ }
8048
+ return { width, rows };
8049
+ }
8050
+ function padRowRight(cells, extraSpaces) {
8051
+ if (extraSpaces <= 0) return cells.slice();
8052
+ const out = cells.slice();
8053
+ for (let i = 0; i < extraSpaces; i++) out.push(SPACE);
8054
+ return out;
8055
+ }
8056
+ function spacerRow(width) {
8057
+ if (width <= 0) return [];
8058
+ return Array.from({ length: width }, () => SPACE);
8059
+ }
8060
+ function vstack(...frames) {
8061
+ if (frames.length === 0) return empty(0);
8062
+ const w = Math.max(...frames.map((f) => f.width));
8063
+ const rows = [];
8064
+ for (const f of frames) {
8065
+ if (f.width === w) {
8066
+ rows.push(...f.rows);
8067
+ } else {
8068
+ const extra = w - f.width;
8069
+ for (const r of f.rows) rows.push(padRowRight(r, extra));
8070
+ }
8071
+ }
8072
+ return { width: w, rows };
8073
+ }
8074
+ function hstack(...frames) {
8075
+ if (frames.length === 0) return empty(0);
8076
+ const h = Math.max(...frames.map((f) => f.rows.length));
8077
+ const w = frames.reduce((a, f) => a + f.width, 0);
8078
+ const rows = [];
8079
+ for (let i = 0; i < h; i++) {
8080
+ const cells = [];
8081
+ for (const f of frames) {
8082
+ const r = f.rows[i] ?? spacerRow(f.width);
8083
+ cells.push(...r);
8084
+ }
8085
+ rows.push(cells);
8086
+ }
8087
+ return { width: w, rows };
8088
+ }
8089
+ function pad(f, top, right, bottom2, left) {
8090
+ const newWidth = f.width + Math.max(0, left) + Math.max(0, right);
8091
+ const tPad = Math.max(0, top);
8092
+ const bPad = Math.max(0, bottom2);
8093
+ const blank2 = spacerRow(newWidth);
8094
+ const rows = [];
8095
+ for (let i = 0; i < tPad; i++) rows.push(blank2);
8096
+ if (left <= 0 && right <= 0) {
8097
+ rows.push(...f.rows);
8098
+ } else {
8099
+ const lPad = spacerRow(Math.max(0, left));
8100
+ const rPad = spacerRow(Math.max(0, right));
8101
+ for (const r of f.rows) rows.push([...lPad, ...r, ...rPad]);
8102
+ }
8103
+ for (let i = 0; i < bPad; i++) rows.push(blank2);
8104
+ return { width: newWidth, rows };
8105
+ }
8106
+ function borderLeft(f, color2, char = "\u2502") {
8107
+ const bar = { char, width: 1, fg: color2 };
8108
+ const newWidth = f.width + 1;
8109
+ const rows = [];
8110
+ for (const r of f.rows) rows.push([bar, ...r]);
8111
+ return { width: newWidth, rows };
8112
+ }
8113
+
8114
+ // src/frame/ansi.ts
8115
+ var ESC = "\x1B";
8116
+ var RESET = `${ESC}[0m`;
8117
+ function sameStyle(a, b) {
8118
+ return a.fg === b.fg && a.bg === b.bg && !!a.bold === !!b.bold && !!a.dim === !!b.dim && !!a.italic === !!b.italic && !!a.underline === !!b.underline && !!a.inverse === !!b.inverse && a.href === b.href;
8119
+ }
8120
+ function fgEscape(color2) {
8121
+ if (!color2) return null;
8122
+ const rgb = parseColor(color2);
8123
+ if (rgb) return `38;2;${rgb[0]};${rgb[1]};${rgb[2]}`;
8124
+ const named = NAMED_FG[color2.toLowerCase()];
8125
+ if (named !== void 0) return String(named);
8126
+ return null;
8127
+ }
8128
+ function bgEscape(color2) {
8129
+ if (!color2) return null;
8130
+ const rgb = parseColor(color2);
8131
+ if (rgb) return `48;2;${rgb[0]};${rgb[1]};${rgb[2]}`;
8132
+ const named = NAMED_BG[color2.toLowerCase()];
8133
+ if (named !== void 0) return String(named);
8134
+ return null;
8135
+ }
8136
+ function parseColor(s) {
8137
+ if (!s.startsWith("#")) return null;
8138
+ const hex = s.slice(1);
8139
+ if (hex.length !== 6) return null;
8140
+ const r = Number.parseInt(hex.slice(0, 2), 16);
8141
+ const g = Number.parseInt(hex.slice(2, 4), 16);
8142
+ const b = Number.parseInt(hex.slice(4, 6), 16);
8143
+ if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
8144
+ return [r, g, b];
8145
+ }
8146
+ var NAMED_FG = {
8147
+ black: 30,
8148
+ red: 31,
8149
+ green: 32,
8150
+ yellow: 33,
8151
+ blue: 34,
8152
+ magenta: 35,
8153
+ cyan: 36,
8154
+ white: 37,
8155
+ gray: 90,
8156
+ grey: 90,
8157
+ brightred: 91,
8158
+ brightgreen: 92,
8159
+ brightyellow: 93,
8160
+ brightblue: 94,
8161
+ brightmagenta: 95,
8162
+ brightcyan: 96,
8163
+ brightwhite: 97
8164
+ };
8165
+ var NAMED_BG = {
8166
+ black: 40,
8167
+ red: 41,
8168
+ green: 42,
8169
+ yellow: 43,
8170
+ blue: 44,
8171
+ magenta: 45,
8172
+ cyan: 46,
8173
+ white: 47,
8174
+ gray: 100,
8175
+ grey: 100
8176
+ };
8177
+ function styleToAnsi(s) {
8178
+ const codes = [];
8179
+ if (s.bold) codes.push("1");
8180
+ if (s.dim) codes.push("2");
8181
+ if (s.italic) codes.push("3");
8182
+ if (s.underline) codes.push("4");
8183
+ if (s.inverse) codes.push("7");
8184
+ const fg = fgEscape(s.fg);
8185
+ if (fg) codes.push(fg);
8186
+ const bg = bgEscape(s.bg);
8187
+ if (bg) codes.push(bg);
8188
+ if (codes.length === 0) return "";
8189
+ return `${ESC}[${codes.join(";")}m`;
8190
+ }
8191
+ var EMPTY_STYLE = {};
8192
+ function frameToAnsi(f, opts = {}) {
8193
+ const out = [];
8194
+ for (let i = 0; i < f.rows.length; i++) {
8195
+ out.push(rowToAnsi(f.rows[i], opts));
8196
+ }
8197
+ return out.join("\n");
8198
+ }
8199
+ function rowToAnsi(row2, opts) {
8200
+ if (opts.plain) {
8201
+ let s = "";
8202
+ for (const c of row2) {
8203
+ if (c.tail) continue;
8204
+ s += c.char;
8205
+ }
8206
+ return s;
8207
+ }
8208
+ let result = "";
8209
+ let curStyle = EMPTY_STYLE;
8210
+ let inHref = false;
8211
+ let curHref;
8212
+ for (const c of row2) {
8213
+ if (c.tail) continue;
8214
+ const cellStyle = {
8215
+ fg: c.fg,
8216
+ bg: c.bg,
8217
+ bold: c.bold,
8218
+ dim: c.dim,
8219
+ italic: c.italic,
8220
+ underline: c.underline,
8221
+ inverse: c.inverse,
8222
+ href: c.href
8223
+ };
8224
+ if (cellStyle.href !== curHref) {
8225
+ if (inHref) {
8226
+ result += `${ESC}]8;;${ESC}\\`;
8227
+ inHref = false;
8228
+ }
8229
+ if (cellStyle.href !== void 0) {
8230
+ result += `${ESC}]8;;${cellStyle.href}${ESC}\\`;
8231
+ inHref = true;
8232
+ }
8233
+ curHref = cellStyle.href;
8234
+ }
8235
+ if (!sameStyle(curStyle, cellStyle)) {
8236
+ result += RESET;
8237
+ result += styleToAnsi(cellStyle);
8238
+ curStyle = cellStyle;
8239
+ }
8240
+ result += c.char;
8241
+ }
8242
+ if (inHref) result += `${ESC}]8;;${ESC}\\`;
8243
+ result += RESET;
8244
+ return result;
8245
+ }
8246
+
7989
8247
  // src/server/index.ts
7990
8248
  import { randomBytes } from "crypto";
7991
8249
  import { createServer } from "http";
@@ -11504,28 +11762,79 @@ function ChoiceConfirmInner({ question, options, allowCustom, onChoose }) {
11504
11762
  var ChoiceConfirm = React5.memo(ChoiceConfirmInner);
11505
11763
 
11506
11764
  // src/cli/ui/ChromeBar.tsx
11507
- import { Box as Box5, Text as Text4, useStdout as useStdout2 } from "ink";
11765
+ import { Box as Box5, Text as Text5, useStdout as useStdout3 } from "ink";
11766
+ import React7 from "react";
11767
+ import stringWidth2 from "string-width";
11768
+
11769
+ // src/cli/ui/primitives.tsx
11770
+ import { Text as Text4, useStdout as useStdout2 } from "ink";
11508
11771
  import React6 from "react";
11509
- var NARROW_BREAKPOINT = 120;
11772
+ function ChromeRule() {
11773
+ const { stdout: stdout4 } = useStdout2();
11774
+ const cols = stdout4?.columns ?? 80;
11775
+ const w = Math.max(20, cols - 2);
11776
+ return /* @__PURE__ */ React6.createElement(Text4, { dimColor: true }, "\u2500".repeat(w));
11777
+ }
11778
+ function formatTokens(n) {
11779
+ if (n < 1024) return String(n);
11780
+ const k = n / 1024;
11781
+ return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;
11782
+ }
11783
+ function Bar({
11784
+ ratio,
11785
+ color: color2,
11786
+ cells = 14,
11787
+ dim
11788
+ }) {
11789
+ const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
11790
+ return /* @__PURE__ */ React6.createElement(Text4, null, /* @__PURE__ */ React6.createElement(Text4, { color: color2, dimColor: dim }, "\u25B0".repeat(filled)), /* @__PURE__ */ React6.createElement(Text4, { dimColor: true }, "\u25B1".repeat(cells - filled)));
11791
+ }
11792
+
11793
+ // src/cli/ui/ChromeBar.tsx
11510
11794
  var COLD_START_TURNS = 3;
11511
11795
  var CACHE_BAR_CELLS = 10;
11512
11796
  function ChromeBar(props) {
11513
- const { stdout: stdout4 } = useStdout2();
11514
- const cols = stdout4?.columns ?? 80;
11515
- const narrow = cols < NARROW_BREAKPOINT;
11797
+ const { stdout: stdout4 } = useStdout3();
11798
+ const cols = (stdout4?.columns ?? 80) - 2;
11516
11799
  const cold = props.summary.turns <= COLD_START_TURNS;
11517
11800
  const projectName = props.rootDir ? basename(props.rootDir) : null;
11518
11801
  const mode2 = pickModePill(props.planMode, props.preset);
11519
11802
  const proPill = props.escalated ? { label: "\u21E7 pro", color: COLOR.err } : props.proArmed ? { label: "\u21E7 pro", color: COLOR.warn } : null;
11520
- const showCache = props.summary.turns > COLD_START_TURNS && !narrow;
11521
- const showBalance = !!props.balance && !narrow;
11522
- return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React6.createElement(Box5, null, /* @__PURE__ */ React6.createElement(Text4, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React6.createElement(Text4, null, projectName), !narrow && props.sessionName ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.info }, props.sessionName)) : null) : null, /* @__PURE__ */ React6.createElement(Box5, { flexGrow: 1 }), props.scrollRatio !== void 0 && props.scrollRatio > 0 ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.accent, bold: true }, `[\u2191 ${Math.round(props.scrollRatio * 100)}%]`), /* @__PURE__ */ React6.createElement(Text4, null, " ")) : null, props.updateAvailable ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.warn, bold: true }, `\u2191 ${props.updateAvailable}`), /* @__PURE__ */ React6.createElement(Text4, null, " ")) : null, mode2 ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: mode2.color, bold: true }, `[${mode2.label}]`), /* @__PURE__ */ React6.createElement(Text4, null, " ")) : null, proPill ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React6.createElement(Text4, null, " ")) : null, /* @__PURE__ */ React6.createElement(CostPill, { summary: props.summary, cold, budgetUsd: props.budgetUsd }), showBalance ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, null, " "), /* @__PURE__ */ React6.createElement(BalancePill, { balance: props.balance })) : null, showCache ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, null, " "), /* @__PURE__ */ React6.createElement(CachePill, { ratio: props.summary.cacheHitRatio })) : null), /* @__PURE__ */ React6.createElement(ChromeRule, null));
11523
- }
11524
- function ChromeRule() {
11525
- const { stdout: stdout4 } = useStdout2();
11526
- const cols = stdout4?.columns ?? 80;
11527
- const w = Math.max(20, cols - 2);
11528
- return /* @__PURE__ */ React6.createElement(Text4, { dimColor: true }, "\u2500".repeat(w));
11803
+ const SEP = 3;
11804
+ const GAP = 1;
11805
+ const scrollLabel = props.scrollRatio !== void 0 && props.scrollRatio > 0 ? `[\u2191 ${Math.round(props.scrollRatio * 100)}%]` : "";
11806
+ const updateLabel = props.updateAvailable ? `\u2191 ${props.updateAvailable}` : "";
11807
+ const balanceLabel = props.balance ? formatBalanceLabel(props.balance) : "";
11808
+ const cachePct = Math.round(props.summary.cacheHitRatio * 100);
11809
+ const cacheLabel = `cache ${"\u2588".repeat(CACHE_BAR_CELLS)} 100%`;
11810
+ const costLabel = `$${props.summary.totalCostUsd.toFixed(4)}${props.budgetUsd && props.budgetUsd > 0 ? ` / $${props.budgetUsd.toFixed(2)}` : ""}`;
11811
+ const brandW = stringWidth2("\u25C8 reasonix");
11812
+ const projectW = projectName ? SEP + stringWidth2(projectName) : 0;
11813
+ const fixedLeft = brandW + projectW;
11814
+ const scrollW = scrollLabel ? stringWidth2(scrollLabel) + GAP : 0;
11815
+ const modeW = mode2 ? stringWidth2(`[${mode2.label}]`) + GAP : 0;
11816
+ const proW = proPill ? stringWidth2(`[${proPill.label}]`) + GAP : 0;
11817
+ const costW = stringWidth2(costLabel);
11818
+ const fixedRight = scrollW + modeW + proW + costW;
11819
+ let budget2 = cols - fixedLeft - fixedRight;
11820
+ const balanceOptW = balanceLabel ? GAP + stringWidth2(balanceLabel) : 0;
11821
+ const cacheOptW = GAP + stringWidth2(cacheLabel);
11822
+ const sessionOptW = props.sessionName ? SEP + stringWidth2(props.sessionName) : 0;
11823
+ const updateOptW = updateLabel ? stringWidth2(updateLabel) + GAP : 0;
11824
+ const showBalance = balanceOptW > 0 && budget2 >= balanceOptW;
11825
+ if (showBalance) budget2 -= balanceOptW;
11826
+ const showCache = budget2 >= cacheOptW;
11827
+ if (showCache) budget2 -= cacheOptW;
11828
+ const showSession = sessionOptW > 0 && budget2 >= sessionOptW;
11829
+ if (showSession) budget2 -= sessionOptW;
11830
+ const showUpdate = updateOptW > 0 && budget2 >= updateOptW;
11831
+ if (showUpdate) budget2 -= updateOptW;
11832
+ return /* @__PURE__ */ React7.createElement(Box5, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React7.createElement(Box5, null, /* @__PURE__ */ React7.createElement(Text5, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React7.createElement(Text5, null, projectName), showSession && props.sessionName ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info }, props.sessionName)) : null) : null, /* @__PURE__ */ React7.createElement(Box5, { flexGrow: 1 }), scrollLabel ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.accent, bold: true }, scrollLabel), /* @__PURE__ */ React7.createElement(Text5, null, " ")) : null, showUpdate ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.warn, bold: true }, updateLabel), /* @__PURE__ */ React7.createElement(Text5, null, " ")) : null, mode2 ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: mode2.color, bold: true }, `[${mode2.label}]`), /* @__PURE__ */ React7.createElement(Text5, null, " ")) : null, proPill ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React7.createElement(Text5, null, " ")) : null, /* @__PURE__ */ React7.createElement(CostPill, { summary: props.summary, cold, budgetUsd: props.budgetUsd }), showBalance && props.balance ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, null, " "), /* @__PURE__ */ React7.createElement(BalancePill, { balance: props.balance })) : null, showCache ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, null, " "), /* @__PURE__ */ React7.createElement(CachePill, { ratio: props.summary.cacheHitRatio, cold, pct: cachePct })) : null), /* @__PURE__ */ React7.createElement(ChromeRule, null));
11833
+ }
11834
+ function formatBalanceLabel(balance) {
11835
+ const sym = balance.currency === "USD" ? "$" : balance.currency === "CNY" ? "\xA5" : "";
11836
+ const suf = sym ? "" : ` ${balance.currency}`;
11837
+ return `w ${sym}${balance.total.toFixed(2)}${suf}`;
11529
11838
  }
11530
11839
  function CostPill({
11531
11840
  summary,
@@ -11534,22 +11843,24 @@ function CostPill({
11534
11843
  }) {
11535
11844
  const cost = summary.totalCostUsd;
11536
11845
  const color2 = cold ? COLOR.info : sessionCostColor(cost);
11537
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: color2, bold: !cold, dimColor: cold }, `$${cost.toFixed(4)}`), budgetUsd && budgetUsd > 0 ? /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.info, dimColor: true }, ` / $${budgetUsd.toFixed(2)}`) : null);
11846
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: color2, bold: !cold, dimColor: cold }, `$${cost.toFixed(4)}`), budgetUsd && budgetUsd > 0 ? /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info, dimColor: true }, ` / $${budgetUsd.toFixed(2)}`) : null);
11538
11847
  }
11539
11848
  function BalancePill({
11540
11849
  balance
11541
11850
  }) {
11542
- const { currency, total } = balance;
11851
+ const { total } = balance;
11543
11852
  const color2 = total < 1 ? COLOR.err : total < 5 ? COLOR.warn : COLOR.ok;
11544
- const sym = currency === "USD" ? "$" : currency === "CNY" ? "\xA5" : "";
11545
- const suf = sym ? "" : ` ${currency}`;
11546
- return /* @__PURE__ */ React6.createElement(Text4, { color: color2 }, `w ${sym}${total.toFixed(2)}${suf}`);
11853
+ return /* @__PURE__ */ React7.createElement(Text5, { color: color2 }, formatBalanceLabel(balance));
11547
11854
  }
11548
- function CachePill({ ratio }) {
11855
+ function CachePill({
11856
+ ratio,
11857
+ cold,
11858
+ pct: pct2
11859
+ }) {
11549
11860
  const color2 = ratio >= 0.7 ? COLOR.ok : ratio >= 0.4 ? COLOR.warn : COLOR.err;
11550
11861
  const filled = Math.max(0, Math.min(CACHE_BAR_CELLS, Math.round(ratio * CACHE_BAR_CELLS)));
11551
11862
  const empty2 = CACHE_BAR_CELLS - filled;
11552
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text4, { color: COLOR.info, dimColor: true }, "cache "), /* @__PURE__ */ React6.createElement(Text4, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React6.createElement(Text4, { dimColor: true }, "\u2591".repeat(empty2)), /* @__PURE__ */ React6.createElement(Text4, { color: color2, bold: true }, ` ${Math.round(ratio * 100)}%`));
11863
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info, dimColor: true }, "cache "), /* @__PURE__ */ React7.createElement(Text5, { color: cold ? COLOR.info : color2, dimColor: cold }, "\u2588".repeat(filled)), /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, "\u2591".repeat(empty2)), /* @__PURE__ */ React7.createElement(Text5, { color: cold ? void 0 : color2, bold: !cold, dimColor: cold }, cold && pct2 === 0 ? " \u2014" : ` ${pct2}%`));
11553
11864
  }
11554
11865
  function pickModePill(planMode, preset2) {
11555
11866
  if (planMode) return { label: "PLAN", color: COLOR.err };
@@ -11558,21 +11869,133 @@ function pickModePill(planMode, preset2) {
11558
11869
  if (preset2 === "flash") return { label: "flash", color: COLOR.info };
11559
11870
  return { label: "auto", color: COLOR.primary };
11560
11871
  }
11561
- function sessionCostColor(cost) {
11562
- if (cost <= 0) return void 0;
11563
- if (cost >= 5) return COLOR.err;
11564
- if (cost >= 0.5) return COLOR.warn;
11565
- return COLOR.ok;
11872
+ function sessionCostColor(cost) {
11873
+ if (cost <= 0) return void 0;
11874
+ if (cost >= 5) return COLOR.err;
11875
+ if (cost >= 0.5) return COLOR.warn;
11876
+ return COLOR.ok;
11877
+ }
11878
+ function basename(path5) {
11879
+ const norm = path5.replace(/\\/g, "/");
11880
+ const i = norm.lastIndexOf("/");
11881
+ return i === -1 ? norm : norm.slice(i + 1);
11882
+ }
11883
+
11884
+ // src/cli/ui/CtxFooter.tsx
11885
+ import { Box as Box7, Text as Text7, useStdout as useStdout4 } from "ink";
11886
+ import React9, { useMemo } from "react";
11887
+ import stringWidth3 from "string-width";
11888
+
11889
+ // src/cli/ui/ctx-breakdown.tsx
11890
+ import { Box as Box6, Text as Text6 } from "ink";
11891
+ import React8 from "react";
11892
+ function computeCtxBreakdown(loop2) {
11893
+ const systemTokens = countTokens(loop2.prefix.system);
11894
+ const toolsTokens = countTokens(JSON.stringify(loop2.prefix.toolSpecs));
11895
+ const entries = loop2.log.toMessages();
11896
+ let userTokens = 0;
11897
+ let assistantTokens = 0;
11898
+ let toolResultTokens = 0;
11899
+ let toolCallTokens = 0;
11900
+ const toolBreakdown = [];
11901
+ let logTurn = 0;
11902
+ for (const e of entries) {
11903
+ const content = typeof e.content === "string" ? e.content : "";
11904
+ if (e.role === "user") {
11905
+ userTokens += countTokens(content);
11906
+ logTurn += 1;
11907
+ } else if (e.role === "assistant") {
11908
+ assistantTokens += countTokens(content);
11909
+ if (Array.isArray(e.tool_calls) && e.tool_calls.length > 0) {
11910
+ toolCallTokens += countTokens(JSON.stringify(e.tool_calls));
11911
+ }
11912
+ } else if (e.role === "tool") {
11913
+ const n = countTokens(content);
11914
+ toolResultTokens += n;
11915
+ toolBreakdown.push({ name: e.name ?? "?", tokens: n, turn: logTurn });
11916
+ }
11917
+ }
11918
+ const logTokens = userTokens + assistantTokens + toolResultTokens + toolCallTokens;
11919
+ const ctxMax = DEEPSEEK_CONTEXT_TOKENS[loop2.model] ?? DEFAULT_CONTEXT_TOKENS;
11920
+ const topTools = [...toolBreakdown].sort((a, b) => b.tokens - a.tokens).slice(0, 5);
11921
+ return {
11922
+ systemTokens,
11923
+ toolsTokens,
11924
+ logTokens,
11925
+ inputTokens: 0,
11926
+ ctxMax,
11927
+ toolsCount: loop2.prefix.toolSpecs.length,
11928
+ logMessages: entries.length,
11929
+ topTools
11930
+ };
11931
+ }
11932
+ function CtxBreakdownBlock({ data }) {
11933
+ const total = data.systemTokens + data.toolsTokens + data.logTokens + data.inputTokens;
11934
+ const winPct = data.ctxMax > 0 ? Math.round(total / data.ctxMax * 100) : 0;
11935
+ const barWidth = 48;
11936
+ const cellOf = (n) => data.ctxMax > 0 ? Math.round(n / data.ctxMax * barWidth) : 0;
11937
+ const sysCells = cellOf(data.systemTokens);
11938
+ const toolsCells = cellOf(data.toolsTokens);
11939
+ const logCells = cellOf(data.logTokens);
11940
+ const inputCells = cellOf(data.inputTokens);
11941
+ const used = sysCells + toolsCells + logCells + inputCells;
11942
+ const freeCells = Math.max(0, barWidth - used);
11943
+ const sevColor = winPct >= 80 ? COLOR.err : winPct >= 60 ? COLOR.warn : COLOR.ok;
11944
+ return /* @__PURE__ */ React8.createElement(
11945
+ Box6,
11946
+ {
11947
+ flexDirection: "column",
11948
+ marginY: 1,
11949
+ borderStyle: "single",
11950
+ borderTop: false,
11951
+ borderRight: false,
11952
+ borderBottom: false,
11953
+ borderColor: COLOR.brand,
11954
+ paddingLeft: 1
11955
+ },
11956
+ /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.brand, bold: true }, "\u25A3 context"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` ${formatTokens(total)} of ${formatTokens(data.ctxMax)}`), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React8.createElement(Text6, { color: sevColor, bold: true }, `${winPct}%`), winPct >= 80 ? /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.err, bold: true }, " \xB7 /compact") : null),
11957
+ /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.brand }, "\u2588".repeat(sysCells)), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.accent }, "\u2588".repeat(toolsCells)), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.primary }, "\u2588".repeat(logCells)), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.tool }, "\u2588".repeat(inputCells)), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.info, dimColor: true }, "\u2591".repeat(freeCells))),
11958
+ /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.brand }, "\u25A0"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` system ${formatTokens(data.systemTokens)}`), /* @__PURE__ */ React8.createElement(Text6, null, " "), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.accent }, "\u25A0"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` tools ${formatTokens(data.toolsTokens)}`), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` (${data.toolsCount})`), /* @__PURE__ */ React8.createElement(Text6, null, " "), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.primary }, "\u25A0"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` log ${formatTokens(data.logTokens)}`), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` (${data.logMessages} msg)`), /* @__PURE__ */ React8.createElement(Text6, null, " "), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.tool }, "\u25A0"), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` input ${formatTokens(data.inputTokens)}`)),
11959
+ data.topTools.length > 0 ? /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` top tool results by cost (${data.topTools.length}):`), data.topTools.map((t2) => /* @__PURE__ */ React8.createElement(Box6, { key: `${t2.turn}-${t2.name}` }, /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` turn ${String(t2.turn).padStart(3)} `), /* @__PURE__ */ React8.createElement(Text6, { color: COLOR.info }, t2.name.padEnd(22)), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, ` ${formatTokens(t2.tokens).padStart(8)}`)))) : null,
11960
+ /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " /compact shrinks oversized tool results \xB7 /new wipes log"))
11961
+ );
11566
11962
  }
11567
- function basename(path5) {
11568
- const norm = path5.replace(/\\/g, "/");
11569
- const i = norm.lastIndexOf("/");
11570
- return i === -1 ? norm : norm.slice(i + 1);
11963
+
11964
+ // src/cli/ui/CtxFooter.tsx
11965
+ var BAR_CELLS = 14;
11966
+ function CtxFooter({ loop: loop2, summary }) {
11967
+ const data = useMemo(() => computeCtxBreakdown(loop2), [loop2, summary.turns]);
11968
+ const { stdout: stdout4 } = useStdout4();
11969
+ const cols = (stdout4?.columns ?? 80) - 2;
11970
+ const total = data.systemTokens + data.toolsTokens + data.logTokens + data.inputTokens;
11971
+ const ratio = data.ctxMax > 0 ? Math.min(1, total / data.ctxMax) : 0;
11972
+ const pct2 = Math.round(ratio * 100);
11973
+ const severity = pct2 >= 80 ? COLOR.err : pct2 >= 60 ? COLOR.warn : COLOR.ok;
11974
+ const labelStr = " ctx ";
11975
+ const totalStr = `${formatTokens(total)}/${formatTokens(data.ctxMax)}`;
11976
+ const pctStr = ` \xB7 ${pct2}%`;
11977
+ const warnStr = pct2 >= 80 ? " \xB7 /compact" : "";
11978
+ const fixedW = stringWidth3(labelStr) + BAR_CELLS + 1 + // space after bar
11979
+ stringWidth3(totalStr) + stringWidth3(pctStr) + stringWidth3(warnStr);
11980
+ let budget2 = cols - fixedW;
11981
+ const sysSeg = ` \xB7 sys ${formatTokens(data.systemTokens)}`;
11982
+ const toolsSeg = ` \xB7 tools ${formatTokens(data.toolsTokens)}`;
11983
+ const logSeg = ` \xB7 log ${formatTokens(data.logTokens)}`;
11984
+ const inputSeg = data.inputTokens > 0 ? ` \xB7 input ${formatTokens(data.inputTokens)}` : "";
11985
+ const showSys = budget2 >= stringWidth3(sysSeg);
11986
+ if (showSys) budget2 -= stringWidth3(sysSeg);
11987
+ const showTools = budget2 >= stringWidth3(toolsSeg);
11988
+ if (showTools) budget2 -= stringWidth3(toolsSeg);
11989
+ const showLog = budget2 >= stringWidth3(logSeg);
11990
+ if (showLog) budget2 -= stringWidth3(logSeg);
11991
+ const showInput = inputSeg !== "" && budget2 >= stringWidth3(inputSeg);
11992
+ if (showInput) budget2 -= stringWidth3(inputSeg);
11993
+ return /* @__PURE__ */ React9.createElement(Box7, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(ChromeRule, null), /* @__PURE__ */ React9.createElement(Text7, null, /* @__PURE__ */ React9.createElement(Text7, { color: COLOR.info, dimColor: true }, labelStr), /* @__PURE__ */ React9.createElement(Bar, { ratio, color: severity, cells: BAR_CELLS }), /* @__PURE__ */ React9.createElement(Text7, null, " "), /* @__PURE__ */ React9.createElement(Text7, { color: severity, bold: true }, totalStr), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, pctStr), showSys ? /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, sysSeg) : null, showTools ? /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, toolsSeg) : null, showLog ? /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, logSeg) : null, showInput ? /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, inputSeg) : null, warnStr ? /* @__PURE__ */ React9.createElement(Text7, { color: COLOR.err, bold: true }, warnStr) : null));
11571
11994
  }
11572
11995
 
11573
11996
  // src/cli/ui/EditConfirm.tsx
11574
- import { Box as Box7, Text as Text6, useStdout as useStdout4 } from "ink";
11575
- import React8, { useMemo, useState as useState2 } from "react";
11997
+ import { Box as Box9, Text as Text9, useStdout as useStdout6 } from "ink";
11998
+ import React11, { useMemo as useMemo2, useState as useState2 } from "react";
11576
11999
 
11577
12000
  // src/code/diff-preview.ts
11578
12001
  function formatEditBlockDiff(block, opts = {}) {
@@ -11724,14 +12147,14 @@ function capLines(lines, maxLines, indent) {
11724
12147
  }
11725
12148
 
11726
12149
  // src/cli/ui/SplitDiff.tsx
11727
- import { Box as Box6, Text as Text5, useStdout as useStdout3 } from "ink";
11728
- import React7 from "react";
12150
+ import { Box as Box8, Text as Text8, useStdout as useStdout5 } from "ink";
12151
+ import React10 from "react";
11729
12152
  function SplitDiff({ rows, totalCols }) {
11730
- const { stdout: stdout4 } = useStdout3();
12153
+ const { stdout: stdout4 } = useStdout5();
11731
12154
  const cols = totalCols ?? stdout4?.columns ?? 80;
11732
12155
  const innerCols = Math.max(40, cols - 6);
11733
12156
  const halfCols = Math.floor((innerCols - 3) / 2);
11734
- return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column" }, rows.map((row2, i) => /* @__PURE__ */ React7.createElement(Box6, { key: `r-${i}-${row2.left.num ?? "p"}-${row2.right.num ?? "p"}` }, /* @__PURE__ */ React7.createElement(Cell, { side: row2.left, width: halfCols, which: "left" }), /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info, dimColor: true }, " \u2502 "), /* @__PURE__ */ React7.createElement(Cell, { side: row2.right, width: halfCols, which: "right" }))));
12157
+ return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, rows.map((row2, i) => /* @__PURE__ */ React10.createElement(Box8, { key: `r-${i}-${row2.left.num ?? "p"}-${row2.right.num ?? "p"}` }, /* @__PURE__ */ React10.createElement(Cell, { side: row2.left, width: halfCols, which: "left" }), /* @__PURE__ */ React10.createElement(Text8, { color: COLOR.info, dimColor: true }, " \u2502 "), /* @__PURE__ */ React10.createElement(Cell, { side: row2.right, width: halfCols, which: "right" }))));
11735
12158
  }
11736
12159
  function Cell({
11737
12160
  side,
@@ -11751,25 +12174,25 @@ function Cell({
11751
12174
  const truncated = raw.length > inner ? `${raw.slice(0, inner - 1)}\u2026` : raw;
11752
12175
  const padded = truncated.padEnd(inner);
11753
12176
  if (side.kind === "del") {
11754
- return /* @__PURE__ */ React7.createElement(Text5, { color: "#fbc8c8", backgroundColor: "#2a1212" }, `${numStr} ${sign} ${padded}`);
12177
+ return /* @__PURE__ */ React10.createElement(Text8, { color: "#fbc8c8", backgroundColor: "#2a1212" }, `${numStr} ${sign} ${padded}`);
11755
12178
  }
11756
12179
  if (side.kind === "add") {
11757
- return /* @__PURE__ */ React7.createElement(Text5, { color: "#bef0c8", backgroundColor: "#0c2718" }, `${numStr} ${sign} ${padded}`);
12180
+ return /* @__PURE__ */ React10.createElement(Text8, { color: "#bef0c8", backgroundColor: "#0c2718" }, `${numStr} ${sign} ${padded}`);
11758
12181
  }
11759
12182
  if (side.kind === "pad") {
11760
- return /* @__PURE__ */ React7.createElement(Text5, { color: COLOR.info, dimColor: true, italic: !!raw }, `${numStr} ${sign} ${padded}`);
12183
+ return /* @__PURE__ */ React10.createElement(Text8, { color: COLOR.info, dimColor: true, italic: !!raw }, `${numStr} ${sign} ${padded}`);
11761
12184
  }
11762
- return /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, `${numStr} ${sign} ${padded}`);
12185
+ return /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, `${numStr} ${sign} ${padded}`);
11763
12186
  }
11764
12187
 
11765
12188
  // src/cli/ui/EditConfirm.tsx
11766
12189
  var MODAL_OVERHEAD_ROWS = 18;
11767
12190
  var MIN_DIFF_ROWS = 8;
11768
12191
  function EditConfirm({ block, onChoose }) {
11769
- const { stdout: stdout4 } = useStdout4();
12192
+ const { stdout: stdout4 } = useStdout6();
11770
12193
  const rows = stdout4?.rows ?? 40;
11771
12194
  const budget2 = Math.max(MIN_DIFF_ROWS, rows - MODAL_OVERHEAD_ROWS);
11772
- const allRows = useMemo(
12195
+ const allRows = useMemo2(
11773
12196
  () => formatEditBlockSplit(block, { contextLines: 2, maxLines: 1e5 }),
11774
12197
  [block]
11775
12198
  );
@@ -11836,8 +12259,8 @@ function EditConfirm({ block, onChoose }) {
11836
12259
  `viewing ${effectiveScroll + 1}-${effectiveScroll + visibleRows.length}/${totalLines}`
11837
12260
  );
11838
12261
  }
11839
- const footer = /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, "[", /* @__PURE__ */ React8.createElement(Text6, { color: "#67e8f9", bold: true }, "y"), "/Enter] apply \xB7 [", /* @__PURE__ */ React8.createElement(Text6, { color: "#67e8f9", bold: true }, "n"), "] reject \xB7 [", /* @__PURE__ */ React8.createElement(Text6, { color: "#67e8f9", bold: true }, "a"), "] apply rest \xB7 [", /* @__PURE__ */ React8.createElement(Text6, { color: "#67e8f9", bold: true }, "A"), "] flip AUTO \xB7 [", /* @__PURE__ */ React8.createElement(Text6, { color: "#67e8f9", bold: true }, "\u2191\u2193/Space"), "] scroll \xB7 [Esc] abort");
11840
- return /* @__PURE__ */ React8.createElement(
12262
+ const footer = /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, "[", /* @__PURE__ */ React11.createElement(Text9, { color: "#67e8f9", bold: true }, "y"), "/Enter] apply \xB7 [", /* @__PURE__ */ React11.createElement(Text9, { color: "#67e8f9", bold: true }, "n"), "] reject \xB7 [", /* @__PURE__ */ React11.createElement(Text9, { color: "#67e8f9", bold: true }, "a"), "] apply rest \xB7 [", /* @__PURE__ */ React11.createElement(Text9, { color: "#67e8f9", bold: true }, "A"), "] flip AUTO \xB7 [", /* @__PURE__ */ React11.createElement(Text9, { color: "#67e8f9", bold: true }, "\u2191\u2193/Space"), "] scroll \xB7 [Esc] abort");
12263
+ return /* @__PURE__ */ React11.createElement(
11841
12264
  ModalCard,
11842
12265
  {
11843
12266
  accent: isNew ? "#86efac" : "#fcd34d",
@@ -11846,17 +12269,17 @@ function EditConfirm({ block, onChoose }) {
11846
12269
  subtitle: subtitleParts.join(" \xB7 "),
11847
12270
  footer
11848
12271
  },
11849
- hiddenAbove > 0 ? /* @__PURE__ */ React8.createElement(
11850
- Text6,
12272
+ hiddenAbove > 0 ? /* @__PURE__ */ React11.createElement(
12273
+ Text9,
11851
12274
  {
11852
12275
  dimColor: true
11853
12276
  },
11854
12277
  ` \u2191 ${hiddenAbove} line${hiddenAbove === 1 ? "" : "s"} above (\u2191/k or PgUp)`
11855
12278
  ) : null,
11856
- /* @__PURE__ */ React8.createElement(SplitDiff, { rows: visibleRows }),
11857
- /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text6, { color: "#fbc8c8", backgroundColor: "#2a1212" }, " - old "), /* @__PURE__ */ React8.createElement(Text6, null, " "), /* @__PURE__ */ React8.createElement(Text6, { color: "#bef0c8", backgroundColor: "#0c2718" }, " + new "), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " side-by-side \xB7 removed lines on the left, added on the right \xB7 paired by offset")),
11858
- hiddenBelow > 0 ? /* @__PURE__ */ React8.createElement(
11859
- Text6,
12279
+ /* @__PURE__ */ React11.createElement(SplitDiff, { rows: visibleRows }),
12280
+ /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text9, { color: "#fbc8c8", backgroundColor: "#2a1212" }, " - old "), /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(Text9, { color: "#bef0c8", backgroundColor: "#0c2718" }, " + new "), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, " side-by-side \xB7 removed lines on the left, added on the right \xB7 paired by offset")),
12281
+ hiddenBelow > 0 ? /* @__PURE__ */ React11.createElement(
12282
+ Text9,
11860
12283
  {
11861
12284
  dimColor: true
11862
12285
  },
@@ -11866,12 +12289,12 @@ function EditConfirm({ block, onChoose }) {
11866
12289
  }
11867
12290
 
11868
12291
  // src/cli/ui/EventLog.tsx
11869
- import { Box as Box12, Text as Text11, useStdout as useStdout5 } from "ink";
11870
- import React14 from "react";
12292
+ import { Box as Box14, Text as Text14, useStdout as useStdout7 } from "ink";
12293
+ import React17 from "react";
11871
12294
 
11872
12295
  // src/cli/ui/PlanStateBlock.tsx
11873
- import { Box as Box8, Text as Text7 } from "ink";
11874
- import React9 from "react";
12296
+ import { Box as Box10, Text as Text10 } from "ink";
12297
+ import React12 from "react";
11875
12298
  function PlanStateBlock({ planState }) {
11876
12299
  const fields = [];
11877
12300
  if (planState.subgoals.length)
@@ -11883,16 +12306,16 @@ function PlanStateBlock({ planState }) {
11883
12306
  if (planState.rejectedPaths.length)
11884
12307
  fields.push(["rejected", planState.rejectedPaths, COLOR.info, true]);
11885
12308
  if (fields.length === 0) return null;
11886
- return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color2, dim]) => /* @__PURE__ */ React9.createElement(Box8, { key: label }, /* @__PURE__ */ React9.createElement(Text7, { color: color2, bold: true, dimColor: dim }, label), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React9.createElement(Text7, { dimColor: dim, color: dim ? void 0 : COLOR.info }, items.join(" \xB7 ")))));
12309
+ return /* @__PURE__ */ React12.createElement(Box10, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color2, dim]) => /* @__PURE__ */ React12.createElement(Box10, { key: label }, /* @__PURE__ */ React12.createElement(Text10, { color: color2, bold: true, dimColor: dim }, label), /* @__PURE__ */ React12.createElement(Text10, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React12.createElement(Text10, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React12.createElement(Text10, { dimColor: dim, color: dim ? void 0 : COLOR.info }, items.join(" \xB7 ")))));
11887
12310
  }
11888
12311
 
11889
12312
  // src/cli/ui/PlanStepList.tsx
11890
- import { Box as Box10, Text as Text9 } from "ink";
11891
- import React11 from "react";
12313
+ import { Box as Box12, Text as Text12 } from "ink";
12314
+ import React14 from "react";
11892
12315
 
11893
12316
  // src/cli/ui/char-bar.tsx
11894
- import { Box as Box9, Text as Text8 } from "ink";
11895
- import React10 from "react";
12317
+ import { Box as Box11, Text as Text11 } from "ink";
12318
+ import React13 from "react";
11896
12319
  function CharBar({
11897
12320
  pct: pct2,
11898
12321
  width = 24,
@@ -11904,7 +12327,7 @@ function CharBar({
11904
12327
  const total = Math.max(4, width);
11905
12328
  const clamped = Math.max(0, Math.min(100, Number.isFinite(pct2) ? pct2 : 0));
11906
12329
  const filled = Math.round(total * clamped / 100);
11907
- return /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text8, { color: color2 }, GLYPH.block.repeat(filled)), /* @__PURE__ */ React10.createElement(Text8, { color: emptyColor ?? COLOR.info, dimColor: true }, GLYPH.shade1.repeat(total - filled)), showLabel ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${label ?? `${Math.round(clamped)}%`}`) : null);
12330
+ return /* @__PURE__ */ React13.createElement(Box11, null, /* @__PURE__ */ React13.createElement(Text11, { color: color2 }, GLYPH.block.repeat(filled)), /* @__PURE__ */ React13.createElement(Text11, { color: emptyColor ?? COLOR.info, dimColor: true }, GLYPH.shade1.repeat(total - filled)), showLabel ? /* @__PURE__ */ React13.createElement(Text11, { dimColor: true }, ` ${label ?? `${Math.round(clamped)}%`}`) : null);
11908
12331
  }
11909
12332
 
11910
12333
  // src/cli/ui/PlanStepList.tsx
@@ -11934,31 +12357,31 @@ function PlanStepListInner({ steps, statuses, focusStepId }) {
11934
12357
  const doneCount = statusList.filter((s) => s === "done").length;
11935
12358
  const pct2 = Math.round(doneCount / total * 100);
11936
12359
  const showProgress = doneCount > 0;
11937
- return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, showProgress ? `${doneCount}/${total} done (${pct2}%) \xB7 ${total} step${total === 1 ? "" : "s"}` : `${total} step${total === 1 ? "" : "s"}`)), /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, steps.map((step, i) => {
12360
+ return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text12, { dimColor: true }, showProgress ? `${doneCount}/${total} done (${pct2}%) \xB7 ${total} step${total === 1 ? "" : "s"}` : `${total} step${total === 1 ? "" : "s"}`)), /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column" }, steps.map((step, i) => {
11938
12361
  const status2 = statusList[i];
11939
12362
  const isLast = i === total - 1;
11940
12363
  const isCur = focusStepId === step.id;
11941
12364
  const sg = statusGlyph(status2, isCur);
11942
12365
  const risk = riskLabel(step.risk);
11943
12366
  const titleDim = status2 === "done" || status2 === "skipped";
11944
- return /* @__PURE__ */ React11.createElement(Box10, { key: step.id }, /* @__PURE__ */ React11.createElement(Text9, { color: COLOR.info, dimColor: true }, isLast ? GLYPH.branchEnd : GLYPH.branch), /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(Text9, { color: sg.color, bold: status2 === "running" || isCur }, sg.glyph), /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(
11945
- Text9,
12367
+ return /* @__PURE__ */ React14.createElement(Box12, { key: step.id }, /* @__PURE__ */ React14.createElement(Text12, { color: COLOR.info, dimColor: true }, isLast ? GLYPH.branchEnd : GLYPH.branch), /* @__PURE__ */ React14.createElement(Text12, null, " "), /* @__PURE__ */ React14.createElement(Text12, { color: sg.color, bold: status2 === "running" || isCur }, sg.glyph), /* @__PURE__ */ React14.createElement(Text12, null, " "), /* @__PURE__ */ React14.createElement(
12368
+ Text12,
11946
12369
  {
11947
12370
  dimColor: titleDim,
11948
12371
  bold: isCur || status2 === "running",
11949
12372
  strikethrough: status2 === "done" || status2 === "skipped"
11950
12373
  },
11951
12374
  `${step.id} \xB7 ${step.title}`
11952
- ), risk ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(Text9, { color: risk.color }, risk.text)) : null);
11953
- })), showProgress ? /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(CharBar, { pct: pct2, width: 24 })) : null);
12375
+ ), risk ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text12, null, " "), /* @__PURE__ */ React14.createElement(Text12, { color: risk.color }, risk.text)) : null);
12376
+ })), showProgress ? /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text12, null, " "), /* @__PURE__ */ React14.createElement(CharBar, { pct: pct2, width: 24 })) : null);
11954
12377
  }
11955
- var PlanStepList = React11.memo(PlanStepListInner);
12378
+ var PlanStepList = React14.memo(PlanStepListInner);
11956
12379
 
11957
12380
  // src/cli/ui/markdown.tsx
11958
12381
  import { readFileSync as readFileSync19, statSync as statSync11 } from "fs";
11959
12382
  import { isAbsolute as isAbsolute5, join as join16 } from "path";
11960
- import { Box as Box11, Text as Text10 } from "ink";
11961
- import React12 from "react";
12383
+ import { Box as Box13, Text as Text13 } from "ink";
12384
+ import React15 from "react";
11962
12385
  var SUPERSCRIPT = {
11963
12386
  "0": "\u2070",
11964
12387
  "1": "\xB9",
@@ -12281,67 +12704,67 @@ function InlineMd({
12281
12704
  for (const m of text2.matchAll(INLINE_RE)) {
12282
12705
  const start = m.index ?? 0;
12283
12706
  if (start > last) {
12284
- parts.push(/* @__PURE__ */ React12.createElement(Text10, { key: `t${idx++}` }, text2.slice(last, start)));
12707
+ parts.push(/* @__PURE__ */ React15.createElement(Text13, { key: `t${idx++}` }, text2.slice(last, start)));
12285
12708
  }
12286
12709
  if (m[2] !== void 0 && m[3] !== void 0) {
12287
12710
  const linkText = m[2];
12288
12711
  const url = m[3];
12289
12712
  if (isExternalUrl(url)) {
12290
12713
  parts.push(
12291
- /* @__PURE__ */ React12.createElement(Text10, { key: `l${idx++}`, color: "blue", underline: true }, linkText)
12714
+ /* @__PURE__ */ React15.createElement(Text13, { key: `l${idx++}`, color: "blue", underline: true }, linkText)
12292
12715
  );
12293
12716
  } else {
12294
12717
  const status2 = citations?.get(url);
12295
12718
  if (status2 && !status2.ok) {
12296
12719
  parts.push(
12297
- /* @__PURE__ */ React12.createElement(Text10, { key: `l${idx++}`, color: "red", strikethrough: true }, `${linkText} \u2717`)
12720
+ /* @__PURE__ */ React15.createElement(Text13, { key: `l${idx++}`, color: "red", strikethrough: true }, `${linkText} \u2717`)
12298
12721
  );
12299
12722
  } else {
12300
12723
  parts.push(
12301
- /* @__PURE__ */ React12.createElement(Text10, { key: `l${idx++}`, color: "cyan", underline: true }, linkText)
12724
+ /* @__PURE__ */ React15.createElement(Text13, { key: `l${idx++}`, color: "cyan", underline: true }, linkText)
12302
12725
  );
12303
12726
  }
12304
12727
  }
12305
12728
  } else if (m[4] !== void 0) {
12306
12729
  parts.push(
12307
- /* @__PURE__ */ React12.createElement(Text10, { key: `bi${idx++}`, bold: true, italic: true }, m[4])
12730
+ /* @__PURE__ */ React15.createElement(Text13, { key: `bi${idx++}`, bold: true, italic: true }, m[4])
12308
12731
  );
12309
12732
  } else if (m[5] !== void 0) {
12310
12733
  parts.push(
12311
- /* @__PURE__ */ React12.createElement(Text10, { key: `b${idx++}`, bold: true }, m[5])
12734
+ /* @__PURE__ */ React15.createElement(Text13, { key: `b${idx++}`, bold: true }, m[5])
12312
12735
  );
12313
12736
  } else if (m[6] !== void 0) {
12314
12737
  const stripped = m[6].replace(/^(\w+)\s+/, "");
12315
12738
  parts.push(
12316
- /* @__PURE__ */ React12.createElement(Text10, { key: `c${idx++}`, color: "yellow" }, stripped)
12739
+ /* @__PURE__ */ React15.createElement(Text13, { key: `c${idx++}`, color: "yellow" }, stripped)
12317
12740
  );
12318
12741
  } else if (m[7] !== void 0) {
12319
12742
  parts.push(
12320
- /* @__PURE__ */ React12.createElement(Text10, { key: `c${idx++}`, color: "yellow" }, m[7])
12743
+ /* @__PURE__ */ React15.createElement(Text13, { key: `c${idx++}`, color: "yellow" }, m[7])
12321
12744
  );
12322
12745
  } else if (m[8] !== void 0) {
12323
12746
  parts.push(
12324
- /* @__PURE__ */ React12.createElement(Text10, { key: `s${idx++}`, strikethrough: true, dimColor: true }, m[8])
12747
+ /* @__PURE__ */ React15.createElement(Text13, { key: `s${idx++}`, strikethrough: true, dimColor: true }, m[8])
12325
12748
  );
12326
12749
  } else if (m[9] !== void 0) {
12327
12750
  parts.push(
12328
- /* @__PURE__ */ React12.createElement(Text10, { key: `i${idx++}`, italic: true }, m[9])
12751
+ /* @__PURE__ */ React15.createElement(Text13, { key: `i${idx++}`, italic: true }, m[9])
12329
12752
  );
12330
12753
  } else if (m[10] !== void 0) {
12331
- parts.push(/* @__PURE__ */ React12.createElement(Text10, { key: `esc${idx++}` }, m[10]));
12754
+ parts.push(/* @__PURE__ */ React15.createElement(Text13, { key: `esc${idx++}` }, m[10]));
12332
12755
  }
12333
12756
  last = start + m[0].length;
12334
12757
  }
12335
12758
  if (last < text2.length) {
12336
- parts.push(/* @__PURE__ */ React12.createElement(Text10, { key: `t${idx++}` }, text2.slice(last)));
12759
+ parts.push(/* @__PURE__ */ React15.createElement(Text13, { key: `t${idx++}` }, text2.slice(last)));
12337
12760
  }
12338
12761
  if (padTo !== void 0) {
12339
12762
  const seen = visibleWidth(text2);
12340
12763
  if (seen < padTo) {
12341
- parts.push(/* @__PURE__ */ React12.createElement(Text10, { key: `pad${idx++}` }, " ".repeat(padTo - seen)));
12764
+ parts.push(/* @__PURE__ */ React15.createElement(Text13, { key: `pad${idx++}` }, " ".repeat(padTo - seen)));
12342
12765
  }
12343
12766
  }
12344
- return /* @__PURE__ */ React12.createElement(Text10, null, parts);
12767
+ return /* @__PURE__ */ React15.createElement(Text13, null, parts);
12345
12768
  }
12346
12769
  function stripInlineMarkup(s) {
12347
12770
  return s.replace(
@@ -12580,34 +13003,34 @@ function parseBulletItem(raw) {
12580
13003
  function BlockView({ block, citations }) {
12581
13004
  switch (block.kind) {
12582
13005
  case "heading":
12583
- return /* @__PURE__ */ React12.createElement(HeadingView, { level: block.level, text: block.text, citations });
13006
+ return /* @__PURE__ */ React15.createElement(HeadingView, { level: block.level, text: block.text, citations });
12584
13007
  case "paragraph":
12585
- return /* @__PURE__ */ React12.createElement(ParagraphView, { text: block.text, citations });
13008
+ return /* @__PURE__ */ React15.createElement(ParagraphView, { text: block.text, citations });
12586
13009
  case "bullet":
12587
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column" }, block.items.map((item, i) => /* @__PURE__ */ React12.createElement(Box11, { key: `${i}-${item.text.slice(0, 24)}` }, /* @__PURE__ */ React12.createElement(Text10, { color: item.task === "done" ? "green" : "cyan" }, bulletPrefix(block, i, item)), item.task === "done" ? /* @__PURE__ */ React12.createElement(Text10, { strikethrough: true, dimColor: true }, /* @__PURE__ */ React12.createElement(InlineMd, { text: item.text, citations })) : /* @__PURE__ */ React12.createElement(InlineMd, { text: item.text, citations }))));
13010
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column" }, block.items.map((item, i) => /* @__PURE__ */ React15.createElement(Box13, { key: `${i}-${item.text.slice(0, 24)}` }, /* @__PURE__ */ React15.createElement(Text13, { color: item.task === "done" ? "green" : "cyan" }, bulletPrefix(block, i, item)), item.task === "done" ? /* @__PURE__ */ React15.createElement(Text13, { strikethrough: true, dimColor: true }, /* @__PURE__ */ React15.createElement(InlineMd, { text: item.text, citations })) : /* @__PURE__ */ React15.createElement(InlineMd, { text: item.text, citations }))));
12588
13011
  case "quote":
12589
- return /* @__PURE__ */ React12.createElement(BlockquoteView, { block, citations });
13012
+ return /* @__PURE__ */ React15.createElement(BlockquoteView, { block, citations });
12590
13013
  case "code":
12591
13014
  if (DIAGRAM_LANGS.has(block.lang.toLowerCase())) {
12592
- return /* @__PURE__ */ React12.createElement(DiagramCodeBlock, { lang: block.lang, text: block.text });
13015
+ return /* @__PURE__ */ React15.createElement(DiagramCodeBlock, { lang: block.lang, text: block.text });
12593
13016
  }
12594
- return /* @__PURE__ */ React12.createElement(CodeBlockView, { lang: block.lang, text: block.text });
13017
+ return /* @__PURE__ */ React15.createElement(CodeBlockView, { lang: block.lang, text: block.text });
12595
13018
  case "edit-block":
12596
- return /* @__PURE__ */ React12.createElement(EditBlockRow, { block });
13019
+ return /* @__PURE__ */ React15.createElement(EditBlockRow, { block });
12597
13020
  case "table":
12598
- return /* @__PURE__ */ React12.createElement(TableBlockRow, { block, citations });
13021
+ return /* @__PURE__ */ React15.createElement(TableBlockRow, { block, citations });
12599
13022
  case "hr":
12600
- return /* @__PURE__ */ React12.createElement(Text10, { 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");
13023
+ return /* @__PURE__ */ React15.createElement(Text13, { 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");
12601
13024
  }
12602
13025
  }
12603
13026
  function ParagraphView({ text: text2, citations }) {
12604
13027
  if (!text2.includes("\n")) {
12605
- return /* @__PURE__ */ React12.createElement(InlineMd, { text: text2, citations });
13028
+ return /* @__PURE__ */ React15.createElement(InlineMd, { text: text2, citations });
12606
13029
  }
12607
13030
  const rows = text2.split("\n");
12608
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column" }, rows.map((row2, i) => (
13031
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column" }, rows.map((row2, i) => (
12609
13032
  // biome-ignore lint/suspicious/noArrayIndexKey: hard-break rows are source-ordered and never reorder
12610
- /* @__PURE__ */ React12.createElement(InlineMd, { key: `ln-${i}`, text: row2, citations })
13033
+ /* @__PURE__ */ React15.createElement(InlineMd, { key: `ln-${i}`, text: row2, citations })
12611
13034
  )));
12612
13035
  }
12613
13036
  function bulletPrefix(block, i, item) {
@@ -12620,8 +13043,8 @@ function BlockquoteView({
12620
13043
  block,
12621
13044
  citations
12622
13045
  }) {
12623
- return /* @__PURE__ */ React12.createElement(
12624
- Box11,
13046
+ return /* @__PURE__ */ React15.createElement(
13047
+ Box13,
12625
13048
  {
12626
13049
  borderStyle: "single",
12627
13050
  borderColor: "#c4b5fd",
@@ -12632,7 +13055,7 @@ function BlockquoteView({
12632
13055
  flexDirection: "column",
12633
13056
  gap: 1
12634
13057
  },
12635
- block.children.map((child, i) => /* @__PURE__ */ React12.createElement(BlockView, { key: `q-${i}-${child.kind}`, block: child, citations }))
13058
+ block.children.map((child, i) => /* @__PURE__ */ React15.createElement(BlockView, { key: `q-${i}-${child.kind}`, block: child, citations }))
12636
13059
  );
12637
13060
  }
12638
13061
  function splitTableRow(line) {
@@ -12650,14 +13073,14 @@ function TableBlockRow({ block, citations }) {
12650
13073
  widths.push(Math.min(40, Math.max(3, ...cellLengths)));
12651
13074
  }
12652
13075
  const separator = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u253C\u2500");
12653
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Box11, null, block.header.map((cell, ci) => (
13076
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Box13, null, block.header.map((cell, ci) => (
12654
13077
  // biome-ignore lint/suspicious/noArrayIndexKey: table columns never reorder — derived from a static header array
12655
- /* @__PURE__ */ React12.createElement(Text10, { key: `h-${ci}`, bold: true, color: "cyan" }, /* @__PURE__ */ React12.createElement(InlineMd, { text: cell, padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
12656
- ))), /* @__PURE__ */ React12.createElement(Text10, { dimColor: true }, separator), block.rows.map((row2, ri) => (
13078
+ /* @__PURE__ */ React15.createElement(Text13, { key: `h-${ci}`, bold: true, color: "cyan" }, /* @__PURE__ */ React15.createElement(InlineMd, { text: cell, padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
13079
+ ))), /* @__PURE__ */ React15.createElement(Text13, { dimColor: true }, separator), block.rows.map((row2, ri) => (
12657
13080
  // biome-ignore lint/suspicious/noArrayIndexKey: table rows render in source order and don't reorder
12658
- /* @__PURE__ */ React12.createElement(Box11, { key: `r-${ri}` }, Array.from({ length: colCount }).map((_, ci) => (
13081
+ /* @__PURE__ */ React15.createElement(Box13, { key: `r-${ri}` }, Array.from({ length: colCount }).map((_, ci) => (
12659
13082
  // biome-ignore lint/suspicious/noArrayIndexKey: same — column axis is fixed by the table shape
12660
- /* @__PURE__ */ React12.createElement(Text10, { key: `c-${ri}-${ci}` }, /* @__PURE__ */ React12.createElement(InlineMd, { text: row2[ci] ?? "", padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
13083
+ /* @__PURE__ */ React15.createElement(Text13, { key: `c-${ri}-${ci}` }, /* @__PURE__ */ React15.createElement(InlineMd, { text: row2[ci] ?? "", padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
12661
13084
  )))
12662
13085
  )));
12663
13086
  }
@@ -12677,7 +13100,7 @@ function EditBlockRow({ block }) {
12677
13100
  const isNewFile = block.search.length === 0;
12678
13101
  const searchLines = block.search.split("\n");
12679
13102
  const replaceLines = block.replace.split("\n");
12680
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React12.createElement(Box11, null, /* @__PURE__ */ React12.createElement(Text10, { bold: true, color: "cyan" }, block.filename), isNewFile ? /* @__PURE__ */ React12.createElement(Text10, { color: "green", bold: true }, " (new file)") : null), isNewFile ? null : /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginTop: 1 }, searchLines.map((line, i) => /* @__PURE__ */ React12.createElement(Text10, { key: `s-${i}-${line.length}`, color: "red" }, `- ${line}`))), /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginTop: isNewFile ? 1 : 0 }, replaceLines.map((line, i) => /* @__PURE__ */ React12.createElement(Text10, { key: `r-${i}-${line.length}`, color: "green" }, `+ ${line}`))));
13103
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React15.createElement(Box13, null, /* @__PURE__ */ React15.createElement(Text13, { bold: true, color: "cyan" }, block.filename), isNewFile ? /* @__PURE__ */ React15.createElement(Text13, { color: "green", bold: true }, " (new file)") : null), isNewFile ? null : /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", marginTop: 1 }, searchLines.map((line, i) => /* @__PURE__ */ React15.createElement(Text13, { key: `s-${i}-${line.length}`, color: "red" }, `- ${line}`))), /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", marginTop: isNewFile ? 1 : 0 }, replaceLines.map((line, i) => /* @__PURE__ */ React15.createElement(Text13, { key: `r-${i}-${line.length}`, color: "green" }, `+ ${line}`))));
12681
13104
  }
12682
13105
  var DIAGRAM_LANGS = /* @__PURE__ */ new Set([
12683
13106
  "mermaid",
@@ -12703,44 +13126,44 @@ function HeadingView({
12703
13126
  citations
12704
13127
  }) {
12705
13128
  if (level === 1) {
12706
- return /* @__PURE__ */ React12.createElement(Box11, { marginY: 1 }, /* @__PURE__ */ React12.createElement(Text10, { backgroundColor: "#67e8f9", color: "black", bold: true }, ` ${text2} `));
13129
+ return /* @__PURE__ */ React15.createElement(Box13, { marginY: 1 }, /* @__PURE__ */ React15.createElement(Text13, { backgroundColor: "#67e8f9", color: "black", bold: true }, ` ${text2} `));
12707
13130
  }
12708
13131
  if (level === 2) {
12709
- return /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text10, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` ${text2} `));
13132
+ return /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` ${text2} `));
12710
13133
  }
12711
13134
  if (level === 3) {
12712
- return /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text10, { backgroundColor: "#f0abfc", color: "black", bold: true }, ` ${text2} `));
13135
+ return /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, { backgroundColor: "#f0abfc", color: "black", bold: true }, ` ${text2} `));
12713
13136
  }
12714
- return /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text10, { bold: true, color: "#f0abfc" }, "\u25B8", " "), /* @__PURE__ */ React12.createElement(Text10, { bold: true }, /* @__PURE__ */ React12.createElement(InlineMd, { text: text2, citations })));
13137
+ return /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, { bold: true, color: "#f0abfc" }, "\u25B8", " "), /* @__PURE__ */ React15.createElement(Text13, { bold: true }, /* @__PURE__ */ React15.createElement(InlineMd, { text: text2, citations })));
12715
13138
  }
12716
13139
  function CodeBlockView({ lang, text: text2 }) {
12717
13140
  const langLabel = lang.trim();
12718
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "#7dd3fc", paddingX: 1 }, langLabel ? /* @__PURE__ */ React12.createElement(Box11, null, /* @__PURE__ */ React12.createElement(Text10, { backgroundColor: "#7dd3fc", color: "black", bold: true }, ` ${langLabel} `)) : null, /* @__PURE__ */ React12.createElement(Text10, { color: "#fde68a" }, text2));
13141
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "#7dd3fc", paddingX: 1 }, langLabel ? /* @__PURE__ */ React15.createElement(Box13, null, /* @__PURE__ */ React15.createElement(Text13, { backgroundColor: "#7dd3fc", color: "black", bold: true }, ` ${langLabel} `)) : null, /* @__PURE__ */ React15.createElement(Text13, { color: "#fde68a" }, text2));
12719
13142
  }
12720
13143
  function DiagramCodeBlock({ lang, text: text2 }) {
12721
13144
  const hint = DIAGRAM_VIEWER_HINT[lang.toLowerCase()] ?? "\u2192 render with the matching viewer to view";
12722
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", borderStyle: "double", borderColor: "magenta", paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text10, { bold: true, color: "magenta" }, `\u25C7 ${lang} diagram (source \u2014 terminal can't draw the graph)`), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text10, { color: "yellow" }, text2)), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text10, { dimColor: true }, hint)));
13145
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", borderStyle: "double", borderColor: "magenta", paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text13, { bold: true, color: "magenta" }, `\u25C7 ${lang} diagram (source \u2014 terminal can't draw the graph)`), /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, { color: "yellow" }, text2)), /* @__PURE__ */ React15.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text13, { dimColor: true }, hint)));
12723
13146
  }
12724
13147
  function Markdown({ text: text2, projectRoot }) {
12725
13148
  const cleaned = expandAutolinks(expandEmoji(stripMath(text2)));
12726
13149
  const root = projectRoot ?? process.cwd();
12727
- const citations = React12.useMemo(() => collectCitations(cleaned, root), [cleaned, root]);
12728
- const blocks = React12.useMemo(() => parseBlocks(cleaned), [cleaned]);
13150
+ const citations = React15.useMemo(() => collectCitations(cleaned, root), [cleaned, root]);
13151
+ const blocks = React15.useMemo(() => parseBlocks(cleaned), [cleaned]);
12729
13152
  const broken = [];
12730
13153
  for (const [url, status2] of citations) {
12731
13154
  if (!status2.ok) broken.push({ url, reason: status2.reason });
12732
13155
  }
12733
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", gap: 1 }, blocks.map((b, i) => /* @__PURE__ */ React12.createElement(BlockView, { key: `${i}-${b.kind}`, block: b, citations })), broken.length > 0 ? /* @__PURE__ */ React12.createElement(BrokenCitationsBlock, { items: broken }) : null);
13156
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", gap: 1 }, blocks.map((b, i) => /* @__PURE__ */ React15.createElement(BlockView, { key: `${i}-${b.kind}`, block: b, citations })), broken.length > 0 ? /* @__PURE__ */ React15.createElement(BrokenCitationsBlock, { items: broken }) : null);
12734
13157
  }
12735
13158
  function BrokenCitationsBlock({ items }) {
12736
- return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text10, { 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) => (
13159
+ return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text13, { 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) => (
12737
13160
  // biome-ignore lint/suspicious/noArrayIndexKey: list is derived from a Map iteration order, stable per render
12738
- /* @__PURE__ */ React12.createElement(Text10, { key: `bc-${i}`, color: "red" }, ` \u2717 ${b.url} \u2192 ${b.reason}`)
13161
+ /* @__PURE__ */ React15.createElement(Text13, { key: `bc-${i}`, color: "red" }, ` \u2717 ${b.url} \u2192 ${b.reason}`)
12739
13162
  )));
12740
13163
  }
12741
13164
 
12742
13165
  // src/cli/ui/ticker.tsx
12743
- import React13, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState3 } from "react";
13166
+ import React16, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState3 } from "react";
12744
13167
  var FAST_TICK_MS = 120;
12745
13168
  var SLOW_TICK_MS = 1e3;
12746
13169
  var FastTickContext = createContext2(0);
@@ -12757,7 +13180,7 @@ function TickerProvider({ children, disabled }) {
12757
13180
  clearInterval(slowId);
12758
13181
  };
12759
13182
  }, [disabled]);
12760
- return /* @__PURE__ */ React13.createElement(FastTickContext.Provider, { value: fast }, /* @__PURE__ */ React13.createElement(SlowTickContext.Provider, { value: slow }, children));
13183
+ return /* @__PURE__ */ React16.createElement(FastTickContext.Provider, { value: fast }, /* @__PURE__ */ React16.createElement(SlowTickContext.Provider, { value: slow }, children));
12761
13184
  }
12762
13185
  function useTick() {
12763
13186
  return useContext2(FastTickContext);
@@ -12913,24 +13336,24 @@ function RoleGlyph({
12913
13336
  glyph,
12914
13337
  color: color2
12915
13338
  }) {
12916
- return /* @__PURE__ */ React14.createElement(Text11, { color: color2, bold: true }, glyph);
13339
+ return /* @__PURE__ */ React17.createElement(Text14, { color: color2, bold: true }, glyph);
12917
13340
  }
12918
13341
  function ToolPill({ label, status: status2 }) {
12919
13342
  const color2 = status2 === "err" ? COLOR.toolErr : COLOR.tool;
12920
13343
  const symbol = status2 === "err" ? GLYPH.toolErr : GLYPH.toolOk;
12921
- return /* @__PURE__ */ React14.createElement(Text11, { color: color2, bold: true }, `${symbol} ${label}`);
13344
+ return /* @__PURE__ */ React17.createElement(Text14, { color: color2, bold: true }, `${symbol} ${label}`);
12922
13345
  }
12923
13346
  function indentContinuationLines(text2) {
12924
13347
  if (!text2.includes("\n")) return text2;
12925
13348
  return text2.split("\n").join("\n ");
12926
13349
  }
12927
- var EventRow = React14.memo(function EventRow2({
13350
+ var EventRow = React17.memo(function EventRow2({
12928
13351
  event,
12929
13352
  projectRoot
12930
13353
  }) {
12931
13354
  if (event.role === "user") {
12932
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column" }, event.leadSeparator ? /* @__PURE__ */ React14.createElement(TurnSeparator, null) : null, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(
12933
- Box12,
13355
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column" }, event.leadSeparator ? /* @__PURE__ */ React17.createElement(TurnSeparator, null) : null, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(
13356
+ Box14,
12934
13357
  {
12935
13358
  flexDirection: "column",
12936
13359
  borderStyle: "single",
@@ -12940,13 +13363,13 @@ var EventRow = React14.memo(function EventRow2({
12940
13363
  borderColor: COLOR.user,
12941
13364
  paddingLeft: 1
12942
13365
  },
12943
- /* @__PURE__ */ React14.createElement(Text11, null, indentContinuationLines(event.text))
13366
+ /* @__PURE__ */ React17.createElement(Text14, null, indentContinuationLines(event.text))
12944
13367
  )));
12945
13368
  }
12946
13369
  if (event.role === "assistant") {
12947
- if (event.streaming) return /* @__PURE__ */ React14.createElement(StreamingAssistant, { event });
12948
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(RoleGlyph, { glyph: ROLE_GLYPH.assistant, color: "green" }), event.stats ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { backgroundColor: COLOR.assistant, color: "black", bold: true }, ` ${event.stats.model.replace(/^deepseek-/, "")} `)) : null), /* @__PURE__ */ React14.createElement(
12949
- Box12,
13370
+ if (event.streaming) return /* @__PURE__ */ React17.createElement(StreamingAssistant, { event });
13371
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(RoleGlyph, { glyph: ROLE_GLYPH.assistant, color: "green" }), event.stats ? /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { backgroundColor: COLOR.assistant, color: "black", bold: true }, ` ${event.stats.model.replace(/^deepseek-/, "")} `)) : null), /* @__PURE__ */ React17.createElement(
13372
+ Box14,
12950
13373
  {
12951
13374
  flexDirection: "column",
12952
13375
  marginTop: 1,
@@ -12957,20 +13380,20 @@ var EventRow = React14.memo(function EventRow2({
12957
13380
  borderColor: COLOR.assistant,
12958
13381
  paddingLeft: 1
12959
13382
  },
12960
- event.branch ? /* @__PURE__ */ React14.createElement(BranchBlock, { branch: event.branch }) : null,
12961
- event.reasoning ? /* @__PURE__ */ React14.createElement(ReasoningBlock, { reasoning: event.reasoning }) : null,
12962
- !isPlanStateEmpty(event.planState) ? /* @__PURE__ */ React14.createElement(PlanStateBlock, { planState: event.planState }) : null,
12963
- event.text ? /* @__PURE__ */ React14.createElement(Markdown, { text: event.text, projectRoot }) : /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, "(empty body \u2014 likely tool-call only)"),
12964
- event.stats ? /* @__PURE__ */ React14.createElement(StatsLine, { stats: event.stats }) : null,
12965
- event.repair ? /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.accent }, event.repair) : null
13383
+ event.branch ? /* @__PURE__ */ React17.createElement(BranchBlock, { branch: event.branch }) : null,
13384
+ event.reasoning ? /* @__PURE__ */ React17.createElement(ReasoningBlock, { reasoning: event.reasoning }) : null,
13385
+ !isPlanStateEmpty(event.planState) ? /* @__PURE__ */ React17.createElement(PlanStateBlock, { planState: event.planState }) : null,
13386
+ event.text ? /* @__PURE__ */ React17.createElement(Markdown, { text: event.text, projectRoot }) : /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, "(empty body \u2014 likely tool-call only)"),
13387
+ event.stats ? /* @__PURE__ */ React17.createElement(StatsLine, { stats: event.stats }) : null,
13388
+ event.repair ? /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.accent }, event.repair) : null
12966
13389
  ));
12967
13390
  }
12968
13391
  if (event.role === "tool") {
12969
13392
  const isExplicitError = event.text.startsWith("ERROR:");
12970
13393
  const isEditFile = (event.toolName === "edit_file" || event.toolName?.endsWith("_edit_file")) && !isExplicitError;
12971
13394
  if (isEditFile) {
12972
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(ToolPill, { label: event.toolName ?? "?", status: "ok" }), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " diff:")), /* @__PURE__ */ React14.createElement(
12973
- Box12,
13395
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(ToolPill, { label: event.toolName ?? "?", status: "ok" }), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " diff:")), /* @__PURE__ */ React17.createElement(
13396
+ Box14,
12974
13397
  {
12975
13398
  flexDirection: "column",
12976
13399
  marginTop: 1,
@@ -12981,15 +13404,15 @@ var EventRow = React14.memo(function EventRow2({
12981
13404
  borderColor: COLOR.tool,
12982
13405
  paddingLeft: 1
12983
13406
  },
12984
- /* @__PURE__ */ React14.createElement(EditFileDiff, { text: event.text })
13407
+ /* @__PURE__ */ React17.createElement(EditFileDiff, { text: event.text })
12985
13408
  ));
12986
13409
  }
12987
13410
  const summary = summarizeToolResult(event.toolName ?? "?", event.text);
12988
13411
  const status2 = summary.isError ? "err" : "ok";
12989
13412
  const durationLabel = event.durationMs !== void 0 && event.durationMs >= 100 ? formatDuration(event.durationMs) : "";
12990
13413
  const indexHint = event.toolIndex !== void 0 ? ` /tool ${event.toolIndex}` : "";
12991
- return /* @__PURE__ */ React14.createElement(
12992
- Box12,
13414
+ return /* @__PURE__ */ React17.createElement(
13415
+ Box14,
12993
13416
  {
12994
13417
  borderStyle: "single",
12995
13418
  borderTop: false,
@@ -12998,16 +13421,16 @@ var EventRow = React14.memo(function EventRow2({
12998
13421
  borderColor: status2 === "err" ? COLOR.toolErr : COLOR.tool,
12999
13422
  paddingLeft: 1
13000
13423
  },
13001
- /* @__PURE__ */ React14.createElement(ToolPill, { label: event.toolName ?? "?", status: status2 }),
13002
- durationLabel ? /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` ${durationLabel}`) : null,
13003
- /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " "),
13004
- /* @__PURE__ */ React14.createElement(Text11, { color: status2 === "err" ? "red" : void 0, dimColor: status2 === "ok" }, summary.summary),
13005
- indexHint ? /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, indexHint) : null
13424
+ /* @__PURE__ */ React17.createElement(ToolPill, { label: event.toolName ?? "?", status: status2 }),
13425
+ durationLabel ? /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, ` ${durationLabel}`) : null,
13426
+ /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " "),
13427
+ /* @__PURE__ */ React17.createElement(Text14, { color: status2 === "err" ? "red" : void 0, dimColor: status2 === "ok" }, summary.summary),
13428
+ indexHint ? /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, indexHint) : null
13006
13429
  );
13007
13430
  }
13008
13431
  if (event.role === "error") {
13009
- return /* @__PURE__ */ React14.createElement(
13010
- Box12,
13432
+ return /* @__PURE__ */ React17.createElement(
13433
+ Box14,
13011
13434
  {
13012
13435
  marginTop: 1,
13013
13436
  borderStyle: "single",
@@ -13017,9 +13440,9 @@ var EventRow = React14.memo(function EventRow2({
13017
13440
  borderColor: COLOR.err,
13018
13441
  paddingLeft: 1
13019
13442
  },
13020
- /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.err, bold: true }, "\u2726 error"),
13021
- /* @__PURE__ */ React14.createElement(Text11, null, " "),
13022
- /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.err }, indentContinuationLines(event.text))
13443
+ /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.err, bold: true }, "\u2726 error"),
13444
+ /* @__PURE__ */ React17.createElement(Text14, null, " "),
13445
+ /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.err }, indentContinuationLines(event.text))
13023
13446
  );
13024
13447
  }
13025
13448
  if (event.role === "info") {
@@ -13031,8 +13454,8 @@ var EventRow = React14.memo(function EventRow2({
13031
13454
  else if (lead === "\u2713") leadColor = COLOR.ok;
13032
13455
  else if (lead === "\u2717" || lead === "\u2716") leadColor = COLOR.err;
13033
13456
  else if (lead === "\u21BB") leadColor = COLOR.primary;
13034
- return /* @__PURE__ */ React14.createElement(
13035
- Box12,
13457
+ return /* @__PURE__ */ React17.createElement(
13458
+ Box14,
13036
13459
  {
13037
13460
  borderStyle: "single",
13038
13461
  borderTop: false,
@@ -13041,19 +13464,19 @@ var EventRow = React14.memo(function EventRow2({
13041
13464
  borderColor: leadColor,
13042
13465
  paddingLeft: 1
13043
13466
  },
13044
- /* @__PURE__ */ React14.createElement(Text11, { color: leadColor, bold: true }, lead),
13045
- /* @__PURE__ */ React14.createElement(Text11, null, " "),
13046
- /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, body)
13467
+ /* @__PURE__ */ React17.createElement(Text14, { color: leadColor, bold: true }, lead),
13468
+ /* @__PURE__ */ React17.createElement(Text14, null, " "),
13469
+ /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, body)
13047
13470
  );
13048
13471
  }
13049
13472
  if (event.role === "plan") {
13050
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { bold: true, color: "cyan" }, "\u{1F4CB} plan proposed \u2014 pick a choice below")), /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Markdown, { text: event.text, projectRoot })));
13473
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: "cyan" }, "\u{1F4CB} plan proposed \u2014 pick a choice below")), /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Markdown, { text: event.text, projectRoot })));
13051
13474
  }
13052
13475
  if (event.role === "step-progress") {
13053
13476
  const sp = event.stepProgress;
13054
13477
  const counter = sp && sp.total > 0 ? `${sp.completed}/${sp.total}` : "";
13055
13478
  const label = sp?.title ? `${sp.stepId} \xB7 ${sp.title}` : sp?.stepId ?? "";
13056
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { backgroundColor: "#4ade80", color: "black", bold: true }, " \u2713 STEP "), counter ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: "#4ade80", bold: true }, counter)) : null, /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: "#86efac" }, label)), event.text ? /* @__PURE__ */ React14.createElement(Box12, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, event.text)) : null, sp?.notes ? /* @__PURE__ */ React14.createElement(Box12, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text11, { color: "#fbbf24", dimColor: true }, `note: ${sp.notes}`)) : null);
13479
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { backgroundColor: "#4ade80", color: "black", bold: true }, " \u2713 STEP "), counter ? /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { color: "#4ade80", bold: true }, counter)) : null, /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { color: "#86efac" }, label)), event.text ? /* @__PURE__ */ React17.createElement(Box14, { paddingLeft: 2 }, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, event.text)) : null, sp?.notes ? /* @__PURE__ */ React17.createElement(Box14, { paddingLeft: 2 }, /* @__PURE__ */ React17.createElement(Text14, { color: "#fbbf24", dimColor: true }, `note: ${sp.notes}`)) : null);
13057
13480
  }
13058
13481
  if (event.role === "plan-resumed") {
13059
13482
  const rp = event.resumedPlan;
@@ -13068,7 +13491,7 @@ var EventRow = React14.memo(function EventRow2({
13068
13491
  ])
13069
13492
  );
13070
13493
  const nextStep = rp.steps.find((s) => !completedSet.has(s.id));
13071
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { backgroundColor: "#67e8f9", color: "black", bold: true }, " \u21BB RESUMED PLAN "), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: "#67e8f9", bold: true }, `${done}/${total}`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` done \xB7 last touched ${rp.relativeTime}`)), rp.summary ? /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: "#67e8f9" }, rp.summary)) : null, /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(PlanStepList, { steps: rp.steps, statuses, focusStepId: nextStep?.id })));
13494
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { backgroundColor: "#67e8f9", color: "black", bold: true }, " \u21BB RESUMED PLAN "), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { color: "#67e8f9", bold: true }, `${done}/${total}`), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, ` done \xB7 last touched ${rp.relativeTime}`)), rp.summary ? /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text14, { color: "#67e8f9" }, rp.summary)) : null, /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(PlanStepList, { steps: rp.steps, statuses, focusStepId: nextStep?.id })));
13072
13495
  }
13073
13496
  if (event.role === "plan-replay") {
13074
13497
  const r = event.replayPlan;
@@ -13080,11 +13503,11 @@ var EventRow = React14.memo(function EventRow2({
13080
13503
  r.steps.map((s) => [s.id, completedSet.has(s.id) ? "done" : "pending"])
13081
13504
  );
13082
13505
  const navHint = r.total > 1 ? ` \xB7 ${r.index}/${r.total}` : "";
13083
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { backgroundColor: "#94a3b8", color: "black", bold: true }, " \u23EA REPLAY "), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: "#94a3b8", bold: true }, `${done}/${total}`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` done \xB7 ${r.relativeTime}${navHint}`)), r.summary ? /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: "#94a3b8" }, r.summary)) : null, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, r.archiveBasename)), r.body ? /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Markdown, { text: r.body, projectRoot })) : null, /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(PlanStepList, { steps: r.steps, statuses })), /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { 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)")));
13506
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { backgroundColor: "#94a3b8", color: "black", bold: true }, " \u23EA REPLAY "), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { color: "#94a3b8", bold: true }, `${done}/${total}`), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, ` done \xB7 ${r.relativeTime}${navHint}`)), r.summary ? /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text14, { color: "#94a3b8" }, r.summary)) : null, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, r.archiveBasename)), r.body ? /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Markdown, { text: r.body, projectRoot })) : null, /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(PlanStepList, { steps: r.steps, statuses })), /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text14, { 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)")));
13084
13507
  }
13085
13508
  if (event.role === "warning") {
13086
- return /* @__PURE__ */ React14.createElement(
13087
- Box12,
13509
+ return /* @__PURE__ */ React17.createElement(
13510
+ Box14,
13088
13511
  {
13089
13512
  borderStyle: "single",
13090
13513
  borderTop: false,
@@ -13093,102 +13516,64 @@ var EventRow = React14.memo(function EventRow2({
13093
13516
  borderColor: COLOR.warn,
13094
13517
  paddingLeft: 1
13095
13518
  },
13096
- /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.warn, bold: true }, "\u25B2 warn"),
13097
- /* @__PURE__ */ React14.createElement(Text11, null, " "),
13098
- /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.warn }, indentContinuationLines(event.text))
13519
+ /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.warn, bold: true }, "\u25B2 warn"),
13520
+ /* @__PURE__ */ React17.createElement(Text14, null, " "),
13521
+ /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.warn }, indentContinuationLines(event.text))
13099
13522
  );
13100
13523
  }
13101
13524
  if (event.role === "ctx-breakdown" && event.ctxBreakdown) {
13102
- return /* @__PURE__ */ React14.createElement(CtxBreakdownBlock, { data: event.ctxBreakdown });
13525
+ return /* @__PURE__ */ React17.createElement(CtxBreakdownBlock, { data: event.ctxBreakdown });
13103
13526
  }
13104
- return /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, null, event.text));
13527
+ return /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, null, event.text));
13105
13528
  });
13106
13529
  function TurnSeparator() {
13107
- const { stdout: stdout4 } = useStdout5();
13530
+ const { stdout: stdout4 } = useStdout7();
13108
13531
  const cols = stdout4?.columns ?? 80;
13109
13532
  const width = Math.max(16, cols - 2);
13110
13533
  const sideWidth = Math.max(2, Math.floor((width - 5) / 2));
13111
13534
  const leftCells = gradientCells(sideWidth, "\u2500");
13112
13535
  const rightCells = gradientCells(sideWidth, "\u2500");
13113
- return /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1, marginBottom: 1 }, leftCells.map((c, i) => (
13536
+ return /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1, marginBottom: 1 }, leftCells.map((c, i) => (
13114
13537
  // biome-ignore lint/suspicious/noArrayIndexKey: fixed-width gradient row
13115
- /* @__PURE__ */ React14.createElement(Text11, { key: `tsep-l-${i}`, color: c.color }, c.ch)
13116
- )), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.brand, bold: true }, " \u25C6 "), rightCells.map((c, i) => (
13538
+ /* @__PURE__ */ React17.createElement(Text14, { key: `tsep-l-${i}`, color: c.color }, c.ch)
13539
+ )), /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.brand, bold: true }, " \u25C6 "), rightCells.map((c, i) => (
13117
13540
  // biome-ignore lint/suspicious/noArrayIndexKey: fixed-width gradient row
13118
- /* @__PURE__ */ React14.createElement(Text11, { key: `tsep-r-${i}`, color: c.color }, c.ch)
13541
+ /* @__PURE__ */ React17.createElement(Text14, { key: `tsep-r-${i}`, color: c.color }, c.ch)
13119
13542
  )));
13120
13543
  }
13121
13544
  function EditFileDiff({ text: text2 }) {
13122
13545
  const lines = text2.split(/\r?\n/);
13123
13546
  const [statusHeader, hunkHeader, ...body] = lines;
13124
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` ${statusHeader ?? ""}`), hunkHeader !== void 0 ? /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` ${hunkHeader.trim()} `)) : null, body.map((line, i) => {
13547
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, ` ${statusHeader ?? ""}`), hunkHeader !== void 0 ? /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text14, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` ${hunkHeader.trim()} `)) : null, body.map((line, i) => {
13125
13548
  const key = `${i}-${line.slice(0, 32)}`;
13126
13549
  const stripped = line.replace(/^ {2}/, "");
13127
13550
  if (stripped.startsWith("- ")) {
13128
- return /* @__PURE__ */ React14.createElement(Box12, { key }, /* @__PURE__ */ React14.createElement(Text11, { color: "#f87171", bold: true }, "\u2212 "), /* @__PURE__ */ React14.createElement(Text11, { color: "#fca5a5" }, stripped.slice(2)));
13551
+ return /* @__PURE__ */ React17.createElement(Box14, { key }, /* @__PURE__ */ React17.createElement(Text14, { color: "#f87171", bold: true }, "\u2212 "), /* @__PURE__ */ React17.createElement(Text14, { color: "#fca5a5" }, stripped.slice(2)));
13129
13552
  }
13130
13553
  if (stripped.startsWith("+ ")) {
13131
- return /* @__PURE__ */ React14.createElement(Box12, { key }, /* @__PURE__ */ React14.createElement(Text11, { color: "#4ade80", bold: true }, "+ "), /* @__PURE__ */ React14.createElement(Text11, { color: "#86efac" }, stripped.slice(2)));
13554
+ return /* @__PURE__ */ React17.createElement(Box14, { key }, /* @__PURE__ */ React17.createElement(Text14, { color: "#4ade80", bold: true }, "+ "), /* @__PURE__ */ React17.createElement(Text14, { color: "#86efac" }, stripped.slice(2)));
13132
13555
  }
13133
- return /* @__PURE__ */ React14.createElement(Box12, { key }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " "), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, stripped));
13556
+ return /* @__PURE__ */ React17.createElement(Box14, { key }, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " "), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, stripped));
13134
13557
  }));
13135
13558
  }
13136
13559
  function BranchBlock({ branch: branch2 }) {
13137
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { backgroundColor: "#93c5fd", color: "black", bold: true }, ` \u2387 BRANCH \xD7${branch2.budget} `), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: "#93c5fd" }, "picked "), /* @__PURE__ */ React14.createElement(Text11, { color: "#93c5fd", bold: true }, "#", branch2.chosenIndex)), /* @__PURE__ */ React14.createElement(Box12, { paddingLeft: 2, marginTop: 1 }, branch2.uncertainties.map((u, i) => {
13560
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { backgroundColor: "#93c5fd", color: "black", bold: true }, ` \u2387 BRANCH \xD7${branch2.budget} `), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { color: "#93c5fd" }, "picked "), /* @__PURE__ */ React17.createElement(Text14, { color: "#93c5fd", bold: true }, "#", branch2.chosenIndex)), /* @__PURE__ */ React17.createElement(Box14, { paddingLeft: 2, marginTop: 1 }, branch2.uncertainties.map((u, i) => {
13138
13561
  const chosen = i === branch2.chosenIndex;
13139
13562
  const t2 = (branch2.temperatures[i] ?? 0).toFixed(1);
13140
13563
  return (
13141
13564
  // biome-ignore lint/suspicious/noArrayIndexKey: branch index is positional and stable
13142
- /* @__PURE__ */ React14.createElement(Text11, { key: `b-${i}` }, /* @__PURE__ */ React14.createElement(Text11, { color: chosen ? "#93c5fd" : "#475569", bold: chosen }, chosen ? "\u25B8 " : " "), /* @__PURE__ */ React14.createElement(Text11, { color: chosen ? "#93c5fd" : "#94a3b8", bold: chosen }, `#${i}`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` T=${t2} u=${u} `))
13565
+ /* @__PURE__ */ React17.createElement(Text14, { key: `b-${i}` }, /* @__PURE__ */ React17.createElement(Text14, { color: chosen ? "#93c5fd" : "#475569", bold: chosen }, chosen ? "\u25B8 " : " "), /* @__PURE__ */ React17.createElement(Text14, { color: chosen ? "#93c5fd" : "#94a3b8", bold: chosen }, `#${i}`), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, ` T=${t2} u=${u} `))
13143
13566
  );
13144
13567
  })));
13145
13568
  }
13146
- function CtxBreakdownBlock({
13147
- data
13148
- }) {
13149
- const total = data.systemTokens + data.toolsTokens + data.logTokens + data.inputTokens;
13150
- const winPct = data.ctxMax > 0 ? Math.round(total / data.ctxMax * 100) : 0;
13151
- const barWidth = 48;
13152
- const cellOf = (n) => data.ctxMax > 0 ? Math.round(n / data.ctxMax * barWidth) : 0;
13153
- const sysCells = cellOf(data.systemTokens);
13154
- const toolsCells = cellOf(data.toolsTokens);
13155
- const logCells = cellOf(data.logTokens);
13156
- const inputCells = cellOf(data.inputTokens);
13157
- const used = sysCells + toolsCells + logCells + inputCells;
13158
- const freeCells = Math.max(0, barWidth - used);
13159
- const sevColor = winPct >= 80 ? COLOR.err : winPct >= 60 ? COLOR.warn : COLOR.ok;
13160
- return /* @__PURE__ */ React14.createElement(
13161
- Box12,
13162
- {
13163
- flexDirection: "column",
13164
- marginY: 1,
13165
- borderStyle: "single",
13166
- borderTop: false,
13167
- borderRight: false,
13168
- borderBottom: false,
13169
- borderColor: COLOR.brand,
13170
- paddingLeft: 1
13171
- },
13172
- /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.brand, bold: true }, "\u25A3 context"), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` ${formatTokensCompact(total)} of ${formatTokensCompact(data.ctxMax)}`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React14.createElement(Text11, { color: sevColor, bold: true }, `${winPct}%`), winPct >= 80 ? /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.err, bold: true }, " \xB7 /compact") : null),
13173
- /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.brand }, "\u2588".repeat(sysCells)), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.accent }, "\u2588".repeat(toolsCells)), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.primary }, "\u2588".repeat(logCells)), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.tool }, "\u2588".repeat(inputCells)), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.info, dimColor: true }, "\u2591".repeat(freeCells))),
13174
- /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.brand }, "\u25A0"), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` system ${formatTokensCompact(data.systemTokens)}`), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.accent }, "\u25A0"), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` tools ${formatTokensCompact(data.toolsTokens)}`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` (${data.toolsCount})`), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.primary }, "\u25A0"), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` log ${formatTokensCompact(data.logTokens)}`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` (${data.logMessages} msg)`), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.tool }, "\u25A0"), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` input ${formatTokensCompact(data.inputTokens)}`)),
13175
- data.topTools.length > 0 ? /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` top tool results by cost (${data.topTools.length}):`), data.topTools.map((t2) => /* @__PURE__ */ React14.createElement(Box12, { key: `${t2.turn}-${t2.name}` }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` turn ${String(t2.turn).padStart(3)} `), /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.info }, t2.name.padEnd(22)), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` ${formatTokensCompact(t2.tokens).padStart(8)}`)))) : null,
13176
- /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " /compact shrinks oversized tool results \xB7 /new wipes log"))
13177
- );
13178
- }
13179
- function formatTokensCompact(n) {
13180
- if (n < 1024) return String(n);
13181
- const k = n / 1024;
13182
- return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;
13183
- }
13184
13569
  function ReasoningBlock({ reasoning }) {
13185
13570
  const max = 260;
13186
13571
  const flat = reasoning.replace(/\s+/g, " ").trim();
13187
13572
  const preview = flat.length <= max ? flat : `\u2026 (+${flat.length - max} earlier chars) ${flat.slice(-max)}`;
13188
13573
  const tokensApprox = Math.max(1, Math.round(flat.length / 4.5));
13189
13574
  const tokLabel = tokensApprox >= 1e3 ? `${(tokensApprox / 1e3).toFixed(1)}k` : `${tokensApprox}`;
13190
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.accent, bold: true }, "R1 \u21AF"), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, ` reasoning \xB7 ~${tokLabel} tok \xB7 /think for full`)), /* @__PURE__ */ React14.createElement(
13191
- Box12,
13575
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.accent, bold: true }, "R1 \u21AF"), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, ` reasoning \xB7 ~${tokLabel} tok \xB7 /think for full`)), /* @__PURE__ */ React17.createElement(
13576
+ Box14,
13192
13577
  {
13193
13578
  borderStyle: "single",
13194
13579
  borderTop: false,
@@ -13197,26 +13582,26 @@ function ReasoningBlock({ reasoning }) {
13197
13582
  borderColor: COLOR.accent,
13198
13583
  paddingLeft: 1
13199
13584
  },
13200
- /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.accent, italic: true, dimColor: true }, preview)
13585
+ /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.accent, italic: true, dimColor: true }, preview)
13201
13586
  ));
13202
13587
  }
13203
13588
  function Elapsed() {
13204
13589
  const s = useElapsedSeconds();
13205
13590
  const mm = String(Math.floor(s / 60)).padStart(2, "0");
13206
13591
  const ss = String(s % 60).padStart(2, "0");
13207
- return /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, `${mm}:${ss}`);
13592
+ return /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, `${mm}:${ss}`);
13208
13593
  }
13209
13594
  function PulsingAssistantGlyph() {
13210
- return /* @__PURE__ */ React14.createElement(Text11, { color: "green", bold: true }, ROLE_GLYPH.assistant);
13595
+ return /* @__PURE__ */ React17.createElement(Text14, { color: "green", bold: true }, ROLE_GLYPH.assistant);
13211
13596
  }
13212
13597
  function StreamingAssistant({ event }) {
13213
13598
  if (event.branchProgress) {
13214
13599
  const p = event.branchProgress;
13215
13600
  if (p.completed === 0) {
13216
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React14.createElement(Text11, { color: "blue" }, " \u2387 launching ", p.total, " parallel samples (R1 thinking in parallel)\u2026 "), /* @__PURE__ */ React14.createElement(Elapsed, null)), /* @__PURE__ */ React14.createElement(Text11, { color: "yellow" }, " ", "spread across T=0.0/0.5/1.0 \xB7 reasoner typically takes 30-90s \u2014 this is normal"));
13601
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React17.createElement(Text14, { color: "blue" }, " \u2387 launching ", p.total, " parallel samples (R1 thinking in parallel)\u2026 "), /* @__PURE__ */ React17.createElement(Elapsed, null)), /* @__PURE__ */ React17.createElement(Text14, { color: "yellow" }, " ", "spread across T=0.0/0.5/1.0 \xB7 reasoner typically takes 30-90s \u2014 this is normal"));
13217
13602
  }
13218
13603
  const pct2 = Math.round(p.completed / p.total * 100);
13219
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React14.createElement(Text11, { color: "blue" }, " \u2387 branching ", p.completed, "/", p.total, " (", pct2, "%) "), /* @__PURE__ */ React14.createElement(Elapsed, null)), /* @__PURE__ */ React14.createElement(Text11, { 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"));
13604
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React17.createElement(Text14, { color: "blue" }, " \u2387 branching ", p.completed, "/", p.total, " (", pct2, "%) "), /* @__PURE__ */ React17.createElement(Elapsed, null)), /* @__PURE__ */ React17.createElement(Text14, { 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"));
13220
13605
  }
13221
13606
  const toolCallBuild = event.toolCallBuild;
13222
13607
  const text2 = event.text;
@@ -13238,8 +13623,8 @@ function StreamingAssistant({ event }) {
13238
13623
  }
13239
13624
  const verb = phaseVerb ?? "responding";
13240
13625
  const verbColor = phaseVerb ? phaseColor : COLOR.info;
13241
- return /* @__PURE__ */ React14.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box12, null, /* @__PURE__ */ React14.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Text11, { color: verbColor, dimColor: !phaseVerb }, verb), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Marquee, null), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Elapsed, null)), /* @__PURE__ */ React14.createElement(
13242
- Box12,
13626
+ return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Text14, { color: verbColor, dimColor: !phaseVerb }, verb), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Marquee, null), /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(Elapsed, null)), /* @__PURE__ */ React17.createElement(
13627
+ Box14,
13243
13628
  {
13244
13629
  marginTop: 1,
13245
13630
  borderStyle: "single",
@@ -13250,14 +13635,14 @@ function StreamingAssistant({ event }) {
13250
13635
  paddingLeft: 1,
13251
13636
  flexDirection: "column"
13252
13637
  },
13253
- reasoning ? /* @__PURE__ */ React14.createElement(ReasoningBlock, { reasoning }) : null,
13254
- text2 ? /* @__PURE__ */ React14.createElement(Text11, null, text2, /* @__PURE__ */ React14.createElement(BlinkingCursor, null)) : /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, preFirstByte ? "waiting for first byte \u2014 5-60s typical" : reasoningOnly ? `R1 thinking \xB7 ~${Math.round((reasoning?.length ?? 0) / 4)} tok so far` : toolCallOnly ? `assembling ${toolCallBuild.name}${formatToolCallIndex(toolCallBuild)} \xB7 ${toolCallBuild.chars} chars${formatReadyTail(toolCallBuild)}` : "", /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(BlinkingCursor, null))
13638
+ reasoning ? /* @__PURE__ */ React17.createElement(ReasoningBlock, { reasoning }) : null,
13639
+ text2 ? /* @__PURE__ */ React17.createElement(Text14, null, text2, /* @__PURE__ */ React17.createElement(BlinkingCursor, null)) : /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, preFirstByte ? "waiting for first byte \u2014 5-60s typical" : reasoningOnly ? `R1 thinking \xB7 ~${Math.round((reasoning?.length ?? 0) / 4)} tok so far` : toolCallOnly ? `assembling ${toolCallBuild.name}${formatToolCallIndex(toolCallBuild)} \xB7 ${toolCallBuild.chars} chars${formatReadyTail(toolCallBuild)}` : "", /* @__PURE__ */ React17.createElement(Text14, null, " "), /* @__PURE__ */ React17.createElement(BlinkingCursor, null))
13255
13640
  ));
13256
13641
  }
13257
13642
  function BlinkingCursor() {
13258
13643
  const tick = useTick();
13259
13644
  const visible = Math.floor(tick / 4) % 2 === 0;
13260
- return /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.primary }, visible ? "\u258C" : " ");
13645
+ return /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.primary }, visible ? "\u258C" : " ");
13261
13646
  }
13262
13647
  var MARQUEE_W = 12;
13263
13648
  var MARQUEE_WAVE = ["\u2592", "\u2593", "\u2588", "\u2593", "\u2592"];
@@ -13267,7 +13652,7 @@ function Marquee() {
13267
13652
  for (let i = 0; i < MARQUEE_WAVE.length; i++) {
13268
13653
  cells[(tick + i) % MARQUEE_W] = MARQUEE_WAVE[i];
13269
13654
  }
13270
- return /* @__PURE__ */ React14.createElement(Text11, { color: COLOR.primary }, cells.join(""));
13655
+ return /* @__PURE__ */ React17.createElement(Text14, { color: COLOR.primary }, cells.join(""));
13271
13656
  }
13272
13657
  function formatToolCallIndex(tb) {
13273
13658
  if (!tb || tb.index === void 0) return "";
@@ -13282,17 +13667,17 @@ function formatReadyTail(tb) {
13282
13667
  function StatsLine({ stats: stats2 }) {
13283
13668
  const hit = (stats2.cacheHitRatio * 100).toFixed(1);
13284
13669
  const hitColor = stats2.cacheHitRatio >= 0.7 ? "#4ade80" : stats2.cacheHitRatio >= 0.4 ? "#fcd34d" : "#f87171";
13285
- return /* @__PURE__ */ React14.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: hitColor, bold: true }, `\u232C ${hit}%`), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React14.createElement(Text11, { color: "#94a3b8" }, "in ", /* @__PURE__ */ React14.createElement(Text11, { color: "#67e8f9", bold: true }, stats2.usage.promptTokens), " \u2192 out ", /* @__PURE__ */ React14.createElement(Text11, { color: "#c4b5fd", bold: true }, stats2.usage.completionTokens)), /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React14.createElement(Text11, { color: "#86efac", bold: true }, `$${stats2.cost.toFixed(6)}`));
13670
+ return /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text14, { color: hitColor, bold: true }, `\u232C ${hit}%`), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React17.createElement(Text14, { color: "#94a3b8" }, "in ", /* @__PURE__ */ React17.createElement(Text14, { color: "#67e8f9", bold: true }, stats2.usage.promptTokens), " \u2192 out ", /* @__PURE__ */ React17.createElement(Text14, { color: "#c4b5fd", bold: true }, stats2.usage.completionTokens)), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React17.createElement(Text14, { color: "#86efac", bold: true }, `$${stats2.cost.toFixed(6)}`));
13286
13671
  }
13287
13672
 
13288
13673
  // src/cli/ui/LiveRows.tsx
13289
- import { Box as Box13, Text as Text12, useStdout as useStdout6 } from "ink";
13290
- import React15 from "react";
13674
+ import { Box as Box15, Text as Text15, useStdout as useStdout8 } from "ink";
13675
+ import React18 from "react";
13291
13676
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
13292
13677
  function StatusRow({ text: text2 }) {
13293
13678
  const tick = useTick();
13294
13679
  const elapsed = useElapsedSeconds();
13295
- return /* @__PURE__ */ React15.createElement(Box13, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text12, { color: "#c4b5fd", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React15.createElement(Text12, null, " "), /* @__PURE__ */ React15.createElement(Text12, { color: "#c4b5fd" }, text2), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, ` \xB7 ${elapsed}s`));
13680
+ return /* @__PURE__ */ React18.createElement(Box15, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React18.createElement(Text15, { color: "#c4b5fd", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React18.createElement(Text15, null, " "), /* @__PURE__ */ React18.createElement(Text15, { color: "#c4b5fd" }, text2), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, ` \xB7 ${elapsed}s`));
13296
13681
  }
13297
13682
  function ModeStatusBar({
13298
13683
  editMode,
@@ -13304,27 +13689,27 @@ function ModeStatusBar({
13304
13689
  }) {
13305
13690
  useSlowTick();
13306
13691
  const running = jobs2?.runningCount() ?? 0;
13307
- const jobsTag = running > 0 ? /* @__PURE__ */ React15.createElement(Text12, { color: "yellow", bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
13692
+ const jobsTag = running > 0 ? /* @__PURE__ */ React18.createElement(Text15, { color: "yellow", bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
13308
13693
  if (planMode) {
13309
- return /* @__PURE__ */ React15.createElement(ModeBarFrame, null, /* @__PURE__ */ React15.createElement(ModePill, { label: "PLAN MODE", bg: "red", flash }), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, " writes gated \xB7 /plan off to leave"), jobsTag);
13694
+ return /* @__PURE__ */ React18.createElement(ModeBarFrame, null, /* @__PURE__ */ React18.createElement(ModePill, { label: "PLAN MODE", bg: "red", flash }), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, " writes gated \xB7 /plan off to leave"), jobsTag);
13310
13695
  }
13311
13696
  const label = editMode === "yolo" ? "YOLO" : editMode === "auto" ? "AUTO" : "REVIEW";
13312
13697
  const bg = editMode === "yolo" ? "red" : editMode === "auto" ? "magenta" : "cyan";
13313
13698
  const mid = editMode === "yolo" ? "edits + shell auto \xB7 /undo to roll back" : editMode === "auto" ? "edits land now \xB7 u to undo" : pendingCount > 0 ? `${pendingCount} queued \xB7 y apply \xB7 n discard` : "edits queued \xB7 y apply \xB7 n discard";
13314
- return /* @__PURE__ */ React15.createElement(ModeBarFrame, null, /* @__PURE__ */ React15.createElement(ModePill, { label, bg, flash }), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
13699
+ return /* @__PURE__ */ React18.createElement(ModeBarFrame, null, /* @__PURE__ */ React18.createElement(ModePill, { label, bg, flash }), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
13315
13700
  }
13316
13701
  function ModeBarFrame({ children }) {
13317
- const { stdout: stdout4 } = useStdout6();
13702
+ const { stdout: stdout4 } = useStdout8();
13318
13703
  const cols = stdout4?.columns ?? 80;
13319
13704
  const ruleWidth = Math.max(20, cols - 2);
13320
- return /* @__PURE__ */ React15.createElement(Box13, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Box13, { paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text12, { color: "#475569", dimColor: true }, "\u254C".repeat(ruleWidth))), /* @__PURE__ */ React15.createElement(Box13, { paddingX: 1 }, children));
13705
+ return /* @__PURE__ */ React18.createElement(Box15, { flexDirection: "column" }, /* @__PURE__ */ React18.createElement(Box15, { paddingX: 1 }, /* @__PURE__ */ React18.createElement(Text15, { color: "#475569", dimColor: true }, "\u254C".repeat(ruleWidth))), /* @__PURE__ */ React18.createElement(Box15, { paddingX: 1 }, children));
13321
13706
  }
13322
13707
  function ModePill({
13323
13708
  label,
13324
13709
  bg,
13325
13710
  flash
13326
13711
  }) {
13327
- return /* @__PURE__ */ React15.createElement(Text12, { color: bg, bold: true, inverse: flash }, `[${label}]`);
13712
+ return /* @__PURE__ */ React18.createElement(Text15, { color: bg, bold: true, inverse: flash }, `[${label}]`);
13328
13713
  }
13329
13714
  function UndoBanner({
13330
13715
  banner
@@ -13337,14 +13722,14 @@ function UndoBanner({
13337
13722
  const total = banner.results.length;
13338
13723
  const urgent = remainingSec <= 1;
13339
13724
  const pct2 = remainingMs / totalMs * 100;
13340
- return /* @__PURE__ */ React15.createElement(Box13, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text12, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, " press "), /* @__PURE__ */ React15.createElement(Text12, { backgroundColor: "#67e8f9", color: "black", bold: true }, " u "), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, " to undo "), /* @__PURE__ */ React15.createElement(CharBar, { pct: pct2, width: 20, color: urgent ? "#f87171" : "#c4b5fd", showLabel: false }), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, " "), /* @__PURE__ */ React15.createElement(Text12, { color: urgent ? "#f87171" : "#c4b5fd", bold: urgent }, `${remainingSec}s`));
13725
+ return /* @__PURE__ */ React18.createElement(Box15, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React18.createElement(Text15, { backgroundColor: "#c4b5fd", color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, " press "), /* @__PURE__ */ React18.createElement(Text15, { backgroundColor: "#67e8f9", color: "black", bold: true }, " u "), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, " to undo "), /* @__PURE__ */ React18.createElement(CharBar, { pct: pct2, width: 20, color: urgent ? "#f87171" : "#c4b5fd", showLabel: false }), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, " "), /* @__PURE__ */ React18.createElement(Text15, { color: urgent ? "#f87171" : "#c4b5fd", bold: urgent }, `${remainingSec}s`));
13341
13726
  }
13342
13727
  function SubagentRow({
13343
13728
  activity
13344
13729
  }) {
13345
13730
  const tick = useTick();
13346
13731
  const seconds = (activity.elapsedMs / 1e3).toFixed(1);
13347
- return /* @__PURE__ */ React15.createElement(Box13, { paddingLeft: 3 }, /* @__PURE__ */ React15.createElement(Text12, { color: "#c4b5fd", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React15.createElement(Text12, null, " "), /* @__PURE__ */ React15.createElement(Text12, { color: "#c4b5fd", bold: true }, "\u232C subagent"), /* @__PURE__ */ React15.createElement(Text12, { color: "#c4b5fd" }, ` ${activity.task}`), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, ` iter ${activity.iter} \xB7 ${seconds}s`));
13732
+ return /* @__PURE__ */ React18.createElement(Box15, { paddingLeft: 3 }, /* @__PURE__ */ React18.createElement(Text15, { color: "#c4b5fd", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React18.createElement(Text15, null, " "), /* @__PURE__ */ React18.createElement(Text15, { color: "#c4b5fd", bold: true }, "\u232C subagent"), /* @__PURE__ */ React18.createElement(Text15, { color: "#c4b5fd" }, ` ${activity.task}`), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, ` iter ${activity.iter} \xB7 ${seconds}s`));
13348
13733
  }
13349
13734
  function OngoingToolRow({
13350
13735
  tool: tool2,
@@ -13353,7 +13738,7 @@ function OngoingToolRow({
13353
13738
  const tick = useTick();
13354
13739
  const elapsed = useElapsedSeconds();
13355
13740
  const summary = summarizeToolArgs(tool2.name, tool2.args);
13356
- return /* @__PURE__ */ React15.createElement(Box13, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React15.createElement(Box13, null, /* @__PURE__ */ React15.createElement(Text12, { color: "#fcd34d", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React15.createElement(Text12, null, " "), /* @__PURE__ */ React15.createElement(Text12, { color: "#fcd34d", bold: true }, `\u25A3 ${tool2.name}`), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React15.createElement(Box13, { paddingLeft: 3 }, /* @__PURE__ */ React15.createElement(Text12, { color: "#67e8f9" }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React15.createElement(Box13, { paddingLeft: 3 }, /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, summary)) : null);
13741
+ return /* @__PURE__ */ React18.createElement(Box15, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text15, { color: "#fcd34d", bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React18.createElement(Text15, null, " "), /* @__PURE__ */ React18.createElement(Text15, { color: "#fcd34d", bold: true }, `\u25A3 ${tool2.name}`), /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React18.createElement(Box15, { paddingLeft: 3 }, /* @__PURE__ */ React18.createElement(Text15, { color: "#67e8f9" }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React18.createElement(Box15, { paddingLeft: 3 }, /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, summary)) : null);
13357
13742
  }
13358
13743
  function renderProgressLine(p) {
13359
13744
  const msg = p.message ? ` ${p.message}` : "";
@@ -13409,8 +13794,8 @@ function summarizeToolArgs(name, args) {
13409
13794
  }
13410
13795
 
13411
13796
  // src/cli/ui/PlanCheckpointConfirm.tsx
13412
- import { Box as Box14 } from "ink";
13413
- import React16 from "react";
13797
+ import { Box as Box16 } from "ink";
13798
+ import React19 from "react";
13414
13799
  function PlanCheckpointConfirmInner({
13415
13800
  stepId,
13416
13801
  title,
@@ -13425,7 +13810,7 @@ function PlanCheckpointConfirmInner({
13425
13810
  const isLast = total > 0 && completed >= total;
13426
13811
  const statuses = buildStatusMap(steps, completedStepIds, stepId, isLast);
13427
13812
  const subtitle = counter ? `${counter} \xB7 ${label}` : label;
13428
- return /* @__PURE__ */ React16.createElement(ModalCard, { accent: "#86efac", icon: "\u2713", title: "checkpoint \u2014 step done", subtitle }, steps && steps.length > 0 ? /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React16.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React16.createElement(
13813
+ return /* @__PURE__ */ React19.createElement(ModalCard, { accent: "#86efac", icon: "\u2713", title: "checkpoint \u2014 step done", subtitle }, steps && steps.length > 0 ? /* @__PURE__ */ React19.createElement(Box16, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React19.createElement(
13429
13814
  SingleSelect,
13430
13815
  {
13431
13816
  initialValue: isLast ? "stop" : "continue",
@@ -13452,7 +13837,7 @@ function PlanCheckpointConfirmInner({
13452
13837
  }
13453
13838
  ));
13454
13839
  }
13455
- var PlanCheckpointConfirm = React16.memo(PlanCheckpointConfirmInner);
13840
+ var PlanCheckpointConfirm = React19.memo(PlanCheckpointConfirmInner);
13456
13841
  function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
13457
13842
  const map = /* @__PURE__ */ new Map();
13458
13843
  if (!steps) return map;
@@ -13469,11 +13854,11 @@ function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
13469
13854
  }
13470
13855
 
13471
13856
  // src/cli/ui/PlanConfirm.tsx
13472
- import { Box as Box15, Text as Text13 } from "ink";
13473
- import React17 from "react";
13857
+ import { Box as Box17, Text as Text16 } from "ink";
13858
+ import React20 from "react";
13474
13859
  function PlanConfirmInner({ plan: plan2, steps, summary, onChoose }) {
13475
13860
  const hasOpenQuestions = /^#{1,6}\s*(open[-\s]?questions?|risks?|unknowns?|assumptions?|unclear)/im.test(plan2) || /^#{1,6}\s*(待确认|开放问题|风险|未知|假设|不确定)/im.test(plan2);
13476
- return /* @__PURE__ */ React17.createElement(
13861
+ return /* @__PURE__ */ React20.createElement(
13477
13862
  ModalCard,
13478
13863
  {
13479
13864
  accent: "#67e8f9",
@@ -13481,9 +13866,9 @@ function PlanConfirmInner({ plan: plan2, steps, summary, onChoose }) {
13481
13866
  title: "plan proposed",
13482
13867
  subtitle: summary ?? "approve / refine / cancel"
13483
13868
  },
13484
- hasOpenQuestions ? /* @__PURE__ */ React17.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Text13, { color: "#fbbf24" }, "\u25B2 the plan flags open questions or risks \u2014 pick", " ", /* @__PURE__ */ React17.createElement(Text13, { bold: true }, "Refine / answer questions"), " to write concrete answers before the model moves on.")) : null,
13485
- steps && steps.length > 0 ? /* @__PURE__ */ React17.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(PlanStepList, { steps })) : null,
13486
- /* @__PURE__ */ React17.createElement(
13869
+ hasOpenQuestions ? /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: "#fbbf24" }, "\u25B2 the plan flags open questions or risks \u2014 pick", " ", /* @__PURE__ */ React20.createElement(Text16, { bold: true }, "Refine / answer questions"), " to write concrete answers before the model moves on.")) : null,
13870
+ steps && steps.length > 0 ? /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React20.createElement(PlanStepList, { steps })) : null,
13871
+ /* @__PURE__ */ React20.createElement(
13487
13872
  SingleSelect,
13488
13873
  {
13489
13874
  initialValue: hasOpenQuestions ? "refine" : "approve",
@@ -13511,11 +13896,11 @@ function PlanConfirmInner({ plan: plan2, steps, summary, onChoose }) {
13511
13896
  )
13512
13897
  );
13513
13898
  }
13514
- var PlanConfirm = React17.memo(PlanConfirmInner);
13899
+ var PlanConfirm = React20.memo(PlanConfirmInner);
13515
13900
 
13516
13901
  // src/cli/ui/PlanRefineInput.tsx
13517
- import { Box as Box16, Text as Text14 } from "ink";
13518
- import React18, { useState as useState4 } from "react";
13902
+ import { Box as Box18, Text as Text17 } from "ink";
13903
+ import React21, { useState as useState4 } from "react";
13519
13904
  function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
13520
13905
  const [value, setValue] = useState4("");
13521
13906
  useKeystroke((ev) => {
@@ -13560,12 +13945,12 @@ function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
13560
13945
  };
13561
13946
  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.";
13562
13947
  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.)";
13563
- return /* @__PURE__ */ React18.createElement(ModalCard, { accent: meta.accent, icon: meta.icon, title: meta.title }, /* @__PURE__ */ React18.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text14, { dimColor: true }, hint, " Enter to send \xB7 Esc to return to the picker.", value === "" ? blankHint : "")), /* @__PURE__ */ React18.createElement(Box16, null, /* @__PURE__ */ React18.createElement(Text14, { color: meta.accent, bold: true }, "\u203A "), /* @__PURE__ */ React18.createElement(Text14, null, value), /* @__PURE__ */ React18.createElement(Text14, { color: meta.accent, bold: true }, cursorOn ? "\u258D" : " ")));
13948
+ return /* @__PURE__ */ React21.createElement(ModalCard, { accent: meta.accent, icon: meta.icon, title: meta.title }, /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, hint, " Enter to send \xB7 Esc to return to the picker.", value === "" ? blankHint : "")), /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text17, { color: meta.accent, bold: true }, "\u203A "), /* @__PURE__ */ React21.createElement(Text17, null, value), /* @__PURE__ */ React21.createElement(Text17, { color: meta.accent, bold: true }, cursorOn ? "\u258D" : " ")));
13564
13949
  }
13565
13950
 
13566
13951
  // src/cli/ui/PlanReviseConfirm.tsx
13567
- import { Box as Box17, Text as Text15 } from "ink";
13568
- import React19 from "react";
13952
+ import { Box as Box19, Text as Text18 } from "ink";
13953
+ import React22 from "react";
13569
13954
  function computeDiff(oldSteps, newSteps) {
13570
13955
  const oldIds = new Set(oldSteps.map((s) => s.id));
13571
13956
  const newIds = new Set(newSteps.map((s) => s.id));
@@ -13601,7 +13986,7 @@ function PlanReviseConfirmInner({
13601
13986
  const removedCount = rows.filter((r) => r.kind === "removed").length;
13602
13987
  const addedCount = rows.filter((r) => r.kind === "added").length;
13603
13988
  const keptCount = rows.filter((r) => r.kind === "kept").length;
13604
- return /* @__PURE__ */ React19.createElement(
13989
+ return /* @__PURE__ */ React22.createElement(
13605
13990
  ModalCard,
13606
13991
  {
13607
13992
  accent: "#fbbf24",
@@ -13609,17 +13994,17 @@ function PlanReviseConfirmInner({
13609
13994
  title: "plan revision proposed",
13610
13995
  subtitle: `\u2212${removedCount} +${addedCount} \xB7 ${keptCount} kept`
13611
13996
  },
13612
- /* @__PURE__ */ React19.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text15, null, reason)),
13613
- summary ? /* @__PURE__ */ React19.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, `updated summary: ${summary}`)) : null,
13614
- /* @__PURE__ */ React19.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, rows.map((row2) => {
13997
+ /* @__PURE__ */ React22.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, reason)),
13998
+ summary ? /* @__PURE__ */ React22.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, `updated summary: ${summary}`)) : null,
13999
+ /* @__PURE__ */ React22.createElement(Box19, { marginBottom: 1, flexDirection: "column" }, rows.map((row2) => {
13615
14000
  const risk = riskDots(row2.step.risk);
13616
14001
  const prefix = row2.kind === "removed" ? "\u2212" : row2.kind === "added" ? "+" : " ";
13617
14002
  const prefixColor = row2.kind === "removed" ? "#f87171" : row2.kind === "added" ? "#4ade80" : "#94a3b8";
13618
14003
  const dim = row2.kind === "kept";
13619
14004
  const strike = row2.kind === "removed";
13620
- return /* @__PURE__ */ React19.createElement(Box17, { key: `${row2.kind}-${row2.step.id}` }, /* @__PURE__ */ React19.createElement(Text15, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React19.createElement(Text15, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React19.createElement(Text15, { dimColor: dim, strikethrough: strike }, ` ${row2.step.id} \xB7 ${row2.step.title}`));
14005
+ return /* @__PURE__ */ React22.createElement(Box19, { key: `${row2.kind}-${row2.step.id}` }, /* @__PURE__ */ React22.createElement(Text18, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React22.createElement(Text18, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React22.createElement(Text18, { dimColor: dim, strikethrough: strike }, ` ${row2.step.id} \xB7 ${row2.step.title}`));
13621
14006
  })),
13622
- /* @__PURE__ */ React19.createElement(
14007
+ /* @__PURE__ */ React22.createElement(
13623
14008
  SingleSelect,
13624
14009
  {
13625
14010
  initialValue: "accept",
@@ -13642,11 +14027,11 @@ function PlanReviseConfirmInner({
13642
14027
  )
13643
14028
  );
13644
14029
  }
13645
- var PlanReviseConfirm = React19.memo(PlanReviseConfirmInner);
14030
+ var PlanReviseConfirm = React22.memo(PlanReviseConfirmInner);
13646
14031
 
13647
14032
  // src/cli/ui/PromptInput.tsx
13648
- import { Box as Box18, Text as Text16, useStdout as useStdout7 } from "ink";
13649
- import React20, { useRef as useRef2, useState as useState5 } from "react";
14033
+ import { Box as Box20, Text as Text19, useStdout as useStdout9 } from "ink";
14034
+ import React23, { useRef as useRef2, useState as useState5 } from "react";
13650
14035
 
13651
14036
  // src/cli/ui/key-normalize.ts
13652
14037
  var CSI_TAIL_TO_FLAGS = [
@@ -14118,7 +14503,7 @@ function PromptInput({
14118
14503
  if (action.historyHandoff === "prev") onHistoryPrev?.();
14119
14504
  if (action.historyHandoff === "next") onHistoryNext?.();
14120
14505
  }, !disabled);
14121
- const { stdout: stdout4 } = useStdout7();
14506
+ const { stdout: stdout4 } = useStdout9();
14122
14507
  const cols = stdout4?.columns ?? 80;
14123
14508
  const narrow = cols <= 90;
14124
14509
  const promptBody = narrow ? "\u203A " : "you \u203A ";
@@ -14135,11 +14520,11 @@ function PromptInput({
14135
14520
  const { line: cursorLine, col: cursorCol } = lineAndColumn(value, cursor);
14136
14521
  const renderItems = collapseLinesForDisplay(lines, cursorLine);
14137
14522
  const showHugeBufferHints = lines.length > 20;
14138
- return /* @__PURE__ */ React20.createElement(Box18, { flexDirection: "column", paddingX: 1 }, renderItems.map((item, renderIdx) => {
14523
+ return /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "column", paddingX: 1 }, renderItems.map((item, renderIdx) => {
14139
14524
  if (item.kind === "skip") {
14140
14525
  return (
14141
14526
  // biome-ignore lint/suspicious/noArrayIndexKey: stable — collapse markers derive from a fixed sliding window
14142
- /* @__PURE__ */ React20.createElement(Box18, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React20.createElement(Text16, { color: barColorAt(renderIdx) }, BAR), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
14527
+ /* @__PURE__ */ React23.createElement(Box20, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React23.createElement(Text19, { color: barColorAt(renderIdx) }, BAR), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
14143
14528
  );
14144
14529
  }
14145
14530
  const i = item.originalIndex;
@@ -14147,7 +14532,7 @@ function PromptInput({
14147
14532
  const isFirst = i === 0;
14148
14533
  const isCursorLine = i === cursorLine;
14149
14534
  const showPlaceholder = isFirst && value.length === 0;
14150
- return /* @__PURE__ */ React20.createElement(
14535
+ return /* @__PURE__ */ React23.createElement(
14151
14536
  PromptLine,
14152
14537
  {
14153
14538
  key: `ln-${i}`,
@@ -14167,7 +14552,7 @@ function PromptInput({
14167
14552
  disabled: disabled === true
14168
14553
  }
14169
14554
  );
14170
- }), showHugeBufferHints && !disabled ? /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React20.createElement(Text16, { 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__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, "[Ctrl+J] newline \xB7 [Enter] submit \xB7 ends with \\ for line continuation")) : null, !disabled && !narrow && value.length === 0 ? /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, "[PgUp/PgDn] scroll log \xB7 [End] jump to latest \xB7 drag to select & copy \xB7 /mouse on for wheel")) : null, disabled ? /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, "[Esc] to stop")) : null);
14555
+ }), showHugeBufferHints && !disabled ? /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React23.createElement(Text19, { 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__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, "[Ctrl+J] newline \xB7 [Enter] submit \xB7 ends with \\ for line continuation")) : null, !disabled && !narrow && value.length === 0 ? /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, "[PgUp/PgDn] scroll log \xB7 [End] jump to latest \xB7 drag to select & copy \xB7 /mouse on for wheel")) : null, disabled ? /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, { color: barColorAt(0) }, BAR), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, continuationIndent.slice(BAR.length)), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, "[Esc] to stop")) : null);
14171
14556
  }
14172
14557
  function PromptLine({
14173
14558
  line,
@@ -14189,10 +14574,10 @@ function PromptLine({
14189
14574
  const bodyPrefix = promptPrefix.slice(BAR.length);
14190
14575
  const bodyContinuation = continuationIndent.slice(BAR.length);
14191
14576
  if (showPlaceholder) {
14192
- return /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: barColor }, barText), /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: accentColor }, bodyPrefix), !disabled ? /* @__PURE__ */ React20.createElement(Text16, { color: accentColor }, cursorVisible ? "\u258C" : " ") : null, /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, placeholderText));
14577
+ return /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, { color: barColor }, barText), /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: accentColor }, bodyPrefix), !disabled ? /* @__PURE__ */ React23.createElement(Text19, { color: accentColor }, cursorVisible ? "\u258C" : " ") : null, /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, placeholderText));
14193
14578
  }
14194
14579
  const viewport2 = buildViewport(line, isCursorLine ? cursorCol : null, visibleCells, pastes);
14195
- return /* @__PURE__ */ React20.createElement(Box18, null, /* @__PURE__ */ React20.createElement(Text16, { color: barColor }, barText), isFirst ? /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: accentColor }, bodyPrefix) : /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, bodyContinuation), viewport2.hiddenLeft ? /* @__PURE__ */ React20.createElement(Text16, { color: "gray", dimColor: true }, "\u2039") : null, /* @__PURE__ */ React20.createElement(
14580
+ return /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, { color: barColor }, barText), isFirst ? /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: accentColor }, bodyPrefix) : /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, bodyContinuation), viewport2.hiddenLeft ? /* @__PURE__ */ React23.createElement(Text19, { color: "gray", dimColor: true }, "\u2039") : null, /* @__PURE__ */ React23.createElement(
14196
14581
  ViewportContent,
14197
14582
  {
14198
14583
  segments: viewport2.segments,
@@ -14200,7 +14585,7 @@ function PromptLine({
14200
14585
  accentColor,
14201
14586
  cursorVisible
14202
14587
  }
14203
- ), viewport2.hiddenRight ? /* @__PURE__ */ React20.createElement(Text16, { color: "gray", dimColor: true }, "\u203A") : null);
14588
+ ), viewport2.hiddenRight ? /* @__PURE__ */ React23.createElement(Text19, { color: "gray", dimColor: true }, "\u203A") : null);
14204
14589
  }
14205
14590
  function ViewportContent({
14206
14591
  segments,
@@ -14209,7 +14594,7 @@ function ViewportContent({
14209
14594
  cursorVisible
14210
14595
  }) {
14211
14596
  if (cursorCell === null) {
14212
- return /* @__PURE__ */ React20.createElement(React20.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
14597
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
14213
14598
  }
14214
14599
  const out = [];
14215
14600
  let cells = 0;
@@ -14228,7 +14613,7 @@ function ViewportContent({
14228
14613
  }
14229
14614
  if (seg.kind === "paste") {
14230
14615
  out.push(
14231
- /* @__PURE__ */ React20.createElement(Text16, { key: `p-${i}-cursor`, color: "magenta", bold: true, inverse: cursorVisible }, seg.label)
14616
+ /* @__PURE__ */ React23.createElement(Text19, { key: `p-${i}-cursor`, color: "magenta", bold: true, inverse: cursorVisible }, seg.label)
14232
14617
  );
14233
14618
  placed = true;
14234
14619
  cells += segCells;
@@ -14237,29 +14622,29 @@ function ViewportContent({
14237
14622
  const offsetIntoSeg = cursorCell - cells;
14238
14623
  const split = splitTextByCells(seg.text, offsetIntoSeg);
14239
14624
  if (split.before.length > 0) {
14240
- out.push(/* @__PURE__ */ React20.createElement(Text16, { key: `t-${i}-b` }, split.before));
14625
+ out.push(/* @__PURE__ */ React23.createElement(Text19, { key: `t-${i}-b` }, split.before));
14241
14626
  }
14242
14627
  if (split.atCursor.length > 0) {
14243
14628
  out.push(
14244
- /* @__PURE__ */ React20.createElement(Text16, { key: `t-${i}-c`, inverse: cursorVisible, color: accentColor }, split.atCursor)
14629
+ /* @__PURE__ */ React23.createElement(Text19, { key: `t-${i}-c`, inverse: cursorVisible, color: accentColor }, split.atCursor)
14245
14630
  );
14246
14631
  } else {
14247
14632
  out.push(
14248
- /* @__PURE__ */ React20.createElement(Text16, { key: `t-${i}-c-eol`, color: accentColor }, cursorVisible ? "\u258C" : " ")
14633
+ /* @__PURE__ */ React23.createElement(Text19, { key: `t-${i}-c-eol`, color: accentColor }, cursorVisible ? "\u258C" : " ")
14249
14634
  );
14250
14635
  }
14251
14636
  if (split.after.length > 0) {
14252
- out.push(/* @__PURE__ */ React20.createElement(Text16, { key: `t-${i}-a` }, split.after));
14637
+ out.push(/* @__PURE__ */ React23.createElement(Text19, { key: `t-${i}-a` }, split.after));
14253
14638
  }
14254
14639
  placed = true;
14255
14640
  cells += segCells;
14256
14641
  }
14257
14642
  if (!placed) {
14258
14643
  out.push(
14259
- /* @__PURE__ */ React20.createElement(Text16, { key: "cursor-eol", color: accentColor }, cursorVisible ? "\u258C" : " ")
14644
+ /* @__PURE__ */ React23.createElement(Text19, { key: "cursor-eol", color: accentColor }, cursorVisible ? "\u258C" : " ")
14260
14645
  );
14261
14646
  }
14262
- return /* @__PURE__ */ React20.createElement(React20.Fragment, null, out);
14647
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, out);
14263
14648
  }
14264
14649
  function segmentCells(seg) {
14265
14650
  if (seg.kind === "paste") return seg.label.length;
@@ -14299,9 +14684,9 @@ function charCellsForText(ch) {
14299
14684
  }
14300
14685
  function renderSegment(seg, key, _inverse) {
14301
14686
  if (seg.kind === "text") {
14302
- return /* @__PURE__ */ React20.createElement(Text16, { key: `s-${key}` }, seg.text);
14687
+ return /* @__PURE__ */ React23.createElement(Text19, { key: `s-${key}` }, seg.text);
14303
14688
  }
14304
- return /* @__PURE__ */ React20.createElement(Text16, { key: `s-${key}`, backgroundColor: "#f0abfc", color: "black", bold: true }, seg.label);
14689
+ return /* @__PURE__ */ React23.createElement(Text19, { key: `s-${key}`, backgroundColor: "#f0abfc", color: "black", bold: true }, seg.label);
14305
14690
  }
14306
14691
  var COLLAPSE_THRESHOLD = 20;
14307
14692
  var COLLAPSE_HEAD_LINES = 3;
@@ -14328,12 +14713,12 @@ function collapseLinesForDisplay(lines, cursorLine) {
14328
14713
  }
14329
14714
 
14330
14715
  // src/cli/ui/ShellConfirm.tsx
14331
- import { Box as Box19, Text as Text17 } from "ink";
14332
- import React21 from "react";
14716
+ import { Box as Box21, Text as Text20 } from "ink";
14717
+ import React24 from "react";
14333
14718
  function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
14334
14719
  const isBackground = kind === "run_background";
14335
14720
  const subtitle = isBackground ? "long-running process \u2014 keeps running after approval, /kill to stop" : "model wants to run a shell command";
14336
- return /* @__PURE__ */ React21.createElement(
14721
+ return /* @__PURE__ */ React24.createElement(
14337
14722
  ModalCard,
14338
14723
  {
14339
14724
  accent: COLOR.err,
@@ -14341,8 +14726,8 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
14341
14726
  title: isBackground ? "background process" : "shell command",
14342
14727
  subtitle
14343
14728
  },
14344
- /* @__PURE__ */ React21.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.primary, bold: true }, "$ "), /* @__PURE__ */ React21.createElement(Text17, { bold: true }, command)),
14345
- /* @__PURE__ */ React21.createElement(
14729
+ /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text20, { color: COLOR.primary, bold: true }, "$ "), /* @__PURE__ */ React24.createElement(Text20, { bold: true }, command)),
14730
+ /* @__PURE__ */ React24.createElement(
14346
14731
  SingleSelect,
14347
14732
  {
14348
14733
  initialValue: "run_once",
@@ -14400,8 +14785,8 @@ function derivePrefix(command) {
14400
14785
  }
14401
14786
 
14402
14787
  // src/cli/ui/SlashArgPicker.tsx
14403
- import { Box as Box20, Text as Text18 } from "ink";
14404
- import React22 from "react";
14788
+ import { Box as Box22, Text as Text21 } from "ink";
14789
+ import React25 from "react";
14405
14790
  function SlashArgPicker({
14406
14791
  matches,
14407
14792
  selectedIndex,
@@ -14409,13 +14794,13 @@ function SlashArgPicker({
14409
14794
  kind,
14410
14795
  partial
14411
14796
  }) {
14412
- const headerRow = /* @__PURE__ */ React22.createElement(Box20, null, /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.accent, bold: true }, `/${spec.cmd}`), spec.argsHint ? /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` ${spec.argsHint}`) : null, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` ${spec.summary}`));
14797
+ const headerRow = /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(Text21, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React25.createElement(Text21, { color: COLOR.accent, bold: true }, `/${spec.cmd}`), spec.argsHint ? /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, ` ${spec.argsHint}`) : null, /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, ` ${spec.summary}`));
14413
14798
  if (kind === "hint") {
14414
- return /* @__PURE__ */ React22.createElement(Box20, { paddingX: 1, marginTop: 1 }, headerRow);
14799
+ return /* @__PURE__ */ React25.createElement(Box22, { paddingX: 1, marginTop: 1 }, headerRow);
14415
14800
  }
14416
14801
  if (matches === null) return null;
14417
14802
  if (matches.length === 0) {
14418
- return /* @__PURE__ */ React22.createElement(Box20, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, /* @__PURE__ */ React22.createElement(Box20, null, /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.warn }, ` no match for "${partial}"`), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " \u2014 keep typing, or Backspace to edit")));
14803
+ return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(Text21, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React25.createElement(Text21, { color: COLOR.warn }, ` no match for "${partial}"`), /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, " \u2014 keep typing, or Backspace to edit")));
14419
14804
  }
14420
14805
  const MAX = 8;
14421
14806
  const total = matches.length;
@@ -14423,22 +14808,22 @@ function SlashArgPicker({
14423
14808
  const shown = matches.slice(windowStart, windowStart + MAX);
14424
14809
  const hiddenAbove = windowStart;
14425
14810
  const hiddenBelow = total - windowStart - shown.length;
14426
- return /* @__PURE__ */ React22.createElement(Box20, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, hiddenAbove > 0 ? /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null, shown.map((value, i) => /* @__PURE__ */ React22.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React22.createElement(Box20, { marginTop: 0 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14811
+ return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, hiddenAbove > 0 ? /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null, shown.map((value, i) => /* @__PURE__ */ React25.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React25.createElement(Box22, { marginTop: 0 }, /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14427
14812
  }
14428
14813
  function ArgRow({ value, isSelected }) {
14429
- return /* @__PURE__ */ React22.createElement(Box20, null, /* @__PURE__ */ React22.createElement(Text18, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React22.createElement(Text18, { color: isSelected ? COLOR.user : COLOR.info, bold: isSelected, dimColor: !isSelected }, value));
14814
+ return /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(Text21, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React25.createElement(Text21, { color: isSelected ? COLOR.user : COLOR.info, bold: isSelected, dimColor: !isSelected }, value));
14430
14815
  }
14431
14816
 
14432
14817
  // src/cli/ui/SlashSuggestions.tsx
14433
- import { Box as Box21, Text as Text19 } from "ink";
14434
- import React23 from "react";
14818
+ import { Box as Box23, Text as Text22 } from "ink";
14819
+ import React26 from "react";
14435
14820
  function SlashSuggestions({
14436
14821
  matches,
14437
14822
  selectedIndex
14438
14823
  }) {
14439
14824
  if (matches === null) return null;
14440
14825
  if (matches.length === 0) {
14441
- return /* @__PURE__ */ React23.createElement(Box21, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React23.createElement(Text19, null, " "), /* @__PURE__ */ React23.createElement(Text19, { color: COLOR.warn }, "no slash command matches that prefix"), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
14826
+ return /* @__PURE__ */ React26.createElement(Box23, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React26.createElement(Text22, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React26.createElement(Text22, null, " "), /* @__PURE__ */ React26.createElement(Text22, { color: COLOR.warn }, "no slash command matches that prefix"), /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
14442
14827
  }
14443
14828
  const MAX = 8;
14444
14829
  const total = matches.length;
@@ -14446,17 +14831,17 @@ function SlashSuggestions({
14446
14831
  const shown = matches.slice(windowStart, windowStart + MAX);
14447
14832
  const hiddenAbove = windowStart;
14448
14833
  const hiddenBelow = total - windowStart - shown.length;
14449
- return /* @__PURE__ */ React23.createElement(Box21, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React23.createElement(Box21, null, /* @__PURE__ */ React23.createElement(Text19, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, `${total} command${total === 1 ? "" : "s"}`), hiddenAbove > 0 ? /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null), shown.map((spec, i) => /* @__PURE__ */ React23.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React23.createElement(Box21, { marginTop: 0 }, /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14834
+ return /* @__PURE__ */ React26.createElement(Box23, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React26.createElement(Box23, null, /* @__PURE__ */ React26.createElement(Text22, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, `${total} command${total === 1 ? "" : "s"}`), hiddenAbove > 0 ? /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null), shown.map((spec, i) => /* @__PURE__ */ React26.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React26.createElement(Box23, { marginTop: 0 }, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14450
14835
  }
14451
14836
  function SuggestionRow({ spec, isSelected }) {
14452
14837
  const name = `/${spec.cmd}`;
14453
14838
  const argsSuffix = spec.argsHint ? spec.argsHint : "";
14454
- return /* @__PURE__ */ React23.createElement(Box21, null, /* @__PURE__ */ React23.createElement(Text19, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React23.createElement(Text19, { color: COLOR.accent, bold: isSelected }, name.padEnd(14)), /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, argsSuffix.padEnd(14)), /* @__PURE__ */ React23.createElement(Text19, null, " "), /* @__PURE__ */ React23.createElement(Text19, { color: isSelected ? COLOR.user : COLOR.info, dimColor: !isSelected }, spec.summary));
14839
+ return /* @__PURE__ */ React26.createElement(Box23, null, /* @__PURE__ */ React26.createElement(Text22, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React26.createElement(Text22, { color: COLOR.accent, bold: isSelected }, name.padEnd(14)), /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, argsSuffix.padEnd(14)), /* @__PURE__ */ React26.createElement(Text22, null, " "), /* @__PURE__ */ React26.createElement(Text22, { color: isSelected ? COLOR.user : COLOR.info, dimColor: !isSelected }, spec.summary));
14455
14840
  }
14456
14841
 
14457
14842
  // src/cli/ui/WelcomeBanner.tsx
14458
- import { Box as Box22, Text as Text20, useStdout as useStdout8 } from "ink";
14459
- import React24 from "react";
14843
+ import { Box as Box24, Text as Text23, useStdout as useStdout10 } from "ink";
14844
+ import React27 from "react";
14460
14845
  var WORDMARK = "REASONIX";
14461
14846
  var TAGLINE_CHAT = "DeepSeek-native agent \xB7 cache-first \xB7 flash-first";
14462
14847
  var TAGLINE_CODE = "DeepSeek-native coding agent \xB7 cache-first \xB7 flash-first";
@@ -14478,7 +14863,7 @@ function WelcomeBanner({
14478
14863
  inCodeMode,
14479
14864
  dashboardUrl
14480
14865
  }) {
14481
- const { stdout: stdout4 } = useStdout8();
14866
+ const { stdout: stdout4 } = useStdout10();
14482
14867
  const cols = stdout4?.columns ?? 80;
14483
14868
  const wordmarkText = `\u25C8 ${WORDMARK.split("").join(" ")}`;
14484
14869
  const wordmarkWidth = wordmarkText.length;
@@ -14489,16 +14874,16 @@ function WelcomeBanner({
14489
14874
  const cardsIndent = Math.max(2, Math.floor((cols - 60) / 2));
14490
14875
  const tipText = "tip \xB7 ctrl+j newline \xB7 trailing \\ also continues";
14491
14876
  const tipPad = Math.max(0, Math.floor((cols - tipText.length) / 2));
14492
- return /* @__PURE__ */ React24.createElement(Box22, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React24.createElement(Box22, null, /* @__PURE__ */ React24.createElement(Text20, null, " ".repeat(wordmarkPad)), /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: GRADIENT[0] }, "\u25C8 "), WORDMARK.split("").map((letter, i) => (
14877
+ return /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React27.createElement(Box24, null, /* @__PURE__ */ React27.createElement(Text23, null, " ".repeat(wordmarkPad)), /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: GRADIENT[0] }, "\u25C8 "), WORDMARK.split("").map((letter, i) => (
14493
14878
  // Wordmark is fixed-string ("REASONIX") — letters are unique
14494
14879
  // and the array never reorders, so per-letter key is stable.
14495
- /* @__PURE__ */ React24.createElement(React24.Fragment, { key: letter }, /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: GRADIENT[i % GRADIENT.length] }, letter), i < WORDMARK.length - 1 ? /* @__PURE__ */ React24.createElement(Text20, null, " ") : null)
14496
- ))), /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text20, null, " ".repeat(taglinePad)), /* @__PURE__ */ React24.createElement(Text20, { color: COLOR.info }, tagline)), /* @__PURE__ */ React24.createElement(Box22, { flexDirection: "column", marginTop: 2 }, cards.map((card) => /* @__PURE__ */ React24.createElement(Box22, { key: card.cmd }, /* @__PURE__ */ React24.createElement(Text20, null, " ".repeat(cardsIndent)), /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: COLOR.accent }, card.cmd.padEnd(14)), /* @__PURE__ */ React24.createElement(Text20, { color: COLOR.info }, card.desc)))), dashboardUrl ? /* @__PURE__ */ React24.createElement(Box22, { marginTop: 2 }, /* @__PURE__ */ React24.createElement(Text20, null, " ".repeat(Math.max(0, Math.floor((cols - (dashboardUrl.length + 9)) / 2)))), /* @__PURE__ */ React24.createElement(Text20, { color: COLOR.brand, bold: true }, "\u25B8 web \xB7 "), /* @__PURE__ */ React24.createElement(Text20, { color: COLOR.accent }, dashboardUrl)) : null, /* @__PURE__ */ React24.createElement(Box22, { marginTop: dashboardUrl ? 1 : 2 }, /* @__PURE__ */ React24.createElement(Text20, null, " ".repeat(tipPad)), /* @__PURE__ */ React24.createElement(Text20, { dimColor: true }, tipText)));
14880
+ /* @__PURE__ */ React27.createElement(React27.Fragment, { key: letter }, /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: GRADIENT[i % GRADIENT.length] }, letter), i < WORDMARK.length - 1 ? /* @__PURE__ */ React27.createElement(Text23, null, " ") : null)
14881
+ ))), /* @__PURE__ */ React27.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text23, null, " ".repeat(taglinePad)), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.info }, tagline)), /* @__PURE__ */ React27.createElement(Box24, { flexDirection: "column", marginTop: 2 }, cards.map((card) => /* @__PURE__ */ React27.createElement(Box24, { key: card.cmd }, /* @__PURE__ */ React27.createElement(Text23, null, " ".repeat(cardsIndent)), /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: COLOR.accent }, card.cmd.padEnd(14)), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.info }, card.desc)))), dashboardUrl ? /* @__PURE__ */ React27.createElement(Box24, { marginTop: 2 }, /* @__PURE__ */ React27.createElement(Text23, null, " ".repeat(Math.max(0, Math.floor((cols - (dashboardUrl.length + 9)) / 2)))), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.brand, bold: true }, "\u25B8 web \xB7 "), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.accent }, dashboardUrl)) : null, /* @__PURE__ */ React27.createElement(Box24, { marginTop: dashboardUrl ? 1 : 2 }, /* @__PURE__ */ React27.createElement(Text23, null, " ".repeat(tipPad)), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, tipText)));
14497
14882
  }
14498
14883
 
14499
14884
  // src/cli/ui/WorkspaceConfirm.tsx
14500
- import { Box as Box23, Text as Text21 } from "ink";
14501
- import React25 from "react";
14885
+ import { Box as Box25, Text as Text24 } from "ink";
14886
+ import React28 from "react";
14502
14887
  function WorkspaceConfirm({
14503
14888
  path: path5,
14504
14889
  currentRoot,
@@ -14506,7 +14891,7 @@ function WorkspaceConfirm({
14506
14891
  onChoose
14507
14892
  }) {
14508
14893
  const subtitle = mcpServerCount > 0 ? `MCP servers (${mcpServerCount}) stay anchored to the original launch root.` : "Re-registers filesystem / shell / memory tools at the new path.";
14509
- return /* @__PURE__ */ React25.createElement(ModalCard, { accent: COLOR.warn, icon: "\u21C4", title: "switch workspace", subtitle }, /* @__PURE__ */ React25.createElement(Box23, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Box23, null, /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, "from "), /* @__PURE__ */ React25.createElement(Text21, { color: COLOR.info }, currentRoot)), /* @__PURE__ */ React25.createElement(Box23, null, /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, "to "), /* @__PURE__ */ React25.createElement(Text21, { color: COLOR.primary, bold: true }, path5))), /* @__PURE__ */ React25.createElement(
14894
+ return /* @__PURE__ */ React28.createElement(ModalCard, { accent: COLOR.warn, icon: "\u21C4", title: "switch workspace", subtitle }, /* @__PURE__ */ React28.createElement(Box25, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Box25, null, /* @__PURE__ */ React28.createElement(Text24, { dimColor: true }, "from "), /* @__PURE__ */ React28.createElement(Text24, { color: COLOR.info }, currentRoot)), /* @__PURE__ */ React28.createElement(Box25, null, /* @__PURE__ */ React28.createElement(Text24, { dimColor: true }, "to "), /* @__PURE__ */ React28.createElement(Text24, { color: COLOR.primary, bold: true }, path5))), /* @__PURE__ */ React28.createElement(
14510
14895
  SingleSelect,
14511
14896
  {
14512
14897
  initialValue: "switch",
@@ -14697,302 +15082,45 @@ function detectHashMemory(text2) {
14697
15082
  if (!body2) return null;
14698
15083
  return { kind: "memory-global", note: body2 };
14699
15084
  }
14700
- const body = text2.slice(1).trim();
14701
- if (!body) return null;
14702
- return { kind: "memory", note: body };
14703
- }
14704
- function appendProjectMemory(rootDir, note) {
14705
- return appendBulletToFile(join17(rootDir, PROJECT_MEMORY_FILE), note, PROJECT_HEADER);
14706
- }
14707
- var GLOBAL_MEMORY_DIR = ".reasonix";
14708
- var GLOBAL_MEMORY_FILE = "REASONIX.md";
14709
- function globalMemoryPath(homeDir = homedir9()) {
14710
- return join17(homeDir, GLOBAL_MEMORY_DIR, GLOBAL_MEMORY_FILE);
14711
- }
14712
- function appendGlobalMemory(note, homeDir) {
14713
- return appendBulletToFile(globalMemoryPath(homeDir), note, GLOBAL_HEADER);
14714
- }
14715
- function appendBulletToFile(path5, note, newFileHeader) {
14716
- const trimmed = note.trim();
14717
- if (!trimmed) throw new Error("note body cannot be empty");
14718
- const bullet = `- ${trimmed}
14719
- `;
14720
- if (!existsSync18(path5)) {
14721
- mkdirSync12(dirname15(path5), { recursive: true });
14722
- writeFileSync12(path5, `${newFileHeader}${bullet}`, "utf8");
14723
- return { path: path5, created: true };
14724
- }
14725
- let prefix = "";
14726
- try {
14727
- const existing = readFileSync20(path5, "utf8");
14728
- if (existing.length > 0 && !existing.endsWith("\n")) prefix = "\n";
14729
- } catch {
14730
- }
14731
- appendFileSync3(path5, `${prefix}${bullet}`, "utf8");
14732
- return { path: path5, created: false };
14733
- }
14734
-
14735
- // src/cli/ui/log-frame.tsx
14736
- import { Box as Box24, Text as Text22 } from "ink";
14737
- import React26 from "react";
14738
-
14739
- // src/frame/width.ts
14740
- import stringWidthLib from "string-width";
14741
- var segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
14742
- function graphemes(s) {
14743
- return Array.from(segmenter.segment(s), (seg) => seg.segment);
14744
- }
14745
- function graphemeWidth(g) {
14746
- if (g.length === 0) return 0;
14747
- const w = stringWidthLib(g);
14748
- if (w <= 0) return 0;
14749
- if (w >= 2) return 2;
14750
- return 1;
14751
- }
14752
-
14753
- // src/frame/frame.ts
14754
- var SPACE = { char: " ", width: 1 };
14755
- var TAIL = { char: "", width: 1, tail: true };
14756
- function empty(width = 0) {
14757
- return { width, rows: [] };
14758
- }
14759
- function text(s, opts) {
14760
- const { width, fg, bg, bold, dim, italic, underline, inverse, href } = opts;
14761
- if (width <= 0) return empty(0);
14762
- const styleOf = (g, w) => {
14763
- const base = { char: g, width: w };
14764
- if (fg !== void 0) base.fg = fg;
14765
- if (bg !== void 0) base.bg = bg;
14766
- if (bold) base.bold = true;
14767
- if (dim) base.dim = true;
14768
- if (italic) base.italic = true;
14769
- if (underline) base.underline = true;
14770
- if (inverse) base.inverse = true;
14771
- if (href !== void 0) base.href = href;
14772
- return base;
14773
- };
14774
- const rows = [];
14775
- const lines = s.split("\n");
14776
- for (const line of lines) {
14777
- if (line.length === 0) {
14778
- rows.push(padRowRight([], width));
14779
- continue;
14780
- }
14781
- let buf = [];
14782
- let bufWidth = 0;
14783
- for (const g of graphemes(line)) {
14784
- const w = graphemeWidth(g);
14785
- if (w === 0) continue;
14786
- if (bufWidth + w > width) {
14787
- rows.push(padRowRight(buf, width - bufWidth));
14788
- buf = [];
14789
- bufWidth = 0;
14790
- }
14791
- buf.push(styleOf(g, w));
14792
- if (w === 2) buf.push(TAIL);
14793
- bufWidth += w;
14794
- }
14795
- rows.push(padRowRight(buf, width - bufWidth));
14796
- }
14797
- return { width, rows };
14798
- }
14799
- function padRowRight(cells, extraSpaces) {
14800
- if (extraSpaces <= 0) return cells.slice();
14801
- const out = cells.slice();
14802
- for (let i = 0; i < extraSpaces; i++) out.push(SPACE);
14803
- return out;
14804
- }
14805
- function spacerRow(width) {
14806
- if (width <= 0) return [];
14807
- return Array.from({ length: width }, () => SPACE);
14808
- }
14809
- function vstack(...frames) {
14810
- if (frames.length === 0) return empty(0);
14811
- const w = Math.max(...frames.map((f) => f.width));
14812
- const rows = [];
14813
- for (const f of frames) {
14814
- if (f.width === w) {
14815
- rows.push(...f.rows);
14816
- } else {
14817
- const extra = w - f.width;
14818
- for (const r of f.rows) rows.push(padRowRight(r, extra));
14819
- }
14820
- }
14821
- return { width: w, rows };
14822
- }
14823
- function hstack(...frames) {
14824
- if (frames.length === 0) return empty(0);
14825
- const h = Math.max(...frames.map((f) => f.rows.length));
14826
- const w = frames.reduce((a, f) => a + f.width, 0);
14827
- const rows = [];
14828
- for (let i = 0; i < h; i++) {
14829
- const cells = [];
14830
- for (const f of frames) {
14831
- const r = f.rows[i] ?? spacerRow(f.width);
14832
- cells.push(...r);
14833
- }
14834
- rows.push(cells);
14835
- }
14836
- return { width: w, rows };
14837
- }
14838
- function pad(f, top, right, bottom2, left) {
14839
- const newWidth = f.width + Math.max(0, left) + Math.max(0, right);
14840
- const tPad = Math.max(0, top);
14841
- const bPad = Math.max(0, bottom2);
14842
- const blank2 = spacerRow(newWidth);
14843
- const rows = [];
14844
- for (let i = 0; i < tPad; i++) rows.push(blank2);
14845
- if (left <= 0 && right <= 0) {
14846
- rows.push(...f.rows);
14847
- } else {
14848
- const lPad = spacerRow(Math.max(0, left));
14849
- const rPad = spacerRow(Math.max(0, right));
14850
- for (const r of f.rows) rows.push([...lPad, ...r, ...rPad]);
14851
- }
14852
- for (let i = 0; i < bPad; i++) rows.push(blank2);
14853
- return { width: newWidth, rows };
14854
- }
14855
- function borderLeft(f, color2, char = "\u2502") {
14856
- const bar = { char, width: 1, fg: color2 };
14857
- const newWidth = f.width + 1;
14858
- const rows = [];
14859
- for (const r of f.rows) rows.push([bar, ...r]);
14860
- return { width: newWidth, rows };
14861
- }
14862
-
14863
- // src/frame/ansi.ts
14864
- var ESC = "\x1B";
14865
- var RESET = `${ESC}[0m`;
14866
- function sameStyle(a, b) {
14867
- return a.fg === b.fg && a.bg === b.bg && !!a.bold === !!b.bold && !!a.dim === !!b.dim && !!a.italic === !!b.italic && !!a.underline === !!b.underline && !!a.inverse === !!b.inverse && a.href === b.href;
14868
- }
14869
- function fgEscape(color2) {
14870
- if (!color2) return null;
14871
- const rgb = parseColor(color2);
14872
- if (rgb) return `38;2;${rgb[0]};${rgb[1]};${rgb[2]}`;
14873
- const named = NAMED_FG[color2.toLowerCase()];
14874
- if (named !== void 0) return String(named);
14875
- return null;
14876
- }
14877
- function bgEscape(color2) {
14878
- if (!color2) return null;
14879
- const rgb = parseColor(color2);
14880
- if (rgb) return `48;2;${rgb[0]};${rgb[1]};${rgb[2]}`;
14881
- const named = NAMED_BG[color2.toLowerCase()];
14882
- if (named !== void 0) return String(named);
14883
- return null;
15085
+ const body = text2.slice(1).trim();
15086
+ if (!body) return null;
15087
+ return { kind: "memory", note: body };
14884
15088
  }
14885
- function parseColor(s) {
14886
- if (!s.startsWith("#")) return null;
14887
- const hex = s.slice(1);
14888
- if (hex.length !== 6) return null;
14889
- const r = Number.parseInt(hex.slice(0, 2), 16);
14890
- const g = Number.parseInt(hex.slice(2, 4), 16);
14891
- const b = Number.parseInt(hex.slice(4, 6), 16);
14892
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
14893
- return [r, g, b];
15089
+ function appendProjectMemory(rootDir, note) {
15090
+ return appendBulletToFile(join17(rootDir, PROJECT_MEMORY_FILE), note, PROJECT_HEADER);
14894
15091
  }
14895
- var NAMED_FG = {
14896
- black: 30,
14897
- red: 31,
14898
- green: 32,
14899
- yellow: 33,
14900
- blue: 34,
14901
- magenta: 35,
14902
- cyan: 36,
14903
- white: 37,
14904
- gray: 90,
14905
- grey: 90,
14906
- brightred: 91,
14907
- brightgreen: 92,
14908
- brightyellow: 93,
14909
- brightblue: 94,
14910
- brightmagenta: 95,
14911
- brightcyan: 96,
14912
- brightwhite: 97
14913
- };
14914
- var NAMED_BG = {
14915
- black: 40,
14916
- red: 41,
14917
- green: 42,
14918
- yellow: 43,
14919
- blue: 44,
14920
- magenta: 45,
14921
- cyan: 46,
14922
- white: 47,
14923
- gray: 100,
14924
- grey: 100
14925
- };
14926
- function styleToAnsi(s) {
14927
- const codes = [];
14928
- if (s.bold) codes.push("1");
14929
- if (s.dim) codes.push("2");
14930
- if (s.italic) codes.push("3");
14931
- if (s.underline) codes.push("4");
14932
- if (s.inverse) codes.push("7");
14933
- const fg = fgEscape(s.fg);
14934
- if (fg) codes.push(fg);
14935
- const bg = bgEscape(s.bg);
14936
- if (bg) codes.push(bg);
14937
- if (codes.length === 0) return "";
14938
- return `${ESC}[${codes.join(";")}m`;
15092
+ var GLOBAL_MEMORY_DIR = ".reasonix";
15093
+ var GLOBAL_MEMORY_FILE = "REASONIX.md";
15094
+ function globalMemoryPath(homeDir = homedir9()) {
15095
+ return join17(homeDir, GLOBAL_MEMORY_DIR, GLOBAL_MEMORY_FILE);
14939
15096
  }
14940
- var EMPTY_STYLE = {};
14941
- function frameToAnsi(f, opts = {}) {
14942
- const out = [];
14943
- for (let i = 0; i < f.rows.length; i++) {
14944
- out.push(rowToAnsi(f.rows[i], opts));
14945
- }
14946
- return out.join("\n");
15097
+ function appendGlobalMemory(note, homeDir) {
15098
+ return appendBulletToFile(globalMemoryPath(homeDir), note, GLOBAL_HEADER);
14947
15099
  }
14948
- function rowToAnsi(row2, opts) {
14949
- if (opts.plain) {
14950
- let s = "";
14951
- for (const c of row2) {
14952
- if (c.tail) continue;
14953
- s += c.char;
14954
- }
14955
- return s;
15100
+ function appendBulletToFile(path5, note, newFileHeader) {
15101
+ const trimmed = note.trim();
15102
+ if (!trimmed) throw new Error("note body cannot be empty");
15103
+ const bullet = `- ${trimmed}
15104
+ `;
15105
+ if (!existsSync18(path5)) {
15106
+ mkdirSync12(dirname15(path5), { recursive: true });
15107
+ writeFileSync12(path5, `${newFileHeader}${bullet}`, "utf8");
15108
+ return { path: path5, created: true };
14956
15109
  }
14957
- let result = "";
14958
- let curStyle = EMPTY_STYLE;
14959
- let inHref = false;
14960
- let curHref;
14961
- for (const c of row2) {
14962
- if (c.tail) continue;
14963
- const cellStyle = {
14964
- fg: c.fg,
14965
- bg: c.bg,
14966
- bold: c.bold,
14967
- dim: c.dim,
14968
- italic: c.italic,
14969
- underline: c.underline,
14970
- inverse: c.inverse,
14971
- href: c.href
14972
- };
14973
- if (cellStyle.href !== curHref) {
14974
- if (inHref) {
14975
- result += `${ESC}]8;;${ESC}\\`;
14976
- inHref = false;
14977
- }
14978
- if (cellStyle.href !== void 0) {
14979
- result += `${ESC}]8;;${cellStyle.href}${ESC}\\`;
14980
- inHref = true;
14981
- }
14982
- curHref = cellStyle.href;
14983
- }
14984
- if (!sameStyle(curStyle, cellStyle)) {
14985
- result += RESET;
14986
- result += styleToAnsi(cellStyle);
14987
- curStyle = cellStyle;
14988
- }
14989
- result += c.char;
15110
+ let prefix = "";
15111
+ try {
15112
+ const existing = readFileSync20(path5, "utf8");
15113
+ if (existing.length > 0 && !existing.endsWith("\n")) prefix = "\n";
15114
+ } catch {
14990
15115
  }
14991
- if (inHref) result += `${ESC}]8;;${ESC}\\`;
14992
- result += RESET;
14993
- return result;
15116
+ appendFileSync3(path5, `${prefix}${bullet}`, "utf8");
15117
+ return { path: path5, created: false };
14994
15118
  }
14995
15119
 
15120
+ // src/cli/ui/log-frame.tsx
15121
+ import { Box as Box26, Text as Text25 } from "ink";
15122
+ import React29 from "react";
15123
+
14996
15124
  // src/cli/ui/markdown-frame.ts
14997
15125
  var INLINE_RE2 = /(\[([^\]\n]+)\]\(([^)\n]+)\)|\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)\*\*|```([^\n]+?)```|`([^`\n]+?)`|~~([^~\n]+?)~~|(?<![*\w])\*([^*\n]+?)\*(?!\w)|\\([*_~`[\](){}#+\-.!\\]))/g;
14998
15126
  function parseInline(input, baseOpts) {
@@ -15227,11 +15355,6 @@ function markdownToFrame(markdown, width) {
15227
15355
  }
15228
15356
 
15229
15357
  // src/cli/ui/log-frame.tsx
15230
- function formatTokensCompact2(n) {
15231
- if (n < 1024) return String(n);
15232
- const k = n / 1024;
15233
- return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;
15234
- }
15235
15358
  var ROLE_GLYPH2 = {
15236
15359
  user: "\u25C7",
15237
15360
  toolOk: GLYPH.toolOk,
@@ -15633,8 +15756,8 @@ function ctxBreakdownFrame(data, width) {
15633
15756
  const innerWidth = width - 2;
15634
15757
  const headerSegments = [
15635
15758
  text("\u25A3 context", { width: 9, fg: COLOR.brand, bold: true }),
15636
- text(` ${formatTokensCompact2(total)} of ${formatTokensCompact2(data.ctxMax)}`, {
15637
- width: 4 + formatTokensCompact2(total).length + formatTokensCompact2(data.ctxMax).length,
15759
+ text(` ${formatTokens(total)} of ${formatTokens(data.ctxMax)}`, {
15760
+ width: 4 + formatTokens(total).length + formatTokens(data.ctxMax).length,
15638
15761
  dim: true
15639
15762
  }),
15640
15763
  text(" \xB7 ", { width: 5, dim: true }),
@@ -15657,26 +15780,26 @@ function ctxBreakdownFrame(data, width) {
15657
15780
  const legend = rowFrame(
15658
15781
  [
15659
15782
  text("\u25A0", { width: 1, fg: COLOR.brand }),
15660
- text(` system ${formatTokensCompact2(data.systemTokens)}`, {
15661
- width: 8 + formatTokensCompact2(data.systemTokens).length,
15783
+ text(` system ${formatTokens(data.systemTokens)}`, {
15784
+ width: 8 + formatTokens(data.systemTokens).length,
15662
15785
  dim: true
15663
15786
  }),
15664
15787
  text(" ", { width: 3 }),
15665
15788
  text("\u25A0", { width: 1, fg: COLOR.accent }),
15666
- text(` tools ${formatTokensCompact2(data.toolsTokens)}`, {
15667
- width: 7 + formatTokensCompact2(data.toolsTokens).length,
15789
+ text(` tools ${formatTokens(data.toolsTokens)}`, {
15790
+ width: 7 + formatTokens(data.toolsTokens).length,
15668
15791
  dim: true
15669
15792
  }),
15670
15793
  text(" ", { width: 3 }),
15671
15794
  text("\u25A0", { width: 1, fg: COLOR.primary }),
15672
- text(` log ${formatTokensCompact2(data.logTokens)}`, {
15673
- width: 5 + formatTokensCompact2(data.logTokens).length,
15795
+ text(` log ${formatTokens(data.logTokens)}`, {
15796
+ width: 5 + formatTokens(data.logTokens).length,
15674
15797
  dim: true
15675
15798
  }),
15676
15799
  text(" ", { width: 3 }),
15677
15800
  text("\u25A0", { width: 1, fg: COLOR.tool }),
15678
- text(` input ${formatTokensCompact2(data.inputTokens)}`, {
15679
- width: 7 + formatTokensCompact2(data.inputTokens).length,
15801
+ text(` input ${formatTokens(data.inputTokens)}`, {
15802
+ width: 7 + formatTokens(data.inputTokens).length,
15680
15803
  dim: true
15681
15804
  })
15682
15805
  ],
@@ -15790,7 +15913,7 @@ function eventToAtom(event, projectRoot, width) {
15790
15913
  kind: "ink",
15791
15914
  id: event.id,
15792
15915
  rows: estimatedHeight(event),
15793
- element: /* @__PURE__ */ React26.createElement(EventRow, { event, projectRoot })
15916
+ element: /* @__PURE__ */ React29.createElement(EventRow, { event, projectRoot })
15794
15917
  };
15795
15918
  }
15796
15919
  function estimatedHeight(e) {
@@ -15866,14 +15989,14 @@ function viewportLog(atoms, scrollOffset, available) {
15866
15989
  return { atoms: sliced, topSkip, bottomSkip, totalRows, maxScrollRows };
15867
15990
  }
15868
15991
  function renderViewport(v) {
15869
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, v.atoms.map((atom, i) => {
15992
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, null, v.atoms.map((atom, i) => {
15870
15993
  if (atom.kind === "ink") {
15871
- return /* @__PURE__ */ React26.createElement(React26.Fragment, { key: atom.id }, atom.element);
15994
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, { key: atom.id }, atom.element);
15872
15995
  }
15873
15996
  const start = i === 0 ? v.topSkip : 0;
15874
15997
  const end = i === v.atoms.length - 1 ? atom.frame.rows.length - v.bottomSkip : atom.frame.rows.length;
15875
15998
  const rows = atom.frame.rows.slice(start, end);
15876
- return /* @__PURE__ */ React26.createElement(React26.Fragment, { key: atom.id }, rows.map((row2, ri) => /* @__PURE__ */ React26.createElement(Box24, { key: `${atom.id}/${start + ri}`, height: 1, flexShrink: 0 }, /* @__PURE__ */ React26.createElement(Text22, null, frameToAnsi({ width: atom.frame.width, rows: [row2] })))));
15999
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, { key: atom.id }, rows.map((row2, ri) => /* @__PURE__ */ React29.createElement(Box26, { key: `${atom.id}/${start + ri}`, height: 1, flexShrink: 0 }, /* @__PURE__ */ React29.createElement(Text25, null, frameToAnsi({ width: atom.frame.width, rows: [row2] })))));
15877
16000
  }));
15878
16001
  }
15879
16002
  function eventsToAtoms(events, projectRoot, width) {
@@ -15883,8 +16006,8 @@ function eventsToAtoms(events, projectRoot, width) {
15883
16006
  }
15884
16007
 
15885
16008
  // src/cli/ui/log-rows.tsx
15886
- import { Box as Box25, Text as Text23 } from "ink";
15887
- import React27 from "react";
16009
+ import { Box as Box27, Text as Text26 } from "ink";
16010
+ import React30 from "react";
15888
16011
  function BottomHint({
15889
16012
  rowsBelow,
15890
16013
  totalRows,
@@ -15899,7 +16022,7 @@ function BottomHint({
15899
16022
  const markerAt = Math.max(0, Math.min(barCells - 1, Math.round(ratioFromTop * (barCells - 1))));
15900
16023
  const left = "\u2500".repeat(markerAt);
15901
16024
  const right = "\u2500".repeat(barCells - 1 - markerAt);
15902
- return /* @__PURE__ */ React27.createElement(Box25, { height: 1, flexShrink: 0 }, /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.primary, bold: true }, `\u2191 ${rowsAbove}`), /* @__PURE__ */ React27.createElement(Text23, null, " "), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "\u2595"), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.info, dimColor: true }, left), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.brand, bold: true }, "\u25CF"), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.info, dimColor: true }, right), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "\u258F"), /* @__PURE__ */ React27.createElement(Text23, null, " "), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.primary, bold: true }, `${pct2}%`), /* @__PURE__ */ React27.createElement(Text23, null, " "), /* @__PURE__ */ React27.createElement(Text23, { color: COLOR.primary }, `\u2193 ${rowsBelow}`), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, " \xB7 End to jump \xB7 wheel to scroll"));
16025
+ return /* @__PURE__ */ React30.createElement(Box27, { height: 1, flexShrink: 0 }, /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.primary, bold: true }, `\u2191 ${rowsAbove}`), /* @__PURE__ */ React30.createElement(Text26, null, " "), /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "\u2595"), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.info, dimColor: true }, left), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.brand, bold: true }, "\u25CF"), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.info, dimColor: true }, right), /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "\u258F"), /* @__PURE__ */ React30.createElement(Text26, null, " "), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.primary, bold: true }, `${pct2}%`), /* @__PURE__ */ React30.createElement(Text26, null, " "), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.primary }, `\u2193 ${rowsBelow}`), /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, " \xB7 End to jump \xB7 wheel to scroll"));
15903
16026
  }
15904
16027
 
15905
16028
  // src/cli/ui/loop.ts
@@ -16327,10 +16450,16 @@ var SLASH_COMMANDS = [
16327
16450
  summary: "toggle terminal mouse tracking \xB7 off by default (lets shift-drag copy work) \xB7 on enables wheel-scroll for log",
16328
16451
  argCompleter: ["on", "off"]
16329
16452
  },
16453
+ {
16454
+ cmd: "copy",
16455
+ summary: "freeze + dump the rendered log to main screen so terminal scrollback + drag-select can copy across viewports \xB7 any key returns"
16456
+ },
16330
16457
  { cmd: "think", summary: "dump the last turn's full R1 reasoning (reasoner only)" },
16331
16458
  {
16332
16459
  cmd: "context",
16333
- summary: "break down where context tokens are going: system / tools / per-turn log"
16460
+ argsHint: "[on|off]",
16461
+ summary: "toggle the always-on context-breakdown footer (system / tools / log / input). no arg \u2192 flip; on/off \u2192 force",
16462
+ argCompleter: ["on", "off"]
16334
16463
  },
16335
16464
  { cmd: "retry", summary: "truncate & resend your last message (fresh sample)" },
16336
16465
  {
@@ -16775,6 +16904,13 @@ var cwd = (args, _loop, ctx) => {
16775
16904
  }
16776
16905
  return { info: lines.join("\n") };
16777
16906
  };
16907
+ var copy = (_args, _loop, ctx) => {
16908
+ if (!ctx.enterCopyMode) {
16909
+ return { info: "/copy is not available in this context (TUI-internal)." };
16910
+ }
16911
+ ctx.enterCopyMode();
16912
+ return {};
16913
+ };
16778
16914
  var mouse = (args) => {
16779
16915
  const arg = (args[0] ?? "").toLowerCase();
16780
16916
  if (arg === "") {
@@ -16802,7 +16938,8 @@ var handlers = {
16802
16938
  cwd,
16803
16939
  update,
16804
16940
  stats,
16805
- mouse
16941
+ mouse,
16942
+ copy
16806
16943
  };
16807
16944
 
16808
16945
  // src/cli/ui/slash/handlers/basic.ts
@@ -18206,52 +18343,18 @@ var tool = (args, _loop, ctx) => {
18206
18343
  ${entry.text}`
18207
18344
  };
18208
18345
  };
18209
- var context = (_args, loop2) => {
18210
- const systemTokens = countTokens(loop2.prefix.system);
18211
- const toolsTokens = countTokens(JSON.stringify(loop2.prefix.toolSpecs));
18212
- const entries = loop2.log.toMessages();
18213
- let userTokens = 0;
18214
- let assistantTokens = 0;
18215
- let toolResultTokens = 0;
18216
- let toolCallTokens = 0;
18217
- const toolBreakdown = [];
18218
- let logTurn = 0;
18219
- for (const e of entries) {
18220
- const content = typeof e.content === "string" ? e.content : "";
18221
- if (e.role === "user") {
18222
- userTokens += countTokens(content);
18223
- logTurn += 1;
18224
- } else if (e.role === "assistant") {
18225
- assistantTokens += countTokens(content);
18226
- if (Array.isArray(e.tool_calls) && e.tool_calls.length > 0) {
18227
- toolCallTokens += countTokens(JSON.stringify(e.tool_calls));
18228
- }
18229
- } else if (e.role === "tool") {
18230
- const n = countTokens(content);
18231
- toolResultTokens += n;
18232
- toolBreakdown.push({ name: e.name ?? "?", tokens: n, turn: logTurn });
18233
- }
18234
- }
18235
- const logTokens = userTokens + assistantTokens + toolResultTokens + toolCallTokens;
18236
- const ctxMax = DEEPSEEK_CONTEXT_TOKENS[loop2.model] ?? DEFAULT_CONTEXT_TOKENS;
18237
- const inputTokens = 0;
18238
- const topTools = [...toolBreakdown].sort((a, b) => b.tokens - a.tokens).slice(0, 5);
18239
- const total = systemTokens + toolsTokens + logTokens + inputTokens;
18240
- const winPct = ctxMax > 0 ? Math.round(total / ctxMax * 100) : 0;
18241
- const fallbackInfo = `context: ~${compactNum(total)} of ${compactNum(ctxMax)} (${winPct}%) \xB7 system ${compactNum(systemTokens)} \xB7 tools ${compactNum(toolsTokens)} \xB7 log ${compactNum(logTokens)}`;
18242
- return {
18243
- info: fallbackInfo,
18244
- ctxBreakdown: {
18245
- systemTokens,
18246
- toolsTokens,
18247
- logTokens,
18248
- inputTokens,
18249
- ctxMax,
18250
- toolsCount: loop2.prefix.toolSpecs.length,
18251
- logMessages: entries.length,
18252
- topTools
18253
- }
18254
- };
18346
+ var context = (args, loop2, ctx) => {
18347
+ if (ctx.toggleCtxFooter) {
18348
+ const arg = (args[0] ?? "").toLowerCase();
18349
+ const force = arg === "on" ? true : arg === "off" ? false : void 0;
18350
+ const next = ctx.toggleCtxFooter(force);
18351
+ return { info: `\u25B8 context footer: ${next ? "on" : "off"}` };
18352
+ }
18353
+ const breakdown = computeCtxBreakdown(loop2);
18354
+ const total = breakdown.systemTokens + breakdown.toolsTokens + breakdown.logTokens + breakdown.inputTokens;
18355
+ const winPct = breakdown.ctxMax > 0 ? Math.round(total / breakdown.ctxMax * 100) : 0;
18356
+ const fallbackInfo = `context: ~${compactNum(total)} of ${compactNum(breakdown.ctxMax)} (${winPct}%) \xB7 system ${compactNum(breakdown.systemTokens)} \xB7 tools ${compactNum(breakdown.toolsTokens)} \xB7 log ${compactNum(breakdown.logTokens)}`;
18357
+ return { info: fallbackInfo, ctxBreakdown: breakdown };
18255
18358
  };
18256
18359
  var status = (_args, loop2, ctx) => {
18257
18360
  const branchBudget = loop2.branchOptions.budget ?? 1;
@@ -18911,7 +19014,7 @@ function handleSlash(cmd, args, loop2, ctx = {}) {
18911
19014
  }
18912
19015
 
18913
19016
  // src/cli/ui/useCompletionPickers.ts
18914
- import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState6 } from "react";
19017
+ import { useCallback, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState6 } from "react";
18915
19018
  function useCompletionPickers({
18916
19019
  input,
18917
19020
  setInput,
@@ -18921,7 +19024,7 @@ function useCompletionPickers({
18921
19024
  mcpServers
18922
19025
  }) {
18923
19026
  const [slashSelected, setSlashSelected] = useState6(0);
18924
- const slashMatches = useMemo2(() => {
19027
+ const slashMatches = useMemo3(() => {
18925
19028
  if (!input.startsWith("/") || input.includes(" ")) return null;
18926
19029
  return suggestSlashCommands(input.slice(1), !!codeMode);
18927
19030
  }, [input, codeMode]);
@@ -18957,12 +19060,12 @@ function useCompletionPickers({
18957
19060
  list.unshift(p);
18958
19061
  if (list.length > 20) list.length = 20;
18959
19062
  }, []);
18960
- const atPicker = useMemo2(() => {
19063
+ const atPicker = useMemo3(() => {
18961
19064
  if (!codeMode) return null;
18962
19065
  if (slashMatches !== null) return null;
18963
19066
  return detectAtPicker(input);
18964
19067
  }, [codeMode, input, slashMatches]);
18965
- const atMatches = useMemo2(() => {
19068
+ const atMatches = useMemo3(() => {
18966
19069
  if (!atPicker) return null;
18967
19070
  return rankPickerCandidates(atFiles, atPicker.query, {
18968
19071
  limit: 40,
@@ -18985,12 +19088,12 @@ function useCompletionPickers({
18985
19088
  [atPicker, input, setInput]
18986
19089
  );
18987
19090
  const [slashArgSelected, setSlashArgSelected] = useState6(0);
18988
- const slashArgContext = useMemo2(() => {
19091
+ const slashArgContext = useMemo3(() => {
18989
19092
  if (!input.startsWith("/")) return null;
18990
19093
  if (slashMatches !== null) return null;
18991
19094
  return detectSlashArgContext(input, !!codeMode);
18992
19095
  }, [input, slashMatches, codeMode]);
18993
- const slashArgMatches = useMemo2(() => {
19096
+ const slashArgMatches = useMemo3(() => {
18994
19097
  if (!slashArgContext || slashArgContext.kind !== "picker") return null;
18995
19098
  const completer = slashArgContext.spec.argCompleter;
18996
19099
  const partial = slashArgContext.partial;
@@ -19415,13 +19518,13 @@ var PLAIN_UI = process.env.REASONIX_UI === "plain";
19415
19518
  function LoopStatusRow({
19416
19519
  loop: loop2
19417
19520
  }) {
19418
- const [, setTick] = React28.useState(0);
19419
- React28.useEffect(() => {
19521
+ const [, setTick] = React31.useState(0);
19522
+ React31.useEffect(() => {
19420
19523
  const id = setInterval(() => setTick((t2) => t2 + 1), 1e3);
19421
19524
  return () => clearInterval(id);
19422
19525
  }, []);
19423
19526
  const nextFireMs = Math.max(0, loop2.nextFireAt - Date.now());
19424
- return /* @__PURE__ */ React28.createElement(Box26, null, /* @__PURE__ */ React28.createElement(Text24, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
19527
+ return /* @__PURE__ */ React31.createElement(Box28, null, /* @__PURE__ */ React31.createElement(Text27, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
19425
19528
  }
19426
19529
  function App({
19427
19530
  model: model2,
@@ -19441,6 +19544,8 @@ function App({
19441
19544
  useAltScreen();
19442
19545
  const [historical, setHistorical] = useState10([]);
19443
19546
  const [streaming, setStreaming] = useState10(null);
19547
+ const [copyMode, setCopyMode] = useState10(false);
19548
+ const [ctxFooterVisible, setCtxFooterVisible] = useState10(true);
19444
19549
  const [logScrollOffset, setLogScrollOffset] = useState10(0);
19445
19550
  const scrollAnimRef = useRef6(null);
19446
19551
  const scrollTargetRef = useRef6(0);
@@ -19520,7 +19625,7 @@ function App({
19520
19625
  }, [busy]);
19521
19626
  const [ongoingTool, setOngoingTool] = useState10(null);
19522
19627
  const [toolProgress, setToolProgress] = useState10(null);
19523
- const { stdout: stdout4 } = useStdout9();
19628
+ const { stdout: stdout4 } = useStdout11();
19524
19629
  useEffect7(() => {
19525
19630
  if (!stdout4 || !stdout4.isTTY) return;
19526
19631
  stdout4.write("\x1B[?2004h");
@@ -19681,7 +19786,7 @@ function App({
19681
19786
  };
19682
19787
  }, []);
19683
19788
  const loopRef = useRef6(null);
19684
- const loop2 = useMemo3(() => {
19789
+ const loop2 = useMemo4(() => {
19685
19790
  if (loopRef.current) return loopRef.current;
19686
19791
  const client = new DeepSeekClient();
19687
19792
  if (tools && !tools.has("run_skill")) {
@@ -19794,6 +19899,60 @@ function App({
19794
19899
  useEffect7(() => {
19795
19900
  currentRootDirRef.current = currentRootDir;
19796
19901
  }, [currentRootDir]);
19902
+ useEffect7(() => {
19903
+ if (!copyMode) return;
19904
+ const cols = (process.stdout?.columns ?? 80) - 2;
19905
+ const atoms = eventsToAtoms(historicalRef.current, currentRootDirRef.current, cols);
19906
+ const lines = [];
19907
+ for (const atom of atoms) {
19908
+ if (atom.kind === "frame") {
19909
+ const ansi = frameToAnsi(atom.frame);
19910
+ if (ansi) lines.push(ansi);
19911
+ } else {
19912
+ lines.push(`(${atom.id ?? "ink-block"} omitted from copy dump)`);
19913
+ }
19914
+ }
19915
+ const wasMouseOn = isMouseTrackingOn();
19916
+ setMouseTracking(false);
19917
+ process.stdout.write("\x1B[?1049l");
19918
+ process.stdout.write("\n=== reasonix \xB7 copy mode \u2014 terminal scrollback active ===\n\n");
19919
+ process.stdout.write(lines.join("\n"));
19920
+ process.stdout.write("\n\n=== end of dump \xB7 press any key to return to reasonix ===\n");
19921
+ const reader = getStdinReader();
19922
+ let exited = false;
19923
+ const restore2 = () => {
19924
+ if (exited) return;
19925
+ exited = true;
19926
+ process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H");
19927
+ if (wasMouseOn) setMouseTracking(true);
19928
+ setCopyMode(false);
19929
+ };
19930
+ const unsub = reader.subscribe(() => {
19931
+ unsub();
19932
+ restore2();
19933
+ });
19934
+ return () => {
19935
+ unsub();
19936
+ if (!exited) {
19937
+ process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H");
19938
+ if (wasMouseOn) setMouseTracking(true);
19939
+ }
19940
+ };
19941
+ }, [copyMode]);
19942
+ const enterCopyMode = useCallback4(() => {
19943
+ setCopyMode(true);
19944
+ }, []);
19945
+ const toggleCtxFooter = useCallback4(
19946
+ (force) => {
19947
+ let next = false;
19948
+ setCtxFooterVisible((prev) => {
19949
+ next = force === void 0 ? !prev : force;
19950
+ return next;
19951
+ });
19952
+ return force === void 0 ? !ctxFooterVisible : force;
19953
+ },
19954
+ [ctxFooterVisible]
19955
+ );
19797
19956
  useEffect7(() => {
19798
19957
  latestVersionRef.current = latestVersion ?? null;
19799
19958
  }, [latestVersion]);
@@ -20213,6 +20372,7 @@ function App({
20213
20372
  relPath = relPath.slice(1);
20214
20373
  }
20215
20374
  if (!relPath) return null;
20375
+ const rootForEdit = currentRootDirRef.current;
20216
20376
  let block;
20217
20377
  if (name === "edit_file") {
20218
20378
  const search = typeof args.search === "string" ? args.search : "";
@@ -20221,11 +20381,11 @@ function App({
20221
20381
  block = { path: relPath, search, replace, offset: 0 };
20222
20382
  } else {
20223
20383
  const content = typeof args.content === "string" ? args.content : "";
20224
- block = toWholeFileEditBlock(relPath, content, currentRootDir);
20384
+ block = toWholeFileEditBlock(relPath, content, rootForEdit);
20225
20385
  }
20226
20386
  const applyNow = () => {
20227
- const snaps = snapshotBeforeEdits([block], currentRootDir);
20228
- const results = applyEditBlocks([block], currentRootDir);
20387
+ const snaps = snapshotBeforeEdits([block], rootForEdit);
20388
+ const results = applyEditBlocks([block], rootForEdit);
20229
20389
  const good = results.some((r) => r.status === "applied" || r.status === "created");
20230
20390
  if (good) {
20231
20391
  recordEdit("auto", [block], results, snaps);
@@ -20886,6 +21046,8 @@ function App({
20886
21046
  return fresh.length;
20887
21047
  },
20888
21048
  setCwd: (newRoot) => applyCwdChange(newRoot),
21049
+ enterCopyMode,
21050
+ toggleCtxFooter,
20889
21051
  latestVersion,
20890
21052
  refreshLatestVersion,
20891
21053
  models: models2,
@@ -21519,7 +21681,9 @@ function App({
21519
21681
  getDashboardUrl,
21520
21682
  broadcastDashboardEvent,
21521
21683
  applyCwdChange,
21522
- touchedPaths
21684
+ touchedPaths,
21685
+ enterCopyMode,
21686
+ toggleCtxFooter
21523
21687
  ]
21524
21688
  );
21525
21689
  useEffect7(() => {
@@ -22028,7 +22192,8 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22028
22192
  async (choice) => handleReviseConfirmRef.current(choice),
22029
22193
  []
22030
22194
  );
22031
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(
22195
+ if (copyMode) return null;
22196
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(
22032
22197
  TickerProvider,
22033
22198
  {
22034
22199
  disabled: PLAIN_UI || isResizing || !!pendingPlan || !!pendingShell || !!pendingWorkspace || !!pendingEditReview || walkthroughActive || !!pendingCheckpoint || !!stagedCheckpointRevise || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || // Idle gate: when nothing is actively happening, suspend the
@@ -22041,15 +22206,15 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22041
22206
  // changes (incoming stream, key press, modal popup).
22042
22207
  !busy && !streaming
22043
22208
  },
22044
- /* @__PURE__ */ React28.createElement(
22045
- Box26,
22209
+ /* @__PURE__ */ React31.createElement(
22210
+ Box28,
22046
22211
  {
22047
22212
  flexDirection: "column",
22048
22213
  height: stdout4?.rows ?? 30,
22049
22214
  width: stdout4?.columns ?? 80,
22050
22215
  overflow: "hidden"
22051
22216
  },
22052
- /* @__PURE__ */ React28.createElement(
22217
+ /* @__PURE__ */ React31.createElement(
22053
22218
  ChromeBar,
22054
22219
  {
22055
22220
  summary,
@@ -22065,16 +22230,16 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22065
22230
  scrollRatio: scrollMaxRowsRef.current > 0 ? logScrollOffset / scrollMaxRowsRef.current : 0
22066
22231
  }
22067
22232
  ),
22068
- /* @__PURE__ */ React28.createElement(
22069
- Box26,
22233
+ /* @__PURE__ */ React31.createElement(
22234
+ Box28,
22070
22235
  {
22071
22236
  flexDirection: "column",
22072
22237
  flexGrow: 1,
22073
22238
  height: pendingShell || pendingWorkspace || pendingPlan || pendingEditReview || pendingCheckpoint || stagedCheckpointRevise || stagedInput || stagedChoiceCustom || pendingChoice || pendingRevision || walkthroughActive ? 0 : Math.max(5, (stdout4?.rows ?? 30) - 9),
22074
22239
  overflow: "hidden"
22075
22240
  },
22076
- /* @__PURE__ */ React28.createElement(Box26, { flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ React28.createElement(
22077
- Box26,
22241
+ /* @__PURE__ */ React31.createElement(Box28, { flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ React31.createElement(
22242
+ Box28,
22078
22243
  {
22079
22244
  flexDirection: "column",
22080
22245
  flexGrow: 1,
@@ -22091,14 +22256,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22091
22256
  lastTotalRowsRef.current = v.totalRows;
22092
22257
  return renderViewport(v);
22093
22258
  })(),
22094
- !historical.some((e) => e.role === "user" || e.role === "assistant") && !busy && !streaming ? /* @__PURE__ */ React28.createElement(WelcomeBanner, { inCodeMode: !!codeMode, dashboardUrl }) : null,
22095
- !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && streaming ? /* @__PURE__ */ React28.createElement(Box26, { marginY: 1 }, /* @__PURE__ */ React28.createElement(EventRow, { event: streaming, projectRoot: currentRootDir })) : null,
22096
- !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && ongoingTool ? /* @__PURE__ */ React28.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null,
22097
- !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && subagentActivity ? /* @__PURE__ */ React28.createElement(SubagentRow, { activity: subagentActivity }) : null,
22098
- !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !ongoingTool && statusLine ? /* @__PURE__ */ React28.createElement(StatusRow, { text: statusLine }) : null,
22099
- !PLAIN_UI && undoBanner && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision ? /* @__PURE__ */ React28.createElement(UndoBanner, { banner: undoBanner }) : null,
22100
- !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && busy && !streaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React28.createElement(StatusRow, { text: "processing\u2026" }) : null
22101
- ), /* @__PURE__ */ React28.createElement(
22259
+ !historical.some((e) => e.role === "user" || e.role === "assistant") && !busy && !streaming ? /* @__PURE__ */ React31.createElement(WelcomeBanner, { inCodeMode: !!codeMode, dashboardUrl }) : null,
22260
+ !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && streaming ? /* @__PURE__ */ React31.createElement(Box28, { marginY: 1 }, /* @__PURE__ */ React31.createElement(EventRow, { event: streaming, projectRoot: currentRootDir })) : null,
22261
+ !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && ongoingTool ? /* @__PURE__ */ React31.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null,
22262
+ !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && subagentActivity ? /* @__PURE__ */ React31.createElement(SubagentRow, { activity: subagentActivity }) : null,
22263
+ !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !ongoingTool && statusLine ? /* @__PURE__ */ React31.createElement(StatusRow, { text: statusLine }) : null,
22264
+ !PLAIN_UI && undoBanner && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision ? /* @__PURE__ */ React31.createElement(UndoBanner, { banner: undoBanner }) : null,
22265
+ !PLAIN_UI && !pendingShell && !pendingWorkspace && !pendingPlan && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && busy && !streaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React31.createElement(StatusRow, { text: "processing\u2026" }) : null
22266
+ ), /* @__PURE__ */ React31.createElement(
22102
22267
  BottomHint,
22103
22268
  {
22104
22269
  rowsBelow: logScrollOffset,
@@ -22110,28 +22275,28 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22110
22275
  }
22111
22276
  ))
22112
22277
  ),
22113
- stagedInput ? /* @__PURE__ */ React28.createElement(
22278
+ stagedInput ? /* @__PURE__ */ React31.createElement(
22114
22279
  PlanRefineInput,
22115
22280
  {
22116
22281
  mode: stagedInput.mode,
22117
22282
  onSubmit: handleStagedInputSubmit,
22118
22283
  onCancel: handleStagedInputCancel
22119
22284
  }
22120
- ) : stagedCheckpointRevise ? /* @__PURE__ */ React28.createElement(
22285
+ ) : stagedCheckpointRevise ? /* @__PURE__ */ React31.createElement(
22121
22286
  PlanRefineInput,
22122
22287
  {
22123
22288
  mode: "checkpoint-revise",
22124
22289
  onSubmit: handleCheckpointReviseSubmit,
22125
22290
  onCancel: handleCheckpointReviseCancel
22126
22291
  }
22127
- ) : stagedChoiceCustom ? /* @__PURE__ */ React28.createElement(
22292
+ ) : stagedChoiceCustom ? /* @__PURE__ */ React31.createElement(
22128
22293
  PlanRefineInput,
22129
22294
  {
22130
22295
  mode: "choice-custom",
22131
22296
  onSubmit: handleChoiceCustomSubmit,
22132
22297
  onCancel: handleChoiceCustomCancel
22133
22298
  }
22134
- ) : pendingChoice ? /* @__PURE__ */ React28.createElement(
22299
+ ) : pendingChoice ? /* @__PURE__ */ React31.createElement(
22135
22300
  ChoiceConfirm,
22136
22301
  {
22137
22302
  question: pendingChoice.question,
@@ -22139,7 +22304,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22139
22304
  allowCustom: pendingChoice.allowCustom,
22140
22305
  onChoose: stableHandleChoiceConfirm
22141
22306
  }
22142
- ) : pendingRevision ? /* @__PURE__ */ React28.createElement(
22307
+ ) : pendingRevision ? /* @__PURE__ */ React31.createElement(
22143
22308
  PlanReviseConfirm,
22144
22309
  {
22145
22310
  reason: pendingRevision.reason,
@@ -22150,7 +22315,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22150
22315
  summary: pendingRevision.summary,
22151
22316
  onChoose: stableHandleReviseConfirm
22152
22317
  }
22153
- ) : pendingCheckpoint ? /* @__PURE__ */ React28.createElement(
22318
+ ) : pendingCheckpoint ? /* @__PURE__ */ React31.createElement(
22154
22319
  PlanCheckpointConfirm,
22155
22320
  {
22156
22321
  stepId: pendingCheckpoint.stepId,
@@ -22161,7 +22326,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22161
22326
  completedStepIds: completedStepIdsRef.current,
22162
22327
  onChoose: stableHandleCheckpointConfirm
22163
22328
  }
22164
- ) : pendingPlan ? /* @__PURE__ */ React28.createElement(
22329
+ ) : pendingPlan ? /* @__PURE__ */ React31.createElement(
22165
22330
  PlanConfirm,
22166
22331
  {
22167
22332
  plan: pendingPlan,
@@ -22170,7 +22335,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22170
22335
  onChoose: stableHandlePlanConfirm,
22171
22336
  projectRoot: currentRootDir
22172
22337
  }
22173
- ) : pendingShell ? /* @__PURE__ */ React28.createElement(
22338
+ ) : pendingShell ? /* @__PURE__ */ React31.createElement(
22174
22339
  ShellConfirm,
22175
22340
  {
22176
22341
  command: pendingShell.command,
@@ -22178,7 +22343,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22178
22343
  kind: pendingShell.kind,
22179
22344
  onChoose: handleShellConfirm
22180
22345
  }
22181
- ) : pendingWorkspace ? /* @__PURE__ */ React28.createElement(
22346
+ ) : pendingWorkspace ? /* @__PURE__ */ React31.createElement(
22182
22347
  WorkspaceConfirm,
22183
22348
  {
22184
22349
  path: pendingWorkspace.path,
@@ -22186,7 +22351,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22186
22351
  mcpServerCount: mcpServers?.length ?? 0,
22187
22352
  onChoose: handleWorkspaceConfirm
22188
22353
  }
22189
- ) : pendingEditReview ? /* @__PURE__ */ React28.createElement(
22354
+ ) : pendingEditReview ? /* @__PURE__ */ React31.createElement(
22190
22355
  EditConfirm,
22191
22356
  {
22192
22357
  block: pendingEditReview,
@@ -22198,14 +22363,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22198
22363
  }
22199
22364
  }
22200
22365
  }
22201
- ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React28.createElement(
22366
+ ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React31.createElement(
22202
22367
  EditConfirm,
22203
22368
  {
22204
22369
  key: `walk-${pendingTick}`,
22205
22370
  block: pendingEdits.current[0],
22206
22371
  onChoose: handleWalkChoice
22207
22372
  }
22208
- ) : /* @__PURE__ */ React28.createElement(React28.Fragment, null, codeMode ? /* @__PURE__ */ React28.createElement(
22373
+ ) : /* @__PURE__ */ React31.createElement(React31.Fragment, null, codeMode ? /* @__PURE__ */ React31.createElement(
22209
22374
  ModeStatusBar,
22210
22375
  {
22211
22376
  editMode,
@@ -22215,7 +22380,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22215
22380
  undoArmed: !!undoBanner || hasUndoable(),
22216
22381
  jobs: codeMode.jobs
22217
22382
  }
22218
- ) : null, activeLoop ? /* @__PURE__ */ React28.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React28.createElement(
22383
+ ) : null, activeLoop ? /* @__PURE__ */ React31.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React31.createElement(
22219
22384
  PromptInput,
22220
22385
  {
22221
22386
  value: input,
@@ -22225,14 +22390,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22225
22390
  onHistoryPrev: recallPrev,
22226
22391
  onHistoryNext: recallNext
22227
22392
  }
22228
- ), /* @__PURE__ */ React28.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }), /* @__PURE__ */ React28.createElement(
22393
+ ), /* @__PURE__ */ React31.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }), /* @__PURE__ */ React31.createElement(
22229
22394
  AtMentionSuggestions,
22230
22395
  {
22231
22396
  matches: atMatches,
22232
22397
  selectedIndex: atSelected,
22233
22398
  query: atPicker?.query ?? ""
22234
22399
  }
22235
- ), slashArgContext ? /* @__PURE__ */ React28.createElement(
22400
+ ), slashArgContext ? /* @__PURE__ */ React31.createElement(
22236
22401
  SlashArgPicker,
22237
22402
  {
22238
22403
  matches: slashArgMatches,
@@ -22241,21 +22406,21 @@ Continue executing from the next pending step. Call mark_step_complete after eac
22241
22406
  kind: slashArgContext.kind,
22242
22407
  partial: slashArgContext.partial
22243
22408
  }
22244
- ) : null)
22409
+ ) : null, ctxFooterVisible ? /* @__PURE__ */ React31.createElement(CtxFooter, { loop: loop2, summary }) : null)
22245
22410
  )
22246
22411
  ));
22247
22412
  }
22248
22413
 
22249
22414
  // src/cli/ui/SessionPicker.tsx
22250
- import { Box as Box27, Text as Text25 } from "ink";
22251
- import React29 from "react";
22415
+ import { Box as Box29, Text as Text28 } from "ink";
22416
+ import React32 from "react";
22252
22417
  function SessionPicker({
22253
22418
  sessionName,
22254
22419
  messageCount,
22255
22420
  lastActive,
22256
22421
  onChoose
22257
22422
  }) {
22258
- return /* @__PURE__ */ React29.createElement(Box27, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React29.createElement(Box27, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: COLOR.brand, bold: true }, GLYPH.brand), /* @__PURE__ */ React29.createElement(Text25, null, " "), /* @__PURE__ */ React29.createElement(Text25, { color: COLOR.primary, bold: true }, `"${sessionName}"`), /* @__PURE__ */ React29.createElement(Text25, { dimColor: true }, ` has ${messageCount} prior message${messageCount === 1 ? "" : "s"}`), /* @__PURE__ */ React29.createElement(Text25, { dimColor: true }, ` \xB7 last active ${relativeTime2(lastActive)}`)), /* @__PURE__ */ React29.createElement(
22423
+ return /* @__PURE__ */ React32.createElement(Box29, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React32.createElement(Box29, { marginBottom: 1 }, /* @__PURE__ */ React32.createElement(Text28, { color: COLOR.brand, bold: true }, GLYPH.brand), /* @__PURE__ */ React32.createElement(Text28, null, " "), /* @__PURE__ */ React32.createElement(Text28, { color: COLOR.primary, bold: true }, `"${sessionName}"`), /* @__PURE__ */ React32.createElement(Text28, { dimColor: true }, ` has ${messageCount} prior message${messageCount === 1 ? "" : "s"}`), /* @__PURE__ */ React32.createElement(Text28, { dimColor: true }, ` \xB7 last active ${relativeTime2(lastActive)}`)), /* @__PURE__ */ React32.createElement(
22259
22424
  SingleSelect,
22260
22425
  {
22261
22426
  initialValue: "new",
@@ -22278,7 +22443,7 @@ function SessionPicker({
22278
22443
  ],
22279
22444
  onSubmit: (v) => onChoose(v)
22280
22445
  }
22281
- ), /* @__PURE__ */ React29.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text25, { dimColor: true }, " \u2191\u2193 navigate \xB7 \u23CE select")));
22446
+ ), /* @__PURE__ */ React32.createElement(Box29, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text28, { dimColor: true }, " \u2191\u2193 navigate \xB7 \u23CE select")));
22282
22447
  }
22283
22448
  function relativeTime2(date) {
22284
22449
  const ms = Date.now() - date.getTime();
@@ -22294,9 +22459,9 @@ function relativeTime2(date) {
22294
22459
  }
22295
22460
 
22296
22461
  // src/cli/ui/Setup.tsx
22297
- import { Box as Box28, Text as Text26, useApp } from "ink";
22462
+ import { Box as Box30, Text as Text29, useApp } from "ink";
22298
22463
  import TextInput from "ink-text-input";
22299
- import React30, { useState as useState11 } from "react";
22464
+ import React33, { useState as useState11 } from "react";
22300
22465
  function Setup({ onReady }) {
22301
22466
  const [value, setValue] = useState11("");
22302
22467
  const [error, setError] = useState11(null);
@@ -22320,7 +22485,7 @@ function Setup({ onReady }) {
22320
22485
  }
22321
22486
  onReady(trimmed);
22322
22487
  };
22323
- return /* @__PURE__ */ React30.createElement(Box28, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React30.createElement(Box28, null, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React30.createElement(Text26, null, " "), /* @__PURE__ */ React30.createElement(Text26, { bold: true }, "Welcome to "), /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React30.createElement(Box28, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React30.createElement(Box28, null, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, " free credit on signup \xB7 "), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React30.createElement(Box28, null, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, " saved to "), /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React30.createElement(Box28, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React30.createElement(
22488
+ return /* @__PURE__ */ React33.createElement(Box30, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React33.createElement(Box30, null, /* @__PURE__ */ React33.createElement(Text29, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React33.createElement(Text29, null, " "), /* @__PURE__ */ React33.createElement(Text29, { bold: true }, "Welcome to "), /* @__PURE__ */ React33.createElement(Text29, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text29, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React33.createElement(Box30, null, /* @__PURE__ */ React33.createElement(Text29, { dimColor: true }, " free credit on signup \xB7 "), /* @__PURE__ */ React33.createElement(Text29, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React33.createElement(Box30, null, /* @__PURE__ */ React33.createElement(Text29, { dimColor: true }, " saved to "), /* @__PURE__ */ React33.createElement(Text29, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text29, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React33.createElement(Text29, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React33.createElement(
22324
22489
  TextInput,
22325
22490
  {
22326
22491
  value,
@@ -22329,7 +22494,7 @@ function Setup({ onReady }) {
22329
22494
  mask: "\u2022",
22330
22495
  placeholder: "sk-..."
22331
22496
  }
22332
- )), error ? /* @__PURE__ */ React30.createElement(Box28, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React30.createElement(Text26, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React30.createElement(Box28, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React30.createElement(Box28, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, " /exit to abort")));
22497
+ )), error ? /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text29, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React33.createElement(Text29, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text29, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text29, { dimColor: true }, " /exit to abort")));
22333
22498
  }
22334
22499
 
22335
22500
  // src/cli/commands/chat.tsx
@@ -22345,7 +22510,7 @@ function Root({
22345
22510
  const [key, setKey] = useState12(initialKey);
22346
22511
  const [pending, setPending] = useState12(sessionPreview);
22347
22512
  if (!key) {
22348
- return /* @__PURE__ */ React31.createElement(
22513
+ return /* @__PURE__ */ React34.createElement(
22349
22514
  Setup,
22350
22515
  {
22351
22516
  onReady: (k) => {
@@ -22357,7 +22522,7 @@ function Root({
22357
22522
  }
22358
22523
  process.env.DEEPSEEK_API_KEY = key;
22359
22524
  if (pending && appProps.session) {
22360
- return /* @__PURE__ */ React31.createElement(KeystrokeProvider, null, /* @__PURE__ */ React31.createElement(
22525
+ return /* @__PURE__ */ React34.createElement(KeystrokeProvider, null, /* @__PURE__ */ React34.createElement(
22361
22526
  SessionPicker,
22362
22527
  {
22363
22528
  sessionName: appProps.session,
@@ -22372,7 +22537,7 @@ function Root({
22372
22537
  }
22373
22538
  ));
22374
22539
  }
22375
- return /* @__PURE__ */ React31.createElement(KeystrokeProvider, null, /* @__PURE__ */ React31.createElement(
22540
+ return /* @__PURE__ */ React34.createElement(KeystrokeProvider, null, /* @__PURE__ */ React34.createElement(
22376
22541
  App,
22377
22542
  {
22378
22543
  model: appProps.model,
@@ -22479,7 +22644,7 @@ async function chatCommand(opts) {
22479
22644
  rewriteSession(opts.session, []);
22480
22645
  }
22481
22646
  const { waitUntilExit } = render(
22482
- /* @__PURE__ */ React31.createElement(
22647
+ /* @__PURE__ */ React34.createElement(
22483
22648
  Root,
22484
22649
  {
22485
22650
  initialKey,
@@ -22832,35 +22997,35 @@ async function commitCommand(opts = {}) {
22832
22997
  import { writeFileSync as writeFileSync15 } from "fs";
22833
22998
  import { basename as basename4 } from "path";
22834
22999
  import { render as render2 } from "ink";
22835
- import React34 from "react";
23000
+ import React37 from "react";
22836
23001
 
22837
23002
  // src/cli/ui/DiffApp.tsx
22838
- import { Box as Box30, Static, Text as Text28, useApp as useApp2, useInput } from "ink";
22839
- import React33, { useState as useState13 } from "react";
23003
+ import { Box as Box32, Static, Text as Text31, useApp as useApp2, useInput } from "ink";
23004
+ import React36, { useState as useState13 } from "react";
22840
23005
 
22841
23006
  // src/cli/ui/RecordView.tsx
22842
- import { Box as Box29, Text as Text27 } from "ink";
22843
- import React32 from "react";
23007
+ import { Box as Box31, Text as Text30 } from "ink";
23008
+ import React35 from "react";
22844
23009
  function RecordView({ rec, compact: compact2 = false }) {
22845
23010
  const toolArgsMax = compact2 ? 120 : 200;
22846
23011
  const toolContentMax = compact2 ? 200 : 400;
22847
23012
  if (rec.role === "user") {
22848
23013
  const content = rec.content.includes("\n") ? rec.content.split("\n").join("\n ") : rec.content;
22849
- return /* @__PURE__ */ React32.createElement(Box29, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text27, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React32.createElement(Text27, null, content));
23014
+ return /* @__PURE__ */ React35.createElement(Box31, { marginTop: 1 }, /* @__PURE__ */ React35.createElement(Text30, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React35.createElement(Text30, null, content));
22850
23015
  }
22851
23016
  if (rec.role === "assistant_final") {
22852
- return /* @__PURE__ */ React32.createElement(Box29, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React32.createElement(Box29, null, /* @__PURE__ */ React32.createElement(Text27, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React32.createElement(Text27, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React32.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React32.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React32.createElement(Text27, null, rec.content) : /* @__PURE__ */ React32.createElement(Text27, { dimColor: true, italic: true }, "(tool-call response only)"));
23017
+ return /* @__PURE__ */ React35.createElement(Box31, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React35.createElement(Box31, null, /* @__PURE__ */ React35.createElement(Text30, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React35.createElement(Text30, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React35.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React35.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React35.createElement(Text30, null, rec.content) : /* @__PURE__ */ React35.createElement(Text30, { dimColor: true, italic: true }, "(tool-call response only)"));
22853
23018
  }
22854
23019
  if (rec.role === "tool") {
22855
- return /* @__PURE__ */ React32.createElement(Box29, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text27, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React32.createElement(Text27, { dimColor: true }, " args: ", truncate2(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React32.createElement(Text27, { dimColor: true }, " \u2192 ", truncate2(rec.content, toolContentMax)));
23020
+ return /* @__PURE__ */ React35.createElement(Box31, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React35.createElement(Text30, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React35.createElement(Text30, { dimColor: true }, " args: ", truncate2(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React35.createElement(Text30, { dimColor: true }, " \u2192 ", truncate2(rec.content, toolContentMax)));
22856
23021
  }
22857
23022
  if (rec.role === "error") {
22858
- return /* @__PURE__ */ React32.createElement(Box29, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text27, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React32.createElement(Text27, { color: "red" }, rec.error ?? rec.content));
23023
+ return /* @__PURE__ */ React35.createElement(Box31, { marginTop: 1 }, /* @__PURE__ */ React35.createElement(Text30, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React35.createElement(Text30, { color: "red" }, rec.error ?? rec.content));
22859
23024
  }
22860
23025
  if (rec.role === "done" || rec.role === "assistant_delta") {
22861
23026
  return null;
22862
23027
  }
22863
- return /* @__PURE__ */ React32.createElement(Box29, null, /* @__PURE__ */ React32.createElement(Text27, { dimColor: true }, "[", rec.role, "] ", rec.content));
23028
+ return /* @__PURE__ */ React35.createElement(Box31, null, /* @__PURE__ */ React35.createElement(Text30, { dimColor: true }, "[", rec.role, "] ", rec.content));
22864
23029
  }
22865
23030
  function CacheBadge({ usage }) {
22866
23031
  const hit = usage.prompt_cache_hit_tokens ?? 0;
@@ -22869,7 +23034,7 @@ function CacheBadge({ usage }) {
22869
23034
  if (total === 0) return null;
22870
23035
  const pct2 = hit / total * 100;
22871
23036
  const color2 = pct2 >= 70 ? "green" : pct2 >= 40 ? "yellow" : "red";
22872
- return /* @__PURE__ */ React32.createElement(Text27, null, /* @__PURE__ */ React32.createElement(Text27, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React32.createElement(Text27, { color: color2 }, pct2.toFixed(1), "%"));
23037
+ return /* @__PURE__ */ React35.createElement(Text30, null, /* @__PURE__ */ React35.createElement(Text30, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React35.createElement(Text30, { color: color2 }, pct2.toFixed(1), "%"));
22873
23038
  }
22874
23039
  function truncate2(s, max) {
22875
23040
  return s.length <= max ? s : `${s.slice(0, max)}\u2026 (+${s.length - max} chars)`;
@@ -22903,7 +23068,7 @@ function DiffApp({ report }) {
22903
23068
  }
22904
23069
  });
22905
23070
  const pair = report.pairs[idx];
22906
- return /* @__PURE__ */ React33.createElement(Box30, { flexDirection: "column" }, /* @__PURE__ */ React33.createElement(DiffHeader, { report }), /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React33.createElement(Text28, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React33.createElement(Text28, null, pair ? /* @__PURE__ */ React33.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React33.createElement(Box30, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React33.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React33.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React33.createElement(Text28, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React33.createElement(Text28, null, pair.divergenceNote)) : null, /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "j"), "/", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "k"), "/", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "N"), "/", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "g"), "/", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React33.createElement(Text28, { bold: true }, "q"), " ", "quit")));
23071
+ return /* @__PURE__ */ React36.createElement(Box32, { flexDirection: "column" }, /* @__PURE__ */ React36.createElement(DiffHeader, { report }), /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React36.createElement(Text31, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React36.createElement(Text31, null, pair ? /* @__PURE__ */ React36.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React36.createElement(Box32, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React36.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React36.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React36.createElement(Text31, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React36.createElement(Text31, null, pair.divergenceNote)) : null, /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "j"), "/", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "k"), "/", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "N"), "/", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "g"), "/", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React36.createElement(Text31, { bold: true }, "q"), " ", "quit")));
22907
23072
  }
22908
23073
  function DiffHeader({ report }) {
22909
23074
  const a = report.a;
@@ -22921,15 +23086,15 @@ function DiffHeader({ report }) {
22921
23086
  } else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {
22922
23087
  prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}\u2026 \u2014 cache delta attributable to log stability, not prompt change.`;
22923
23088
  }
22924
- return /* @__PURE__ */ React33.createElement(Box30, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React33.createElement(Box30, { justifyContent: "space-between" }, /* @__PURE__ */ React33.createElement(Text28, null, /* @__PURE__ */ React33.createElement(Text28, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React33.createElement(Text28, { color: "blue" }, a.label), /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, " vs B="), /* @__PURE__ */ React33.createElement(Text28, { color: "magenta" }, b.label)), /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React33.createElement(Text28, null, /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, "cache "), /* @__PURE__ */ React33.createElement(Text28, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React33.createElement(Text28, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React33.createElement(Text28, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React33.createElement(Text28, null, /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, "cost "), /* @__PURE__ */ React33.createElement(Text28, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React33.createElement(Text28, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React33.createElement(Text28, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React33.createElement(Text28, null, /* @__PURE__ */ React33.createElement(Text28, { dimColor: true }, "model calls "), /* @__PURE__ */ React33.createElement(Text28, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text28, { dimColor: true, italic: true }, prefixLine)) : null);
23089
+ return /* @__PURE__ */ React36.createElement(Box32, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React36.createElement(Box32, { justifyContent: "space-between" }, /* @__PURE__ */ React36.createElement(Text31, null, /* @__PURE__ */ React36.createElement(Text31, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React36.createElement(Text31, { color: "blue" }, a.label), /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, " vs B="), /* @__PURE__ */ React36.createElement(Text31, { color: "magenta" }, b.label)), /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React36.createElement(Text31, null, /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, "cache "), /* @__PURE__ */ React36.createElement(Text31, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React36.createElement(Text31, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React36.createElement(Text31, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React36.createElement(Text31, null, /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, "cost "), /* @__PURE__ */ React36.createElement(Text31, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React36.createElement(Text31, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React36.createElement(Text31, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React36.createElement(Text31, null, /* @__PURE__ */ React36.createElement(Text31, { dimColor: true }, "model calls "), /* @__PURE__ */ React36.createElement(Text31, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React36.createElement(Text31, { dimColor: true, italic: true }, prefixLine)) : null);
22925
23090
  }
22926
23091
  function Pane({
22927
23092
  label,
22928
23093
  headerColor,
22929
23094
  records
22930
23095
  }) {
22931
- return /* @__PURE__ */ React33.createElement(
22932
- Box30,
23096
+ return /* @__PURE__ */ React36.createElement(
23097
+ Box32,
22933
23098
  {
22934
23099
  flexDirection: "column",
22935
23100
  flexGrow: 1,
@@ -22937,21 +23102,21 @@ function Pane({
22937
23102
  borderStyle: "single",
22938
23103
  borderColor: headerColor
22939
23104
  },
22940
- /* @__PURE__ */ React33.createElement(Text28, { color: headerColor, bold: true }, label),
22941
- records.length === 0 ? /* @__PURE__ */ React33.createElement(Box30, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(Text28, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React33.createElement(Static, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React33.createElement(RecordView, { key, rec, compact: true }))
23105
+ /* @__PURE__ */ React36.createElement(Text31, { color: headerColor, bold: true }, label),
23106
+ records.length === 0 ? /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React36.createElement(Text31, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React36.createElement(Static, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React36.createElement(RecordView, { key, rec, compact: true }))
22942
23107
  );
22943
23108
  }
22944
23109
  function KindBadge({ kind }) {
22945
23110
  if (kind === "match") {
22946
- return /* @__PURE__ */ React33.createElement(Text28, { color: "green" }, "\u2713 match");
23111
+ return /* @__PURE__ */ React36.createElement(Text31, { color: "green" }, "\u2713 match");
22947
23112
  }
22948
23113
  if (kind === "diverge") {
22949
- return /* @__PURE__ */ React33.createElement(Text28, { color: "yellow" }, "\u2605 diverge");
23114
+ return /* @__PURE__ */ React36.createElement(Text31, { color: "yellow" }, "\u2605 diverge");
22950
23115
  }
22951
23116
  if (kind === "only_in_a") {
22952
- return /* @__PURE__ */ React33.createElement(Text28, { color: "blue" }, "\u2190 only in A");
23117
+ return /* @__PURE__ */ React36.createElement(Text31, { color: "blue" }, "\u2190 only in A");
22953
23118
  }
22954
- return /* @__PURE__ */ React33.createElement(Text28, { color: "magenta" }, "\u2192 only in B");
23119
+ return /* @__PURE__ */ React36.createElement(Text31, { color: "magenta" }, "\u2192 only in B");
22955
23120
  }
22956
23121
  function paneRecords(pair, side) {
22957
23122
  if (!pair) return [];
@@ -22982,7 +23147,7 @@ markdown report written to ${opts.mdPath}`);
22982
23147
  return;
22983
23148
  }
22984
23149
  if (wantTui) {
22985
- const { waitUntilExit } = render2(React34.createElement(DiffApp, { report }), {
23150
+ const { waitUntilExit } = render2(React37.createElement(DiffApp, { report }), {
22986
23151
  exitOnCtrlC: true,
22987
23152
  patchConsole: false
22988
23153
  });
@@ -23622,44 +23787,32 @@ function pad3(s, width) {
23622
23787
 
23623
23788
  // src/cli/commands/replay.ts
23624
23789
  import { render as render3 } from "ink";
23625
- import React37 from "react";
23790
+ import React40 from "react";
23626
23791
 
23627
23792
  // src/cli/ui/ReplayApp.tsx
23628
- import { Box as Box32, Static as Static2, Text as Text30, useApp as useApp3, useInput as useInput2 } from "ink";
23629
- import React36, { useMemo as useMemo4, useState as useState14 } from "react";
23793
+ import { Box as Box34, Static as Static2, Text as Text33, useApp as useApp3, useInput as useInput2 } from "ink";
23794
+ import React39, { useMemo as useMemo5, useState as useState14 } from "react";
23630
23795
 
23631
23796
  // src/cli/ui/StatsPanel.tsx
23632
23797
  import { basename as basename5 } from "path";
23633
- import { Box as Box31, Text as Text29, useStdout as useStdout10 } from "ink";
23634
- import React35 from "react";
23635
- var NARROW_BREAKPOINT2 = 120;
23798
+ import { Box as Box33, Text as Text32, useStdout as useStdout12 } from "ink";
23799
+ import React38 from "react";
23800
+ import stringWidth4 from "string-width";
23636
23801
  var COLD_START_TURNS2 = 3;
23637
23802
  function StatsPanel({
23638
23803
  summary,
23639
- model: model2,
23640
- prefixHash,
23641
- harvestOn,
23642
- branchBudget,
23643
- reasoningEffort,
23644
23804
  planMode,
23645
23805
  editMode,
23646
23806
  balance,
23647
23807
  updateAvailable,
23648
- busy,
23649
23808
  proArmed,
23650
23809
  escalated,
23651
23810
  budgetUsd,
23652
23811
  rootDir,
23653
23812
  sessionName
23654
23813
  }) {
23655
- const branchOn = (branchBudget ?? 1) > 1;
23656
- const ctxMax = DEEPSEEK_CONTEXT_TOKENS[model2] ?? DEFAULT_CONTEXT_TOKENS;
23657
- const ctxRatio = summary.lastPromptTokens / ctxMax;
23658
- const { stdout: stdout4 } = useStdout10();
23659
- const columns = stdout4?.columns ?? 80;
23660
- const narrow = columns < NARROW_BREAKPOINT2;
23661
23814
  const coldStart = summary.turns <= COLD_START_TURNS2;
23662
- return /* @__PURE__ */ React35.createElement(Box31, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React35.createElement(
23815
+ return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React38.createElement(
23663
23816
  ChromeRow,
23664
23817
  {
23665
23818
  editMode,
@@ -23671,16 +23824,9 @@ function StatsPanel({
23671
23824
  rootDir,
23672
23825
  sessionName: sessionName ?? null,
23673
23826
  updateAvailable,
23674
- balance: balance ?? null,
23675
- narrow
23827
+ balance: balance ?? null
23676
23828
  }
23677
- ), /* @__PURE__ */ React35.createElement(ChromeRule2, null), budgetUsd !== null && budgetUsd !== void 0 ? /* @__PURE__ */ React35.createElement(BudgetRow, { spent: summary.totalCostUsd, cap: budgetUsd }) : null);
23678
- }
23679
- function ChromeRule2() {
23680
- const { stdout: stdout4 } = useStdout10();
23681
- const cols = stdout4?.columns ?? 80;
23682
- const w = Math.max(20, cols - 2);
23683
- return /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, "\u2500".repeat(w));
23829
+ ), /* @__PURE__ */ React38.createElement(ChromeRule, null), budgetUsd !== null && budgetUsd !== void 0 ? /* @__PURE__ */ React38.createElement(BudgetRow, { spent: summary.totalCostUsd, cap: budgetUsd }) : null);
23684
23830
  }
23685
23831
  function ChromeRow({
23686
23832
  editMode,
@@ -23692,23 +23838,56 @@ function ChromeRow({
23692
23838
  rootDir,
23693
23839
  sessionName,
23694
23840
  updateAvailable,
23695
- balance,
23696
- narrow
23841
+ balance
23697
23842
  }) {
23698
23843
  const modePill = pickModePill2(planMode, editMode);
23699
23844
  const proPill = escalated ? { label: "\u21E7 pro", color: COLOR.err } : proArmed ? { label: "\u21E7 pro", color: COLOR.warn } : null;
23700
23845
  const projectName = rootDir ? basename5(rootDir) : null;
23701
23846
  const cachePct = Math.round(summary.cacheHitRatio * 100);
23702
23847
  const cacheColor = summary.cacheHitRatio >= 0.7 ? COLOR.ok : summary.cacheHitRatio >= 0.4 ? COLOR.warn : COLOR.err;
23703
- return /* @__PURE__ */ React35.createElement(Box31, null, /* @__PURE__ */ React35.createElement(Text29, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React35.createElement(Text29, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React35.createElement(Text29, null, projectName), !narrow && sessionName ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React35.createElement(Text29, { color: COLOR.info }, sessionName)) : null) : null, /* @__PURE__ */ React35.createElement(Box31, { flexGrow: 1 }), updateAvailable ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, { color: COLOR.warn, bold: true }, `\u2191 ${updateAvailable}`), /* @__PURE__ */ React35.createElement(Text29, null, " ")) : null, modePill ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, { color: modePill.color, bold: true }, `[${modePill.label}]`), /* @__PURE__ */ React35.createElement(Text29, null, " ")) : null, proPill ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React35.createElement(Text29, null, " ")) : null, /* @__PURE__ */ React35.createElement(
23704
- Text29,
23848
+ const balanceLabel = balance ? `[w ${balance.currency === "USD" ? "$" : ""}${balance.total.toFixed(2)}${balance.currency !== "USD" ? ` ${balance.currency}` : ""}]` : "";
23849
+ const costLabel = `[$${summary.totalCostUsd.toFixed(4)}]`;
23850
+ const cacheLabel = "[c \u25B0\u25B0\u25B0\u25B0\u25B0\u25B0 100%]";
23851
+ const updateLabel = updateAvailable ? `\u2191 ${updateAvailable}` : "";
23852
+ const { stdout: stdout4 } = useStdout12();
23853
+ const cols = (stdout4?.columns ?? 80) - 2;
23854
+ const SEP_DOT = stringWidth4(" \xB7 ");
23855
+ const SEP_ARROW = stringWidth4(" \u203A ");
23856
+ const GAP = 2;
23857
+ const fixedLeft = stringWidth4("\u25C8 reasonix") + (projectName ? SEP_DOT + stringWidth4(projectName) : 0);
23858
+ const modeW = modePill ? GAP + stringWidth4(`[${modePill.label}]`) : 0;
23859
+ const proW = proPill ? GAP + stringWidth4(`[${proPill.label}]`) : 0;
23860
+ const fixedRight = modeW + proW + stringWidth4(costLabel);
23861
+ let budget2 = cols - fixedLeft - fixedRight;
23862
+ const balW = balance ? GAP + stringWidth4(balanceLabel) : 0;
23863
+ const cacheW = GAP + stringWidth4(cacheLabel);
23864
+ const sessionW = sessionName ? SEP_ARROW + stringWidth4(sessionName) : 0;
23865
+ const updateW = updateLabel ? GAP + stringWidth4(updateLabel) : 0;
23866
+ const showBalance = balW > 0 && budget2 >= balW;
23867
+ if (showBalance) budget2 -= balW;
23868
+ const showCache = budget2 >= cacheW;
23869
+ if (showCache) budget2 -= cacheW;
23870
+ const showSession = sessionW > 0 && budget2 >= sessionW;
23871
+ if (showSession) budget2 -= sessionW;
23872
+ const showUpdate = updateW > 0 && budget2 >= updateW;
23873
+ if (showUpdate) budget2 -= updateW;
23874
+ return /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text32, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React38.createElement(Text32, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React38.createElement(Text32, null, projectName), showSession && sessionName ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React38.createElement(Text32, { color: COLOR.info }, sessionName)) : null) : null, /* @__PURE__ */ React38.createElement(Box33, { flexGrow: 1 }), showUpdate ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, { color: COLOR.warn, bold: true }, updateLabel), /* @__PURE__ */ React38.createElement(Text32, null, " ")) : null, modePill ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, { color: modePill.color, bold: true }, `[${modePill.label}]`), /* @__PURE__ */ React38.createElement(Text32, null, " ")) : null, proPill ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React38.createElement(Text32, null, " ")) : null, /* @__PURE__ */ React38.createElement(
23875
+ Text32,
23705
23876
  {
23706
23877
  color: summary.turns === 0 || coldStart ? COLOR.info : sessionCostColor2(summary.totalCostUsd),
23707
23878
  bold: summary.turns > 0 && !coldStart,
23708
23879
  dimColor: summary.turns === 0 || coldStart
23709
23880
  },
23710
- `[$${summary.totalCostUsd.toFixed(4)}]`
23711
- ), balance && !narrow ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, null, " "), /* @__PURE__ */ React35.createElement(Text29, { color: balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok }, `[w ${balance.currency === "USD" ? "$" : ""}${balance.total.toFixed(2)}${balance.currency !== "USD" ? ` ${balance.currency}` : ""}]`)) : null, summary.turns > 3 && !narrow ? /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(Text29, null, " "), /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, "["), /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, "c "), /* @__PURE__ */ React35.createElement(Bar, { ratio: summary.cacheHitRatio, color: cacheColor, cells: 6 }), /* @__PURE__ */ React35.createElement(Text29, null, " "), /* @__PURE__ */ React35.createElement(Text29, { color: cacheColor }, `${cachePct}%`), /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, "]")) : null);
23881
+ costLabel
23882
+ ), showBalance && balance ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, null, " "), /* @__PURE__ */ React38.createElement(Text32, { color: balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok }, balanceLabel)) : null, showCache ? /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(Text32, null, " "), /* @__PURE__ */ React38.createElement(Text32, { dimColor: true }, "["), /* @__PURE__ */ React38.createElement(Text32, { dimColor: true }, "c "), /* @__PURE__ */ React38.createElement(
23883
+ Bar,
23884
+ {
23885
+ ratio: summary.cacheHitRatio,
23886
+ color: coldStart ? COLOR.info : cacheColor,
23887
+ cells: 6,
23888
+ dim: coldStart
23889
+ }
23890
+ ), /* @__PURE__ */ React38.createElement(Text32, null, " "), /* @__PURE__ */ React38.createElement(Text32, { color: coldStart ? void 0 : cacheColor, dimColor: coldStart }, coldStart && summary.turns === 0 ? "\u2014" : `${cachePct}%`), /* @__PURE__ */ React38.createElement(Text32, { dimColor: true }, "]")) : null);
23712
23891
  }
23713
23892
  function pickModePill2(planMode, editMode) {
23714
23893
  if (planMode) return { label: "PLAN", color: COLOR.err };
@@ -23720,7 +23899,7 @@ function pickModePill2(planMode, editMode) {
23720
23899
  function BudgetRow({ spent, cap }) {
23721
23900
  const pct2 = Math.max(0, spent / cap * 100);
23722
23901
  const color2 = pct2 >= 100 ? "#f87171" : pct2 >= 80 ? "#fbbf24" : "#94a3b8";
23723
- return /* @__PURE__ */ React35.createElement(Box31, null, /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, " budget "), /* @__PURE__ */ React35.createElement(Text29, { color: color2 }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
23902
+ return /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text32, { dimColor: true }, " budget "), /* @__PURE__ */ React38.createElement(Text32, { color: color2 }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React38.createElement(Text32, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
23724
23903
  }
23725
23904
  function sessionCostColor2(cost) {
23726
23905
  if (cost <= 0) return void 0;
@@ -23728,14 +23907,6 @@ function sessionCostColor2(cost) {
23728
23907
  if (cost >= 0.5) return COLOR.warn;
23729
23908
  return COLOR.ok;
23730
23909
  }
23731
- function Bar({
23732
- ratio,
23733
- color: color2,
23734
- cells = 14
23735
- }) {
23736
- const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
23737
- return /* @__PURE__ */ React35.createElement(Text29, null, /* @__PURE__ */ React35.createElement(Text29, { color: color2 }, "\u25B0".repeat(filled)), /* @__PURE__ */ React35.createElement(Text29, { dimColor: true }, "\u25B1".repeat(cells - filled)));
23738
- }
23739
23910
 
23740
23911
  // src/cli/ui/ReplayApp.tsx
23741
23912
  function ReplayApp({ meta, pages }) {
@@ -23761,7 +23932,7 @@ function ReplayApp({ meta, pages }) {
23761
23932
  setIdx(maxIdx);
23762
23933
  }
23763
23934
  });
23764
- const cumStats = useMemo4(() => computeCumulativeStats(pages, idx), [pages, idx]);
23935
+ const cumStats = useMemo5(() => computeCumulativeStats(pages, idx), [pages, idx]);
23765
23936
  const summary = {
23766
23937
  turns: cumStats.turns,
23767
23938
  totalCostUsd: cumStats.totalCostUsd,
@@ -23777,14 +23948,7 @@ function ReplayApp({ meta, pages }) {
23777
23948
  const prefixHash = cumStats.prefixHashes.length === 1 ? cumStats.prefixHashes[0].slice(0, 16) : cumStats.prefixHashes.length === 0 ? "(untracked)" : `(churned \xD7${cumStats.prefixHashes.length})`;
23778
23949
  const currentPage = pages[idx];
23779
23950
  const progressLabel = pages.length === 0 ? "empty transcript" : `turn ${idx + 1} / ${pages.length}`;
23780
- return /* @__PURE__ */ React36.createElement(Box32, { flexDirection: "column" }, /* @__PURE__ */ React36.createElement(
23781
- StatsPanel,
23782
- {
23783
- summary,
23784
- model: cumStats.models[0] ?? meta?.model ?? "?",
23785
- prefixHash
23786
- }
23787
- ), /* @__PURE__ */ React36.createElement(Box32, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React36.createElement(Box32, { justifyContent: "space-between" }, /* @__PURE__ */ React36.createElement(Text30, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React36.createElement(Text30, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React36.createElement(Static2, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React36.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React36.createElement(Text30, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React36.createElement(Box32, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React36.createElement(Text30, { dimColor: true }, /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "j"), "/", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "k"), "/", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React36.createElement(Text30, { bold: true }, "q"), " quit")));
23951
+ return /* @__PURE__ */ React39.createElement(Box34, { flexDirection: "column" }, /* @__PURE__ */ React39.createElement(StatsPanel, { summary }), /* @__PURE__ */ React39.createElement(Box34, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React39.createElement(Box34, { justifyContent: "space-between" }, /* @__PURE__ */ React39.createElement(Text33, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React39.createElement(Text33, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React39.createElement(Static2, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React39.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React39.createElement(Text33, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React39.createElement(Box34, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React39.createElement(Text33, { dimColor: true }, /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "j"), "/", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "k"), "/", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React39.createElement(Text33, { bold: true }, "q"), " quit")));
23788
23952
  }
23789
23953
 
23790
23954
  // src/cli/commands/replay.ts
@@ -23796,7 +23960,7 @@ async function replayCommand(opts) {
23796
23960
  }
23797
23961
  const { parsed } = replayFromFile(opts.path);
23798
23962
  const pages = groupRecordsByTurn(parsed.records);
23799
- const { waitUntilExit } = render3(React37.createElement(ReplayApp, { meta: parsed.meta, pages }), {
23963
+ const { waitUntilExit } = render3(React40.createElement(ReplayApp, { meta: parsed.meta, pages }), {
23800
23964
  exitOnCtrlC: true,
23801
23965
  patchConsole: false
23802
23966
  });
@@ -24102,12 +24266,12 @@ function truncate3(s, max) {
24102
24266
 
24103
24267
  // src/cli/commands/setup.tsx
24104
24268
  import { render as render4 } from "ink";
24105
- import React39 from "react";
24269
+ import React42 from "react";
24106
24270
 
24107
24271
  // src/cli/ui/Wizard.tsx
24108
- import { Box as Box33, Text as Text31, useApp as useApp4, useInput as useInput3 } from "ink";
24272
+ import { Box as Box35, Text as Text34, useApp as useApp4, useInput as useInput3 } from "ink";
24109
24273
  import TextInput2 from "ink-text-input";
24110
- import React38, { useState as useState15 } from "react";
24274
+ import React41, { useState as useState15 } from "react";
24111
24275
  var CATALOG_BY_NAME = new Map(MCP_CATALOG.map((e) => [e.name, e]));
24112
24276
  function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24113
24277
  const { exit: exit2 } = useApp4();
@@ -24123,7 +24287,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24123
24287
  if (key.escape && step !== "saved" && onCancel) onCancel();
24124
24288
  });
24125
24289
  if (step === "apiKey") {
24126
- return /* @__PURE__ */ React38.createElement(
24290
+ return /* @__PURE__ */ React41.createElement(
24127
24291
  ApiKeyStep,
24128
24292
  {
24129
24293
  onSubmit: (key) => {
@@ -24137,7 +24301,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24137
24301
  );
24138
24302
  }
24139
24303
  if (step === "preset") {
24140
- return /* @__PURE__ */ React38.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React38.createElement(
24304
+ return /* @__PURE__ */ React41.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React41.createElement(
24141
24305
  SingleSelect,
24142
24306
  {
24143
24307
  items: presetItems(),
@@ -24147,10 +24311,10 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24147
24311
  setStep("mcp");
24148
24312
  }
24149
24313
  }
24150
- ), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
24314
+ ), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
24151
24315
  }
24152
24316
  if (step === "mcp") {
24153
- return /* @__PURE__ */ React38.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React38.createElement(
24317
+ return /* @__PURE__ */ React41.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React41.createElement(
24154
24318
  MultiSelect,
24155
24319
  {
24156
24320
  items: mcpItems(),
@@ -24175,7 +24339,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24175
24339
  }
24176
24340
  const currentName = pending[0];
24177
24341
  const entry = CATALOG_BY_NAME.get(currentName);
24178
- return /* @__PURE__ */ React38.createElement(
24342
+ return /* @__PURE__ */ React41.createElement(
24179
24343
  McpArgsStep,
24180
24344
  {
24181
24345
  entry,
@@ -24193,7 +24357,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24193
24357
  }
24194
24358
  if (step === "review") {
24195
24359
  const specs = data.selectedCatalog.map((name) => buildSpec(name, data.catalogArgs));
24196
- return /* @__PURE__ */ React38.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, /* @__PURE__ */ React38.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React38.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React38.createElement(
24360
+ return /* @__PURE__ */ React41.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React41.createElement(Box35, { flexDirection: "column" }, /* @__PURE__ */ React41.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React41.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React41.createElement(
24197
24361
  SummaryLine,
24198
24362
  {
24199
24363
  label: "MCP",
@@ -24201,8 +24365,8 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24201
24365
  }
24202
24366
  ), specs.map((spec, i) => (
24203
24367
  // biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
24204
- /* @__PURE__ */ React38.createElement(Box33, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "\xB7 ", spec))
24205
- )), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { color: "red" }, error)) : null, /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React38.createElement(
24368
+ /* @__PURE__ */ React41.createElement(Box35, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "\xB7 ", spec))
24369
+ )), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { color: "red" }, error)) : null, /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React41.createElement(
24206
24370
  ReviewConfirm,
24207
24371
  {
24208
24372
  onConfirm: () => {
@@ -24228,7 +24392,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
24228
24392
  }
24229
24393
  ));
24230
24394
  }
24231
- return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React38.createElement(Text31, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React38.createElement(ExitOnEnter, { onExit: exit2 }));
24395
+ return /* @__PURE__ */ React41.createElement(Box35, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React41.createElement(Text34, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React41.createElement(ExitOnEnter, { onExit: exit2 }));
24232
24396
  }
24233
24397
  function ApiKeyStep({
24234
24398
  onSubmit,
@@ -24236,7 +24400,7 @@ function ApiKeyStep({
24236
24400
  onError
24237
24401
  }) {
24238
24402
  const [value, setValue] = useState15("");
24239
- return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React38.createElement(Text31, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React38.createElement(
24403
+ return /* @__PURE__ */ React41.createElement(Box35, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React41.createElement(Text34, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React41.createElement(
24240
24404
  TextInput2,
24241
24405
  {
24242
24406
  value,
@@ -24253,7 +24417,7 @@ function ApiKeyStep({
24253
24417
  mask: "\u2022",
24254
24418
  placeholder: "sk-..."
24255
24419
  }
24256
- )), error ? /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { color: "red" }, error)) : value ? /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "preview: ", redactKey(value))) : null);
24420
+ )), error ? /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { color: "red" }, error)) : value ? /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "preview: ", redactKey(value))) : null);
24257
24421
  }
24258
24422
  function McpArgsStep({
24259
24423
  entry,
@@ -24262,7 +24426,7 @@ function McpArgsStep({
24262
24426
  onError
24263
24427
  }) {
24264
24428
  const [value, setValue] = useState15("");
24265
- return /* @__PURE__ */ React38.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, /* @__PURE__ */ React38.createElement(Text31, null, entry.summary), entry.note ? /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, null, "Required parameter: "), /* @__PURE__ */ React38.createElement(Text31, { bold: true }, entry.userArgs)), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React38.createElement(
24429
+ return /* @__PURE__ */ React41.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React41.createElement(Box35, { flexDirection: "column" }, /* @__PURE__ */ React41.createElement(Text34, null, entry.summary), entry.note ? /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, null, "Required parameter: "), /* @__PURE__ */ React41.createElement(Text34, { bold: true }, entry.userArgs)), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React41.createElement(
24266
24430
  TextInput2,
24267
24431
  {
24268
24432
  value,
@@ -24278,7 +24442,7 @@ function McpArgsStep({
24278
24442
  },
24279
24443
  placeholder: placeholderFor(entry)
24280
24444
  }
24281
- )), error ? /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1 }, /* @__PURE__ */ React38.createElement(Text31, { color: "red" }, error)) : null));
24445
+ )), error ? /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1 }, /* @__PURE__ */ React41.createElement(Text34, { color: "red" }, error)) : null));
24282
24446
  }
24283
24447
  function ReviewConfirm({ onConfirm }) {
24284
24448
  useInput3((_i, key) => {
@@ -24298,10 +24462,10 @@ function StepFrame({
24298
24462
  total,
24299
24463
  children
24300
24464
  }) {
24301
- return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text31, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React38.createElement(Text31, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React38.createElement(Box33, { marginTop: 1, flexDirection: "column" }, children));
24465
+ return /* @__PURE__ */ React41.createElement(Box35, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React41.createElement(Box35, null, /* @__PURE__ */ React41.createElement(Text34, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React41.createElement(Text34, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React41.createElement(Box35, { marginTop: 1, flexDirection: "column" }, children));
24302
24466
  }
24303
24467
  function SummaryLine({ label, value }) {
24304
- return /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text31, null, label.padEnd(12)), /* @__PURE__ */ React38.createElement(Text31, { bold: true }, value));
24468
+ return /* @__PURE__ */ React41.createElement(Box35, null, /* @__PURE__ */ React41.createElement(Text34, null, label.padEnd(12)), /* @__PURE__ */ React41.createElement(Text34, { bold: true }, value));
24305
24469
  }
24306
24470
  function presetItems() {
24307
24471
  return ["auto", "flash", "pro"].map((name) => ({
@@ -24357,7 +24521,7 @@ async function setupCommand(_opts = {}) {
24357
24521
  const existingKey = loadApiKey();
24358
24522
  const existing = readConfig();
24359
24523
  const { waitUntilExit, unmount } = render4(
24360
- /* @__PURE__ */ React39.createElement(
24524
+ /* @__PURE__ */ React42.createElement(
24361
24525
  Wizard,
24362
24526
  {
24363
24527
  existingApiKey: existingKey,