reasonix 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -7116,7 +7116,7 @@ import { render } from "ink";
7116
7116
  import React23, { useState as useState12 } from "react";
7117
7117
 
7118
7118
  // src/cli/ui/App.tsx
7119
- import { Box as Box19, Static, useApp, useInput as useInput5, useStdout as useStdout4 } from "ink";
7119
+ import { Box as Box19, Static, useApp, useInput as useInput5, useStdout as useStdout5 } from "ink";
7120
7120
  import React20, { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef5, useState as useState10 } from "react";
7121
7121
 
7122
7122
  // src/code/pending-edits.ts
@@ -7419,7 +7419,7 @@ function AtMentionSuggestions({
7419
7419
  }) {
7420
7420
  if (matches === null) return null;
7421
7421
  if (matches.length === 0) {
7422
- return /* @__PURE__ */ React.createElement(Box, { paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, 'no files match "@', query, '"'), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " ", "\u2014 keep typing, or Backspace to edit. Paths resolve from the code root."));
7422
+ return /* @__PURE__ */ React.createElement(Box, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, 'no files match "@', query, '"'), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " ", "\u2014 keep typing, or Backspace to edit. Paths resolve from the code root."));
7423
7423
  }
7424
7424
  const MAX = 8;
7425
7425
  const total = matches.length;
