@crazyhappyone/dsh-tui 0.1.0-alpha.26 → 0.1.0-alpha.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // tui-render/src/index.ts
2
2
  import { render, renderToString, Text as Text32 } from "ink";
3
- import { createElement as createElement3 } from "react";
3
+ import React, { createElement as createElement3 } from "react";
4
4
 
5
5
  // tui-render/src/app-shell.tsx
6
6
  import { Box, Text, useWindowSize } from "ink";
@@ -126,20 +126,20 @@ function wrapDisplayLines(text, maxCols) {
126
126
  const source = text.split("\n");
127
127
  if (maxCols <= 0) return source;
128
128
  const out = [];
129
- for (const line8 of source) {
130
- if (line8 === "" || displayWidth(line8) <= maxCols) {
131
- out.push(line8);
129
+ for (const line5 of source) {
130
+ if (line5 === "" || displayWidth(line5) <= maxCols) {
131
+ out.push(line5);
132
132
  continue;
133
133
  }
134
- if (/^[\x20-\x7e]*$/u.test(line8)) {
135
- for (let i = 0; i < line8.length; i += maxCols) {
136
- out.push(line8.slice(i, i + maxCols));
134
+ if (/^[\x20-\x7e]*$/u.test(line5)) {
135
+ for (let i = 0; i < line5.length; i += maxCols) {
136
+ out.push(line5.slice(i, i + maxCols));
137
137
  }
138
138
  continue;
139
139
  }
140
140
  let curLine = "";
141
141
  let curCols = 0;
142
- for (const { segment: segment2 } of GRAPHEME.segment(line8)) {
142
+ for (const { segment: segment2 } of GRAPHEME.segment(line5)) {
143
143
  const width = displayWidth(segment2);
144
144
  if (curCols + width > maxCols && curLine !== "") {
145
145
  out.push(curLine);
@@ -225,7 +225,7 @@ var THEME_LEVELS = {
225
225
  truecolor: {
226
226
  bg: "#151618",
227
227
  messageBg: "#25282C",
228
- toolBg: "#1A1C1F",
228
+ toolBg: "#252830",
229
229
  inputBg: "#23262B",
230
230
  codeBg: "#202328",
231
231
  fg: "#EEF0F2",
@@ -250,7 +250,7 @@ var THEME_LEVELS = {
250
250
  "256": {
251
251
  bg: "233",
252
252
  messageBg: "235",
253
- toolBg: "234",
253
+ toolBg: "236",
254
254
  inputBg: "235",
255
255
  codeBg: "235",
256
256
  fg: "255",
@@ -856,11 +856,11 @@ function trimPartialClosingFence(root, source) {
856
856
  }
857
857
 
858
858
  // tui-render/src/painted-line.ts
859
- function paintLineFromRenderLine(line8, hyperlinks2 = hyperlinksEnabled()) {
860
- if (line8.spans.length === 0) return paintRow([]);
859
+ function paintLineFromRenderLine(line5, hyperlinks2 = hyperlinksEnabled()) {
860
+ if (line5.spans.length === 0) return paintRow([]);
861
861
  const parts = [];
862
- for (const span of line8.spans) {
863
- const text = displayColumnSlice(line8.text, span.start, span.end);
862
+ for (const span of line5.spans) {
863
+ const text = displayColumnSlice(line5.text, span.start, span.end);
864
864
  if (text === "") continue;
865
865
  const styledText = styled(text, span.token, void 0, span.bold);
866
866
  if (span.href !== void 0 && hyperlinks2 && isOsc8Href(span.href)) {
@@ -869,11 +869,11 @@ function paintLineFromRenderLine(line8, hyperlinks2 = hyperlinksEnabled()) {
869
869
  parts.push(styledText);
870
870
  }
871
871
  }
872
- if (line8.background !== void 0 && line8.background !== "bg") {
872
+ if (line5.background !== void 0 && line5.background !== "bg") {
873
873
  return paintBackgroundRow(
874
874
  parts,
875
- line8.background,
876
- line8.backgroundColumns ?? Math.max(line8.displayWidth, 1)
875
+ line5.background,
876
+ line5.backgroundColumns ?? Math.max(line5.displayWidth, 1)
877
877
  );
878
878
  }
879
879
  return paintRow(parts);
@@ -893,10 +893,10 @@ var PLAIN_TEXT_RENDERER = {
893
893
  if (text === "") return [emptyLine(blockIndex)];
894
894
  const wrapped = wrapDisplayLines(text, scope.width);
895
895
  const startOffset = node.position?.start.offset ?? 0;
896
- return wrapped.map((line8, index) => ({
897
- text: line8,
898
- displayWidth: displayWidth(line8),
899
- spans: [{ start: 0, end: displayWidth(line8), token: "fg", bold: false }],
896
+ return wrapped.map((line5, index) => ({
897
+ text: line5,
898
+ displayWidth: displayWidth(line5),
899
+ spans: [{ start: 0, end: displayWidth(line5), token: "fg", bold: false }],
900
900
  rowInBlock: index,
901
901
  sourceStart: index === 0 ? startOffset : -1,
902
902
  sourceEnd: -1,
@@ -1410,7 +1410,7 @@ function appendedRowsPreserveTableMetrics(rows, metrics) {
1410
1410
  const metric = metrics[column];
1411
1411
  const values = rows.map((row) => row[column] ?? "");
1412
1412
  for (const value of values) {
1413
- if (value.split("\n").some((line8) => !metric.wrapWidths.includes(displayWidth(line8)))) return false;
1413
+ if (value.split("\n").some((line5) => !metric.wrapWidths.includes(displayWidth(line5)))) return false;
1414
1414
  if (longestFittingIdentifier(value, DEFAULT_WORD_CAP) > metric.minimum) return false;
1415
1415
  }
1416
1416
  const appendedCategory = classifyColumn(values);
@@ -1562,16 +1562,16 @@ function buildGridLayout(headerCells, bodyCells, metrics, widths, maxCols, divid
1562
1562
  const ruleMid = ruleText(widths, "mid", dividerChar);
1563
1563
  const ruleBottom = ruleText(widths, "bottom", dividerChar);
1564
1564
  lines.push({ kind: "rule", text: ruleTop });
1565
- for (const line8 of wrapRow(headerCells, widths, true)) {
1566
- lines.push(line8);
1565
+ for (const line5 of wrapRow(headerCells, widths, true)) {
1566
+ lines.push(line5);
1567
1567
  }
1568
1568
  lines.push({ kind: "rule", text: ruleMid });
1569
1569
  let previousMultiline = false;
1570
1570
  for (const [index, row] of bodyCells.entries()) {
1571
1571
  const multiline = isMultilineTableRow(row.map((cell) => cell.text), widths);
1572
1572
  if (index > 0 && (previousMultiline || multiline)) lines.push({ kind: "rule", text: ruleMid });
1573
- for (const line8 of wrapRow(row, widths, false)) {
1574
- lines.push(line8);
1573
+ for (const line5 of wrapRow(row, widths, false)) {
1574
+ lines.push(line5);
1575
1575
  }
1576
1576
  previousMultiline = multiline;
1577
1577
  }
@@ -1611,18 +1611,18 @@ function wrapTableCell(text, width) {
1611
1611
  if (width <= 0) return text.split("\n");
1612
1612
  const out = [];
1613
1613
  for (const source of text.split("\n")) {
1614
- let line8 = "";
1614
+ let line5 = "";
1615
1615
  for (const token of source.match(/\s+|\S+/gu) ?? []) {
1616
- if (displayWidth(line8 + token) <= width) {
1617
- line8 += token;
1616
+ if (displayWidth(line5 + token) <= width) {
1617
+ line5 += token;
1618
1618
  continue;
1619
1619
  }
1620
- if (line8.trimEnd() !== "") out.push(line8.trimEnd());
1620
+ if (line5.trimEnd() !== "") out.push(line5.trimEnd());
1621
1621
  const pieces = wrapDisplayLines(token.trimStart(), width);
1622
1622
  out.push(...pieces.slice(0, -1));
1623
- line8 = pieces.at(-1) ?? "";
1623
+ line5 = pieces.at(-1) ?? "";
1624
1624
  }
1625
- out.push(line8.trimEnd());
1625
+ out.push(line5.trimEnd());
1626
1626
  }
1627
1627
  return out;
1628
1628
  }
@@ -1827,9 +1827,9 @@ function renderHeading(node, width, rowOffset, sourceStart) {
1827
1827
  const prefix = depth ? "\u2501\u2501\u2501 " : "\u2501 ";
1828
1828
  const suffix = depth ? " \u2501\u2501\u2501" : "";
1829
1829
  const wrapped = wrapDisplayLines(`${prefix}${escapeContent(formatSymbolSpacing(text))}${suffix}`, width);
1830
- return wrapped.map((line8, index) => {
1830
+ return wrapped.map((line5, index) => {
1831
1831
  const buffer = makeBuffer();
1832
- appendSegment(buffer, { text: line8, token: "accentText", bold: true });
1832
+ appendSegment(buffer, { text: line5, token: "accentText", bold: true });
1833
1833
  return freezeLine(buffer, rowOffset + index, index === 0 ? sourceStart : -1);
1834
1834
  });
1835
1835
  }
@@ -1838,9 +1838,9 @@ function renderBlockquote(children, width, rowOffset, sourceStart, hyperlinks2)
1838
1838
  for (const child of children) segments.push(...inlineToSegments(child, hyperlinks2));
1839
1839
  const merged = segments.map((s) => s.text).join("");
1840
1840
  const wrapped = wrapDisplayLines(`\u2502 ${escapeContent(merged)}`, width);
1841
- return wrapped.map((line8, index) => {
1841
+ return wrapped.map((line5, index) => {
1842
1842
  const buffer = makeBuffer();
1843
- appendSegment(buffer, { text: line8, token: "fgDim", bold: false });
1843
+ appendSegment(buffer, { text: line5, token: "fgDim", bold: false });
1844
1844
  return freezeLine(buffer, rowOffset + index, index === 0 ? sourceStart : -1);
1845
1845
  });
1846
1846
  }
@@ -1860,8 +1860,8 @@ function renderCode(value, width, rowOffset, sourceStart) {
1860
1860
  const lines = value.split("\n");
1861
1861
  const out = [];
1862
1862
  let row = rowOffset;
1863
- for (const [index, line8] of lines.entries()) {
1864
- const wrapped = wrapDisplayLines(escapeContent(line8), Math.max(1, width - 2));
1863
+ for (const [index, line5] of lines.entries()) {
1864
+ const wrapped = wrapDisplayLines(escapeContent(line5), Math.max(1, width - 2));
1865
1865
  if (wrapped.length === 0) {
1866
1866
  out.push(freezeEmpty(row, index === 0 ? sourceStart : -1));
1867
1867
  row += 1;
@@ -1873,12 +1873,12 @@ function renderCode(value, width, rowOffset, sourceStart) {
1873
1873
  for (const tk of tokens) {
1874
1874
  appendSegment(buffer, { text: tk.text, token: tk.token, bold: tk.bold });
1875
1875
  }
1876
- const line9 = freezeLine(
1876
+ const line6 = freezeLine(
1877
1877
  buffer,
1878
1878
  row,
1879
1879
  index === 0 && partIndex === 0 ? sourceStart : -1
1880
1880
  );
1881
- out.push({ ...line9, background: "codeBg" });
1881
+ out.push({ ...line6, background: "codeBg" });
1882
1882
  row += 1;
1883
1883
  }
1884
1884
  }
@@ -1982,8 +1982,8 @@ function renderTableCells(cells, width, rowOffset, sourceStart) {
1982
1982
  renderRecordLayout(layout, Math.max(1, width), appendLine);
1983
1983
  return lines;
1984
1984
  }
1985
- for (const line8 of layout.lines) {
1986
- appendLine(gridLayoutSegments(line8));
1985
+ for (const line5 of layout.lines) {
1986
+ appendLine(gridLayoutSegments(line5));
1987
1987
  }
1988
1988
  return lines;
1989
1989
  }
@@ -2125,44 +2125,44 @@ function renderGridRow(row, widths, header, rowOffset, sourceStart) {
2125
2125
  }
2126
2126
  return out;
2127
2127
  }
2128
- function gridLayoutSegments(line8) {
2129
- if (line8.kind === "rule" || line8.kind === "plain") {
2130
- return [{ text: line8.text, token: line8.kind === "rule" ? "fgDim" : "fg", bold: false }];
2128
+ function gridLayoutSegments(line5) {
2129
+ if (line5.kind === "rule" || line5.kind === "plain") {
2130
+ return [{ text: line5.text, token: line5.kind === "rule" ? "fgDim" : "fg", bold: false }];
2131
2131
  }
2132
- if (line8.kind === "record") return [];
2132
+ if (line5.kind === "record") return [];
2133
2133
  const segments = [{ text: "\u2502 ", token: "fgDim", bold: false }];
2134
- for (const [index, cell] of line8.cells.entries()) {
2134
+ for (const [index, cell] of line5.cells.entries()) {
2135
2135
  if (index > 0) segments.push({ text: " \u2502 ", token: "fgDim", bold: false });
2136
2136
  segments.push({
2137
2137
  text: cell.text,
2138
- token: line8.header ? "accentText" : "fg",
2139
- bold: line8.header
2138
+ token: line5.header ? "accentText" : "fg",
2139
+ bold: line5.header
2140
2140
  });
2141
2141
  }
2142
2142
  segments.push({ text: " \u2502", token: "fgDim", bold: false });
2143
2143
  return segments;
2144
2144
  }
2145
2145
  function renderRecordLayout(layout, width, appendLine) {
2146
- const records = layout.lines.filter((line8) => line8.kind === "record");
2146
+ const records = layout.lines.filter((line5) => line5.kind === "record");
2147
2147
  if (records.length <= 1) {
2148
2148
  const header = layout.header.map((cell) => cell.text).join(" | ");
2149
- for (const line8 of wrapDisplayLines(header, width)) {
2150
- appendLine([{ text: line8, token: "accentText", bold: true }]);
2149
+ for (const line5 of wrapDisplayLines(header, width)) {
2150
+ appendLine([{ text: line5, token: "accentText", bold: true }]);
2151
2151
  }
2152
2152
  return;
2153
2153
  }
2154
- for (const line8 of layout.lines) {
2155
- if (line8.kind === "rule") {
2156
- appendLine([{ text: line8.text, token: "fgDim", bold: false }]);
2154
+ for (const line5 of layout.lines) {
2155
+ if (line5.kind === "rule") {
2156
+ appendLine([{ text: line5.text, token: "fgDim", bold: false }]);
2157
2157
  continue;
2158
2158
  }
2159
- if (line8.kind !== "record" || line8.key.row === 0) continue;
2159
+ if (line5.kind !== "record" || line5.key.row === 0) continue;
2160
2160
  const keyLabel = layout.header[0]?.text ?? "key";
2161
- const keyText = keyLabel === "" ? line8.key.text : `${keyLabel}: ${line8.key.text}`;
2161
+ const keyText = keyLabel === "" ? line5.key.text : `${keyLabel}: ${line5.key.text}`;
2162
2162
  for (const text of wrapTableCell(keyText, width)) {
2163
2163
  appendLine([{ text, token: "accentText", bold: true }]);
2164
2164
  }
2165
- for (const value of line8.values) {
2165
+ for (const value of line5.values) {
2166
2166
  const label = layout.header[value.column]?.text ?? `#${String(value.column + 1)}`;
2167
2167
  const indent = wcwidthSafeSlice(layout.valueIndent, Math.max(0, width - 1));
2168
2168
  for (const text of wrapTableCell(`${label}: ${value.text}`, width - displayWidth(indent))) {
@@ -2308,19 +2308,19 @@ var TableScanner = class {
2308
2308
  if (buf.charCodeAt(i) === 10) {
2309
2309
  let end = i;
2310
2310
  if (end > lineStart && buf.charCodeAt(end - 1) === 13) end -= 1;
2311
- const line8 = buf.slice(lineStart, end);
2311
+ const line5 = buf.slice(lineStart, end);
2312
2312
  const startOff = this.bufferBaseOffset + lineStart;
2313
2313
  const endOff = this.bufferBaseOffset + end;
2314
- this.handleLine(line8, startOff, endOff);
2314
+ this.handleLine(line5, startOff, endOff);
2315
2315
  lineStart = i + 1;
2316
2316
  }
2317
2317
  i += 1;
2318
2318
  }
2319
2319
  if (forceFlush && lineStart < buf.length) {
2320
- const line8 = buf.slice(lineStart);
2320
+ const line5 = buf.slice(lineStart);
2321
2321
  const startOff = this.bufferBaseOffset + lineStart;
2322
2322
  const endOff = this.bufferBaseOffset + buf.length;
2323
- this.handleLine(line8, startOff, endOff);
2323
+ this.handleLine(line5, startOff, endOff);
2324
2324
  lineStart = buf.length;
2325
2325
  }
2326
2326
  if (lineStart > 0) {
@@ -2329,8 +2329,8 @@ var TableScanner = class {
2329
2329
  }
2330
2330
  }
2331
2331
  /** Dispatch one completed line through the state machine. */
2332
- handleLine(line8, start, end) {
2333
- const fence = detectFence(line8);
2332
+ handleLine(line5, start, end) {
2333
+ const fence = detectFence(line5);
2334
2334
  if (fence !== null) {
2335
2335
  if (this.fenceMarker === null) {
2336
2336
  this.fenceMarker = fence.marker;
@@ -2343,20 +2343,20 @@ var TableScanner = class {
2343
2343
  return;
2344
2344
  }
2345
2345
  if (this.fenceMarker !== null) return;
2346
- const cells = parsePipeRow(line8);
2346
+ const cells = parsePipeRow(line5);
2347
2347
  if (cells === null) {
2348
2348
  this.closeTable();
2349
2349
  return;
2350
2350
  }
2351
2351
  if (this.stateKind === "none") {
2352
2352
  this.stateKind = "pending-header";
2353
- this.headerRow = { text: line8, cells, start, end, isDelimiter: false };
2353
+ this.headerRow = { text: line5, cells, start, end, isDelimiter: false };
2354
2354
  return;
2355
2355
  }
2356
2356
  if (this.stateKind === "pending-header" && this.headerRow) {
2357
2357
  if (isDelimiterRow(cells) && cells.length === this.headerRow.cells.length) {
2358
2358
  const delimiter = {
2359
- text: line8,
2359
+ text: line5,
2360
2360
  cells,
2361
2361
  start,
2362
2362
  end,
@@ -2367,12 +2367,12 @@ var TableScanner = class {
2367
2367
  this.bodyRows = [];
2368
2368
  return;
2369
2369
  }
2370
- this.headerRow = { text: line8, cells, start, end, isDelimiter: false };
2370
+ this.headerRow = { text: line5, cells, start, end, isDelimiter: false };
2371
2371
  return;
2372
2372
  }
2373
2373
  if (this.stateKind === "confirmed-table" && this.delimiterRow) {
2374
2374
  if (cells.length === this.delimiterRow.cells.length) {
2375
- this.bodyRows.push({ text: line8, cells, start, end, isDelimiter: false });
2375
+ this.bodyRows.push({ text: line5, cells, start, end, isDelimiter: false });
2376
2376
  return;
2377
2377
  }
2378
2378
  this.closeTable();
@@ -2418,26 +2418,26 @@ var TableScanner = class {
2418
2418
  return { kind: "none" };
2419
2419
  }
2420
2420
  };
2421
- function detectFence(line8) {
2421
+ function detectFence(line5) {
2422
2422
  let i = 0;
2423
- while (i < line8.length && (line8.charCodeAt(i) === 32 || line8.charCodeAt(i) === 9)) i += 1;
2423
+ while (i < line5.length && (line5.charCodeAt(i) === 32 || line5.charCodeAt(i) === 9)) i += 1;
2424
2424
  if (i >= 4) return null;
2425
- if (i >= line8.length) return null;
2426
- const ch = line8.charCodeAt(i);
2425
+ if (i >= line5.length) return null;
2426
+ const ch = line5.charCodeAt(i);
2427
2427
  if (ch !== 96 && ch !== 126) return null;
2428
2428
  const runStart = i;
2429
- while (i < line8.length && line8.charCodeAt(i) === ch) i += 1;
2429
+ while (i < line5.length && line5.charCodeAt(i) === ch) i += 1;
2430
2430
  const length = i - runStart;
2431
2431
  if (length < FENCE_MIN) return null;
2432
2432
  if (ch === 96) {
2433
- for (let j = i; j < line8.length; j += 1) {
2434
- if (line8.charCodeAt(j) === 96) return null;
2433
+ for (let j = i; j < line5.length; j += 1) {
2434
+ if (line5.charCodeAt(j) === 96) return null;
2435
2435
  }
2436
2436
  }
2437
2437
  return { marker: String.fromCharCode(ch), length };
2438
2438
  }
2439
- function parsePipeRow(line8) {
2440
- const trimmed = line8.trim();
2439
+ function parsePipeRow(line5) {
2440
+ const trimmed = line5.trim();
2441
2441
  if (trimmed === "") return null;
2442
2442
  let pipeCount = 0;
2443
2443
  for (let i2 = 0; i2 < trimmed.length; i2 += 1) {
@@ -2475,8 +2475,8 @@ function parsePipeRow(line8) {
2475
2475
  cells.push(current.trim());
2476
2476
  return cells;
2477
2477
  }
2478
- function parsePipeTableCells(line8) {
2479
- return parsePipeRow(line8) ?? void 0;
2478
+ function parsePipeTableCells(line5) {
2479
+ return parsePipeRow(line5) ?? void 0;
2480
2480
  }
2481
2481
  function isDelimiterRow(cells) {
2482
2482
  if (cells.length === 0) return false;
@@ -2595,7 +2595,7 @@ function tokenize(source, lang) {
2595
2595
  return cached;
2596
2596
  }
2597
2597
  tokenMisses += 1;
2598
- const tokens = source.split("\n").flatMap((line8) => tokenizeLine(line8));
2598
+ const tokens = source.split("\n").flatMap((line5) => tokenizeLine(line5));
2599
2599
  lruSet2(tokenCache, key, tokens, () => {
2600
2600
  tokenEvictions += 1;
2601
2601
  });
@@ -2642,10 +2642,10 @@ function CodeBlock({
2642
2642
  tail
2643
2643
  }) {
2644
2644
  const lines = source.split("\n");
2645
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: lines.map((line8, index) => /* @__PURE__ */ jsx2(
2645
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: lines.map((line5, index) => /* @__PURE__ */ jsx2(
2646
2646
  HighlightedLine,
2647
2647
  {
2648
- source: line8,
2648
+ source: line5,
2649
2649
  lang,
2650
2650
  prefix: index === 0 ? lead : rest,
2651
2651
  tail: index === lines.length - 1 ? tail : void 0
@@ -2653,13 +2653,13 @@ function CodeBlock({
2653
2653
  index
2654
2654
  )) });
2655
2655
  }
2656
- function paintedLineFromRenderLine(line8, hyperlinks2) {
2657
- return paintLineFromRenderLine(line8, hyperlinks2 && hyperlinksEnabled());
2656
+ function paintedLineFromRenderLine(line5, hyperlinks2) {
2657
+ return paintLineFromRenderLine(line5, hyperlinks2 && hyperlinksEnabled());
2658
2658
  }
2659
2659
  function linesToJsx(lines, affixes, hyperlinks2) {
2660
2660
  if (lines.length === 0) return null;
2661
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", width: "100%", children: lines.map((line8, index) => {
2662
- const painted = paintedLineFromRenderLine(line8, hyperlinks2);
2661
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", width: "100%", children: lines.map((line5, index) => {
2662
+ const painted = paintedLineFromRenderLine(line5, hyperlinks2);
2663
2663
  const prefix = index === 0 ? affixes.lead : affixes.rest;
2664
2664
  const tail = index === lines.length - 1 ? affixes.tail : void 0;
2665
2665
  return /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
@@ -2811,16 +2811,7 @@ function MarkdownBlock({
2811
2811
  ) }, "tail")
2812
2812
  );
2813
2813
  }
2814
- if (out.length === 0 && tail === void 0) {
2815
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", width: "100%" });
2816
- }
2817
- if (out.length === 0) {
2818
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsxs2(Text2, { children: [
2819
- prefix?.first,
2820
- tail
2821
- ] }) });
2822
- }
2823
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", width: "100%", children: out });
2814
+ return wrapMarkdownOutput(out, tail, prefix);
2824
2815
  }
2825
2816
  function renderBlockEntry(block, affixes, state, _scope) {
2826
2817
  const rangeKey2 = `${block.range.start}:${block.range.end}`;
@@ -2899,6 +2890,9 @@ function renderFullSource(source, bodyWidth, prefix, tail, settled) {
2899
2890
  };
2900
2891
  out.push(/* @__PURE__ */ jsx2(Fragment, { children: renderActiveTable(snap.rows, bodyWidth, tableAffixes, hyperlinks2) }, "full-active-table"));
2901
2892
  }
2893
+ return wrapMarkdownOutput(out, tail, prefix);
2894
+ }
2895
+ function wrapMarkdownOutput(out, tail, prefix) {
2902
2896
  if (out.length === 0 && tail === void 0) {
2903
2897
  return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", width: "100%" });
2904
2898
  }
@@ -3051,18 +3045,18 @@ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
3051
3045
  function formatSeconds(ms) {
3052
3046
  return (ms / 1e3).toFixed(1);
3053
3047
  }
3054
- function thinkingHeader(durationMs, expanded, live = false) {
3048
+ function thinkingHeader(durationMs, expanded, live = false, width) {
3055
3049
  const mark = expanded ? "\u25BE " : "";
3056
3050
  const icon = live ? getBrailleSpinnerFrame(durationMs) : "\u273B";
3057
- return paintRow([
3058
- styled(
3059
- `${mark}${icon} \u601D\u8003 (${formatSeconds(durationMs)}s)`,
3060
- "fgDim"
3061
- )
3062
- ]);
3051
+ const parts = [
3052
+ ...mark !== "" ? [styled(mark, "accentText")] : [],
3053
+ styled(`${icon} \u601D\u8003`, "accentText"),
3054
+ styled(` (${formatSeconds(durationMs)}s)`, "fgDim")
3055
+ ];
3056
+ return paintBackgroundRow(parts, "toolBg", width !== void 0 && width > 0 ? width : 0);
3063
3057
  }
3064
- function bodyRow(line8, key) {
3065
- return /* @__PURE__ */ jsx3(Text3, { children: paintRow([styled(` ${escapeContent(line8)}`, "fgDim")]) }, key);
3058
+ function bodyRow(line5, key, width) {
3059
+ return /* @__PURE__ */ jsx3(Text3, { wrap: "truncate", children: paintBackgroundRow([styled("\u2502 ", "accentText"), styled(escapeContent(line5), "fgDim")], "toolBg", width !== void 0 && width > 0 ? width : 0) }, key);
3066
3060
  }
3067
3061
  function ReasoningBlock({
3068
3062
  text,
@@ -3073,11 +3067,12 @@ function ReasoningBlock({
3073
3067
  }) {
3074
3068
  const { columns } = useWindowSize3();
3075
3069
  if (collapsed || text === "") return null;
3070
+ const width = maxCols ?? columns;
3076
3071
  const escaped = escapeContent(text);
3077
- const body = wrapDisplayLines(escaped, Math.max(1, (maxCols ?? columns) - 4));
3078
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width: "100%", children: [
3079
- /* @__PURE__ */ jsx3(Text3, { children: thinkingHeader(durationMs, !live, live) }),
3080
- body.map((line8, index) => bodyRow(line8, index))
3072
+ const body = wrapDisplayLines(escaped, Math.max(1, width - 4));
3073
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width: "100%", backgroundColor: inkColor("toolBg"), children: [
3074
+ /* @__PURE__ */ jsx3(Text3, { wrap: "truncate", children: thinkingHeader(durationMs, !live, live, width) }),
3075
+ body.map((line5, index) => bodyRow(line5, index, width))
3081
3076
  ] });
3082
3077
  }
3083
3078
 
@@ -3085,19 +3080,26 @@ function ReasoningBlock({
3085
3080
  import { Box as Box4, Text as Text4 } from "ink";
3086
3081
 
3087
3082
  // tui-render/src/row-source.ts
3083
+ function clampSliceOffset(index, length) {
3084
+ const truncated = Math.trunc(index);
3085
+ return Math.min(length, Math.max(0, index < 0 ? length + truncated : truncated));
3086
+ }
3087
+ function resolveItemIndex(index, length) {
3088
+ const integer = Math.trunc(index);
3089
+ const absolute = integer < 0 ? length + integer : integer;
3090
+ return absolute < 0 || absolute >= length ? void 0 : absolute;
3091
+ }
3088
3092
  function indexedRows(length, read) {
3089
- const offset = (index) => Math.min(length, Math.max(0, index < 0 ? length + Math.trunc(index) : Math.trunc(index)));
3090
3093
  return Object.freeze({
3091
3094
  length,
3092
3095
  at(index) {
3093
- const integer = Math.trunc(index);
3094
- const absolute = integer < 0 ? length + integer : integer;
3095
- return absolute < 0 || absolute >= length ? void 0 : read(absolute);
3096
+ const absolute = resolveItemIndex(index, length);
3097
+ return absolute === void 0 ? void 0 : read(absolute);
3096
3098
  },
3097
3099
  slice(start = 0, end = length) {
3098
3100
  const out = [];
3099
- const last = offset(end);
3100
- for (let index = offset(start); index < last; index += 1) out.push(read(index));
3101
+ const last = clampSliceOffset(end, length);
3102
+ for (let index = clampSliceOffset(start, length); index < last; index += 1) out.push(read(index));
3101
3103
  return out;
3102
3104
  }
3103
3105
  });
@@ -3142,19 +3144,17 @@ var RowSequence = class {
3142
3144
  }
3143
3145
  return low;
3144
3146
  };
3145
- const offset = (index) => Math.min(length, Math.max(0, index < 0 ? length + Math.trunc(index) : Math.trunc(index)));
3146
3147
  return Object.freeze({
3147
3148
  length,
3148
3149
  at(index) {
3149
- const integer = Math.trunc(index);
3150
- const absolute = integer < 0 ? length + integer : integer;
3151
- if (absolute < 0 || absolute >= length) return void 0;
3150
+ const absolute = resolveItemIndex(index, length);
3151
+ if (absolute === void 0) return void 0;
3152
3152
  const segment2 = segments[locate(absolute)];
3153
3153
  return segment2.rows.at(absolute - segment2.start);
3154
3154
  },
3155
3155
  slice(start = 0, end = length) {
3156
- const first = offset(start);
3157
- const last = offset(end);
3156
+ const first = clampSliceOffset(start, length);
3157
+ const last = clampSliceOffset(end, length);
3158
3158
  const out = [];
3159
3159
  for (let index = locate(first); index < segments.length; index += 1) {
3160
3160
  const segment2 = segments[index];
@@ -3169,6 +3169,220 @@ var RowSequence = class {
3169
3169
  }
3170
3170
  };
3171
3171
 
3172
+ // tui-render/src/tool-cards.ts
3173
+ import { isAbsolute } from "node:path";
3174
+ import { pathToFileURL } from "node:url";
3175
+ function toolCardDisplayStatus(card) {
3176
+ const terminal = card.resultView?.card === "terminal" ? card.resultView : void 0;
3177
+ if (terminal?.signal !== void 0) return "error";
3178
+ if (terminal?.exitCode !== void 0 && terminal.exitCode !== 0) return "error";
3179
+ return card.status;
3180
+ }
3181
+ function collapsedResultTail(text) {
3182
+ if (text === void 0) return void 0;
3183
+ const line5 = text.split(/\r?\n/u).map((item) => item.trim()).filter(Boolean).at(-1);
3184
+ return line5 === void 0 ? void 0 : escapeContent(line5);
3185
+ }
3186
+ function collapsedFailureSummary(card) {
3187
+ const terminal = card.resultView?.card === "terminal" ? card.resultView : void 0;
3188
+ const identity = terminal?.exitCode !== void 0 ? `exitCode ${String(terminal.exitCode)}` : terminal?.signal !== void 0 ? `signal ${terminal.signal}` : card.error?.code;
3189
+ const detail = collapsedResultTail(terminal?.output ?? card.resultText);
3190
+ if (identity === void 0) return detail;
3191
+ return detail === void 0 || detail === identity ? identity : `${identity} \xB7 ${detail}`;
3192
+ }
3193
+ function collapsedToolCardSummary(card) {
3194
+ if (toolCardDisplayStatus(card) === "error") {
3195
+ const failure = collapsedFailureSummary(card);
3196
+ if (failure !== void 0) return failure;
3197
+ }
3198
+ const result = card.resultView;
3199
+ const kind = result?.card ?? card.callView?.card ?? "generic";
3200
+ switch (kind) {
3201
+ case "terminal":
3202
+ if (result?.card === "terminal" && result.exitCode !== void 0) {
3203
+ return `exitCode ${String(result.exitCode)}`;
3204
+ }
3205
+ if (result?.card === "terminal" && result.signal !== void 0) {
3206
+ return `signal ${result.signal}`;
3207
+ }
3208
+ if (result?.card === "terminal" && result.output !== void 0 && result.output !== "") {
3209
+ return escapeContent(result.output.replace(/\n/g, " "));
3210
+ }
3211
+ return card.callView?.card === "terminal" && card.callView.cwd !== void 0 ? escapeContent(card.callView.cwd) : void 0;
3212
+ case "diff": {
3213
+ const paths = card.callView?.card === "diff" ? card.callView.locations ?? card.callView.diffs.map((diff) => ({ path: diff.path })) : result.diffs.map((diff) => ({ path: diff.path }));
3214
+ return paths.length === 0 ? void 0 : escapeContent(paths.map((entry) => entry.path).join(" \xB7 "));
3215
+ }
3216
+ case "search":
3217
+ return result?.card === "search" ? `${String(result.total)} matches` : void 0;
3218
+ case "read":
3219
+ return result?.card === "read" ? escapeContent(result.path) : void 0;
3220
+ case "web":
3221
+ if (result?.card !== "web") return void 0;
3222
+ if (result.kind === "fetch") {
3223
+ return escapeContent(`${result.url} \xB7 ${String(result.statusCode)}`);
3224
+ }
3225
+ if (result.sources.length === 0) return void 0;
3226
+ return escapeContent(result.sources.length === 1 ? result.sources[0]?.title ?? result.sources[0]?.url : `${String(result.sources.length)} sources`);
3227
+ default:
3228
+ return card.callView === void 0 ? collapsedCardSummary(card.arguments) : void 0;
3229
+ }
3230
+ }
3231
+ function cardsFrom(content) {
3232
+ const pending = /* @__PURE__ */ new Map();
3233
+ const ordered = [];
3234
+ for (const item of content) {
3235
+ if (item.kind === "tool-call") {
3236
+ const card2 = {
3237
+ callId: item.callId,
3238
+ name: item.name,
3239
+ arguments: item.arguments,
3240
+ status: "running"
3241
+ };
3242
+ pending.set(item.callId, card2);
3243
+ ordered.push(card2);
3244
+ continue;
3245
+ }
3246
+ if (item.kind !== "tool-result") continue;
3247
+ const card = pending.get(item.callId);
3248
+ if (card === void 0) continue;
3249
+ card.status = item.isError ? "error" : "ok";
3250
+ card.resultText = item.text;
3251
+ if (item.meta !== void 0) card.meta = item.meta;
3252
+ if (item.error !== void 0) card.error = item.error;
3253
+ }
3254
+ return ordered;
3255
+ }
3256
+ function cardsFromActiveTurn(toolCalls, content = []) {
3257
+ const calls = toolCalls.map((call) => ({
3258
+ kind: "tool-call",
3259
+ callId: call.callId,
3260
+ name: call.name,
3261
+ arguments: call.arguments
3262
+ }));
3263
+ const results = content.filter(
3264
+ (item) => item.kind === "tool-result"
3265
+ );
3266
+ return cardsFrom([...calls, ...results]);
3267
+ }
3268
+ function cardsFromTurn(turn) {
3269
+ return cardsFromActiveTurn(turn.toolCalls, turn.content ?? []);
3270
+ }
3271
+ function attachPresenterViews(tools, card) {
3272
+ if (tools === void 0) return card;
3273
+ let args;
3274
+ try {
3275
+ args = JSON.parse(card.arguments);
3276
+ } catch {
3277
+ return card;
3278
+ }
3279
+ const def = tools.get(card.name);
3280
+ if (def === void 0) return card;
3281
+ let callView;
3282
+ try {
3283
+ const view = def.presentCall?.(args);
3284
+ if (view !== void 0 && typeof view.title === "string" && view.title !== "") {
3285
+ callView = view;
3286
+ }
3287
+ } catch {
3288
+ }
3289
+ let resultView;
3290
+ if (card.status !== "running") {
3291
+ try {
3292
+ const view = def.presentResult?.(args, {
3293
+ content: [{ type: "text", text: card.resultText ?? "" }],
3294
+ isError: card.status === "error",
3295
+ ...card.meta === void 0 ? {} : { meta: card.meta }
3296
+ });
3297
+ if (view !== void 0) {
3298
+ resultView = view;
3299
+ }
3300
+ } catch {
3301
+ }
3302
+ }
3303
+ if (callView === void 0 && resultView === void 0) return card;
3304
+ return {
3305
+ ...card,
3306
+ ...callView === void 0 ? {} : { callView },
3307
+ ...resultView === void 0 ? {} : { resultView }
3308
+ };
3309
+ }
3310
+ function parseSubagentArguments(argumentsJson) {
3311
+ if (argumentsJson === "" || argumentsJson === "{}") return void 0;
3312
+ try {
3313
+ const parsed = JSON.parse(argumentsJson);
3314
+ if (parsed !== null && typeof parsed === "object") {
3315
+ const obj = parsed;
3316
+ const description = typeof obj.description === "string" && obj.description !== "" ? obj.description : void 0;
3317
+ const prompt = typeof obj.prompt === "string" && obj.prompt !== "" ? obj.prompt : void 0;
3318
+ const model = typeof obj.model === "string" && obj.model !== "" ? obj.model : void 0;
3319
+ const runInBackground = typeof obj.run_in_background === "boolean" ? obj.run_in_background : void 0;
3320
+ if (description !== void 0 || prompt !== void 0 || model !== void 0) {
3321
+ return { description, prompt, model, runInBackground };
3322
+ }
3323
+ }
3324
+ } catch {
3325
+ }
3326
+ return void 0;
3327
+ }
3328
+ function collapsedCardSummary(argumentsJson) {
3329
+ if (argumentsJson === "") return void 0;
3330
+ let command;
3331
+ try {
3332
+ const parsed = JSON.parse(argumentsJson);
3333
+ if (parsed !== null && typeof parsed === "object") {
3334
+ const obj = parsed;
3335
+ if (typeof obj.command === "string" && obj.command !== "") {
3336
+ command = obj.command;
3337
+ } else if (typeof obj.description === "string" && obj.description !== "") {
3338
+ command = obj.description;
3339
+ } else if (typeof obj.prompt === "string" && obj.prompt !== "") {
3340
+ command = obj.prompt;
3341
+ } else if (typeof obj.query === "string" && obj.query !== "") {
3342
+ command = obj.query;
3343
+ } else if (typeof obj.task === "string" && obj.task !== "") {
3344
+ command = obj.task;
3345
+ }
3346
+ }
3347
+ } catch {
3348
+ }
3349
+ return escapeContent(command ?? argumentsJson).replace(/\n/g, " ");
3350
+ }
3351
+ function truncateDisplay(text, maxCols) {
3352
+ if (maxCols <= 0) return "";
3353
+ if (displayWidth(text) <= maxCols) return text;
3354
+ if (maxCols === 1) return "\u2026";
3355
+ return `${wcwidthSafeSlice(text, maxCols - 1)}\u2026`;
3356
+ }
3357
+ var FILE_PATH_KEYS = ["path", "file_path", "file", "target_file", "target"];
3358
+ function fileUrlFromToolArguments(argumentsJson) {
3359
+ try {
3360
+ const parsed = JSON.parse(argumentsJson);
3361
+ if (parsed === null || typeof parsed !== "object") return void 0;
3362
+ const record = parsed;
3363
+ for (const key of FILE_PATH_KEYS) {
3364
+ const value = record[key];
3365
+ if (typeof value !== "string" || !isAbsolute(value)) continue;
3366
+ if (/[\u0000-\u001f\u007f]/.test(value)) continue;
3367
+ return pathToFileURL(value).href;
3368
+ }
3369
+ } catch {
3370
+ }
3371
+ return void 0;
3372
+ }
3373
+ function tokenizeCommandHeading(heading) {
3374
+ const trimmed = heading.trimStart();
3375
+ const leading = heading.slice(0, heading.length - trimmed.length);
3376
+ const firstSpace = trimmed.indexOf(" ");
3377
+ const cmd = firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace);
3378
+ const rest = firstSpace === -1 ? "" : trimmed.slice(firstSpace);
3379
+ const tokens = [];
3380
+ if (leading !== "") tokens.push({ text: leading, token: "fgSoft" });
3381
+ if (cmd !== "") tokens.push({ text: cmd, token: "codeCommand" });
3382
+ if (rest !== "") tokens.push({ text: rest, token: "fgSoft" });
3383
+ return Object.freeze(tokens);
3384
+ }
3385
+
3172
3386
  // tui-render/src/tool-body.ts
3173
3387
  var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
3174
3388
  function textLines(text, prefix = "") {
@@ -3195,8 +3409,8 @@ function splitDiffLines(text) {
3195
3409
  return normalized.split(/\r?\n/u);
3196
3410
  }
3197
3411
  function diffLines(oldLines, newLines) {
3198
- if (oldLines.length === 0) return newLines.map((line8) => `+${line8}`);
3199
- if (newLines.length === 0) return oldLines.map((line8) => `-${line8}`);
3412
+ if (oldLines.length === 0) return newLines.map((line5) => `+${line5}`);
3413
+ if (newLines.length === 0) return oldLines.map((line5) => `-${line5}`);
3200
3414
  const m = oldLines.length;
3201
3415
  const n = newLines.length;
3202
3416
  if (m * n > 5e5) {
@@ -3216,9 +3430,9 @@ function diffLines(oldLines, newLines) {
3216
3430
  const midN = trimmedNew.length;
3217
3431
  const middle = [];
3218
3432
  if (midM === 0) {
3219
- for (const line8 of trimmedNew) middle.push(`+${line8}`);
3433
+ for (const line5 of trimmedNew) middle.push(`+${line5}`);
3220
3434
  } else if (midN === 0) {
3221
- for (const line8 of trimmedOld) middle.push(`-${line8}`);
3435
+ for (const line5 of trimmedOld) middle.push(`-${line5}`);
3222
3436
  } else {
3223
3437
  const stride = midN + 1;
3224
3438
  const dp = new Int32Array((midM + 1) * stride);
@@ -3259,8 +3473,8 @@ function diffLines(oldLines, newLines) {
3259
3473
  for (let k = 0; k < prefixCount; k++) {
3260
3474
  result.push(` ${oldLines[k]}`);
3261
3475
  }
3262
- for (const line8 of middle) {
3263
- result.push(line8);
3476
+ for (const line5 of middle) {
3477
+ result.push(line5);
3264
3478
  }
3265
3479
  for (let k = m - suffixCount; k < m; k++) {
3266
3480
  result.push(` ${oldLines[k]}`);
@@ -3295,7 +3509,7 @@ function createToolBodyDocument(card, options) {
3295
3509
  let lastPath;
3296
3510
  for (const diff of diffs) {
3297
3511
  if (diff.path !== lastPath) {
3298
- source.push({ text: `--- ${diff.path}`, token: "codeBg" });
3512
+ source.push({ text: `--- ${diff.path}`, token: "codeBg", diffKind: "header" });
3299
3513
  lastPath = diff.path;
3300
3514
  }
3301
3515
  const oldStart = diff.oldStart ?? (diff.oldText === null ? 0 : 1);
@@ -3309,7 +3523,7 @@ function createToolBodyDocument(card, options) {
3309
3523
  newLinesCount ??= splitDiffLines(diff.newText).length;
3310
3524
  } else if (diff.oldText === null) {
3311
3525
  const split = splitDiffLines(diff.newText);
3312
- lines = split.map((line8) => `+${line8}`);
3526
+ lines = split.map((line5) => `+${line5}`);
3313
3527
  oldLinesCount = 0;
3314
3528
  newLinesCount = split.length;
3315
3529
  } else {
@@ -3321,7 +3535,7 @@ function createToolBodyDocument(card, options) {
3321
3535
  }
3322
3536
  const oldHunk = `${oldStart}${oldLinesCount !== 1 ? `,${oldLinesCount}` : ""}`;
3323
3537
  const newHunk = `${newStart}${newLinesCount !== 1 ? `,${newLinesCount}` : ""}`;
3324
- source.push({ text: `@@ -${oldHunk} +${newHunk} @@`, token: "codeBg" });
3538
+ source.push({ text: `@@ -${oldHunk} +${newHunk} @@`, token: "codeBg", diffKind: "hunk" });
3325
3539
  const maxLine = Math.max(oldStart + oldLinesCount, newStart + newLinesCount, 1);
3326
3540
  const gutterWidth = Math.max(3, String(maxLine).length);
3327
3541
  let curOld = oldStart === 0 ? 1 : oldStart;
@@ -3330,20 +3544,20 @@ function createToolBodyDocument(card, options) {
3330
3544
  if (raw.startsWith("\\")) continue;
3331
3545
  if (raw.startsWith("-")) {
3332
3546
  const num = String(curOld).padStart(gutterWidth, " ");
3333
- source.push({ text: `${num} \u2502 - ${raw.slice(1)}`, token: "codeBg" });
3547
+ source.push({ text: `${num} \u2502 - ${raw.slice(1)}`, token: "codeBg", diffKind: "delete" });
3334
3548
  curOld++;
3335
3549
  } else if (raw.startsWith("+")) {
3336
3550
  const num = String(curNew).padStart(gutterWidth, " ");
3337
- source.push({ text: `${num} \u2502 + ${raw.slice(1)}`, token: "codeBg" });
3551
+ source.push({ text: `${num} \u2502 + ${raw.slice(1)}`, token: "codeBg", diffKind: "add" });
3338
3552
  curNew++;
3339
3553
  } else if (raw.startsWith(" ")) {
3340
3554
  const num = String(curNew).padStart(gutterWidth, " ");
3341
- source.push({ text: `${num} \u2502 ${raw.slice(1)}`, token: "codeBg" });
3555
+ source.push({ text: `${num} \u2502 ${raw.slice(1)}`, token: "codeBg", diffKind: "context" });
3342
3556
  curOld++;
3343
3557
  curNew++;
3344
3558
  } else {
3345
3559
  const num = String(curNew).padStart(gutterWidth, " ");
3346
- source.push({ text: `${num} \u2502 ${raw}`, token: "codeBg" });
3560
+ source.push({ text: `${num} \u2502 ${raw}`, token: "codeBg", diffKind: "context" });
3347
3561
  curOld++;
3348
3562
  curNew++;
3349
3563
  }
@@ -3367,8 +3581,8 @@ function createToolBodyDocument(card, options) {
3367
3581
  }
3368
3582
  case "read":
3369
3583
  if (result?.card === "read") section(tuiCopy("result", options.locale), indexedRows(result.lines.length, (index) => {
3370
- const line8 = result.lines[index];
3371
- return { text: `${line8.number} ${line8.text}`, token: "codeBg" };
3584
+ const line5 = result.lines[index];
3585
+ return { text: `${line5.number} ${line5.text}`, token: "codeBg" };
3372
3586
  }));
3373
3587
  break;
3374
3588
  case "web":
@@ -3383,10 +3597,31 @@ function createToolBodyDocument(card, options) {
3383
3597
  }
3384
3598
  }
3385
3599
  break;
3386
- default:
3387
- args();
3600
+ default: {
3601
+ const isSubagent = card.name === "subagent" || card.name.startsWith("subagent_") || card.name === "delegate";
3602
+ const subInfo = isSubagent ? parseSubagentArguments(card.arguments) : void 0;
3603
+ if (subInfo !== void 0) {
3604
+ if (subInfo.description !== void 0) {
3605
+ section(options.locale === "zh-CN" ? "\u4EFB\u52A1\u76EE\u6807" : "Task", textLines(subInfo.description));
3606
+ }
3607
+ if (subInfo.model !== void 0) {
3608
+ section(options.locale === "zh-CN" ? "\u59D4\u6D3E\u6A21\u578B" : "Model", textLines(subInfo.model));
3609
+ }
3610
+ if (card.status === "running") {
3611
+ section(
3612
+ options.locale === "zh-CN" ? "\u8FD0\u884C\u72B6\u6001" : "Status",
3613
+ textLines(options.locale === "zh-CN" ? "\u25CF \u6B63\u5728\u6267\u884C\u5B50\u4EE3\u7406\u4EFB\u52A1..." : "\u25CF Running subagent task...")
3614
+ );
3615
+ }
3616
+ if (subInfo.prompt !== void 0) {
3617
+ section(options.locale === "zh-CN" ? "\u4EFB\u52A1\u6307\u4EE4" : "Prompt", textLines(subInfo.prompt));
3618
+ }
3619
+ } else {
3620
+ args();
3621
+ }
3388
3622
  if (card.resultText !== void 0) section(tuiCopy("result", options.locale), textLines(card.resultText));
3389
3623
  break;
3624
+ }
3390
3625
  }
3391
3626
  if (result === void 0 && kind !== "generic" && card.resultText !== void 0) {
3392
3627
  section(tuiCopy("result", options.locale), textLines(card.resultText));
@@ -3412,214 +3647,33 @@ function fragmentEnd(text, start, width) {
3412
3647
  }
3413
3648
  function planToolBodyWindow(document, cursor, width, maxRows) {
3414
3649
  const fragments = [];
3415
- let line8 = cursor.line;
3650
+ let line5 = cursor.line;
3416
3651
  let offset = cursor.offset;
3417
- while (line8 < document.length && fragments.length < maxRows) {
3418
- const source = document.at(line8);
3652
+ while (line5 < document.length && fragments.length < maxRows) {
3653
+ const source = document.at(line5);
3419
3654
  const end = fragmentEnd(source.text, offset, width);
3420
- fragments.push({ line: line8, start: offset, end });
3655
+ fragments.push({ line: line5, start: offset, end });
3421
3656
  if (end === source.text.length) {
3422
- line8 += 1;
3657
+ line5 += 1;
3423
3658
  offset = 0;
3424
3659
  } else offset = end;
3425
3660
  }
3426
- return { fragments, next: line8 < document.length ? { line: line8, offset } : void 0, remainingLines: document.length - line8 };
3661
+ return { fragments, next: line5 < document.length ? { line: line5, offset } : void 0, remainingLines: document.length - line5 };
3427
3662
  }
3428
3663
  function materializeToolBodyRow(document, fragment) {
3429
3664
  const source = document.at(fragment.line);
3430
- return { text: escapeToolText(source.text.slice(fragment.start, fragment.end)), token: source.token };
3431
- }
3432
- function toolCardOriginalText(card, options) {
3433
- const parts = [card.name, tuiCopy("arguments", options.locale), card.arguments];
3434
- if (card.resultText !== void 0) parts.push(tuiCopy("result", options.locale), card.resultText);
3435
- if (options.diagnostics && card.meta !== void 0) parts.push(tuiCopy("diagnostics", options.locale), JSON.stringify(card.meta));
3436
- return `${parts.join("\n")}
3437
- `;
3438
- }
3439
-
3440
- // tui-render/src/tool-cards.ts
3441
- import { isAbsolute } from "node:path";
3442
- import { pathToFileURL } from "node:url";
3443
- function toolCardDisplayStatus(card) {
3444
- const terminal = card.resultView?.card === "terminal" ? card.resultView : void 0;
3445
- if (terminal?.signal !== void 0) return "error";
3446
- if (terminal?.exitCode !== void 0 && terminal.exitCode !== 0) return "error";
3447
- return card.status;
3448
- }
3449
- function collapsedResultTail(text) {
3450
- if (text === void 0) return void 0;
3451
- const line8 = text.split(/\r?\n/u).map((item) => item.trim()).filter(Boolean).at(-1);
3452
- return line8 === void 0 ? void 0 : escapeContent(line8);
3453
- }
3454
- function collapsedFailureSummary(card) {
3455
- const terminal = card.resultView?.card === "terminal" ? card.resultView : void 0;
3456
- const identity = terminal?.exitCode !== void 0 ? `exitCode ${String(terminal.exitCode)}` : terminal?.signal !== void 0 ? `signal ${terminal.signal}` : card.error?.code;
3457
- const detail = collapsedResultTail(terminal?.output ?? card.resultText);
3458
- if (identity === void 0) return detail;
3459
- return detail === void 0 || detail === identity ? identity : `${identity} \xB7 ${detail}`;
3460
- }
3461
- function collapsedToolCardSummary(card) {
3462
- if (toolCardDisplayStatus(card) === "error") {
3463
- const failure = collapsedFailureSummary(card);
3464
- if (failure !== void 0) return failure;
3465
- }
3466
- const result = card.resultView;
3467
- const kind = result?.card ?? card.callView?.card ?? "generic";
3468
- switch (kind) {
3469
- case "terminal":
3470
- if (result?.card === "terminal" && result.exitCode !== void 0) {
3471
- return `exitCode ${String(result.exitCode)}`;
3472
- }
3473
- if (result?.card === "terminal" && result.signal !== void 0) {
3474
- return `signal ${result.signal}`;
3475
- }
3476
- if (result?.card === "terminal" && result.output !== void 0 && result.output !== "") {
3477
- return escapeContent(result.output.replace(/\n/g, " "));
3478
- }
3479
- return card.callView?.card === "terminal" && card.callView.cwd !== void 0 ? escapeContent(card.callView.cwd) : void 0;
3480
- case "diff": {
3481
- const paths = card.callView?.card === "diff" ? card.callView.locations ?? card.callView.diffs.map((diff) => ({ path: diff.path })) : result.diffs.map((diff) => ({ path: diff.path }));
3482
- return paths.length === 0 ? void 0 : escapeContent(paths.map((entry) => entry.path).join(" \xB7 "));
3483
- }
3484
- case "search":
3485
- return result?.card === "search" ? `${String(result.total)} matches` : void 0;
3486
- case "read":
3487
- return result?.card === "read" ? escapeContent(result.path) : void 0;
3488
- case "web":
3489
- if (result?.card !== "web") return void 0;
3490
- if (result.kind === "fetch") {
3491
- return escapeContent(`${result.url} \xB7 ${String(result.statusCode)}`);
3492
- }
3493
- if (result.sources.length === 0) return void 0;
3494
- return escapeContent(result.sources.length === 1 ? result.sources[0]?.title ?? result.sources[0]?.url : `${String(result.sources.length)} sources`);
3495
- default:
3496
- return card.callView === void 0 ? collapsedCardSummary(card.arguments) : void 0;
3497
- }
3498
- }
3499
- function cardsFrom(content) {
3500
- const pending = /* @__PURE__ */ new Map();
3501
- const ordered = [];
3502
- for (const item of content) {
3503
- if (item.kind === "tool-call") {
3504
- const card2 = {
3505
- callId: item.callId,
3506
- name: item.name,
3507
- arguments: item.arguments,
3508
- status: "running"
3509
- };
3510
- pending.set(item.callId, card2);
3511
- ordered.push(card2);
3512
- continue;
3513
- }
3514
- if (item.kind !== "tool-result") continue;
3515
- const card = pending.get(item.callId);
3516
- if (card === void 0) continue;
3517
- card.status = item.isError ? "error" : "ok";
3518
- card.resultText = item.text;
3519
- if (item.meta !== void 0) card.meta = item.meta;
3520
- if (item.error !== void 0) card.error = item.error;
3521
- }
3522
- return ordered;
3523
- }
3524
- function cardsFromActiveTurn(toolCalls, content = []) {
3525
- const calls = toolCalls.map((call) => ({
3526
- kind: "tool-call",
3527
- callId: call.callId,
3528
- name: call.name,
3529
- arguments: call.arguments
3530
- }));
3531
- const results = content.filter(
3532
- (item) => item.kind === "tool-result"
3533
- );
3534
- return cardsFrom([...calls, ...results]);
3535
- }
3536
- function cardsFromTurn(turn) {
3537
- return cardsFromActiveTurn(turn.toolCalls, turn.content ?? []);
3538
- }
3539
- function attachPresenterViews(tools, card) {
3540
- if (tools === void 0) return card;
3541
- let args;
3542
- try {
3543
- args = JSON.parse(card.arguments);
3544
- } catch {
3545
- return card;
3546
- }
3547
- const def = tools.get(card.name);
3548
- if (def === void 0) return card;
3549
- let callView;
3550
- try {
3551
- const view = def.presentCall?.(args);
3552
- if (view !== void 0 && typeof view.title === "string" && view.title !== "") {
3553
- callView = view;
3554
- }
3555
- } catch {
3556
- }
3557
- let resultView;
3558
- if (card.status !== "running") {
3559
- try {
3560
- const view = def.presentResult?.(args, {
3561
- content: [{ type: "text", text: card.resultText ?? "" }],
3562
- isError: card.status === "error",
3563
- ...card.meta === void 0 ? {} : { meta: card.meta }
3564
- });
3565
- if (view !== void 0) {
3566
- resultView = view;
3567
- }
3568
- } catch {
3569
- }
3570
- }
3571
- if (callView === void 0 && resultView === void 0) return card;
3572
3665
  return {
3573
- ...card,
3574
- ...callView === void 0 ? {} : { callView },
3575
- ...resultView === void 0 ? {} : { resultView }
3666
+ text: escapeToolText(source.text.slice(fragment.start, fragment.end)),
3667
+ token: source.token,
3668
+ ...source.diffKind !== void 0 ? { diffKind: source.diffKind } : {}
3576
3669
  };
3577
3670
  }
3578
- function collapsedCardSummary(argumentsJson) {
3579
- if (argumentsJson === "") return void 0;
3580
- let command;
3581
- try {
3582
- const parsed = JSON.parse(argumentsJson);
3583
- if (parsed !== null && typeof parsed === "object" && "command" in parsed && typeof parsed.command === "string") {
3584
- command = parsed.command;
3585
- }
3586
- } catch {
3587
- }
3588
- return escapeContent(command ?? argumentsJson).replace(/\n/g, " ");
3589
- }
3590
- function truncateDisplay(text, maxCols) {
3591
- if (maxCols <= 0) return "";
3592
- if (displayWidth(text) <= maxCols) return text;
3593
- if (maxCols === 1) return "\u2026";
3594
- return `${wcwidthSafeSlice(text, maxCols - 1)}\u2026`;
3595
- }
3596
- var FILE_PATH_KEYS = ["path", "file_path", "file", "target_file", "target"];
3597
- function fileUrlFromToolArguments(argumentsJson) {
3598
- try {
3599
- const parsed = JSON.parse(argumentsJson);
3600
- if (parsed === null || typeof parsed !== "object") return void 0;
3601
- const record = parsed;
3602
- for (const key of FILE_PATH_KEYS) {
3603
- const value = record[key];
3604
- if (typeof value !== "string" || !isAbsolute(value)) continue;
3605
- if (/[\u0000-\u001f\u007f]/.test(value)) continue;
3606
- return pathToFileURL(value).href;
3607
- }
3608
- } catch {
3609
- }
3610
- return void 0;
3611
- }
3612
- function tokenizeCommandHeading(heading) {
3613
- const trimmed = heading.trimStart();
3614
- const leading = heading.slice(0, heading.length - trimmed.length);
3615
- const firstSpace = trimmed.indexOf(" ");
3616
- const cmd = firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace);
3617
- const rest = firstSpace === -1 ? "" : trimmed.slice(firstSpace);
3618
- const tokens = [];
3619
- if (leading !== "") tokens.push({ text: leading, token: "fgSoft" });
3620
- if (cmd !== "") tokens.push({ text: cmd, token: "codeCommand" });
3621
- if (rest !== "") tokens.push({ text: rest, token: "fgSoft" });
3622
- return Object.freeze(tokens);
3671
+ function toolCardOriginalText(card, options) {
3672
+ const parts = [card.name, tuiCopy("arguments", options.locale), card.arguments];
3673
+ if (card.resultText !== void 0) parts.push(tuiCopy("result", options.locale), card.resultText);
3674
+ if (options.diagnostics && card.meta !== void 0) parts.push(tuiCopy("diagnostics", options.locale), JSON.stringify(card.meta));
3675
+ return `${parts.join("\n")}
3676
+ `;
3623
3677
  }
3624
3678
 
3625
3679
  // tui-render/src/tool-rows.ts
@@ -3664,8 +3718,48 @@ function toolRow(parts, index, width, background) {
3664
3718
  }
3665
3719
  function toolHeadingRow(card, width, expanded, locale) {
3666
3720
  const status = toolCardDisplayStatus(card);
3667
- const label = status === "ok" ? "\u2713" : tuiCopy(status === "error" ? "failed" : "running", locale);
3668
3721
  const glyph = expanded ? "\u25BE" : "\u25B8";
3722
+ const isSubagent = card.name === "subagent" || card.name.startsWith("subagent_") || card.name === "delegate";
3723
+ const subagentInfo = isSubagent ? parseSubagentArguments(card.arguments) : void 0;
3724
+ if (isSubagent) {
3725
+ const statusLabel = status === "ok" ? locale === "zh-CN" ? "\u2713 \u5DF2\u5B8C\u6210" : "\u2713 completed" : status === "error" ? locale === "zh-CN" ? "\u2717 \u5931\u8D25" : "\u2717 failed" : locale === "zh-CN" ? "\u25CF \u8FD0\u884C\u4E2D" : "\u25CF running";
3726
+ const statusToken2 = status === "error" ? "error" : status === "running" ? "accentText" : "success";
3727
+ const glyphToken = status === "running" ? "accentText" : "fgDim";
3728
+ const tag = locale === "zh-CN" ? "[\u5B50\u4EE3\u7406] " : "[Subagent] ";
3729
+ if (width < displayWidth(`${glyph} \u2026 \xB7 ${statusLabel}`)) {
3730
+ return toolRow([{ text: truncateDisplay(`${glyph} ${statusLabel}`, width), token: statusToken2 }], 0, width, "toolBg");
3731
+ }
3732
+ const headingText = subagentInfo?.description !== void 0 && subagentInfo.description !== "" ? subagentInfo.description : card.resultView?.title ?? card.callView?.title ?? card.name;
3733
+ const heading2 = escapeContent(headingText).replace(/[\n\t]/gu, " ");
3734
+ const prefixBudget = displayWidth(`${glyph} ${tag} \xB7 ${statusLabel}`);
3735
+ const fitted2 = truncateMiddleDisplay(heading2, Math.max(1, width - prefixBudget), 0.6);
3736
+ const parts2 = [
3737
+ { text: `${glyph} `, token: glyphToken },
3738
+ { text: tag, token: "codeKeyword" },
3739
+ { text: `${fitted2} \xB7 `, token: "fg" },
3740
+ { text: statusLabel, token: statusToken2 }
3741
+ ];
3742
+ if (subagentInfo?.model !== void 0) {
3743
+ parts2.push({ text: ` [${subagentInfo.model}]`, token: "markdownCode" });
3744
+ }
3745
+ let summary2;
3746
+ if (status === "error") {
3747
+ summary2 = collapsedToolCardSummary(card);
3748
+ } else if (!expanded) {
3749
+ if (subagentInfo?.prompt !== void 0 && subagentInfo.prompt !== "") {
3750
+ summary2 = escapeContent(subagentInfo.prompt).replace(/\n/g, " ");
3751
+ } else {
3752
+ summary2 = collapsedToolCardSummary(card);
3753
+ }
3754
+ }
3755
+ const available2 = width - parts2.reduce((sum, part) => sum + displayWidth(part.text), 0) - 1;
3756
+ const href2 = fileUrlFromToolArguments(card.arguments);
3757
+ if (summary2 !== void 0 && available2 >= 2) {
3758
+ parts2.push({ text: ` ${truncateDisplay(summary2, available2)}`, token: "fgSoft", ...href2 === void 0 ? {} : { href: href2 } });
3759
+ }
3760
+ return toolRow(parts2, 0, width, "toolBg");
3761
+ }
3762
+ const label = status === "ok" ? "\u2713" : tuiCopy(status === "error" ? "failed" : "running", locale);
3669
3763
  if (width < displayWidth(`${glyph} \u2026 \xB7 ${label}`)) return toolRow([{ text: truncateDisplay(`${glyph} ${label}`, width), token: status === "error" ? "error" : "fgDim" }], 0, width, "toolBg");
3670
3764
  const heading = escapeContent(card.resultView?.title ?? card.callView?.title ?? card.name).replace(/[\n\t]/gu, " ");
3671
3765
  const terminal = card.callView?.card === "terminal" || card.resultView?.card === "terminal";
@@ -3678,8 +3772,69 @@ function toolHeadingRow(card, width, expanded, locale) {
3678
3772
  if (summary !== void 0 && available >= 2) parts.push({ text: ` ${truncateDisplay(summary, available)}`, token: "fgDim", ...href === void 0 ? {} : { href } });
3679
3773
  return toolRow(parts, 0, width, "toolBg");
3680
3774
  }
3681
- function toolBodyRenderRow(line8, index, width) {
3682
- return toolRow([{ text: ` ${line8.text}`, token: line8.token === "codeBg" ? "fgSoft" : "fgDim" }], index, width, line8.token === "codeBg" ? "codeBg" : "toolBg");
3775
+ var GUTTER_SEPARATOR = " \u2502 ";
3776
+ function inferDiffKind(text) {
3777
+ if (text.startsWith("--- ")) return "header";
3778
+ if (/^@@ -\d+.* @@$/u.test(text)) return "hunk";
3779
+ if (text.includes(" \u2502 + ")) return "add";
3780
+ if (text.includes(" \u2502 - ")) return "delete";
3781
+ if (/^\s*\d+ │ /u.test(text)) return "context";
3782
+ return void 0;
3783
+ }
3784
+ function formatDiffParts(text, kind) {
3785
+ switch (kind) {
3786
+ case "header":
3787
+ return [{ text: ` ${text}`, token: "fgDim" }];
3788
+ case "hunk":
3789
+ return [{ text: ` ${text}`, token: "accentText" }];
3790
+ case "add": {
3791
+ const sepIndex = text.indexOf(GUTTER_SEPARATOR);
3792
+ if (sepIndex !== -1) {
3793
+ const gutter = text.slice(0, sepIndex + GUTTER_SEPARATOR.length);
3794
+ const content = text.slice(sepIndex + GUTTER_SEPARATOR.length);
3795
+ return [
3796
+ { text: ` ${gutter}`, token: "fgDim" },
3797
+ { text: content, token: "success" }
3798
+ ];
3799
+ }
3800
+ return [{ text: ` ${text}`, token: "success" }];
3801
+ }
3802
+ case "delete": {
3803
+ const sepIndex = text.indexOf(GUTTER_SEPARATOR);
3804
+ if (sepIndex !== -1) {
3805
+ const gutter = text.slice(0, sepIndex + GUTTER_SEPARATOR.length);
3806
+ const content = text.slice(sepIndex + GUTTER_SEPARATOR.length);
3807
+ return [
3808
+ { text: ` ${gutter}`, token: "fgDim" },
3809
+ { text: content, token: "error" }
3810
+ ];
3811
+ }
3812
+ return [{ text: ` ${text}`, token: "error" }];
3813
+ }
3814
+ case "context": {
3815
+ const sepIndex = text.indexOf(GUTTER_SEPARATOR);
3816
+ if (sepIndex !== -1) {
3817
+ const gutter = text.slice(0, sepIndex + GUTTER_SEPARATOR.length);
3818
+ const content = text.slice(sepIndex + GUTTER_SEPARATOR.length);
3819
+ return [
3820
+ { text: ` ${gutter}`, token: "fgDim" },
3821
+ { text: content, token: "fgSoft" }
3822
+ ];
3823
+ }
3824
+ return [{ text: ` ${text}`, token: "fgSoft" }];
3825
+ }
3826
+ }
3827
+ }
3828
+ function toolBodyRenderRow(line5, index, width) {
3829
+ const bg = line5.token === "codeBg" ? "codeBg" : "toolBg";
3830
+ const diffKind = line5.diffKind ?? inferDiffKind(line5.text);
3831
+ if (diffKind !== void 0) {
3832
+ return toolRow(formatDiffParts(line5.text, diffKind), index, width, bg);
3833
+ }
3834
+ if (line5.text.includes("\u25CF \u6B63\u5728\u6267\u884C") || line5.text.includes("\u25CF Running")) {
3835
+ return toolRow([{ text: ` ${line5.text}`, token: "accentText" }], index, width, bg);
3836
+ }
3837
+ return toolRow([{ text: ` ${line5.text}`, token: line5.token === "codeBg" ? "fgSoft" : "fgDim" }], index, width, bg);
3683
3838
  }
3684
3839
  function toolRemainingRow(remaining, width, index, locale) {
3685
3840
  const action = tuiCopy("toolDetails", locale);
@@ -3828,7 +3983,7 @@ import { jsx as jsx4 } from "react/jsx-runtime";
3828
3983
  function ToolCard({ card, expanded = false, maxCols = 80, locale = "zh-CN", policy = toolPolicyDefaults() }) {
3829
3984
  const cache2 = new ToolRowCache(policy);
3830
3985
  const rows = cache2.rows(card.callId, card, maxCols, expanded, locale).slice();
3831
- return /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", width: "100%", backgroundColor: inkColor("toolBg"), children: rows.map((line8, index) => /* @__PURE__ */ jsx4(Text4, { wrap: "truncate", children: paintLineFromRenderLine(line8, hyperlinksEnabled()) }, index)) });
3986
+ return /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", width: "100%", backgroundColor: inkColor("toolBg"), children: rows.map((line5, index) => /* @__PURE__ */ jsx4(Text4, { wrap: "truncate", children: paintLineFromRenderLine(line5, hyperlinksEnabled()) }, index)) });
3832
3987
  }
3833
3988
 
3834
3989
  // tui-render/src/tool-presenter-cache.ts
@@ -3899,10 +4054,12 @@ var PlainTextRowCache = class {
3899
4054
  * @param id - stable owning text id.
3900
4055
  * @param source - canonical, unabridged reasoning text.
3901
4056
  * @param width - body width excluding its two-column indentation.
4057
+ * @param backgroundColumns - optional surface width in terminal columns.
4058
+ * @param background - optional surface token painted behind every row.
3902
4059
  * @returns every physical body row; the main transcript owns clipping and scrolling.
3903
4060
  */
3904
- rows(id, source, width) {
3905
- const key = `${id}\0${width}`;
4061
+ rows(id, source, width, backgroundColumns, background = "toolBg") {
4062
+ const key = `${id}\0${width}\0${backgroundColumns ?? ""}\0${background}`;
3906
4063
  const cached = this.entries.get(key);
3907
4064
  if (cached?.source === source) {
3908
4065
  this.entries.delete(key);
@@ -3911,30 +4068,51 @@ var PlainTextRowCache = class {
3911
4068
  }
3912
4069
  if (cached !== void 0) this.remove(key, cached);
3913
4070
  for (const entry of this.entries.values()) {
3914
- if (entry.source === source && entry.naturalWidth <= Math.min(width, entry.width)) {
4071
+ if (entry.source === source && entry.naturalWidth <= Math.min(width, entry.width) && (backgroundColumns === void 0 || entry.backgroundColumns === backgroundColumns) && entry.background === background) {
3915
4072
  this.remember(key, entry);
3916
4073
  return entry.rows;
3917
4074
  }
3918
4075
  }
3919
4076
  const wrapped = [];
3920
4077
  let naturalWidth = 0;
3921
- for (const line8 of escapeContent(source).replace(/\t/gu, "\\t").split("\n")) {
3922
- const columns = displayWidth(line8);
4078
+ for (const line5 of escapeContent(source).replace(/\t/gu, "\\t").split("\n")) {
4079
+ const columns = displayWidth(line5);
3923
4080
  naturalWidth = Math.max(naturalWidth, columns);
3924
- if (columns <= width) wrapped.push(line8);
3925
- else wrapped.push(...wrapDisplayLines(line8, width));
4081
+ if (columns <= width) wrapped.push(line5);
4082
+ else wrapped.push(...wrapDisplayLines(line5, width));
3926
4083
  }
3927
4084
  const materialized = /* @__PURE__ */ new Map();
3928
4085
  const rows = indexedRows(wrapped.length, (index) => {
3929
4086
  const hit = materialized.get(index);
3930
4087
  if (hit !== void 0) return hit;
3931
- const text = ` ${wrapped[index]}`;
4088
+ const text = `\u2502 ${wrapped[index]}`;
3932
4089
  const columns = displayWidth(text);
3933
- const row = { text, displayWidth: columns, spans: [{ start: 0, end: columns, token: "fgDim", bold: false }], rowInBlock: index + 1, sourceStart: -1, sourceEnd: -1, rawTail: false };
4090
+ const row = {
4091
+ text,
4092
+ displayWidth: columns,
4093
+ spans: [
4094
+ { start: 0, end: 2, token: "accentText", bold: false },
4095
+ { start: 2, end: columns, token: "fgDim", bold: false }
4096
+ ],
4097
+ rowInBlock: index + 1,
4098
+ sourceStart: -1,
4099
+ sourceEnd: -1,
4100
+ rawTail: false,
4101
+ background,
4102
+ ...backgroundColumns !== void 0 ? { backgroundColumns } : {}
4103
+ };
3934
4104
  materialized.set(index, row);
3935
4105
  return row;
3936
4106
  });
3937
- this.remember(key, { source, rows, naturalWidth, width, bytes: Buffer.byteLength(source) + wrapped.length * 128 });
4107
+ this.remember(key, {
4108
+ source,
4109
+ rows,
4110
+ naturalWidth,
4111
+ width,
4112
+ bytes: Buffer.byteLength(source) + wrapped.length * 128,
4113
+ ...backgroundColumns !== void 0 ? { backgroundColumns } : {},
4114
+ background
4115
+ });
3938
4116
  return rows;
3939
4117
  }
3940
4118
  remember(key, entry) {
@@ -4287,6 +4465,19 @@ function layoutState(state, action) {
4287
4465
  if (state.contentRows === next.contentRows && state.viewportRows === next.viewportRows && state.offsetFromBottom === next.offsetFromBottom && state.unseenRows === next.unseenRows && state.anchor?.blockId === next.anchor?.blockId && state.anchor?.rowWithinBlock === next.anchor?.rowWithinBlock && state.anchor?.viewportRow === next.anchor?.viewportRow && sameBlocks(state.blocks, next.blocks)) return state;
4288
4466
  return next;
4289
4467
  }
4468
+ function applyOffsetAndFollow(state, offsetFromBottom, follow) {
4469
+ if (offsetFromBottom === state.offsetFromBottom && follow === state.follow && (follow ? 0 : state.unseenRows) === state.unseenRows) {
4470
+ return state;
4471
+ }
4472
+ const nextTop = topRow({ ...state, offsetFromBottom });
4473
+ return {
4474
+ ...state,
4475
+ follow,
4476
+ offsetFromBottom,
4477
+ unseenRows: follow ? 0 : state.unseenRows,
4478
+ anchor: follow ? void 0 : anchorForRow(nextTop, state.blocks)
4479
+ };
4480
+ }
4290
4481
  function reduceTranscriptViewport(state, action) {
4291
4482
  switch (action.kind) {
4292
4483
  case "layout":
@@ -4303,17 +4494,7 @@ function reduceTranscriptViewport(state, action) {
4303
4494
  state.viewportRows
4304
4495
  );
4305
4496
  const follow = offsetFromBottom === 0 ? true : action.delta > 0 ? false : state.follow;
4306
- if (offsetFromBottom === state.offsetFromBottom && follow === state.follow && (follow ? 0 : state.unseenRows) === state.unseenRows) {
4307
- return state;
4308
- }
4309
- const nextTop = topRow({ ...state, offsetFromBottom });
4310
- return {
4311
- ...state,
4312
- follow,
4313
- offsetFromBottom,
4314
- unseenRows: follow ? 0 : state.unseenRows,
4315
- anchor: follow ? void 0 : anchorForRow(nextTop, state.blocks)
4316
- };
4497
+ return applyOffsetAndFollow(state, offsetFromBottom, follow);
4317
4498
  }
4318
4499
  case "offset": {
4319
4500
  const offsetFromBottom = clampOffset(
@@ -4321,35 +4502,13 @@ function reduceTranscriptViewport(state, action) {
4321
4502
  state.contentRows,
4322
4503
  state.viewportRows
4323
4504
  );
4324
- const follow = offsetFromBottom === 0;
4325
- if (offsetFromBottom === state.offsetFromBottom && follow === state.follow && (follow ? 0 : state.unseenRows) === state.unseenRows) {
4326
- return state;
4327
- }
4328
- const nextTop = topRow({ ...state, offsetFromBottom });
4329
- return {
4330
- ...state,
4331
- follow,
4332
- offsetFromBottom,
4333
- unseenRows: follow ? 0 : state.unseenRows,
4334
- anchor: follow ? void 0 : anchorForRow(nextTop, state.blocks)
4335
- };
4505
+ return applyOffsetAndFollow(state, offsetFromBottom, offsetFromBottom === 0);
4336
4506
  }
4337
4507
  case "position": {
4338
4508
  const available = maxOffset(state.contentRows, state.viewportRows);
4339
4509
  const fraction = Math.max(0, Math.min(action.fraction, 1));
4340
4510
  const offsetFromBottom = Math.round(available * (1 - fraction));
4341
- const follow = offsetFromBottom === 0;
4342
- if (offsetFromBottom === state.offsetFromBottom && follow === state.follow && (follow ? 0 : state.unseenRows) === state.unseenRows) {
4343
- return state;
4344
- }
4345
- const nextTop = topRow({ ...state, offsetFromBottom });
4346
- return {
4347
- ...state,
4348
- follow,
4349
- offsetFromBottom,
4350
- unseenRows: follow ? 0 : state.unseenRows,
4351
- anchor: follow ? void 0 : anchorForRow(nextTop, state.blocks)
4352
- };
4511
+ return applyOffsetAndFollow(state, offsetFromBottom, offsetFromBottom === 0);
4353
4512
  }
4354
4513
  case "edge": {
4355
4514
  if (action.edge === "latest") {
@@ -4608,22 +4767,22 @@ function visibleFrameSnapshot() {
4608
4767
  return publishedSnapshot;
4609
4768
  }
4610
4769
  var lineIdentityCache = /* @__PURE__ */ new WeakMap();
4611
- function physicalLineIdentity(line8) {
4612
- let cached = lineIdentityCache.get(line8);
4770
+ function physicalLineIdentity(line5) {
4771
+ let cached = lineIdentityCache.get(line5);
4613
4772
  if (cached !== void 0) return cached;
4614
4773
  cached = JSON.stringify([
4615
- line8.text,
4616
- line8.displayWidth,
4617
- line8.background ?? "bg",
4618
- line8.backgroundColumns ?? line8.displayWidth,
4619
- line8.spans.map((span) => [
4774
+ line5.text,
4775
+ line5.displayWidth,
4776
+ line5.background ?? "bg",
4777
+ line5.backgroundColumns ?? line5.displayWidth,
4778
+ line5.spans.map((span) => [
4620
4779
  span.text,
4621
4780
  span.token,
4622
4781
  span.bold === true ? 1 : 0,
4623
4782
  span.href ?? ""
4624
4783
  ])
4625
4784
  ]);
4626
- lineIdentityCache.set(line8, cached);
4785
+ lineIdentityCache.set(line5, cached);
4627
4786
  return cached;
4628
4787
  }
4629
4788
  function createFrameSnapshotRow(input) {
@@ -4644,8 +4803,8 @@ function sameGeometry(a, b) {
4644
4803
  function screenRowKey(row) {
4645
4804
  return row.row << 16 | row.col;
4646
4805
  }
4647
- function paintedColumns(line8) {
4648
- return line8.backgroundColumns ?? line8.displayWidth;
4806
+ function paintedColumns(line5) {
4807
+ return line5.backgroundColumns ?? line5.displayWidth;
4649
4808
  }
4650
4809
  function diffVisibleFrameSnapshots(previous, next) {
4651
4810
  const forced = previous === void 0 || !sameGeometry(previous.geometry, next.geometry);
@@ -4761,24 +4920,24 @@ function railOverlay(tier, force = false) {
4761
4920
  return cells === "" ? "" : `\x1B7${cells}\x1B8`;
4762
4921
  }
4763
4922
  var paintedPhysicalLineCache = /* @__PURE__ */ new WeakMap();
4764
- function paintPhysicalLine(line8, tier) {
4923
+ function paintPhysicalLine(line5, tier) {
4765
4924
  const hyperlinks2 = hyperlinksEnabled();
4766
4925
  const cacheKey = `${tier}:${hyperlinks2 ? 1 : 0}`;
4767
- let byTier = paintedPhysicalLineCache.get(line8);
4926
+ let byTier = paintedPhysicalLineCache.get(line5);
4768
4927
  if (byTier === void 0) {
4769
4928
  byTier = /* @__PURE__ */ new Map();
4770
- paintedPhysicalLineCache.set(line8, byTier);
4929
+ paintedPhysicalLineCache.set(line5, byTier);
4771
4930
  }
4772
4931
  const cached = byTier.get(cacheKey);
4773
4932
  if (cached !== void 0) return cached;
4774
- const parts = line8.spans.map((span) => {
4933
+ const parts = line5.spans.map((span) => {
4775
4934
  const text = styled(span.text, span.token, tier, span.bold);
4776
4935
  return span.href !== void 0 && hyperlinks2 && isOsc8Href(span.href) ? wrapOsc8(text, span.href) : text;
4777
4936
  });
4778
- const painted = line8.background !== void 0 && line8.background !== "bg" ? paintBackgroundRow(
4937
+ const painted = line5.background !== void 0 && line5.background !== "bg" ? paintBackgroundRow(
4779
4938
  parts,
4780
- line8.background,
4781
- line8.backgroundColumns ?? Math.max(1, line8.displayWidth),
4939
+ line5.background,
4940
+ line5.backgroundColumns ?? Math.max(1, line5.displayWidth),
4782
4941
  tier
4783
4942
  ) : paintRow(parts, tier);
4784
4943
  byTier.set(cacheKey, painted);
@@ -4936,21 +5095,21 @@ function wrapStdoutForFrameBg(stdout, getTier = currentTier, frameMetrics) {
4936
5095
  var TERMINAL_CONTROL_PATTERN = /\x1b\][^\x07]*(?:\x07|\x1b\\)|\x1b\[[0-?]*[ -/]*[@-~]|\x1b./gu;
4937
5096
  function countWrittenCells(chunk) {
4938
5097
  const printable = chunk.replace(TERMINAL_CONTROL_PATTERN, (control) => control.startsWith("\x1B]") || control.startsWith("\x1B[") && control.endsWith("m") ? "" : "\n").replace(/[\u0000-\u0009\u000b-\u001f\u007f]/gu, "");
4939
- return printable.split("\n").reduce((cells, line8) => cells + displayWidth(line8), 0);
5098
+ return printable.split("\n").reduce((cells, line5) => cells + displayWidth(line5), 0);
4940
5099
  }
4941
5100
 
4942
5101
  // tui-render/src/screen-atlas.ts
4943
5102
  var GRAPHEME2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
4944
- function paintSnapshotLine(line8) {
4945
- const parts = line8.spans.map((span) => {
5103
+ function paintSnapshotLine(line5) {
5104
+ const parts = line5.spans.map((span) => {
4946
5105
  const painted = styled(span.text, span.token, void 0, span.bold);
4947
- const href = span.href ?? line8.osc8?.href;
5106
+ const href = span.href ?? line5.osc8?.href;
4948
5107
  return href === void 0 || !hyperlinksEnabled() ? painted : wrapOsc8(painted, href);
4949
5108
  });
4950
- return line8.background !== void 0 && line8.background !== "bg" ? paintBackgroundRow(
5109
+ return line5.background !== void 0 && line5.background !== "bg" ? paintBackgroundRow(
4951
5110
  parts,
4952
- line8.background,
4953
- line8.backgroundColumns ?? Math.max(1, line8.displayWidth)
5111
+ line5.background,
5112
+ line5.backgroundColumns ?? Math.max(1, line5.displayWidth)
4954
5113
  ) : paintRow(parts);
4955
5114
  }
4956
5115
  function orderedPoints(a, b) {
@@ -5243,17 +5402,55 @@ var ScreenAtlas = class {
5243
5402
  for (let row = start.row; row <= end.row; row++) {
5244
5403
  const from = row === start.row ? start.col : 1;
5245
5404
  const to = row === end.row ? end.col : this.width;
5246
- let line8 = "";
5405
+ let line5 = "";
5247
5406
  for (let col = from; col <= to; col++) {
5248
5407
  if (this.isSnapshotRailControlCell(col, row)) continue;
5249
5408
  const cell = this.cellAt(col, row);
5250
5409
  if (cell === void 0 || cell.ch === "") continue;
5251
- line8 += cell.ch;
5410
+ line5 += cell.ch;
5252
5411
  }
5253
- lines.push(line8.replace(/ +$/u, ""));
5412
+ lines.push(line5.replace(/ +$/u, ""));
5254
5413
  }
5255
5414
  return lines.join("\n");
5256
5415
  }
5416
+ collectRowTextRuns(row, from, to, onRun) {
5417
+ let run = "";
5418
+ let runCol = 0;
5419
+ const flush = () => {
5420
+ if (run === "" || runCol === 0) return;
5421
+ onRun(runCol, run);
5422
+ run = "";
5423
+ runCol = 0;
5424
+ };
5425
+ for (let col = from; col <= to; col++) {
5426
+ if (this.isSnapshotRailControlCell(col, row)) {
5427
+ flush();
5428
+ continue;
5429
+ }
5430
+ const cell = this.cellAt(col, row);
5431
+ if (cell === void 0 || !cell.written || cell.ch === "") {
5432
+ flush();
5433
+ continue;
5434
+ }
5435
+ if (run === "") runCol = col;
5436
+ run += cell.ch;
5437
+ }
5438
+ flush();
5439
+ }
5440
+ /**
5441
+ * Iterate over screen rows within a selection range, calculating the column span.
5442
+ * @param a - one endpoint.
5443
+ * @param b - the other endpoint.
5444
+ * @param callback - visitor receiving row index and column bounds [from, to].
5445
+ */
5446
+ forEachRowInRange(a, b, callback) {
5447
+ const { start, end } = orderedPoints(a, b);
5448
+ for (let row = start.row; row <= end.row; row++) {
5449
+ const from = row === start.row ? start.col : 1;
5450
+ const to = row === end.row ? end.col : this.width;
5451
+ callback(row, from, to);
5452
+ }
5453
+ }
5257
5454
  /**
5258
5455
  * Reverse-video overlay that rewrites selectable cells. Published rail cells
5259
5456
  * are excluded. Empty when the range has no glyphs.
@@ -5262,34 +5459,12 @@ var ScreenAtlas = class {
5262
5459
  * @returns CUP + reverse SGR bytes.
5263
5460
  */
5264
5461
  selectionOverlay(a, b) {
5265
- const { start, end } = orderedPoints(a, b);
5266
5462
  let out = "";
5267
- for (let row = start.row; row <= end.row; row++) {
5268
- const from = row === start.row ? start.col : 1;
5269
- const to = row === end.row ? end.col : this.width;
5270
- let run = "";
5271
- let runCol = 0;
5272
- const flush = () => {
5273
- if (run === "" || runCol === 0) return;
5463
+ this.forEachRowInRange(a, b, (row, from, to) => {
5464
+ this.collectRowTextRuns(row, from, to, (runCol, run) => {
5274
5465
  out += `\x1B[${row};${runCol}H\x1B[7m${run}\x1B[27m`;
5275
- run = "";
5276
- runCol = 0;
5277
- };
5278
- for (let col = from; col <= to; col++) {
5279
- if (this.isSnapshotRailControlCell(col, row)) {
5280
- flush();
5281
- continue;
5282
- }
5283
- const cell = this.cellAt(col, row);
5284
- if (cell === void 0 || !cell.written || cell.ch === "") {
5285
- flush();
5286
- continue;
5287
- }
5288
- if (run === "") runCol = col;
5289
- run += cell.ch;
5290
- }
5291
- flush();
5292
- }
5466
+ });
5467
+ });
5293
5468
  return out;
5294
5469
  }
5295
5470
  /**
@@ -5301,39 +5476,17 @@ var ScreenAtlas = class {
5301
5476
  * @returns CUP + normal painted runs for the occupied cells.
5302
5477
  */
5303
5478
  restoreOverlay(a, b) {
5304
- const { start, end } = orderedPoints(a, b);
5305
5479
  let out = "";
5306
- for (let row = start.row; row <= end.row; row++) {
5307
- const from = row === start.row ? start.col : 1;
5308
- const to = row === end.row ? end.col : this.width;
5480
+ this.forEachRowInRange(a, b, (row, from, to) => {
5309
5481
  const snapshotRow = this.snapshotRows.get(row);
5310
5482
  if (snapshotRow !== void 0 && !this.snapshotRowOverlapsRailControl(snapshotRow) && from <= snapshotRow.col + snapshotRow.line.displayWidth - 1 && to >= snapshotRow.col) {
5311
5483
  out += `\x1B[${row};${snapshotRow.col}H${paintSnapshotLine(snapshotRow.line)}`;
5312
- continue;
5484
+ return;
5313
5485
  }
5314
- let run = "";
5315
- let runCol = 0;
5316
- const flush = () => {
5317
- if (run === "" || runCol === 0) return;
5486
+ this.collectRowTextRuns(row, from, to, (runCol, run) => {
5318
5487
  out += `\x1B[${row};${runCol}H${paintRow([styled(run, "fg")])}`;
5319
- run = "";
5320
- runCol = 0;
5321
- };
5322
- for (let col = from; col <= to; col++) {
5323
- if (this.isSnapshotRailControlCell(col, row)) {
5324
- flush();
5325
- continue;
5326
- }
5327
- const cell = this.cellAt(col, row);
5328
- if (cell === void 0 || !cell.written || cell.ch === "") {
5329
- flush();
5330
- continue;
5331
- }
5332
- if (run === "") runCol = col;
5333
- run += cell.ch;
5334
- }
5335
- flush();
5336
- }
5488
+ });
5489
+ });
5337
5490
  return out;
5338
5491
  }
5339
5492
  blank() {
@@ -6155,23 +6308,23 @@ function appendMarkdownBlock(out, lines) {
6155
6308
  if (out.length > 0) out.push(MARKDOWN_BLOCK_GAP_LINE);
6156
6309
  out.push(...lines);
6157
6310
  }
6158
- function wrapRawTailRows(line8, width) {
6159
- const pieces = wrapDisplayLines(line8.text, Math.max(1, width));
6160
- const style = line8.spans[0] ?? {
6311
+ function wrapRawTailRows(line5, width) {
6312
+ const pieces = wrapDisplayLines(line5.text, Math.max(1, width));
6313
+ const style = line5.spans[0] ?? {
6161
6314
  start: 0,
6162
- end: line8.displayWidth,
6315
+ end: line5.displayWidth,
6163
6316
  token: "fg",
6164
6317
  bold: false
6165
6318
  };
6166
6319
  return pieces.map((text, index) => {
6167
- const row = lineForText(text, style.token, style.bold, line8.rowInBlock + index);
6320
+ const row = lineForText(text, style.token, style.bold, line5.rowInBlock + index);
6168
6321
  return {
6169
6322
  ...row,
6170
- sourceStart: index === 0 ? line8.sourceStart : -1,
6171
- sourceEnd: index === pieces.length - 1 ? line8.sourceEnd : -1,
6323
+ sourceStart: index === 0 ? line5.sourceStart : -1,
6324
+ sourceEnd: index === pieces.length - 1 ? line5.sourceEnd : -1,
6172
6325
  rawTail: true,
6173
- ...line8.background === void 0 ? {} : { background: line8.background },
6174
- ...line8.backgroundColumns === void 0 ? {} : { backgroundColumns: line8.backgroundColumns }
6326
+ ...line5.background === void 0 ? {} : { background: line5.background },
6327
+ ...line5.backgroundColumns === void 0 ? {} : { backgroundColumns: line5.backgroundColumns }
6175
6328
  };
6176
6329
  });
6177
6330
  }
@@ -6196,22 +6349,40 @@ function projectReasoningEntry(entry, scope) {
6196
6349
  return { revision: 0, sourceLength: entry.source.length, lines: [] };
6197
6350
  }
6198
6351
  const icon = live ? getBrailleSpinnerFrame(reasoningDurationMs) : "\u273B";
6199
- const headerText = `${live ? "" : "\u25BE "}${icon} \u601D\u8003 (${secondsLabel}s)`;
6200
- const lines = [
6201
- lineForText(headerText, "fgDim", false, 0)
6202
- ];
6352
+ const prefix = live ? "" : "\u25BE ";
6353
+ const headerLine = surfaceLine([
6354
+ ...prefix !== "" ? [{ text: prefix, token: "accentText", bold: false }] : [],
6355
+ { text: `${icon} \u601D\u8003`, token: "accentText", bold: false },
6356
+ { text: ` (${secondsLabel}s)`, token: "fgDim", bold: false }
6357
+ ], 0, "toolBg", scope.width);
6358
+ const lines = [headerLine];
6203
6359
  const escaped = escapeContent(entry.source);
6204
6360
  const body = wrapDisplayLines(escaped, Math.max(1, scope.width - 4));
6205
6361
  for (const row of body) {
6206
- lines.push(lineForText(` ${row}`, "fgDim", false, lines.length));
6362
+ const text = `\u2502 ${row}`;
6363
+ const cols = displayWidth(text);
6364
+ lines.push({
6365
+ text,
6366
+ displayWidth: cols,
6367
+ spans: [
6368
+ { start: 0, end: 2, token: "accentText", bold: false },
6369
+ { start: 2, end: cols, token: "fgDim", bold: false }
6370
+ ],
6371
+ rowInBlock: lines.length,
6372
+ sourceStart: -1,
6373
+ sourceEnd: -1,
6374
+ rawTail: false,
6375
+ background: "toolBg",
6376
+ backgroundColumns: scope.width
6377
+ });
6207
6378
  }
6208
6379
  return { revision: 0, sourceLength: entry.source.length, lines };
6209
6380
  }
6210
6381
  function projectToolCardEntry(entry, scope) {
6211
6382
  const card = entry.meta?.toolCard;
6212
6383
  if (card === void 0) {
6213
- const line8 = lineForText(entry.source, "fg", false, 0);
6214
- return { revision: 0, sourceLength: entry.source.length, lines: [line8] };
6384
+ const line5 = lineForText(entry.source, "fg", false, 0);
6385
+ return { revision: 0, sourceLength: entry.source.length, lines: [line5] };
6215
6386
  }
6216
6387
  const cache2 = new ToolRowCache(toolPolicyDefaults());
6217
6388
  const lines = cache2.rows(entry.id, card, scope.width, scope.fold.tools, scope.locale ?? "zh-CN").slice();
@@ -6221,8 +6392,8 @@ function projectDividerEntry(entry, scope) {
6221
6392
  if (entry.source === "" || entry.source === "\u2500") {
6222
6393
  return { revision: 0, sourceLength: entry.source.length, lines: [messageSeparatorLine(scope.width)] };
6223
6394
  }
6224
- const line8 = lineForText(entry.source, "fgDim", false, 0);
6225
- return { revision: 0, sourceLength: entry.source.length, lines: [line8] };
6395
+ const line5 = lineForText(entry.source, "fgDim", false, 0);
6396
+ return { revision: 0, sourceLength: entry.source.length, lines: [line5] };
6226
6397
  }
6227
6398
  function projectCompactionEntry(entry) {
6228
6399
  const shadowed = entry.meta?.compactionShadowedCount;
@@ -6266,8 +6437,8 @@ function projectTurnTailEntry(entry, scope) {
6266
6437
  function projectToolSummaryEntry(entry, scope) {
6267
6438
  const status = entry.meta?.toolSummaryStatus;
6268
6439
  const token = status === "error" ? "error" : status === "running" ? "accentText" : "fgDim";
6269
- const line8 = lineForText(entry.source, token, false, 0, "toolBg", scope.width);
6270
- return { revision: 0, sourceLength: entry.source.length, lines: [line8] };
6440
+ const line5 = lineForText(entry.source, token, false, 0, "toolBg", scope.width);
6441
+ return { revision: 0, sourceLength: entry.source.length, lines: [line5] };
6271
6442
  }
6272
6443
  function projectActivePlaceholderEntry(entry) {
6273
6444
  const text = entry.meta?.activePlaceholder ?? "\u25CF \u6B63\u5728\u601D\u8003\u2026";
@@ -6279,8 +6450,8 @@ function projectActivePlaceholderEntry(entry) {
6279
6450
  ] : [
6280
6451
  { text, token: "fg", bold: false }
6281
6452
  ];
6282
- const line8 = mixedLine(segments, 0);
6283
- return { revision: 0, sourceLength: entry.source.length, lines: [line8] };
6453
+ const line5 = mixedLine(segments, 0);
6454
+ return { revision: 0, sourceLength: entry.source.length, lines: [line5] };
6284
6455
  }
6285
6456
  function lineForText(text, token, bold, blockRow, background, backgroundColumns) {
6286
6457
  const width = displayWidth(text);
@@ -6412,7 +6583,7 @@ function createPhysicalLine(input) {
6412
6583
  ...span.href === void 0 ? {} : { href: span.href }
6413
6584
  }))
6414
6585
  );
6415
- const line8 = {
6586
+ const line5 = {
6416
6587
  blockId: input.blockId,
6417
6588
  text,
6418
6589
  displayWidth: displayWidth(text),
@@ -6425,15 +6596,15 @@ function createPhysicalLine(input) {
6425
6596
  ...input.osc8 === void 0 ? {} : { osc8: Object.freeze({ href: input.osc8.href, id: input.osc8.id }) },
6426
6597
  ...input.graphemeSources === void 0 ? {} : { graphemeSources: Object.freeze([...input.graphemeSources]) }
6427
6598
  };
6428
- return Object.freeze(line8);
6599
+ return Object.freeze(line5);
6429
6600
  }
6430
- function physicalLineByteSize(line8) {
6601
+ function physicalLineByteSize(line5) {
6431
6602
  let bytes = 0;
6432
- bytes += line8.text.length;
6433
- for (const span of line8.spans) bytes += span.text.length + (span.href?.length ?? 0);
6434
- bytes += line8.sourceEnd - line8.sourceStart;
6435
- if (line8.osc8 !== void 0) bytes += line8.osc8.href.length + line8.osc8.id.length;
6436
- if (line8.graphemeSources !== void 0) bytes += line8.graphemeSources.length * 4;
6603
+ bytes += line5.text.length;
6604
+ for (const span of line5.spans) bytes += span.text.length + (span.href?.length ?? 0);
6605
+ bytes += line5.sourceEnd - line5.sourceStart;
6606
+ if (line5.osc8 !== void 0) bytes += line5.osc8.href.length + line5.osc8.id.length;
6607
+ if (line5.graphemeSources !== void 0) bytes += line5.graphemeSources.length * 4;
6437
6608
  return bytes;
6438
6609
  }
6439
6610
 
@@ -6669,7 +6840,7 @@ var TranscriptRenderStoreImpl = class {
6669
6840
  }
6670
6841
  cachedBlocks += 1;
6671
6842
  cachedRows += lines.length;
6672
- for (const line8 of lines) cachedBytes += physicalLineByteSize(line8);
6843
+ for (const line5 of lines) cachedBytes += physicalLineByteSize(line5);
6673
6844
  }
6674
6845
  return {
6675
6846
  hits: this.counters.hits,
@@ -6767,7 +6938,7 @@ var TranscriptRenderStoreImpl = class {
6767
6938
  const settled = entry.settledLines;
6768
6939
  const rowCount = settled.length;
6769
6940
  let byteCount = 0;
6770
- for (const line8 of settled) byteCount += physicalLineByteSize(line8);
6941
+ for (const line5 of settled) byteCount += physicalLineByteSize(line5);
6771
6942
  entry.settledLines = null;
6772
6943
  entry.lastAccess = 0;
6773
6944
  this.counters.evictions += 1;
@@ -6780,9 +6951,9 @@ var TranscriptRenderStoreImpl = class {
6780
6951
  let bytes = 0;
6781
6952
  for (const entry of this.entries.values()) {
6782
6953
  const lines = entry.activeRevision === null ? entry.settledLines ?? EMPTY_LINES : entry.activeRevision.lines;
6783
- for (const line8 of lines) {
6954
+ for (const line5 of lines) {
6784
6955
  rows += 1;
6785
- bytes += physicalLineByteSize(line8);
6956
+ bytes += physicalLineByteSize(line5);
6786
6957
  }
6787
6958
  }
6788
6959
  return { rows, bytes };
@@ -7333,7 +7504,7 @@ function liveDurationTarget(turn, status) {
7333
7504
  if (part?.kind === "card" && part.card.status !== "running" || part?.kind === "tool-summary" && part.summary.runningCount === 0) {
7334
7505
  return {
7335
7506
  identity: `turn-${String(turn.turn)}-pending-after-tool-${String(index)}`,
7336
- durationMs: turn.reasoningDurationMs ?? 0
7507
+ durationMs: turn.reasoningDurationMs
7337
7508
  };
7338
7509
  }
7339
7510
  return void 0;
@@ -7410,17 +7581,17 @@ function latestAssistantId(history, activeTurn) {
7410
7581
  return void 0;
7411
7582
  }
7412
7583
  var baseMarkdownLineCache = /* @__PURE__ */ new WeakMap();
7413
- function markdownLineToPhysicalLine(blockId, line8) {
7414
- let byBlock = baseMarkdownLineCache.get(line8);
7584
+ function markdownLineToPhysicalLine(blockId, line5) {
7585
+ let byBlock = baseMarkdownLineCache.get(line5);
7415
7586
  if (byBlock === void 0) {
7416
7587
  byBlock = /* @__PURE__ */ new Map();
7417
- baseMarkdownLineCache.set(line8, byBlock);
7588
+ baseMarkdownLineCache.set(line5, byBlock);
7418
7589
  }
7419
7590
  const cached = byBlock.get(blockId);
7420
7591
  if (cached !== void 0) return cached;
7421
7592
  const segments = [];
7422
- for (const span of line8.spans) {
7423
- const text = displayColumnSlice(line8.text, span.start, span.end);
7593
+ for (const span of line5.spans) {
7594
+ const text = displayColumnSlice(line5.text, span.start, span.end);
7424
7595
  if (text === "") continue;
7425
7596
  segments.push({
7426
7597
  text,
@@ -7429,16 +7600,16 @@ function markdownLineToPhysicalLine(blockId, line8) {
7429
7600
  ...span.href === void 0 ? {} : { href: span.href }
7430
7601
  });
7431
7602
  }
7432
- const sourceStart = Math.max(0, line8.sourceStart);
7433
- const sourceEnd = Math.max(sourceStart, line8.sourceEnd < 0 ? sourceStart : line8.sourceEnd);
7603
+ const sourceStart = Math.max(0, line5.sourceStart);
7604
+ const sourceEnd = Math.max(sourceStart, line5.sourceEnd < 0 ? sourceStart : line5.sourceEnd);
7434
7605
  const created = createPhysicalLine({
7435
7606
  blockId,
7436
7607
  spans: segments.length === 0 ? [{ text: "", token: "fg", bold: false }] : segments,
7437
7608
  sourceStart,
7438
7609
  sourceEnd,
7439
- blockRow: Math.max(0, line8.rowInBlock),
7440
- ...line8.background === void 0 ? {} : { background: line8.background },
7441
- ...line8.backgroundColumns === void 0 ? {} : { backgroundColumns: line8.backgroundColumns }
7610
+ blockRow: Math.max(0, line5.rowInBlock),
7611
+ ...line5.background === void 0 ? {} : { background: line5.background },
7612
+ ...line5.backgroundColumns === void 0 ? {} : { backgroundColumns: line5.backgroundColumns }
7442
7613
  });
7443
7614
  byBlock.set(blockId, created);
7444
7615
  return created;
@@ -7478,17 +7649,28 @@ function overlayPromptOnSpans(spans, prompt) {
7478
7649
  return result;
7479
7650
  }
7480
7651
  var frameLineCache = /* @__PURE__ */ new WeakMap();
7481
- function framePhysicalLine(blockId, line8, lead, active, prompt) {
7652
+ function clonePhysicalLineWithSpans(base, blockId, spans) {
7653
+ return createPhysicalLine({
7654
+ blockId,
7655
+ spans,
7656
+ sourceStart: base.sourceStart,
7657
+ sourceEnd: base.sourceEnd,
7658
+ blockRow: base.blockRow,
7659
+ ...base.background === void 0 ? {} : { background: base.background },
7660
+ ...base.backgroundColumns === void 0 ? {} : { backgroundColumns: base.backgroundColumns }
7661
+ });
7662
+ }
7663
+ function framePhysicalLine(blockId, line5, lead, active, prompt) {
7482
7664
  if (prompt === void 0) {
7483
- let byLine = frameLineCache.get(line8);
7665
+ let byLine = frameLineCache.get(line5);
7484
7666
  if (byLine === void 0) {
7485
7667
  byLine = /* @__PURE__ */ new Map();
7486
- frameLineCache.set(line8, byLine);
7668
+ frameLineCache.set(line5, byLine);
7487
7669
  }
7488
7670
  const key = `${blockId}:${lead}:${active ? "1" : "0"}`;
7489
7671
  const cached = byLine.get(key);
7490
7672
  if (cached !== void 0) return cached;
7491
- const base2 = markdownLineToPhysicalLine(blockId, line8);
7673
+ const base2 = markdownLineToPhysicalLine(blockId, line5);
7492
7674
  const spans2 = lead === "" ? base2.spans : [
7493
7675
  {
7494
7676
  text: lead,
@@ -7497,19 +7679,11 @@ function framePhysicalLine(blockId, line8, lead, active, prompt) {
7497
7679
  },
7498
7680
  ...base2.spans
7499
7681
  ];
7500
- const created = lead === "" ? base2 : createPhysicalLine({
7501
- blockId,
7502
- spans: spans2,
7503
- sourceStart: base2.sourceStart,
7504
- sourceEnd: base2.sourceEnd,
7505
- blockRow: base2.blockRow,
7506
- ...base2.background === void 0 ? {} : { background: base2.background },
7507
- ...base2.backgroundColumns === void 0 ? {} : { backgroundColumns: base2.backgroundColumns }
7508
- });
7682
+ const created = lead === "" ? base2 : clonePhysicalLineWithSpans(base2, blockId, spans2);
7509
7683
  byLine.set(key, created);
7510
7684
  return created;
7511
7685
  }
7512
- const base = markdownLineToPhysicalLine(blockId, line8);
7686
+ const base = markdownLineToPhysicalLine(blockId, line5);
7513
7687
  const initialSpans = [
7514
7688
  ...lead === "" ? [] : [{
7515
7689
  text: lead,
@@ -7519,15 +7693,7 @@ function framePhysicalLine(blockId, line8, lead, active, prompt) {
7519
7693
  ...base.spans
7520
7694
  ];
7521
7695
  const spans = overlayPromptOnSpans(initialSpans, prompt);
7522
- return createPhysicalLine({
7523
- blockId,
7524
- spans,
7525
- sourceStart: base.sourceStart,
7526
- sourceEnd: base.sourceEnd,
7527
- blockRow: base.blockRow,
7528
- ...base.background === void 0 ? {} : { background: base.background },
7529
- ...base.backgroundColumns === void 0 ? {} : { backgroundColumns: base.backgroundColumns }
7530
- });
7696
+ return clonePhysicalLineWithSpans(base, blockId, spans);
7531
7697
  }
7532
7698
  function projectorStateFor(cache2, blockId, scope, aliases = [], source) {
7533
7699
  const projectorScope = scope.scopeKey.replace(/\|(streaming|settled)$/u, "");
@@ -7607,15 +7773,15 @@ function intersectingLayoutIndexes(layouts, start, end) {
7607
7773
  return indexes;
7608
7774
  }
7609
7775
  var paintedRenderLineCache = /* @__PURE__ */ new WeakMap();
7610
- function cachedPaintedRenderLine(line8, cacheKey, hyperlinks2) {
7611
- let variants = paintedRenderLineCache.get(line8);
7776
+ function cachedPaintedRenderLine(line5, cacheKey, hyperlinks2) {
7777
+ let variants = paintedRenderLineCache.get(line5);
7612
7778
  if (variants === void 0) {
7613
7779
  variants = /* @__PURE__ */ new Map();
7614
- paintedRenderLineCache.set(line8, variants);
7780
+ paintedRenderLineCache.set(line5, variants);
7615
7781
  }
7616
7782
  const cached = variants.get(cacheKey);
7617
7783
  if (cached !== void 0) return cached;
7618
- const painted = paintLineFromRenderLine(line8, hyperlinks2);
7784
+ const painted = paintLineFromRenderLine(line5, hyperlinks2);
7619
7785
  variants.set(cacheKey, painted);
7620
7786
  return painted;
7621
7787
  }
@@ -7631,11 +7797,11 @@ var SlicedLinesBlock = memo(function SlicedLinesBlock2(props) {
7631
7797
  const hyperlinks2 = hyperlinksEnabled();
7632
7798
  const paintCacheKey = `${currentTier()}:${hyperlinks2 ? "links" : "plain"}`;
7633
7799
  for (let index = start; index < end; index += 1) {
7634
- const line8 = lines.at(index);
7635
- if (line8 === void 0) {
7800
+ const line5 = lines.at(index);
7801
+ if (line5 === void 0) {
7636
7802
  continue;
7637
7803
  }
7638
- const painted = cachedPaintedRenderLine(line8, paintCacheKey, hyperlinks2);
7804
+ const painted = cachedPaintedRenderLine(line5, paintCacheKey, hyperlinks2);
7639
7805
  const lead = slicedLead(prefix, textRanges, index);
7640
7806
  const trailing = index === effectiveTailRow ? tail : void 0;
7641
7807
  out.push(
@@ -7657,9 +7823,27 @@ function projectBlockEntry(deps, ownerId, entry, scope, state, active) {
7657
7823
  }
7658
7824
  if (entry.kind === "reasoning" && entry.meta?.reasoningExpanded === true && entry.source !== "") {
7659
7825
  const rows = new RowSequence();
7660
- const header = `${entry.meta.reasoningLive === true ? "" : "\u25BE "}\u273B ${tuiCopy("reasoning", deps.locale)} (${((entry.meta.reasoningDurationMs ?? 0) / 1e3).toFixed(1)}s)`;
7661
- rows.push({ ...GAP_LINE, text: header, displayWidth: displayWidth(header), spans: [{ start: 0, end: displayWidth(header), token: "fgDim", bold: false }] });
7662
- rows.append(deps.plainRows.rows(entry.id, entry.source, Math.max(1, scope.width - 4)));
7826
+ const prefix = entry.meta.reasoningLive === true ? "" : "\u25BE ";
7827
+ const title = `\u273B ${tuiCopy("reasoning", deps.locale)}`;
7828
+ const duration = ` (${((entry.meta.reasoningDurationMs ?? 0) / 1e3).toFixed(1)}s)`;
7829
+ const header = `${prefix}${title}${duration}`;
7830
+ const prefixWidth = displayWidth(prefix);
7831
+ const titleWidth = displayWidth(title);
7832
+ const totalWidth = displayWidth(header);
7833
+ const spans = [
7834
+ ...prefixWidth > 0 ? [{ start: 0, end: prefixWidth, token: "accentText", bold: false }] : [],
7835
+ { start: prefixWidth, end: prefixWidth + titleWidth, token: "accentText", bold: false },
7836
+ { start: prefixWidth + titleWidth, end: totalWidth, token: "fgDim", bold: false }
7837
+ ];
7838
+ rows.push({
7839
+ ...GAP_LINE,
7840
+ text: header,
7841
+ displayWidth: totalWidth,
7842
+ spans,
7843
+ background: "toolBg",
7844
+ backgroundColumns: scope.width
7845
+ });
7846
+ rows.append(deps.plainRows.rows(entry.id, entry.source, Math.max(1, scope.width - 4), scope.width, "toolBg"));
7663
7847
  return { lines: rows.build() };
7664
7848
  }
7665
7849
  const projection = projectBlockRows(entry, scope, state);
@@ -7672,6 +7856,36 @@ function projectBlockEntry(deps, ownerId, entry, scope, state, active) {
7672
7856
  });
7673
7857
  return projection;
7674
7858
  }
7859
+ function makeBlockProjector(deps, storeBlocks) {
7860
+ return (ownerId, entry, scope, state, active) => projectBlockEntry({ ...deps, storeBlocks }, ownerId, entry, scope, state, active);
7861
+ }
7862
+ function makeToolSummaryBlockEntry(id, summary, contentWidth) {
7863
+ return {
7864
+ id: `${id}-tool-summary`,
7865
+ kind: "tool-summary",
7866
+ source: toolSummaryText(summary, contentWidth),
7867
+ meta: { toolSummaryStatus: toolSummaryStatus(summary) }
7868
+ };
7869
+ }
7870
+ function makeToolCardBlockEntry(id, card) {
7871
+ return {
7872
+ id: `${id}-c-${card.callId}`,
7873
+ kind: "tool-card",
7874
+ source: "",
7875
+ meta: {
7876
+ toolCard: {
7877
+ name: card.name,
7878
+ arguments: card.arguments,
7879
+ status: card.status,
7880
+ ...card.resultText === void 0 ? {} : { resultText: card.resultText },
7881
+ ...card.meta === void 0 ? {} : { meta: card.meta },
7882
+ ...card.error === void 0 ? {} : { error: card.error },
7883
+ ...card.callView === void 0 ? {} : { callView: card.callView },
7884
+ ...card.resultView === void 0 ? {} : { resultView: card.resultView }
7885
+ }
7886
+ }
7887
+ };
7888
+ }
7675
7889
  function StreamView({
7676
7890
  model,
7677
7891
  presenters,
@@ -7727,7 +7941,7 @@ function StreamView({
7727
7941
  throw new Error(`TranscriptRenderStore: missing source descriptor for ${blockId}`);
7728
7942
  }
7729
7943
  const state = descriptor.entry.kind === "markdown" || descriptor.entry.kind === "assistant-prose" ? createMarkdownProjectorState(blockId, descriptor.scope) : void 0;
7730
- return projectBlockRows(descriptor.entry, descriptor.scope, state).lines.map((line8) => markdownLineToPhysicalLine(blockId, line8));
7944
+ return projectBlockRows(descriptor.entry, descriptor.scope, state).lines.map((line5) => markdownLineToPhysicalLine(blockId, line5));
7731
7945
  }
7732
7946
  });
7733
7947
  }
@@ -7907,7 +8121,7 @@ function StreamView({
7907
8121
  const textRanges = /* @__PURE__ */ new Map();
7908
8122
  const storeBlocks = /* @__PURE__ */ new Map();
7909
8123
  const projectorCache = projectorStates.current;
7910
- const project = (ownerId, entry, scope, state, active) => projectBlockEntry({ toolRows, plainRows, locale, storeBlocks }, ownerId, entry, scope, state, active);
8124
+ const project = makeBlockProjector({ toolRows, plainRows, locale }, storeBlocks);
7911
8125
  const latestAssistant = hasActiveTurn ? void 0 : latestAssistantId(history, void 0);
7912
8126
  for (const [index, row] of transcript.entries()) {
7913
8127
  const id = transcriptBlockId(row);
@@ -7960,33 +8174,23 @@ function StreamView({
7960
8174
  continue;
7961
8175
  }
7962
8176
  if (part.kind === "tool-summary") {
7963
- rows2.append(project(id, {
7964
- id: `${id}-tool-summary`,
7965
- kind: "tool-summary",
7966
- source: toolSummaryText(part.summary, contentWidth),
7967
- meta: { toolSummaryStatus: toolSummaryStatus(part.summary) }
7968
- }, settledBlockRowsScope, void 0, false).lines);
8177
+ rows2.append(project(
8178
+ id,
8179
+ makeToolSummaryBlockEntry(id, part.summary, contentWidth),
8180
+ settledBlockRowsScope,
8181
+ void 0,
8182
+ false
8183
+ ).lines);
7969
8184
  continue;
7970
8185
  }
7971
8186
  if (part.kind === "card") {
7972
- const card = part.card;
7973
- rows2.append(project(id, {
7974
- id: `${id}-c-${card.callId}`,
7975
- kind: "tool-card",
7976
- source: "",
7977
- meta: {
7978
- toolCard: {
7979
- name: card.name,
7980
- arguments: card.arguments,
7981
- status: card.status,
7982
- ...card.resultText === void 0 ? {} : { resultText: card.resultText },
7983
- ...card.meta === void 0 ? {} : { meta: card.meta },
7984
- ...card.error === void 0 ? {} : { error: card.error },
7985
- ...card.callView === void 0 ? {} : { callView: card.callView },
7986
- ...card.resultView === void 0 ? {} : { resultView: card.resultView }
7987
- }
7988
- }
7989
- }, settledBlockRowsScope, void 0, false).lines);
8187
+ rows2.append(project(
8188
+ id,
8189
+ makeToolCardBlockEntry(id, part.card),
8190
+ settledBlockRowsScope,
8191
+ void 0,
8192
+ false
8193
+ ).lines);
7990
8194
  continue;
7991
8195
  }
7992
8196
  const start = rows2.length;
@@ -8062,7 +8266,7 @@ function StreamView({
8062
8266
  } };
8063
8267
  const storeBlocks = /* @__PURE__ */ new Map();
8064
8268
  const projectorCache = projectorStates.current;
8065
- const project = (ownerId, entry, scope, state, active) => projectBlockEntry({ toolRows, plainRows, locale, storeBlocks }, ownerId, entry, scope, state, active);
8269
+ const project = makeBlockProjector({ toolRows, plainRows, locale }, storeBlocks);
8066
8270
  const id = `assistant-turn-${String(activeTurn.turn)}`;
8067
8271
  const rawParts = partsFromTurn(activeTurn);
8068
8272
  const visibleParts = displayedParts(rawParts, reasoningExpanded);
@@ -8110,33 +8314,23 @@ function StreamView({
8110
8314
  continue;
8111
8315
  }
8112
8316
  if (part.kind === "tool-summary") {
8113
- rows2.append(project(id, {
8114
- id: `${id}-tool-summary`,
8115
- kind: "tool-summary",
8116
- source: toolSummaryText(part.summary, contentWidth),
8117
- meta: { toolSummaryStatus: toolSummaryStatus(part.summary) }
8118
- }, blockRowsScope, void 0, status === "generating").lines);
8317
+ rows2.append(project(
8318
+ id,
8319
+ makeToolSummaryBlockEntry(id, part.summary, contentWidth),
8320
+ blockRowsScope,
8321
+ void 0,
8322
+ status === "generating"
8323
+ ).lines);
8119
8324
  continue;
8120
8325
  }
8121
8326
  if (part.kind === "card") {
8122
- const card = part.card;
8123
- rows2.append(project(id, {
8124
- id: `${id}-c-${card.callId}`,
8125
- kind: "tool-card",
8126
- source: "",
8127
- meta: {
8128
- toolCard: {
8129
- name: card.name,
8130
- arguments: card.arguments,
8131
- status: card.status,
8132
- ...card.resultText === void 0 ? {} : { resultText: card.resultText },
8133
- ...card.meta === void 0 ? {} : { meta: card.meta },
8134
- ...card.error === void 0 ? {} : { error: card.error },
8135
- ...card.callView === void 0 ? {} : { callView: card.callView },
8136
- ...card.resultView === void 0 ? {} : { resultView: card.resultView }
8137
- }
8138
- }
8139
- }, blockRowsScope, void 0, status === "generating").lines);
8327
+ rows2.append(project(
8328
+ id,
8329
+ makeToolCardBlockEntry(id, part.card),
8330
+ blockRowsScope,
8331
+ void 0,
8332
+ status === "generating"
8333
+ ).lines);
8140
8334
  continue;
8141
8335
  }
8142
8336
  const start = rows2.length;
@@ -8259,15 +8453,15 @@ function StreamView({
8259
8453
  String(descriptor.lines.length)
8260
8454
  ]);
8261
8455
  if (!descriptor.active && !activeLineRevisions.current.has(descriptor.entry.id) && storedLineSignatures.current.get(descriptor.entry.id) === signature) continue;
8262
- const physical = descriptor.lines.map((line8) => {
8263
- let byBlock = physicalLineCache.current.get(line8);
8456
+ const physical = descriptor.lines.map((line5) => {
8457
+ let byBlock = physicalLineCache.current.get(line5);
8264
8458
  if (byBlock === void 0) {
8265
8459
  byBlock = /* @__PURE__ */ new Map();
8266
- physicalLineCache.current.set(line8, byBlock);
8460
+ physicalLineCache.current.set(line5, byBlock);
8267
8461
  }
8268
8462
  let cached = byBlock.get(descriptor.entry.id);
8269
8463
  if (cached === void 0) {
8270
- cached = markdownLineToPhysicalLine(descriptor.entry.id, line8);
8464
+ cached = markdownLineToPhysicalLine(descriptor.entry.id, line5);
8271
8465
  byBlock.set(descriptor.entry.id, cached);
8272
8466
  }
8273
8467
  return cached;
@@ -8682,8 +8876,8 @@ function StreamView({
8682
8876
  const assistant = entry.kind === "active" || entry.row.kind === "message" && entry.row.message.kind === "assistant";
8683
8877
  const ranges = assistant ? activeEntryRows.textRanges.get(entry.id) ?? EMPTY_TEXT_RANGES : EMPTY_TEXT_RANGES;
8684
8878
  for (let index = start; index < end; index += 1) {
8685
- const line8 = entry.lines.at(index);
8686
- if (line8 === void 0) continue;
8879
+ const line5 = entry.lines.at(index);
8880
+ if (line5 === void 0) continue;
8687
8881
  const absoluteRow = 3 + verticalBase + layout.top + index - visibleTop;
8688
8882
  if (absoluteRow < 3 || absoluteRow >= 3 + effectiveViewportRows) continue;
8689
8883
  const isBottomRow = absoluteRow === 3 + effectiveViewportRows - 1;
@@ -8698,7 +8892,7 @@ function StreamView({
8698
8892
  id: `${entry.id}:${String(index)}`,
8699
8893
  row: absoluteRow,
8700
8894
  col: contentLeft + 1,
8701
- line: framePhysicalLine(entry.id, line8, lead, entry.kind === "active", promptOverlay)
8895
+ line: framePhysicalLine(entry.id, line5, lead, entry.kind === "active", promptOverlay)
8702
8896
  }));
8703
8897
  }
8704
8898
  }
@@ -9346,7 +9540,7 @@ function HelpPane({ lines, offset }) {
9346
9540
  safeOffset,
9347
9541
  " \u884C"
9348
9542
  ] }) : null,
9349
- visible.map((line8, index) => /* @__PURE__ */ jsx10(Text10, { children: escapeContent(line8) }, safeOffset + index)),
9543
+ visible.map((line5, index) => /* @__PURE__ */ jsx10(Text10, { children: escapeContent(line5) }, safeOffset + index)),
9350
9544
  /* @__PURE__ */ jsx10(Text10, { children: styled(escapeContent("\u2191\u2193/jk \u6EDA\u52A8 \xB7 Esc/Enter \u5173\u95ED"), "fgDim") })
9351
9545
  ] });
9352
9546
  }
@@ -9424,8 +9618,36 @@ function ApprovalPane({
9424
9618
  }
9425
9619
 
9426
9620
  // tui-render/src/permission-pane.tsx
9621
+ import { Box as Box13, Text as Text13 } from "ink";
9622
+
9623
+ // tui-render/src/overlay-shell.tsx
9427
9624
  import { Box as Box12, Text as Text12 } from "ink";
9428
9625
  import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
9626
+ var EMPTY_OVERLAY_PANE = { open: false };
9627
+ function renderPaneLine(text, token, bold = false) {
9628
+ return /* @__PURE__ */ jsx12(Text12, { children: paintRow([styled(escapeContent(text), token, void 0, bold)]) });
9629
+ }
9630
+ var line2 = renderPaneLine;
9631
+ function OverlayShell({
9632
+ title,
9633
+ body,
9634
+ footnote,
9635
+ error,
9636
+ errorNext,
9637
+ children
9638
+ }) {
9639
+ return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", width: "100%", children: [
9640
+ line2(title, "fg", true),
9641
+ body !== void 0 && body !== "" ? line2(body, "fg") : null,
9642
+ children,
9643
+ error !== void 0 && error !== "" ? line2(`\u2717 ${error}`, "error") : null,
9644
+ error !== void 0 && error !== "" && errorNext !== void 0 && errorNext !== "" ? line2(errorNext, "fgDim") : null,
9645
+ line2(footnote, "fgDim")
9646
+ ] });
9647
+ }
9648
+
9649
+ // tui-render/src/permission-pane.tsx
9650
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
9429
9651
  var TITLE = "\u6743\u9650\u9884\u8BBE";
9430
9652
  var FOOTNOTE = "\u2191\u2193/jk \u9009\u62E9 \xB7 1-3 \u76F4\u8FBE \xB7 Enter \u5E94\u7528 \xB7 Esc \u5173\u95ED";
9431
9653
  var CONFIRM = "\u786E\u8BA4\u5207\u6362\u5230 danger-full-access\uFF1F";
@@ -9439,9 +9661,6 @@ var EMPTY_PERMISSION_PANE = {
9439
9661
  currentName: "",
9440
9662
  confirmDanger: false
9441
9663
  };
9442
- function line2(text, token, bold = false) {
9443
- return /* @__PURE__ */ jsx12(Text12, { children: paintRow([styled(escapeContent(text), token, void 0, bold)]) });
9444
- }
9445
9664
  function PermissionPane({
9446
9665
  names,
9447
9666
  selectedIndex,
@@ -9451,38 +9670,38 @@ function PermissionPane({
9451
9670
  switchError
9452
9671
  }) {
9453
9672
  if (confirmDanger) {
9454
- return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", width: "100%", children: [
9455
- line2(CONFIRM, "fg", true),
9456
- line2(CONFIRM_FOOTNOTE, "fgDim")
9673
+ return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", width: "100%", children: [
9674
+ renderPaneLine(CONFIRM, "fg", true),
9675
+ renderPaneLine(CONFIRM_FOOTNOTE, "fgDim")
9457
9676
  ] });
9458
9677
  }
9459
9678
  const errorReason = switchError ?? (names.length === 0 ? EMPTY_TABLE_REASON : void 0);
9460
- return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", width: "100%", children: [
9461
- line2(TITLE, "fg", true),
9679
+ return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", width: "100%", children: [
9680
+ renderPaneLine(TITLE, "fg", true),
9462
9681
  names.map((name, index) => {
9463
9682
  const selected = index === selectedIndex;
9464
9683
  const current = name === currentName;
9465
9684
  const description = descriptions?.[index];
9466
9685
  const label = current ? `${name} \xB7 \u5F53\u524D` : name;
9467
- return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", width: "100%", children: [
9468
- /* @__PURE__ */ jsxs11(Box12, { width: "100%", children: [
9469
- /* @__PURE__ */ jsx12(Text12, { children: selected ? styled(escapeContent("\u203A "), "accent", void 0, true) : " " }),
9470
- /* @__PURE__ */ jsx12(Text12, { children: paintRow([styled(escapeContent(label), selected ? "fg" : "fgDim")]) })
9686
+ return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", width: "100%", children: [
9687
+ /* @__PURE__ */ jsxs12(Box13, { width: "100%", children: [
9688
+ /* @__PURE__ */ jsx13(Text13, { children: selected ? styled(escapeContent("\u203A "), "accent", void 0, true) : " " }),
9689
+ /* @__PURE__ */ jsx13(Text13, { children: paintRow([styled(escapeContent(label), selected ? "fg" : "fgDim")]) })
9471
9690
  ] }),
9472
- description !== void 0 && description !== "" ? line2(description, "fgDim") : null
9691
+ description !== void 0 && description !== "" ? renderPaneLine(description, "fgDim") : null
9473
9692
  ] }, name);
9474
9693
  }),
9475
- errorReason !== void 0 ? /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", width: "100%", children: [
9476
- line2(`\u2717 \u5207\u6362\u6743\u9650\u5931\u8D25\uFF1A${errorReason}`, "error"),
9477
- line2(FAIL_NEXT, "fgDim")
9694
+ errorReason !== void 0 ? /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", width: "100%", children: [
9695
+ renderPaneLine(`\u2717 \u5207\u6362\u6743\u9650\u5931\u8D25\uFF1A${errorReason}`, "error"),
9696
+ renderPaneLine(FAIL_NEXT, "fgDim")
9478
9697
  ] }) : null,
9479
- line2(FOOTNOTE, "fgDim")
9698
+ renderPaneLine(FOOTNOTE, "fgDim")
9480
9699
  ] });
9481
9700
  }
9482
9701
 
9483
9702
  // tui-render/src/settings-pane.tsx
9484
- import { Box as Box13, Text as Text13, useWindowSize as useWindowSize5 } from "ink";
9485
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
9703
+ import { Box as Box14, Text as Text14, useWindowSize as useWindowSize5 } from "ink";
9704
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
9486
9705
  var TITLE2 = "\u8BBE\u7F6E";
9487
9706
  var ONBOARDING_TITLE = "\u9996\u6B21\u8BBE\u7F6E";
9488
9707
  var FOOTNOTE2 = "\u2191\u2193/jk \u9009\u62E9 \xB7 Enter \u7F16\u8F91 \xB7 e \u5BFC\u51FA \xB7 r \u91CD\u8F7D \xB7 Esc \u5173\u95ED";
@@ -9500,9 +9719,6 @@ var EMPTY_SETTINGS_PANE = {
9500
9719
  selectedIndex: 0,
9501
9720
  editing: false
9502
9721
  };
9503
- function line3(text, token, bold = false) {
9504
- return /* @__PURE__ */ jsx13(Text13, { children: paintRow([styled(escapeContent(text), token, void 0, bold)]) });
9505
- }
9506
9722
  function fitValue(value, maxCols) {
9507
9723
  if (maxCols <= 0) return "";
9508
9724
  if (displayWidth(value) <= maxCols) return value;
@@ -9560,57 +9776,30 @@ function SettingsPane({
9560
9776
  rows.length - size
9561
9777
  );
9562
9778
  const visible = rows.slice(start, start + size);
9563
- return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", width: "100%", children: [
9564
- line3(onboarding === true ? ONBOARDING_TITLE : TITLE2, "fg", true),
9565
- start > 0 ? line3(`\u2026 \u8FD8\u6709 ${String(start)} \u9879`, "fgDim") : null,
9779
+ return /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", width: "100%", children: [
9780
+ renderPaneLine(onboarding === true ? ONBOARDING_TITLE : TITLE2, "fg", true),
9781
+ start > 0 ? renderPaneLine(`\u2026 \u8FD8\u6709 ${String(start)} \u9879`, "fgDim") : null,
9566
9782
  visible.map((row, index) => {
9567
9783
  const absolute = start + index;
9568
9784
  const selected = absolute === selectedIndex;
9569
9785
  const localized = row.namespace === "tui" && (row.field === "reasoning" || row.field === "scrollbar" || row.field === "statusDetails" || row.field === "locale") ? `${row.field} \xB7 ${tuiCopy(row.field, locale)}` : row.field === "apiKeyEnv" ? `${row.field} \xB7 \u73AF\u5883\u53D8\u91CF\u540D` : row.field;
9570
9786
  const label = `${row.namespace} \xB7 ${localized}`;
9571
- return /* @__PURE__ */ jsx13(Box13, { width: "100%", children: /* @__PURE__ */ jsx13(Text13, { children: paintRow(fieldRow(label, row.value, selected, width)) }) }, `${row.namespace}:${row.field}`);
9787
+ return /* @__PURE__ */ jsx14(Box14, { width: "100%", children: /* @__PURE__ */ jsx14(Text14, { children: paintRow(fieldRow(label, row.value, selected, width)) }) }, `${row.namespace}:${row.field}`);
9572
9788
  }),
9573
- rows.length > start + size ? line3(`\u2026 \u8FD8\u6709 ${String(rows.length - start - size)} \u9879`, "fgDim") : null,
9574
- errorReason !== void 0 ? /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", width: "100%", children: [
9575
- line3(
9789
+ rows.length > start + size ? renderPaneLine(`\u2026 \u8FD8\u6709 ${String(rows.length - start - size)} \u9879`, "fgDim") : null,
9790
+ errorReason !== void 0 ? /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", width: "100%", children: [
9791
+ renderPaneLine(
9576
9792
  errorReason === EMPTY_TABLE_REASON2 ? EMPTY_TABLE_REASON2 : `\u2717 \u66F4\u65B0\u5931\u8D25\uFF1A${errorReason}`,
9577
9793
  "error"
9578
9794
  ),
9579
- errorReason === EMPTY_TABLE_REASON2 ? null : line3(FAIL_NEXT2, "fgDim")
9795
+ errorReason === EMPTY_TABLE_REASON2 ? null : renderPaneLine(FAIL_NEXT2, "fgDim")
9580
9796
  ] }) : null,
9581
- line3(footnote, "fgDim")
9797
+ renderPaneLine(footnote, "fgDim")
9582
9798
  ] });
9583
9799
  }
9584
9800
 
9585
9801
  // tui-render/src/agent-hub-pane.tsx
9586
9802
  import { Box as Box15, Text as Text15 } from "ink";
9587
-
9588
- // tui-render/src/overlay-shell.tsx
9589
- import { Box as Box14, Text as Text14 } from "ink";
9590
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
9591
- var EMPTY_OVERLAY_PANE = { open: false };
9592
- function line4(text, token, bold = false) {
9593
- return /* @__PURE__ */ jsx14(Text14, { children: paintRow([styled(escapeContent(text), token, void 0, bold)]) });
9594
- }
9595
- function OverlayShell({
9596
- title,
9597
- body,
9598
- footnote,
9599
- error,
9600
- errorNext,
9601
- children
9602
- }) {
9603
- return /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", width: "100%", children: [
9604
- line4(title, "fg", true),
9605
- body !== void 0 && body !== "" ? line4(body, "fg") : null,
9606
- children,
9607
- error !== void 0 && error !== "" ? line4(`\u2717 ${error}`, "error") : null,
9608
- error !== void 0 && error !== "" && errorNext !== void 0 && errorNext !== "" ? line4(errorNext, "fgDim") : null,
9609
- line4(footnote, "fgDim")
9610
- ] });
9611
- }
9612
-
9613
- // tui-render/src/agent-hub-pane.tsx
9614
9803
  import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
9615
9804
  function formatTokens(value) {
9616
9805
  const scaled = (next) => next >= 100 ? String(Math.round(next)) : String(Math.round(next * 10) / 10);
@@ -9685,8 +9874,8 @@ function AgentHubPane({
9685
9874
  }
9686
9875
  );
9687
9876
  }
9688
- const lines = (transcript ?? "").split("\n").filter((line8) => line8 !== "");
9689
- return /* @__PURE__ */ jsx15(OverlayShell, { title: "\u5B50\u4EE3\u7406", footnote: "Esc \u8FD4\u56DE", children: lines.map((line8, index) => /* @__PURE__ */ jsx15(Text15, { children: paintRow([styled(escapeContent(line8), "fg")]) }, index)) });
9877
+ const lines = (transcript ?? "").split("\n").filter((line5) => line5 !== "");
9878
+ return /* @__PURE__ */ jsx15(OverlayShell, { title: "\u5B50\u4EE3\u7406", footnote: "Esc \u8FD4\u56DE", children: lines.map((line5, index) => /* @__PURE__ */ jsx15(Text15, { children: paintRow([styled(escapeContent(line5), "fg")]) }, index)) });
9690
9879
  }
9691
9880
  if (error !== void 0 && error !== "") {
9692
9881
  return /* @__PURE__ */ jsx15(
@@ -9742,7 +9931,7 @@ function directoryRow(label, selected, current) {
9742
9931
  /* @__PURE__ */ jsx16(Text16, { children: paintRow([styled(escapeContent(text), selected ? "fg" : "fgDim")]) })
9743
9932
  ] }, label);
9744
9933
  }
9745
- function line5(text, token) {
9934
+ function line3(text, token) {
9746
9935
  return /* @__PURE__ */ jsx16(Text16, { children: paintRow([styled(escapeContent(text), token)]) });
9747
9936
  }
9748
9937
  function PlanDirectoryPane({
@@ -9770,8 +9959,8 @@ function PlanDirectoryPane({
9770
9959
  )
9771
9960
  ),
9772
9961
  switchError !== void 0 && switchError !== "" ? /* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", width: "100%", children: [
9773
- line5(`\u2717 \u5207\u6362\u8BA1\u5212\u5931\u8D25\uFF1A${switchError}`, "error"),
9774
- line5(SWITCH_NEXT, "fgDim")
9962
+ line3(`\u2717 \u5207\u6362\u8BA1\u5212\u5931\u8D25\uFF1A${switchError}`, "error"),
9963
+ line3(SWITCH_NEXT, "fgDim")
9775
9964
  ] }) : null
9776
9965
  ] });
9777
9966
  }
@@ -9787,7 +9976,7 @@ var PLAN_REVIEW_WINDOW = 12;
9787
9976
  var EMPTY_PLAN_REVIEW_PANE = {
9788
9977
  open: false
9789
9978
  };
9790
- function line6(text, token, bold = false) {
9979
+ function line4(text, token, bold = false) {
9791
9980
  return /* @__PURE__ */ jsx17(Text17, { children: paintRow([styled(escapeContent(text), token, void 0, bold)]) });
9792
9981
  }
9793
9982
  function PlanReviewPane({
@@ -9800,14 +9989,14 @@ function PlanReviewPane({
9800
9989
  const safeOffset = Math.max(0, offset);
9801
9990
  const windowed = lines.slice(safeOffset, safeOffset + PLAN_REVIEW_WINDOW).join("\n");
9802
9991
  return /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", width: "100%", children: [
9803
- line6(TITLE4, "fg", true),
9992
+ line4(TITLE4, "fg", true),
9804
9993
  deliveryError !== void 0 && deliveryError !== "" ? /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", width: "100%", children: [
9805
- line6(`\u2717 \u8BA1\u5212\u8BC4\u5BA1\u672A\u80FD\u9001\u8FBE\uFF1A${deliveryError}`, "error"),
9806
- line6(DELIVERY_NEXT2, "fgDim")
9807
- ] }) : empty ? line6(EMPTY_BODY, "fg") : /* @__PURE__ */ jsx17(MarkdownBlock, { source: windowed }),
9808
- line6("\u6279\u51C6", "fg"),
9809
- line6("\u7EE7\u7EED\u89C4\u5212", "fg"),
9810
- line6(FOOTNOTE4, "fgDim")
9994
+ line4(`\u2717 \u8BA1\u5212\u8BC4\u5BA1\u672A\u80FD\u9001\u8FBE\uFF1A${deliveryError}`, "error"),
9995
+ line4(DELIVERY_NEXT2, "fgDim")
9996
+ ] }) : empty ? line4(EMPTY_BODY, "fg") : /* @__PURE__ */ jsx17(MarkdownBlock, { source: windowed }),
9997
+ line4("\u6279\u51C6", "fg"),
9998
+ line4("\u7EE7\u7EED\u89C4\u5212", "fg"),
9999
+ line4(FOOTNOTE4, "fgDim")
9811
10000
  ] });
9812
10001
  }
9813
10002
 
@@ -9823,9 +10012,6 @@ var EMPTY_ASK_USER_PANE = {
9823
10012
  options: [],
9824
10013
  selectedIndex: 0
9825
10014
  };
9826
- function line7(text, token, bold = false) {
9827
- return /* @__PURE__ */ jsx18(Text18, { children: paintRow([styled(escapeContent(text), token, void 0, bold)]) });
9828
- }
9829
10015
  function AskUserPane({
9830
10016
  header,
9831
10017
  options,
@@ -9833,13 +10019,13 @@ function AskUserPane({
9833
10019
  }) {
9834
10020
  if (options.length === 0) {
9835
10021
  return /* @__PURE__ */ jsxs17(Box18, { flexDirection: "column", width: "100%", children: [
9836
- line7(INVALID_TITLE, "error", true),
9837
- line7(INVALID_NEXT, "fgDim")
10022
+ renderPaneLine(INVALID_TITLE, "error", true),
10023
+ renderPaneLine(INVALID_NEXT, "fgDim")
9838
10024
  ] });
9839
10025
  }
9840
10026
  const footnote = FOOTNOTE5;
9841
10027
  return /* @__PURE__ */ jsxs17(Box18, { flexDirection: "column", width: "100%", children: [
9842
- header !== "" ? line7(header, "fg", true) : null,
10028
+ header !== "" ? renderPaneLine(header, "fg", true) : null,
9843
10029
  /* @__PURE__ */ jsx18(Box18, { flexDirection: "column", marginTop: header !== "" ? 1 : 0, width: "100%", children: options.map((label, index) => {
9844
10030
  const selected = index === selectedIndex;
9845
10031
  const numbered = `${index + 1} ${label}`;
@@ -9848,7 +10034,7 @@ function AskUserPane({
9848
10034
  /* @__PURE__ */ jsx18(Text18, { children: paintRow([styled(escapeContent(numbered), selected ? "fg" : "fgDim", void 0, selected)]) })
9849
10035
  ] }, `${index}:${label}`);
9850
10036
  }) }),
9851
- /* @__PURE__ */ jsx18(Box18, { marginTop: 1, width: "100%", children: line7(footnote, "fgDim") })
10037
+ /* @__PURE__ */ jsx18(Box18, { marginTop: 1, width: "100%", children: renderPaneLine(footnote, "fgDim") })
9852
10038
  ] });
9853
10039
  }
9854
10040
 
@@ -9888,8 +10074,8 @@ function TimelineView({
9888
10074
  ] });
9889
10075
  }
9890
10076
  function firstLine(text) {
9891
- const line8 = text.split("\n")[0];
9892
- return line8.length > FIRST_LINE_MAX ? `${line8.slice(0, FIRST_LINE_MAX)}\u2026` : line8;
10077
+ const line5 = text.split("\n")[0];
10078
+ return line5.length > FIRST_LINE_MAX ? `${line5.slice(0, FIRST_LINE_MAX)}\u2026` : line5;
9893
10079
  }
9894
10080
 
9895
10081
  // tui-render/src/input-bar.tsx
@@ -10085,8 +10271,8 @@ function InputBar({
10085
10271
  const caret = Math.max(0, Math.min(caretIndex ?? text.length, text.length));
10086
10272
  const caretLine = text.slice(0, caret).split("\n").length - 1;
10087
10273
  const caretLineStart = caret === 0 ? 0 : text.lastIndexOf("\n", caret - 1) + 1;
10088
- const windows = lines.map((line8, index) => composerLineWindow(
10089
- line8,
10274
+ const windows = lines.map((line5, index) => composerLineWindow(
10275
+ line5,
10090
10276
  index === caretLine ? caret - caretLineStart : void 0,
10091
10277
  Math.max(1, columns - 4)
10092
10278
  ));
@@ -10136,11 +10322,11 @@ function InputBar({
10136
10322
  backgroundColor: inkColor("inputBg"),
10137
10323
  children: [
10138
10324
  /* @__PURE__ */ jsx20(Text20, { wrap: "truncate", children: paintBackgroundRow(headerParts, "inputBg", columns) }),
10139
- lines.map((line8, lineIndex) => {
10325
+ lines.map((line5, lineIndex) => {
10140
10326
  const window = windows[lineIndex];
10141
10327
  let sourceColumn = 0;
10142
10328
  const endColumn = window.startColumn + displayWidth(window.text);
10143
- const tokenParts = tokenizeComposer(line8).map((token) => {
10329
+ const tokenParts = tokenizeComposer(line5).map((token) => {
10144
10330
  const safe = escapeContent(token.text).replace(/\t/gu, "\\t");
10145
10331
  const width = displayWidth(safe);
10146
10332
  const visible = displayColumnSlice(
@@ -10375,7 +10561,8 @@ function workspaceSegments(view, columns) {
10375
10561
  }
10376
10562
  if (view.gitBranch !== void 0 && view.gitBranch !== "") {
10377
10563
  const git = segment(`git: ${escapeContent(view.gitBranch)}`, "accentText");
10378
- const candidate = selected.length > 1 ? [selected[0], git, ...selected.slice(1)] : [...selected, git];
10564
+ const first = selected[0];
10565
+ const candidate = selected.length > 1 && first !== void 0 ? [first, git, ...selected.slice(1)] : [...selected, git];
10379
10566
  if (displayWidth(segmentsText(candidate)) <= columns) {
10380
10567
  selected = candidate;
10381
10568
  }
@@ -10916,7 +11103,7 @@ function ToolDetailsPane({ state, columns, maxRows, pageRows, locale }) {
10916
11103
  }
10917
11104
  return /* @__PURE__ */ jsxs21(Box23, { flexDirection: "column", width: "100%", children: [
10918
11105
  /* @__PURE__ */ jsx29(Text29, { wrap: "truncate", children: heading }),
10919
- lines.map((line8, index) => /* @__PURE__ */ jsx29(Text29, { wrap: "truncate", children: line8 }, index)),
11106
+ lines.map((line5, index) => /* @__PURE__ */ jsx29(Text29, { wrap: "truncate", children: line5 }, index)),
10920
11107
  /* @__PURE__ */ jsx29(Text29, { dimColor: true, wrap: "truncate", children: escapeContent(tuiCopy(state.detail ? "toolPageHint" : "toolListHint", locale)) })
10921
11108
  ] });
10922
11109
  }
@@ -10931,38 +11118,112 @@ function QueueChip({ count }) {
10931
11118
  const text = queueChipText(count);
10932
11119
  return text === void 0 ? null : /* @__PURE__ */ jsx30(Text30, { children: paintRow([styled(escapeContent(text), "fg")]) });
10933
11120
  }
10934
-
10935
- // tui-render/src/loop.tsx
10936
- var CHORD_WINDOW_MS = 600;
10937
- function activeMentionQuery(text) {
10938
- if (!text.startsWith("@")) return void 0;
10939
- const query = text.slice(1);
10940
- if (query === "") return "";
10941
- return /\s/u.test(query) ? void 0 : query;
11121
+
11122
+ // tui-render/src/loop.tsx
11123
+ var CHORD_WINDOW_MS = 600;
11124
+ function activeMentionQuery(text) {
11125
+ if (!text.startsWith("@")) return void 0;
11126
+ const query = text.slice(1);
11127
+ if (query === "") return "";
11128
+ return /\s/u.test(query) ? void 0 : query;
11129
+ }
11130
+ function hasControlCodepoint(value) {
11131
+ for (const char of value) {
11132
+ const code = char.codePointAt(0);
11133
+ if (code <= 31 || code === 127) return true;
11134
+ }
11135
+ return false;
11136
+ }
11137
+ function isTextInput(key, keyInfo) {
11138
+ return key.length > 0 && !keyInfo.ctrl && !keyInfo.meta && !key.startsWith("[") && !hasControlCodepoint(key);
11139
+ }
11140
+ function holdComposer(state, action) {
11141
+ return {
11142
+ kind: "dispatch",
11143
+ action,
11144
+ text: state.text,
11145
+ commandQuery: state.commandQuery,
11146
+ prefixG: false,
11147
+ renaming: state.renaming,
11148
+ mentionSelectedIndex: state.mentionSelectedIndex,
11149
+ mentionDismissed: state.mentionDismissed,
11150
+ commandSelectedIndex: state.commandSelectedIndex,
11151
+ commandDismissed: state.commandDismissed,
11152
+ caretIndex: state.caretIndex,
11153
+ historyIndex: state.historyIndex,
11154
+ historyDraft: state.historyDraft
11155
+ };
11156
+ }
11157
+ function resetComposerDispatch(state, action, text = "") {
11158
+ return {
11159
+ kind: "dispatch",
11160
+ action,
11161
+ text,
11162
+ commandQuery: state.commandQuery,
11163
+ prefixG: false,
11164
+ renaming: state.renaming
11165
+ };
11166
+ }
11167
+ function restoreHistoryDraft(state) {
11168
+ const restored = state.historyDraft ?? "";
11169
+ return {
11170
+ kind: "dispatch",
11171
+ action: { kind: "none" },
11172
+ text: restored,
11173
+ commandQuery: void 0,
11174
+ prefixG: false,
11175
+ renaming: state.renaming,
11176
+ caretIndex: restored.length,
11177
+ historyIndex: void 0,
11178
+ historyDraft: void 0
11179
+ };
11180
+ }
11181
+ function applySelectedMention(state, candidate) {
11182
+ if (candidate === void 0) return { kind: "none" };
11183
+ const inserted = normalizeMentionInsertion(candidate);
11184
+ return {
11185
+ kind: "dispatch",
11186
+ action: { kind: "none" },
11187
+ text: inserted,
11188
+ commandQuery: void 0,
11189
+ prefixG: false,
11190
+ renaming: state.renaming,
11191
+ mentionSelectedIndex: 0,
11192
+ mentionDismissed: false,
11193
+ commandSelectedIndex: 0,
11194
+ commandDismissed: false,
11195
+ caretIndex: inserted.length
11196
+ };
10942
11197
  }
10943
- function hasControlCodepoint(value) {
10944
- for (const char of value) {
10945
- const code = char.codePointAt(0);
10946
- if (code <= 31 || code === 127) return true;
11198
+ function verticalNavEffect(key, keyInfo, state, actionForDelta) {
11199
+ if (key === "j" || keyInfo.downArrow) {
11200
+ return holdComposer(state, actionForDelta(1));
10947
11201
  }
10948
- return false;
11202
+ if (key === "k" || keyInfo.upArrow) {
11203
+ return holdComposer(state, actionForDelta(-1));
11204
+ }
11205
+ return void 0;
10949
11206
  }
10950
- function isTextInput(key, keyInfo) {
10951
- return key.length > 0 && !keyInfo.ctrl && !keyInfo.meta && !key.startsWith("[") && !hasControlCodepoint(key);
11207
+ function appendQueryFilterEffect(state, char, makeAction) {
11208
+ const appended = state.text + char;
11209
+ return {
11210
+ kind: "dispatch",
11211
+ action: makeAction(appended),
11212
+ text: appended,
11213
+ commandQuery: state.commandQuery,
11214
+ prefixG: false,
11215
+ renaming: state.renaming
11216
+ };
10952
11217
  }
10953
- function holdComposer(state, action) {
11218
+ function moveCaretToEffect(state, caretIndex) {
10954
11219
  return {
10955
11220
  kind: "dispatch",
10956
- action,
11221
+ action: { kind: "none" },
10957
11222
  text: state.text,
10958
11223
  commandQuery: state.commandQuery,
10959
11224
  prefixG: false,
10960
11225
  renaming: state.renaming,
10961
- mentionSelectedIndex: state.mentionSelectedIndex,
10962
- mentionDismissed: state.mentionDismissed,
10963
- commandSelectedIndex: state.commandSelectedIndex,
10964
- commandDismissed: state.commandDismissed,
10965
- caretIndex: state.caretIndex,
11226
+ caretIndex,
10966
11227
  historyIndex: state.historyIndex,
10967
11228
  historyDraft: state.historyDraft
10968
11229
  };
@@ -11306,34 +11567,13 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11306
11567
  return holdComposer(state, { kind: "workflow-overlay-escape" });
11307
11568
  }
11308
11569
  if (modelPane.open) {
11309
- return {
11310
- kind: "dispatch",
11311
- action: { kind: "model-pane" },
11312
- text: "",
11313
- commandQuery: state.commandQuery,
11314
- prefixG: false,
11315
- renaming: state.renaming
11316
- };
11570
+ return resetComposerDispatch(state, { kind: "model-pane" });
11317
11571
  }
11318
11572
  if (helpPane.open) {
11319
- return {
11320
- kind: "dispatch",
11321
- action: { kind: "help-pane" },
11322
- text: state.text,
11323
- commandQuery: state.commandQuery,
11324
- prefixG: false,
11325
- renaming: state.renaming
11326
- };
11573
+ return holdComposer(state, { kind: "help-pane" });
11327
11574
  }
11328
11575
  if (search.open) {
11329
- return {
11330
- kind: "dispatch",
11331
- action: { kind: "search-pane" },
11332
- text: "",
11333
- commandQuery: state.commandQuery,
11334
- prefixG: false,
11335
- renaming: state.renaming
11336
- };
11576
+ return resetComposerDispatch(state, { kind: "search-pane" });
11337
11577
  }
11338
11578
  if (state.renaming) {
11339
11579
  return {
@@ -11366,18 +11606,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11366
11606
  };
11367
11607
  }
11368
11608
  if (state.historyIndex !== void 0) {
11369
- const restored = state.historyDraft ?? "";
11370
- return {
11371
- kind: "dispatch",
11372
- action: { kind: "none" },
11373
- text: restored,
11374
- commandQuery: void 0,
11375
- prefixG: false,
11376
- renaming: state.renaming,
11377
- caretIndex: restored.length,
11378
- historyIndex: void 0,
11379
- historyDraft: void 0
11380
- };
11609
+ return restoreHistoryDraft(state);
11381
11610
  }
11382
11611
  return {
11383
11612
  kind: "dispatch",
@@ -11390,19 +11619,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11390
11619
  }
11391
11620
  if (keyInfo.return) {
11392
11621
  if (mention.open) {
11393
- if (mention.selectedCandidate === void 0) return { kind: "none" };
11394
- const inserted = normalizeMentionInsertion(mention.selectedCandidate);
11395
- return {
11396
- kind: "dispatch",
11397
- action: { kind: "none" },
11398
- text: inserted,
11399
- commandQuery: void 0,
11400
- prefixG: false,
11401
- renaming: state.renaming,
11402
- mentionSelectedIndex: 0,
11403
- mentionDismissed: false,
11404
- caretIndex: inserted.length
11405
- };
11622
+ return applySelectedMention(state, mention.selectedCandidate);
11406
11623
  }
11407
11624
  if (agentHubOpen) {
11408
11625
  return holdComposer(state, { kind: "agent-hub-enter" });
@@ -11428,35 +11645,20 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11428
11645
  }
11429
11646
  if (modelPane.open) {
11430
11647
  if (modelPane.selectedId === void 0) return { kind: "none" };
11431
- return {
11432
- kind: "dispatch",
11433
- action: { kind: "select-model", id: modelPane.selectedId },
11434
- text: "",
11435
- commandQuery: state.commandQuery,
11436
- prefixG: false,
11437
- renaming: state.renaming
11438
- };
11648
+ return resetComposerDispatch(state, {
11649
+ kind: "select-model",
11650
+ id: modelPane.selectedId
11651
+ });
11439
11652
  }
11440
11653
  if (helpPane.open) {
11441
- return {
11442
- kind: "dispatch",
11443
- action: { kind: "help-pane" },
11444
- text: state.text,
11445
- commandQuery: state.commandQuery,
11446
- prefixG: false,
11447
- renaming: state.renaming
11448
- };
11654
+ return holdComposer(state, { kind: "help-pane" });
11449
11655
  }
11450
11656
  if (search.open) {
11451
11657
  if (search.selectedId === void 0) return { kind: "none" };
11452
- return {
11453
- kind: "dispatch",
11454
- action: { kind: "select-session", id: search.selectedId },
11455
- text: "",
11456
- commandQuery: state.commandQuery,
11457
- prefixG: false,
11458
- renaming: state.renaming
11459
- };
11658
+ return resetComposerDispatch(state, {
11659
+ kind: "select-session",
11660
+ id: search.selectedId
11661
+ });
11460
11662
  }
11461
11663
  if (state.renaming) {
11462
11664
  return {
@@ -11574,21 +11776,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11574
11776
  }
11575
11777
  if (key === " " || keyInfo.tab) {
11576
11778
  if (mention.open) {
11577
- if (mention.selectedCandidate === void 0) return { kind: "none" };
11578
- const inserted = normalizeMentionInsertion(mention.selectedCandidate);
11579
- return {
11580
- kind: "dispatch",
11581
- action: { kind: "none" },
11582
- text: inserted,
11583
- commandQuery: void 0,
11584
- prefixG: false,
11585
- renaming: state.renaming,
11586
- mentionSelectedIndex: 0,
11587
- mentionDismissed: false,
11588
- commandSelectedIndex: 0,
11589
- commandDismissed: false,
11590
- caretIndex: inserted.length
11591
- };
11779
+ return applySelectedMention(state, mention.selectedCandidate);
11592
11780
  }
11593
11781
  if (commandMode) {
11594
11782
  const query = state.commandQuery ?? state.text.slice(1);
@@ -11674,125 +11862,29 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11674
11862
  }
11675
11863
  }
11676
11864
  if (search.open) {
11677
- if (key === "j" || keyInfo.downArrow) {
11678
- return {
11679
- kind: "dispatch",
11680
- action: { kind: "session-pane-move", delta: 1 },
11681
- text: state.text,
11682
- commandQuery: state.commandQuery,
11683
- prefixG: false,
11684
- renaming: state.renaming,
11685
- caretIndex: state.caretIndex
11686
- };
11687
- }
11688
- if (key === "k" || keyInfo.upArrow) {
11689
- return {
11690
- kind: "dispatch",
11691
- action: { kind: "session-pane-move", delta: -1 },
11692
- text: state.text,
11693
- commandQuery: state.commandQuery,
11694
- prefixG: false,
11695
- renaming: state.renaming,
11696
- caretIndex: state.caretIndex
11697
- };
11698
- }
11865
+ const nav = verticalNavEffect(key, keyInfo, state, (delta) => ({ kind: "session-pane-move", delta }));
11866
+ if (nav !== void 0) return nav;
11699
11867
  if (isTextInput(key, keyInfo)) {
11700
- const appended = state.text + key;
11701
- return {
11702
- kind: "dispatch",
11703
- action: { kind: "search", query: appended },
11704
- text: appended,
11705
- commandQuery: state.commandQuery,
11706
- prefixG: false,
11707
- renaming: state.renaming
11708
- };
11868
+ return appendQueryFilterEffect(state, key, (query) => ({ kind: "search", query }));
11709
11869
  }
11710
11870
  return { kind: "none" };
11711
11871
  }
11712
11872
  if (timeline.open) {
11713
- if (key === "j" || keyInfo.downArrow) {
11714
- return {
11715
- kind: "dispatch",
11716
- action: { kind: "timeline-scroll", delta: 1 },
11717
- text: state.text,
11718
- commandQuery: state.commandQuery,
11719
- prefixG: false,
11720
- renaming: state.renaming,
11721
- caretIndex: state.caretIndex
11722
- };
11723
- }
11724
- if (key === "k" || keyInfo.upArrow) {
11725
- return {
11726
- kind: "dispatch",
11727
- action: { kind: "timeline-scroll", delta: -1 },
11728
- text: state.text,
11729
- commandQuery: state.commandQuery,
11730
- prefixG: false,
11731
- renaming: state.renaming,
11732
- caretIndex: state.caretIndex
11733
- };
11734
- }
11873
+ const nav = verticalNavEffect(key, keyInfo, state, (delta) => ({ kind: "timeline-scroll", delta }));
11874
+ if (nav !== void 0) return nav;
11735
11875
  return { kind: "none" };
11736
11876
  }
11737
11877
  if (modelPane.open) {
11738
- if (key === "j" || keyInfo.downArrow) {
11739
- return {
11740
- kind: "dispatch",
11741
- action: { kind: "model-move", delta: 1 },
11742
- text: state.text,
11743
- commandQuery: state.commandQuery,
11744
- prefixG: false,
11745
- renaming: state.renaming,
11746
- caretIndex: state.caretIndex
11747
- };
11748
- }
11749
- if (key === "k" || keyInfo.upArrow) {
11750
- return {
11751
- kind: "dispatch",
11752
- action: { kind: "model-move", delta: -1 },
11753
- text: state.text,
11754
- commandQuery: state.commandQuery,
11755
- prefixG: false,
11756
- renaming: state.renaming,
11757
- caretIndex: state.caretIndex
11758
- };
11759
- }
11878
+ const nav = verticalNavEffect(key, keyInfo, state, (delta) => ({ kind: "model-move", delta }));
11879
+ if (nav !== void 0) return nav;
11760
11880
  if (isTextInput(key, keyInfo)) {
11761
- const appended = state.text + key;
11762
- return {
11763
- kind: "dispatch",
11764
- action: { kind: "model-filter", query: appended },
11765
- text: appended,
11766
- commandQuery: state.commandQuery,
11767
- prefixG: false,
11768
- renaming: state.renaming
11769
- };
11881
+ return appendQueryFilterEffect(state, key, (query) => ({ kind: "model-filter", query }));
11770
11882
  }
11771
11883
  return { kind: "none" };
11772
11884
  }
11773
11885
  if (helpPane.open) {
11774
- if (key === "j" || keyInfo.downArrow) {
11775
- return {
11776
- kind: "dispatch",
11777
- action: { kind: "help-scroll", delta: 1 },
11778
- text: state.text,
11779
- commandQuery: state.commandQuery,
11780
- prefixG: false,
11781
- renaming: state.renaming,
11782
- caretIndex: state.caretIndex
11783
- };
11784
- }
11785
- if (key === "k" || keyInfo.upArrow) {
11786
- return {
11787
- kind: "dispatch",
11788
- action: { kind: "help-scroll", delta: -1 },
11789
- text: state.text,
11790
- commandQuery: state.commandQuery,
11791
- prefixG: false,
11792
- renaming: state.renaming,
11793
- caretIndex: state.caretIndex
11794
- };
11795
- }
11886
+ const nav = verticalNavEffect(key, keyInfo, state, (delta) => ({ kind: "help-scroll", delta }));
11887
+ if (nav !== void 0) return nav;
11796
11888
  return { kind: "none" };
11797
11889
  }
11798
11890
  if (key === "g" && state.text === "") {
@@ -11895,28 +11987,8 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11895
11987
  return { kind: "none" };
11896
11988
  }
11897
11989
  if (pane.open) {
11898
- if (key === "j" || keyInfo.downArrow) {
11899
- return {
11900
- kind: "dispatch",
11901
- action: { kind: "session-pane-move", delta: 1 },
11902
- text: state.text,
11903
- commandQuery: state.commandQuery,
11904
- prefixG: false,
11905
- renaming: state.renaming,
11906
- caretIndex: state.caretIndex
11907
- };
11908
- }
11909
- if (key === "k" || keyInfo.upArrow) {
11910
- return {
11911
- kind: "dispatch",
11912
- action: { kind: "session-pane-move", delta: -1 },
11913
- text: state.text,
11914
- commandQuery: state.commandQuery,
11915
- prefixG: false,
11916
- renaming: state.renaming,
11917
- caretIndex: state.caretIndex
11918
- };
11919
- }
11990
+ const nav = verticalNavEffect(key, keyInfo, state, (delta) => ({ kind: "session-pane-move", delta }));
11991
+ if (nav !== void 0) return nav;
11920
11992
  if (key === "r") {
11921
11993
  return {
11922
11994
  kind: "dispatch",
@@ -11981,17 +12053,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
11981
12053
  const caret = clampCaretIndex(state.text, state.caretIndex);
11982
12054
  const targetCaret = moveCaretUpLine(state.text, caret);
11983
12055
  if (targetCaret !== void 0) {
11984
- return {
11985
- kind: "dispatch",
11986
- action: { kind: "none" },
11987
- text: state.text,
11988
- commandQuery: state.commandQuery,
11989
- prefixG: false,
11990
- renaming: state.renaming,
11991
- caretIndex: targetCaret,
11992
- historyIndex: state.historyIndex,
11993
- historyDraft: state.historyDraft
11994
- };
12056
+ return moveCaretToEffect(state, targetCaret);
11995
12057
  }
11996
12058
  }
11997
12059
  if (state.text === "" && queuedDraft.headText !== void 0) {
@@ -12032,17 +12094,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
12032
12094
  const caret = clampCaretIndex(state.text, state.caretIndex);
12033
12095
  const targetCaret = moveCaretDownLine(state.text, caret);
12034
12096
  if (targetCaret !== void 0) {
12035
- return {
12036
- kind: "dispatch",
12037
- action: { kind: "none" },
12038
- text: state.text,
12039
- commandQuery: state.commandQuery,
12040
- prefixG: false,
12041
- renaming: state.renaming,
12042
- caretIndex: targetCaret,
12043
- historyIndex: state.historyIndex,
12044
- historyDraft: state.historyDraft
12045
- };
12097
+ return moveCaretToEffect(state, targetCaret);
12046
12098
  }
12047
12099
  }
12048
12100
  if (state.historyIndex !== void 0) {
@@ -12061,18 +12113,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search, timeline = { o
12061
12113
  historyDraft: state.historyDraft
12062
12114
  };
12063
12115
  }
12064
- const restored = state.historyDraft ?? "";
12065
- return {
12066
- kind: "dispatch",
12067
- action: { kind: "none" },
12068
- text: restored,
12069
- commandQuery: void 0,
12070
- prefixG: false,
12071
- renaming: state.renaming,
12072
- caretIndex: restored.length,
12073
- historyIndex: void 0,
12074
- historyDraft: void 0
12075
- };
12116
+ return restoreHistoryDraft(state);
12076
12117
  }
12077
12118
  return { kind: "none" };
12078
12119
  }
@@ -12251,7 +12292,9 @@ function TuiLoop({
12251
12292
  const timer = setInterval(() => {
12252
12293
  setGeneratingTick((t) => (t + 1) % 1e4);
12253
12294
  }, 100);
12254
- return () => clearInterval(timer);
12295
+ return () => {
12296
+ clearInterval(timer);
12297
+ };
12255
12298
  }, [model.status]);
12256
12299
  const footerSpinner = model.status === "generating" ? getBrailleSpinnerFrame(Date.now()) : void 0;
12257
12300
  const interaction = useSyncExternalStore(
@@ -12861,7 +12904,7 @@ function TuiLoop({
12861
12904
  const visibleLines = [
12862
12905
  truncateDisplay(workspace.join(" \xB7 "), Math.max(1, columns)),
12863
12906
  truncateDisplay(identity.join(" \xB7 "), Math.max(1, columns))
12864
- ].filter((line8) => line8 !== "");
12907
+ ].filter((line5) => line5 !== "");
12865
12908
  statusRowCount = visibleLines.length;
12866
12909
  status = createElement2(
12867
12910
  Box24,
@@ -12870,15 +12913,15 @@ function TuiLoop({
12870
12913
  width: "100%",
12871
12914
  backgroundColor: inkColor("bg")
12872
12915
  },
12873
- ...visibleLines.map((line8, index) => createElement2(
12916
+ ...visibleLines.map((line5, index) => createElement2(
12874
12917
  Text31,
12875
12918
  { key: `fallback-footer-${String(index)}` },
12876
- paintBackgroundRow([styled(line8, "fgDim")], "bg", columns)
12919
+ paintBackgroundRow([styled(line5, "fgDim")], "bg", columns)
12877
12920
  ))
12878
12921
  );
12879
12922
  }
12880
- const brandBlocked = state.text !== "" || model.status !== "idle" || pane.open || search.open || timelineOpen || modelPane.open || helpPane.open || toolDetailsPane.open || approvalPane.open || askUserPane.open || permissionPane.open || settingsPane.open || agentHubPane.open || planDirectoryPane.open || workspacePane.open || feedbackPane.open || workflowOverlay.open || planReviewPane.open;
12881
12923
  const viewportMotionPaused = pane.open || search.open || timelineOpen || modelPane.open || helpPane.open || toolDetailsPane.open || approvalPane.open || askUserPane.open || permissionPane.open || settingsPane.open || agentHubPane.open || planDirectoryPane.open || workspacePane.open || feedbackPane.open || workflowOverlay.open || planReviewPane.open;
12924
+ const brandBlocked = state.text !== "" || model.status !== "idle" || viewportMotionPaused;
12882
12925
  const brandLifecycleAllowed = !brandBlocked && (brandAnimationMode === "on" || brandAnimationMode === "auto" && brandAutoEligible);
12883
12926
  if (brandRevealStartedRef.current && !brandLifecycleAllowed) {
12884
12927
  brandRevealStoppedRef.current = true;
@@ -13191,16 +13234,16 @@ function lastFencedCode(text) {
13191
13234
  let openingLength;
13192
13235
  let bodyStart = 0;
13193
13236
  let latest;
13194
- for (const [index, line8] of lines.entries()) {
13237
+ for (const [index, line5] of lines.entries()) {
13195
13238
  if (openingLength === void 0) {
13196
- const opening = /^ {0,3}(`{3,})[^`]*$/u.exec(line8);
13239
+ const opening = /^ {0,3}(`{3,})[^`]*$/u.exec(line5);
13197
13240
  if (opening !== null) {
13198
13241
  openingLength = opening[1].length;
13199
13242
  bodyStart = index + 1;
13200
13243
  }
13201
13244
  continue;
13202
13245
  }
13203
- const closing = /^ {0,3}(`{3,})[ \t]*$/u.exec(line8);
13246
+ const closing = /^ {0,3}(`{3,})[ \t]*$/u.exec(line5);
13204
13247
  if (closing === null || closing[1].length < openingLength) continue;
13205
13248
  latest = lines.slice(bodyStart, index).join("\n");
13206
13249
  openingLength = void 0;
@@ -13642,6 +13685,10 @@ function reduceInteraction(state, event) {
13642
13685
  }
13643
13686
 
13644
13687
  // tui-render/src/index.ts
13688
+ if (typeof globalThis.React === "undefined") {
13689
+ ;
13690
+ globalThis.React = React;
13691
+ }
13645
13692
  function mountTuiRender(node, options = {}) {
13646
13693
  const env = options.env ?? process.env;
13647
13694
  const policy = options.renderPolicy ?? renderPolicyDefaults();
@@ -13884,6 +13931,7 @@ export {
13884
13931
  notifyBytes,
13885
13932
  paintBackgroundRow,
13886
13933
  paintRow,
13934
+ parseSubagentArguments,
13887
13935
  physicalLineIdentity,
13888
13936
  physicalScrollRailGeometry,
13889
13937
  planToolBodyWindow,