@@ -7427,7 +7427,7 @@ function AtMentionSuggestions({
7427
7427
  const shown = matches.slice(windowStart, windowStart + MAX);
7428
7428
  const hiddenAbove = windowStart;
7429
7429
  const hiddenBelow = total - windowStart - shown.length;
7430
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((path, i) => /* @__PURE__ */ React.createElement(FileRow, { key: path, path, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick \xB7 file content inlined on send"));
7430
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1, marginTop: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((path, i) => /* @__PURE__ */ React.createElement(FileRow, { key: path, path, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick \xB7 file content inlined on send"));
7431
7431
  }
7432
7432
  function FileRow({ path, isSelected }) {
7433
7433
  const marker = isSelected ? "\u25B8" : " ";
@@ -7722,7 +7722,7 @@ function EditConfirm({ block, onChoose }) {
7722
7722
  const hiddenBelow = Math.max(0, allLines.length - effectiveScroll - budget);
7723
7723
  const totalLines = allLines.length;
7724
7724
  const showScrollHud = hiddenAbove + hiddenBelow > 0;
7725
- return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: "cyan" }, "\u25B8 model wants to edit a file")), /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "cyan", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React4.createElement(Box4, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(Text4, null, /* @__PURE__ */ React4.createElement(Text4, { color: isNew ? "green" : "yellow", bold: true }, `[${tag}] `), /* @__PURE__ */ React4.createElement(Text4, { color: "cyan" }, block.path), /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, ` (-${removed} +${added} lines)`), showScrollHud ? /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, ` \xB7 viewing ${effectiveScroll + 1}-${effectiveScroll + visibleLines.length}/${totalLines}`) : null)), hiddenAbove > 0 ? /* @__PURE__ */ React4.createElement(
7725
+ return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: "yellow" }, "\u25B8 model wants to edit a file")), /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "yellow", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React4.createElement(Box4, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(Text4, null, /* @__PURE__ */ React4.createElement(Text4, { color: isNew ? "green" : "yellow", bold: true }, `[${tag}] `), /* @__PURE__ */ React4.createElement(Text4, { color: "cyan" }, block.path), /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, ` (-${removed} +${added} lines)`), showScrollHud ? /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, ` \xB7 viewing ${effectiveScroll + 1}-${effectiveScroll + visibleLines.length}/${totalLines}`) : null)), hiddenAbove > 0 ? /* @__PURE__ */ React4.createElement(
7726
7726
  Text4,
7727
7727
  {
7728
7728
  dimColor: true
@@ -8606,7 +8606,8 @@ function summarizeStructured(content) {
8606
8606
  }
8607
8607
  }
8608
8608
  function summarizeKnownTool(toolName, content) {
8609
- if (toolName === "read_file") {
8609
+ const hasSuffix = (s) => toolName === s || toolName.endsWith(`_${s}`);
8610
+ if (hasSuffix("read_file")) {
8610
8611
  const lines = formatLineCount(content);
8611
8612
  const bytes = formatBytes(content.length);
8612
8613
  const head = clip(
@@ -8618,11 +8619,11 @@ function summarizeKnownTool(toolName, content) {
8618
8619
  isError: false
8619
8620
  };
8620
8621
  }
8621
- if (toolName === "list_directory" || toolName === "directory_tree") {
8622
+ if (hasSuffix("list_directory") || hasSuffix("directory_tree")) {
8622
8623
  const entries = content.split(/\r?\n/).filter((l) => l.trim()).length;
8623
8624
  return { summary: `${entries} entr${entries === 1 ? "y" : "ies"}`, isError: false };
8624
8625
  }
8625
- if (toolName === "search_files" || toolName === "search_content") {
8626
+ if (hasSuffix("search_files") || hasSuffix("search_content")) {
8626
8627
  const matches = content.split(/\r?\n/).filter((l) => l.trim()).length;
8627
8628
  if (matches === 0) return { summary: "no matches", isError: false };
8628
8629
  const first = firstNonEmptyLine(content);
@@ -8631,7 +8632,12 @@ function summarizeKnownTool(toolName, content) {
8631
8632
  isError: false
8632
8633
  };
8633
8634
  }
8634
- if (toolName === "run_command" || toolName === "run_background") {
8635
+ if (hasSuffix("write_file")) {
8636
+ const lines = formatLineCount(content);
8637
+ const bytes = formatBytes(content.length);
8638
+ return { summary: `wrote ${lines} \xB7 ${bytes}`, isError: false };
8639
+ }
8640
+ if (hasSuffix("run_command") || hasSuffix("run_background")) {
8635
8641
  const exitMatch = content.match(/exit (?:code )?(-?\d+)/i);
8636
8642
  const first = firstNonEmptyLine(content);
8637
8643
  if (exitMatch) {
@@ -8683,12 +8689,16 @@ function RoleGlyph({
8683
8689
  }) {
8684
8690
  return /* @__PURE__ */ React9.createElement(Text8, { color, bold: true }, glyph);
8685
8691
  }
8692
+ function indentContinuationLines(text) {
8693
+ if (!text.includes("\n")) return text;
8694
+ return text.split("\n").join("\n ");
8695
+ }
8686
8696
  var EventRow = React9.memo(function EventRow2({
8687
8697
  event,
8688
8698
  projectRoot
8689
8699
  }) {
8690
8700
  if (event.role === "user") {
8691
- return /* @__PURE__ */ React9.createElement(Box8, { marginTop: event.leadSeparator ? 1 : 0 }, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React9.createElement(Text8, null, " ", event.text));
8701
+ return /* @__PURE__ */ React9.createElement(Box8, { marginTop: event.leadSeparator ? 1 : 0 }, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React9.createElement(Text8, null, " ", indentContinuationLines(event.text)));
8692
8702
  }
8693
8703
  if (event.role === "assistant") {
8694
8704
  if (event.streaming) return /* @__PURE__ */ React9.createElement(StreamingAssistant, { event });
@@ -8709,7 +8719,7 @@ var EventRow = React9.memo(function EventRow2({
8709
8719
  return /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph, color }), /* @__PURE__ */ React9.createElement(Text8, { color, bold: true }, ` ${event.toolName ?? "?"}`), durationLabel ? /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, durationLabel) : null, /* @__PURE__ */ React9.createElement(Text8, { color, dimColor: true }, ` ${marker} `), /* @__PURE__ */ React9.createElement(Text8, { color: summary.isError ? "red" : void 0, dimColor: !summary.isError }, summary.summary), indexHint ? /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, indexHint) : null);
8710
8720
  }
8711
8721
  if (event.role === "error") {
8712
- return /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph: ROLE_GLYPH.error, color: "red" }), /* @__PURE__ */ React9.createElement(Text8, { color: "red" }, " ", event.text));
8722
+ return /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph: ROLE_GLYPH.error, color: "red" }), /* @__PURE__ */ React9.createElement(Text8, { color: "red" }, " ", indentContinuationLines(event.text)));
8713
8723
  }
8714
8724
  if (event.role === "info") {
8715
8725
  return /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, event.text));
@@ -8757,7 +8767,7 @@ var EventRow = React9.memo(function EventRow2({
8757
8767
  )), r.summary ? /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, ` ${r.summary}`)) : null, /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, ` ${r.archiveBasename}`))), r.body ? /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Markdown, { text: r.body, projectRoot })) : null, /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(PlanStepList, { steps: r.steps, statuses })), /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, r.total > 1 ? `(read-only \xB7 /replay ${r.index === 1 ? 2 : 1} for the ${r.index === 1 ? "next" : "newest"} archive)` : "(read-only \xB7 this is an archived plan)")));
8758
8768
  }
8759
8769
  if (event.role === "warning") {
8760
- return /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph: ROLE_GLYPH.warning, color: "yellow" }), /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, " ", event.text));
8770
+ return /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(RoleGlyph, { glyph: ROLE_GLYPH.warning, color: "yellow" }), /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, " ", indentContinuationLines(event.text)));
8761
8771
  }
8762
8772
  return /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text8, null, event.text));
8763
8773
  });
@@ -9167,7 +9177,7 @@ function PlanReviseConfirmInner({
9167
9177
  var PlanReviseConfirm = React14.memo(PlanReviseConfirmInner);
9168
9178
 
9169
9179
  // src/cli/ui/PromptInput.tsx
9170
- import { Box as Box14, Text as Text14, useInput as useInput4 } from "ink";
9180
+ import { Box as Box14, Text as Text14, useInput as useInput4, useStdout as useStdout3 } from "ink";
9171
9181
  import React15, { useRef, useState as useState5 } from "react";
9172
9182
 
9173
9183
  // src/cli/ui/multiline-keys.ts
@@ -9497,17 +9507,23 @@ function PromptInput({
9497
9507
  },
9498
9508
  { isActive: !disabled }
9499
9509
  );
9500
- const effectivePlaceholder = disabled ? placeholder ?? "\u2026waiting for response\u2026 \xB7 [Esc] to stop" : placeholder ?? "type a message, or /command \xB7 [Shift+Enter] / [Ctrl+J] newline";
9510
+ const { stdout: stdout2 } = useStdout3();
9511
+ const cols = stdout2?.columns ?? 80;
9512
+ const narrow = cols <= 90;
9513
+ const promptPrefix = narrow ? "\u203A " : "you \u203A ";
9514
+ const continuationIndent = narrow ? " " : " ";
9515
+ const placeholderActive = narrow ? "type a message, or /command" : "type a message, or /command \xB7 [Shift+Enter] / [Ctrl+J] newline";
9516
+ const effectivePlaceholder = disabled ? placeholder ?? "\u2026waiting for response\u2026" : placeholder ?? placeholderActive;
9501
9517
  const lines = value.length > 0 ? value.split("\n") : [""];
9502
9518
  const borderColor = disabled ? "gray" : "cyan";
9503
9519
  const { line: cursorLine, col: cursorCol } = lineAndColumn(value, cursor);
9504
9520
  const renderItems = collapseLinesForDisplay(lines, cursorLine);
9505
9521
  const showHugeBufferHints = lines.length > 20;
9506
- return /* @__PURE__ */ React15.createElement(Box14, { borderStyle: "round", borderColor, paddingX: 1, flexDirection: "column" }, renderItems.map((item, renderIdx) => {
9522
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Box14, { borderStyle: "round", borderColor, paddingX: 1, flexDirection: "column" }, renderItems.map((item, renderIdx) => {
9507
9523
  if (item.kind === "skip") {
9508
9524
  return (
9509
9525
  // biome-ignore lint/suspicious/noArrayIndexKey: stable — skip markers are derived from a fixed-size window over `lines`
9510
- /* @__PURE__ */ React15.createElement(Box14, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, " "), /* @__PURE__ */ React15.createElement(
9526
+ /* @__PURE__ */ React15.createElement(Box14, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, continuationIndent), /* @__PURE__ */ React15.createElement(
9511
9527
  Text14,
9512
9528
  {
9513
9529
  dimColor: true
@@ -9521,7 +9537,7 @@ function PromptInput({
9521
9537
  const isFirst = i === 0;
9522
9538
  const showPlaceholder = isFirst && value.length === 0;
9523
9539
  const isCursorLine = i === cursorLine;
9524
- return /* @__PURE__ */ React15.createElement(Box14, { key: `ln-${i}` }, isFirst ? /* @__PURE__ */ React15.createElement(Text14, { bold: true, color: borderColor }, "you \u203A", " ") : /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, " "), showPlaceholder ? /* @__PURE__ */ React15.createElement(React15.Fragment, null, isCursorLine && !disabled ? /* @__PURE__ */ React15.createElement(Text14, { color: borderColor }, showCursor ? "\u258C" : " ") : null, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, effectivePlaceholder)) : isCursorLine && !disabled ? /* @__PURE__ */ React15.createElement(
9540
+ return /* @__PURE__ */ React15.createElement(Box14, { key: `ln-${i}` }, isFirst ? /* @__PURE__ */ React15.createElement(Text14, { bold: true, color: borderColor }, promptPrefix) : /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, continuationIndent), showPlaceholder ? /* @__PURE__ */ React15.createElement(React15.Fragment, null, isCursorLine && !disabled ? /* @__PURE__ */ React15.createElement(Text14, { color: borderColor }, showCursor ? "\u258C" : " ") : null, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, effectivePlaceholder)) : isCursorLine && !disabled ? /* @__PURE__ */ React15.createElement(
9525
9541
  LineWithCursor,
9526
9542
  {
9527
9543
  line,
@@ -9531,7 +9547,7 @@ function PromptInput({
9531
9547
  pastes: pastesRef.current
9532
9548
  }
9533
9549
  ) : /* @__PURE__ */ React15.createElement(RenderLine, { line, pastes: pastesRef.current }));
9534
- }), showHugeBufferHints && !disabled ? /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, " "), /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, `[${lines.length} lines \xB7 PageUp/PageDown jump to top/bottom \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null);
9550
+ }), showHugeBufferHints && !disabled ? /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, continuationIndent), /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, `[${lines.length} lines \xB7 PageUp/PageDown jump to top/bottom \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null), disabled ? /* @__PURE__ */ React15.createElement(Box14, { paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "[Esc] to stop")) : null);
9535
9551
  }
9536
9552
  var COLLAPSE_THRESHOLD = 20;
9537
9553
  var COLLAPSE_HEAD_LINES = 3;
@@ -9612,7 +9628,7 @@ import { Box as Box15, Text as Text15 } from "ink";
9612
9628
  import React16 from "react";
9613
9629
  function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
9614
9630
  const isBackground = kind === "run_background";
9615
- return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { bold: true, color: "yellow" }, isBackground ? "\u25B8 model wants to start a BACKGROUND process" : "\u25B8 model wants to run a shell command")), isBackground ? /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, " (long-running: dev server / watcher; keeps running after approval, /kill to stop)")) : null, /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { color: "yellow", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text15, null, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "$ "), /* @__PURE__ */ React16.createElement(Text15, { color: "cyan" }, command))), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
9631
+ return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { bold: true, color: "red" }, isBackground ? "\u25B8 model wants to start a BACKGROUND process" : "\u25B8 model wants to run a shell command")), isBackground ? /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, " (long-running: dev server / watcher; keeps running after approval, /kill to stop)")) : null, /* @__PURE__ */ React16.createElement(Box15, null, /* @__PURE__ */ React16.createElement(Text15, { color: "red", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text15, null, /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "$ "), /* @__PURE__ */ React16.createElement(Text15, { color: "cyan" }, command))), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
9616
9632
  SingleSelect,
9617
9633
  {
9618
9634
  initialValue: "run_once",
@@ -9679,11 +9695,11 @@ function SlashArgPicker({
9679
9695
  partial
9680
9696
  }) {
9681
9697
  if (kind === "hint") {
9682
- return /* @__PURE__ */ React17.createElement(Box16, { paddingX: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary));
9698
+ return /* @__PURE__ */ React17.createElement(Box16, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary));
9683
9699
  }
9684
9700
  if (matches === null) return null;
9685
9701
  if (matches.length === 0) {
9686
- return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), /* @__PURE__ */ React17.createElement(Text16, { color: "yellow" }, ' no match for "', partial, '" \u2014 keep typing, or Backspace to edit'));
9702
+ return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), /* @__PURE__ */ React17.createElement(Text16, { color: "yellow" }, ' no match for "', partial, '" \u2014 keep typing, or Backspace to edit'));
9687
9703
  }
9688
9704
  const MAX = 8;
9689
9705
  const total = matches.length;
@@ -9691,7 +9707,7 @@ function SlashArgPicker({
9691
9707
  const shown = matches.slice(windowStart, windowStart + MAX);
9692
9708
  const hiddenAbove = windowStart;
9693
9709
  const hiddenBelow = total - windowStart - shown.length;
9694
- return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), hiddenAbove > 0 ? /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((value, i) => /* @__PURE__ */ React17.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
9710
+ return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " ", /* @__PURE__ */ React17.createElement(Text16, { bold: true }, "/", spec.cmd), spec.argsHint ? ` ${spec.argsHint}` : "", " \u2014 ", spec.summary), hiddenAbove > 0 ? /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((value, i) => /* @__PURE__ */ React17.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
9695
9711
  }
9696
9712
  function ArgRow({ value, isSelected }) {
9697
9713
  const marker = isSelected ? "\u25B8" : " ";
@@ -9710,7 +9726,7 @@ function SlashSuggestions({
9710
9726
  }) {
9711
9727
  if (matches === null) return null;
9712
9728
  if (matches.length === 0) {
9713
- return /* @__PURE__ */ React18.createElement(Box17, { paddingX: 1 }, /* @__PURE__ */ React18.createElement(Text17, { color: "yellow" }, "no slash command matches that prefix"), /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
9729
+ return /* @__PURE__ */ React18.createElement(Box17, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text17, { color: "yellow" }, "no slash command matches that prefix"), /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
9714
9730
  }
9715
9731
  const MAX = 8;
9716
9732
  const total = matches.length;
@@ -9718,7 +9734,7 @@ function SlashSuggestions({
9718
9734
  const shown = matches.slice(windowStart, windowStart + MAX);
9719
9735
  const hiddenAbove = windowStart;
9720
9736
  const hiddenBelow = total - windowStart - shown.length;
9721
- return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", paddingX: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((spec, i) => /* @__PURE__ */ React18.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
9737
+ return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", paddingX: 1, marginTop: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((spec, i) => /* @__PURE__ */ React18.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
9722
9738
  }
9723
9739
  function SuggestionRow({ spec, isSelected }) {
9724
9740
  const marker = isSelected ? "\u25B8" : " ";
@@ -9731,7 +9747,7 @@ function SuggestionRow({ spec, isSelected }) {
9731
9747
  }
9732
9748
 
9733
9749
  // src/cli/ui/StatsPanel.tsx
9734
- import { Box as Box18, Text as Text18, useStdout as useStdout3 } from "ink";
9750
+ import { Box as Box18, Text as Text18, useStdout as useStdout4 } from "ink";
9735
9751
  import React19 from "react";
9736
9752
  var WORDMARK_STYLES = [
9737
9753
  { ch: "\u25C8", color: "#5eead4", isLogo: true },
@@ -9780,7 +9796,7 @@ function StatsPanel({
9780
9796
  const branchOn = (branchBudget ?? 1) > 1;
9781
9797
  const ctxMax = DEEPSEEK_CONTEXT_TOKENS[model2] ?? DEFAULT_CONTEXT_TOKENS;
9782
9798
  const ctxRatio = summary.lastPromptTokens / ctxMax;
9783
- const { stdout: stdout2 } = useStdout3();
9799
+ const { stdout: stdout2 } = useStdout4();
9784
9800
  const columns = stdout2?.columns ?? 80;
9785
9801
  const narrow = columns < NARROW_BREAKPOINT;
9786
9802
  const coldStart = summary.turns <= COLD_START_TURNS;
@@ -12283,7 +12299,7 @@ function App({
12283
12299
  const abortedThisTurn = useRef5(false);
12284
12300
  const [ongoingTool, setOngoingTool] = useState10(null);
12285
12301
  const [toolProgress, setToolProgress] = useState10(null);
12286
- const { stdout: stdout2 } = useStdout4();
12302
+ const { stdout: stdout2 } = useStdout5();
12287
12303
  useEffect5(() => {
12288
12304
  if (!stdout2 || !stdout2.isTTY) return;
12289
12305
  stdout2.write("\x1B[?2004h");
@@ -12750,7 +12766,7 @@ function App({
12750
12766
  if (!codeMode) return "not in code mode";
12751
12767
  const blocks = pendingEdits.current;
12752
12768
  if (blocks.length === 0) {
12753
- return "nothing pending \u2014 the assistant hasn't proposed edits since the last /apply or /discard.";
12769
+ return "nothing pending \u2014 the model hasn't proposed edits since the last /apply or /discard.";
12754
12770
  }
12755
12771
  const snaps = snapshotBeforeEdits(blocks, codeMode.rootDir);
12756
12772
  const results = applyEditBlocks(blocks, codeMode.rootDir);
@@ -14019,7 +14035,7 @@ function SessionPicker({
14019
14035
  ],
14020
14036
  onSubmit: (v) => onChoose(v)
14021
14037
  }
14022
- ), /* @__PURE__ */ React21.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text19, { dimColor: true }, "\u2191\u2193 to move \xB7 Enter to pick")));
14038
+ ), /* @__PURE__ */ React21.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text19, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] select")));
14023
14039
  }
14024
14040
  function relativeTime2(date) {
14025
14041
  const ms = Date.now() - date.getTime();
@@ -14303,7 +14319,8 @@ function RecordView({ rec, compact: compact2 = false }) {
14303
14319
  const toolArgsMax = compact2 ? 120 : 200;
14304
14320
  const toolContentMax = compact2 ? 200 : 400;
14305
14321
  if (rec.role === "user") {
14306
- return /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React24.createElement(Text21, null, rec.content));
14322
+ const content = rec.content.includes("\n") ? rec.content.split("\n").join("\n ") : rec.content;
14323
+ return /* @__PURE__ */ React24.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React24.createElement(Text21, null, content));
14307
14324
  }
14308
14325
  if (rec.role === "assistant_final") {
14309
14326
  return /* @__PURE__ */ React24.createElement(Box22, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React24.createElement(Box22, null, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React24.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React24.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React24.createElement(Text21, null, rec.content) : /* @__PURE__ */ React24.createElement(Text21, { dimColor: true, italic: true }, "(tool-call response only)"));
@@ -15025,7 +15042,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15025
15042
  setStep("mcp");
15026
15043
  }
15027
15044
  }
15028
- ), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "\u2191/\u2193 move \xB7 enter confirm \xB7 esc cancel")));
15045
+ ), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
15029
15046
  }
15030
15047
  if (step === "mcp") {
15031
15048
  return /* @__PURE__ */ React29.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React29.createElement(
@@ -15038,7 +15055,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15038
15055
  const needsArgs = selected.some((name) => CATALOG_BY_NAME.get(name)?.userArgs);
15039
15056
  setStep(needsArgs ? "mcpArgs" : "review");
15040
15057
  },
15041
- footer: "\u2191/\u2193 move \xB7 space toggle \xB7 enter confirm \xB7 esc cancel \xB7 leave empty to skip"
15058
+ footer: "[\u2191\u2193] navigate \xB7 [Space] toggle \xB7 [Enter] confirm \xB7 [Esc] cancel \xB7 empty = skip"
15042
15059
  }
15043
15060
  ));
15044
15061
  }
@@ -15080,7 +15097,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15080
15097
  ), specs.map((spec, i) => (
15081
15098
  // biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
15082
15099
  /* @__PURE__ */ React29.createElement(Box25, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "\xB7 ", spec))
15083
- )), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: "red" }, error)) : null, /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "enter save \xB7 esc cancel"))), /* @__PURE__ */ React29.createElement(
15100
+ )), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: "red" }, error)) : null, /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React29.createElement(
15084
15101
  ReviewConfirm,
15085
15102
  {
15086
15103
  onConfirm: () => {
@@ -15106,7 +15123,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
15106
15123
  }
15107
15124
  ));
15108
15125
  }
15109
- return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "Press enter to exit.")), /* @__PURE__ */ React29.createElement(ExitOnEnter, { onExit: exit2 }));
15126
+ return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React29.createElement(ExitOnEnter, { onExit: exit2 }));
15110
15127
  }
15111
15128
  function ApiKeyStep({
15112
15129
  onSubmit,