reasonix 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  memoryEnabled,
13
13
  readProjectMemory,
14
14
  sanitizeMemoryName
15
- } from "./chunk-RTVI2CLX.js";
15
+ } from "./chunk-R2L5YEEF.js";
16
16
 
17
17
  // src/cli/index.ts
18
18
  import { Command } from "commander";
@@ -1286,6 +1286,39 @@ function hasDotKey(obj) {
1286
1286
  return false;
1287
1287
  }
1288
1288
 
1289
+ // src/mcp/latency.ts
1290
+ var SAMPLE_SIZE = 5;
1291
+ var DEFAULT_THRESHOLD_MS = 4e3;
1292
+ var LatencyTracker = class {
1293
+ constructor(serverName, opts = {}) {
1294
+ this.serverName = serverName;
1295
+ this.thresholdMs = opts.thresholdMs ?? DEFAULT_THRESHOLD_MS;
1296
+ this.onSlow = opts.onSlow;
1297
+ }
1298
+ serverName;
1299
+ samples = [];
1300
+ wasOverThreshold = false;
1301
+ thresholdMs;
1302
+ onSlow;
1303
+ record(elapsedMs) {
1304
+ this.samples.push(elapsedMs);
1305
+ if (this.samples.length > SAMPLE_SIZE) this.samples.shift();
1306
+ if (this.samples.length < SAMPLE_SIZE) return;
1307
+ const p95 = computeP95(this.samples);
1308
+ const nowOver = p95 > this.thresholdMs;
1309
+ if (nowOver && !this.wasOverThreshold) {
1310
+ this.onSlow?.({ serverName: this.serverName, p95Ms: p95, sampleSize: this.samples.length });
1311
+ }
1312
+ this.wasOverThreshold = nowOver;
1313
+ }
1314
+ };
1315
+ function computeP95(samples) {
1316
+ if (samples.length === 0) return 0;
1317
+ const sorted = [...samples].sort((a, b) => a - b);
1318
+ const idx = Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95));
1319
+ return sorted[idx] ?? 0;
1320
+ }
1321
+
1289
1322
  // src/mcp/registry.ts
1290
1323
  var DEFAULT_MAX_RESULT_CHARS = 32e3;
1291
1324
  var DEFAULT_MAX_RESULT_TOKENS = 8e3;
@@ -1294,6 +1327,8 @@ async function bridgeMcpTools(client, opts = {}) {
1294
1327
  const prefix = opts.namePrefix ?? "";
1295
1328
  const maxResultChars = opts.maxResultChars ?? DEFAULT_MAX_RESULT_CHARS;
1296
1329
  const result = { registry, registeredNames: [], skipped: [] };
1330
+ const serverName = opts.serverName ?? prefix.replace(/_$/, "") ?? "anon";
1331
+ const tracker = opts.onSlow ? new LatencyTracker(serverName, { thresholdMs: opts.slowThresholdMs, onSlow: opts.onSlow }) : null;
1297
1332
  const listed = await client.listTools();
1298
1333
  for (const mcpTool of listed.tools) {
1299
1334
  if (!mcpTool.name) {
@@ -1306,6 +1341,7 @@ async function bridgeMcpTools(client, opts = {}) {
1306
1341
  description: mcpTool.description ?? "",
1307
1342
  parameters: mcpTool.inputSchema,
1308
1343
  fn: async (args, ctx) => {
1344
+ const t0 = tracker ? Date.now() : 0;
1309
1345
  const toolResult = await client.callTool(mcpTool.name, args, {
1310
1346
  // Forward server-side progress frames to the bridge caller,
1311
1347
  // tagged with the registered name so multi-server UIs can
@@ -1319,6 +1355,7 @@ async function bridgeMcpTools(client, opts = {}) {
1319
1355
  // pending promise immediately, no "wait for subprocess".
1320
1356
  signal: ctx?.signal
1321
1357
  });
1358
+ if (tracker) tracker.record(Date.now() - t0);
1322
1359
  return flattenMcpResult(toolResult, { maxChars: maxResultChars });
1323
1360
  }
1324
1361
  });
@@ -7196,7 +7233,7 @@ function shellSplit(input) {
7196
7233
  }
7197
7234
 
7198
7235
  // src/mcp/spec.ts
7199
- var NAME_PREFIX = /^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/;
7236
+ var NAME_PREFIX = /^([a-zA-Z_][a-zA-Z0-9_-]*)=(.*)$/;
7200
7237
  var HTTP_URL = /^https?:\/\//i;
7201
7238
  var STREAMABLE_PREFIX = /^streamable\+(https?:\/\/.+)$/i;
7202
7239
  function parseMcpSpec(input) {
@@ -7591,11 +7628,11 @@ function formatLogSize(path5 = defaultUsageLogPath()) {
7591
7628
 
7592
7629
  // src/cli/commands/chat.tsx
7593
7630
  import { render } from "ink";
7594
- import React55, { useState as useState16 } from "react";
7631
+ import React56, { useState as useState17 } from "react";
7595
7632
 
7596
7633
  // src/cli/ui/App.tsx
7597
- import { Box as Box45, Text as Text47, useStdout as useStdout14 } from "ink";
7598
- import React53, { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo6, useRef as useRef6, useState as useState14 } from "react";
7634
+ import { Box as Box46, Text as Text48, useStdout as useStdout14 } from "ink";
7635
+ import React54, { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo6, useRef as useRef6, useState as useState15 } from "react";
7599
7636
 
7600
7637
  // src/adapters/event-sink-jsonl.ts
7601
7638
  import { chmodSync as chmodSync3, createWriteStream as createWriteStream2, mkdirSync as mkdirSync6 } from "fs";
@@ -12938,17 +12975,59 @@ function EditConfirm({ block: block2, onChoose }) {
12938
12975
  );
12939
12976
  }
12940
12977
 
12978
+ // src/cli/ui/McpBrowser.tsx
12979
+ import { Box as Box7, Text as Text7 } from "ink";
12980
+ import React9, { useState as useState4 } from "react";
12981
+ function McpBrowser({ servers, configPath, onClose }) {
12982
+ const [index, setIndex] = useState4(0);
12983
+ const max = Math.max(0, servers.length - 1);
12984
+ useKeystroke((ev) => {
12985
+ if (ev.paste) return;
12986
+ if (ev.upArrow) setIndex((i) => Math.max(0, i - 1));
12987
+ else if (ev.downArrow) setIndex((i) => Math.min(max, i + 1));
12988
+ else if (ev.escape) onClose();
12989
+ });
12990
+ return /* @__PURE__ */ React9.createElement(Box7, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Box7, null, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: COLOR.brand }, "\u25C8 MCP browser"), /* @__PURE__ */ React9.createElement(
12991
+ Text7,
12992
+ {
12993
+ dimColor: true
12994
+ },
12995
+ ` \xB7 ${configPath} \xB7 ${servers.length} server${servers.length === 1 ? "" : "s"}`
12996
+ )), /* @__PURE__ */ React9.createElement(Box7, { marginTop: 1, flexDirection: "column" }, servers.length === 0 ? /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "No MCP servers attached. Run `reasonix setup` to pick some, or launch with --mcp.") : servers.map((s, i) => /* @__PURE__ */ React9.createElement(ServerRow, { key: s.label + s.spec, server: s, active: i === index }))), /* @__PURE__ */ React9.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u2191\u2193 pick \xB7 [r] reconnect (Stage C) \xB7 [d] disable (Stage C) \xB7 esc quit")));
12997
+ }
12998
+ function ServerRow({ server, active }) {
12999
+ const { label, toolCount, report } = server;
13000
+ const resourceCount = report.resources.supported ? report.resources.items.length : 0;
13001
+ const promptCount = report.prompts.supported ? report.prompts.items.length : 0;
13002
+ const elapsed = report.elapsedMs;
13003
+ const health = healthBadge(elapsed);
13004
+ const counts = `${toolCount} tools \xB7 ${resourceCount} resources \xB7 ${promptCount} prompts`;
13005
+ return /* @__PURE__ */ React9.createElement(Box7, { flexDirection: "column", marginBottom: active ? 1 : 0 }, /* @__PURE__ */ React9.createElement(Box7, null, /* @__PURE__ */ React9.createElement(Text7, { color: active ? COLOR.brand : void 0 }, active ? "\u25B8 " : " "), /* @__PURE__ */ React9.createElement(Text7, { bold: active, color: active ? "#e6edf3" : void 0 }, label.padEnd(14)), /* @__PURE__ */ React9.createElement(Text7, { color: health.color }, `${health.glyph} ${health.label}`), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, ` ${counts}`)), active ? /* @__PURE__ */ React9.createElement(Box7, null, /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, ` ${capabilityList(server)}`)) : null);
13006
+ }
13007
+ function healthBadge(elapsedMs) {
13008
+ if (elapsedMs === 0) return { glyph: "\u2717", label: "no inspect data", color: COLOR.err };
13009
+ if (elapsedMs < 500) return { glyph: "\u25CF", label: `healthy \xB7 ${elapsedMs}ms`, color: COLOR.ok };
13010
+ if (elapsedMs < 3e3) return { glyph: "\u25CC", label: `slow \xB7 ${elapsedMs}ms`, color: COLOR.warn };
13011
+ return { glyph: "\u2717", label: `very slow \xB7 ${elapsedMs}ms`, color: COLOR.err };
13012
+ }
13013
+ function capabilityList(s) {
13014
+ const caps = ["tools/list", "tools/call"];
13015
+ if (s.report.resources.supported) caps.push("resources/list");
13016
+ if (s.report.prompts.supported) caps.push("prompts/list");
13017
+ return caps.join(" ");
13018
+ }
13019
+
12941
13020
  // src/cli/ui/PlanCheckpointConfirm.tsx
12942
- import { Box as Box9 } from "ink";
12943
- import React11 from "react";
13021
+ import { Box as Box10 } from "ink";
13022
+ import React12 from "react";
12944
13023
 
12945
13024
  // src/cli/ui/PlanStepList.tsx
12946
- import { Box as Box8, Text as Text8 } from "ink";
12947
- import React10 from "react";
13025
+ import { Box as Box9, Text as Text9 } from "ink";
13026
+ import React11 from "react";
12948
13027
 
12949
13028
  // src/cli/ui/char-bar.tsx
12950
- import { Box as Box7, Text as Text7 } from "ink";
12951
- import React9 from "react";
13029
+ import { Box as Box8, Text as Text8 } from "ink";
13030
+ import React10 from "react";
12952
13031
  function CharBar({
12953
13032
  pct: pct2,
12954
13033
  width = 24,
@@ -12960,7 +13039,7 @@ function CharBar({
12960
13039
  const total = Math.max(4, width);
12961
13040
  const clamped = Math.max(0, Math.min(100, Number.isFinite(pct2) ? pct2 : 0));
12962
13041
  const filled = Math.round(total * clamped / 100);
12963
- return /* @__PURE__ */ React9.createElement(Box7, null, /* @__PURE__ */ React9.createElement(Text7, { color: color2 }, GLYPH.block.repeat(filled)), /* @__PURE__ */ React9.createElement(Text7, { color: emptyColor ?? COLOR.info, dimColor: true }, GLYPH.shade1.repeat(total - filled)), showLabel ? /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, ` ${label ?? `${Math.round(clamped)}%`}`) : null);
13042
+ return /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { color: color2 }, GLYPH.block.repeat(filled)), /* @__PURE__ */ React10.createElement(Text8, { color: emptyColor ?? COLOR.info, dimColor: true }, GLYPH.shade1.repeat(total - filled)), showLabel ? /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, ` ${label ?? `${Math.round(clamped)}%`}`) : null);
12964
13043
  }
12965
13044
 
12966
13045
  // src/cli/ui/PlanStepList.tsx
@@ -12990,25 +13069,25 @@ function PlanStepListInner({ steps, statuses, focusStepId }) {
12990
13069
  const doneCount = statusList.filter((s) => s === "done").length;
12991
13070
  const pct2 = Math.round(doneCount / total * 100);
12992
13071
  const showProgress = doneCount > 0;
12993
- return /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, showProgress ? `${doneCount}/${total} done (${pct2}%) \xB7 ${total} step${total === 1 ? "" : "s"}` : `${total} step${total === 1 ? "" : "s"}`)), /* @__PURE__ */ React10.createElement(Box8, { flexDirection: "column" }, steps.map((step, i) => {
13072
+ return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, showProgress ? `${doneCount}/${total} done (${pct2}%) \xB7 ${total} step${total === 1 ? "" : "s"}` : `${total} step${total === 1 ? "" : "s"}`)), /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column" }, steps.map((step, i) => {
12994
13073
  const status3 = statusList[i];
12995
13074
  const isLast = i === total - 1;
12996
13075
  const isCur = focusStepId === step.id;
12997
13076
  const sg = statusGlyph(status3, isCur);
12998
13077
  const risk = riskLabel(step.risk);
12999
13078
  const titleDim = status3 === "done" || status3 === "skipped";
13000
- return /* @__PURE__ */ React10.createElement(Box8, { key: step.id }, /* @__PURE__ */ React10.createElement(Text8, { color: COLOR.info, dimColor: true }, isLast ? GLYPH.branchEnd : GLYPH.branch), /* @__PURE__ */ React10.createElement(Text8, null, " "), /* @__PURE__ */ React10.createElement(Text8, { color: sg.color, bold: status3 === "running" || isCur }, sg.glyph), /* @__PURE__ */ React10.createElement(Text8, null, " "), /* @__PURE__ */ React10.createElement(
13001
- Text8,
13079
+ return /* @__PURE__ */ React11.createElement(Box9, { key: step.id }, /* @__PURE__ */ React11.createElement(Text9, { color: COLOR.info, dimColor: true }, isLast ? GLYPH.branchEnd : GLYPH.branch), /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(Text9, { color: sg.color, bold: status3 === "running" || isCur }, sg.glyph), /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(
13080
+ Text9,
13002
13081
  {
13003
13082
  dimColor: titleDim,
13004
13083
  bold: isCur || status3 === "running",
13005
13084
  strikethrough: status3 === "done" || status3 === "skipped"
13006
13085
  },
13007
13086
  `${step.id} \xB7 ${step.title}`
13008
- ), risk ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Text8, null, " "), /* @__PURE__ */ React10.createElement(Text8, { color: risk.color }, risk.text)) : null);
13009
- })), showProgress ? /* @__PURE__ */ React10.createElement(Box8, null, /* @__PURE__ */ React10.createElement(Text8, null, " "), /* @__PURE__ */ React10.createElement(CharBar, { pct: pct2, width: 24 })) : null);
13087
+ ), risk ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(Text9, { color: risk.color }, risk.text)) : null);
13088
+ })), showProgress ? /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(Text9, null, " "), /* @__PURE__ */ React11.createElement(CharBar, { pct: pct2, width: 24 })) : null);
13010
13089
  }
13011
- var PlanStepList = React10.memo(PlanStepListInner);
13090
+ var PlanStepList = React11.memo(PlanStepListInner);
13012
13091
 
13013
13092
  // src/cli/ui/PlanCheckpointConfirm.tsx
13014
13093
  function PlanCheckpointConfirmInner({
@@ -13025,7 +13104,7 @@ function PlanCheckpointConfirmInner({
13025
13104
  const isLast = total > 0 && completed >= total;
13026
13105
  const statuses = buildStatusMap(steps, completedStepIds, stepId, isLast);
13027
13106
  const subtitle = counter ? `${counter} \xB7 ${label}` : label;
13028
- return /* @__PURE__ */ React11.createElement(ApprovalCard, { tone: "ok", glyph: "\u26C1", title: "Checkpoint \u2014 step done", metaRight: subtitle }, steps && steps.length > 0 ? /* @__PURE__ */ React11.createElement(Box9, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React11.createElement(
13107
+ return /* @__PURE__ */ React12.createElement(ApprovalCard, { tone: "ok", glyph: "\u26C1", title: "Checkpoint \u2014 step done", metaRight: subtitle }, steps && steps.length > 0 ? /* @__PURE__ */ React12.createElement(Box10, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React12.createElement(
13029
13108
  SingleSelect,
13030
13109
  {
13031
13110
  initialValue: isLast ? "stop" : "continue",
@@ -13051,7 +13130,7 @@ function PlanCheckpointConfirmInner({
13051
13130
  }
13052
13131
  ));
13053
13132
  }
13054
- var PlanCheckpointConfirm = React11.memo(PlanCheckpointConfirmInner);
13133
+ var PlanCheckpointConfirm = React12.memo(PlanCheckpointConfirmInner);
13055
13134
  function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
13056
13135
  const map = /* @__PURE__ */ new Map();
13057
13136
  if (!steps) return map;
@@ -13067,11 +13146,11 @@ function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
13067
13146
  }
13068
13147
 
13069
13148
  // src/cli/ui/PlanConfirm.tsx
13070
- import { Box as Box10, Text as Text9 } from "ink";
13071
- import React12 from "react";
13149
+ import { Box as Box11, Text as Text10 } from "ink";
13150
+ import React13 from "react";
13072
13151
  function PlanConfirmInner({ plan: plan3, steps, onChoose }) {
13073
13152
  const hasOpenQuestions = /^#{1,6}\s*(open[-\s]?questions?|risks?|unknowns?|assumptions?|unclear)/im.test(plan3) || /^#{1,6}\s*(待确认|开放问题|风险|未知|假设|不确定)/im.test(plan3);
13074
- return /* @__PURE__ */ React12.createElement(
13153
+ return /* @__PURE__ */ React13.createElement(
13075
13154
  ApprovalCard,
13076
13155
  {
13077
13156
  tone: "accent",
@@ -13080,9 +13159,9 @@ function PlanConfirmInner({ plan: plan3, steps, onChoose }) {
13080
13159
  metaRight: "awaiting",
13081
13160
  metaRightColor: CARD.plan.color
13082
13161
  },
13083
- hasOpenQuestions ? /* @__PURE__ */ React12.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text9, { color: TONE.warn }, "\u25B2 the plan flags open questions or risks \u2014 pick ", /* @__PURE__ */ React12.createElement(Text9, { bold: true }, "refine"), " to write concrete answers before the model moves on.")) : null,
13084
- steps && steps.length > 0 ? /* @__PURE__ */ React12.createElement(Box10, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(PlanStepList, { steps })) : null,
13085
- /* @__PURE__ */ React12.createElement(
13162
+ hasOpenQuestions ? /* @__PURE__ */ React13.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text10, { color: TONE.warn }, "\u25B2 the plan flags open questions or risks \u2014 pick ", /* @__PURE__ */ React13.createElement(Text10, { bold: true }, "refine"), " to write concrete answers before the model moves on.")) : null,
13163
+ steps && steps.length > 0 ? /* @__PURE__ */ React13.createElement(Box11, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React13.createElement(PlanStepList, { steps })) : null,
13164
+ /* @__PURE__ */ React13.createElement(
13086
13165
  SingleSelect,
13087
13166
  {
13088
13167
  initialValue: hasOpenQuestions ? "refine" : "approve",
@@ -13114,21 +13193,21 @@ function PlanConfirmInner({ plan: plan3, steps, onChoose }) {
13114
13193
  )
13115
13194
  );
13116
13195
  }
13117
- var PlanConfirm = React12.memo(PlanConfirmInner);
13196
+ var PlanConfirm = React13.memo(PlanConfirmInner);
13118
13197
 
13119
13198
  // src/cli/ui/PlanRefineInput.tsx
13120
- import { Box as Box11, Text as Text10 } from "ink";
13121
- import React14, { useState as useState5 } from "react";
13199
+ import { Box as Box12, Text as Text11 } from "ink";
13200
+ import React15, { useState as useState6 } from "react";
13122
13201
 
13123
13202
  // src/cli/ui/ticker.tsx
13124
- import React13, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState4 } from "react";
13203
+ import React14, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState5 } from "react";
13125
13204
  var FAST_TICK_MS = 120;
13126
13205
  var SLOW_TICK_MS = 1e3;
13127
13206
  var FastTickContext = createContext2(0);
13128
13207
  var SlowTickContext = createContext2(0);
13129
13208
  function TickerProvider({ children, disabled }) {
13130
- const [fast, setFast] = useState4(0);
13131
- const [slow, setSlow] = useState4(0);
13209
+ const [fast, setFast] = useState5(0);
13210
+ const [slow, setSlow] = useState5(0);
13132
13211
  useEffect2(() => {
13133
13212
  if (disabled) return;
13134
13213
  const fastId = setInterval(() => setFast((t2) => t2 + 1), FAST_TICK_MS);
@@ -13138,7 +13217,7 @@ function TickerProvider({ children, disabled }) {
13138
13217
  clearInterval(slowId);
13139
13218
  };
13140
13219
  }, [disabled]);
13141
- return /* @__PURE__ */ React13.createElement(FastTickContext.Provider, { value: fast }, /* @__PURE__ */ React13.createElement(SlowTickContext.Provider, { value: slow }, children));
13220
+ return /* @__PURE__ */ React14.createElement(FastTickContext.Provider, { value: fast }, /* @__PURE__ */ React14.createElement(SlowTickContext.Provider, { value: slow }, children));
13142
13221
  }
13143
13222
  function useTick() {
13144
13223
  return useContext2(FastTickContext);
@@ -13147,7 +13226,7 @@ function useSlowTick() {
13147
13226
  return useContext2(SlowTickContext);
13148
13227
  }
13149
13228
  function useElapsedSeconds() {
13150
- const [start] = useState4(() => Date.now());
13229
+ const [start] = useState5(() => Date.now());
13151
13230
  useSlowTick();
13152
13231
  return Math.floor((Date.now() - start) / 1e3);
13153
13232
  }
@@ -13188,7 +13267,7 @@ var MODES = {
13188
13267
  }
13189
13268
  };
13190
13269
  function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
13191
- const [value, setValue] = useState5("");
13270
+ const [value, setValue] = useState6("");
13192
13271
  useKeystroke((ev) => {
13193
13272
  if (ev.paste) {
13194
13273
  setValue((v) => v + ev.input.replace(/\r?\n/g, " "));
@@ -13213,7 +13292,7 @@ function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
13213
13292
  const tick = useTick();
13214
13293
  const cursorOn = Math.floor(tick / 4) % 2 === 0;
13215
13294
  const meta = MODES[mode2];
13216
- return /* @__PURE__ */ React14.createElement(
13295
+ return /* @__PURE__ */ React15.createElement(
13217
13296
  ApprovalCard,
13218
13297
  {
13219
13298
  tone: meta.tone,
@@ -13221,14 +13300,14 @@ function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
13221
13300
  title: meta.title,
13222
13301
  footerHint: "\u23CE send \xB7 esc return to picker"
13223
13302
  },
13224
- /* @__PURE__ */ React14.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text10, { color: FG.sub }, meta.hint, value === "" ? meta.blankHint : "")),
13225
- /* @__PURE__ */ React14.createElement(Box11, null, /* @__PURE__ */ React14.createElement(Text10, { color: meta.cursorColor, bold: true }, "\u203A "), /* @__PURE__ */ React14.createElement(Text10, null, value), /* @__PURE__ */ React14.createElement(Text10, { color: meta.cursorColor, bold: true }, cursorOn ? "\u258D" : " "))
13303
+ /* @__PURE__ */ React15.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text11, { color: FG.sub }, meta.hint, value === "" ? meta.blankHint : "")),
13304
+ /* @__PURE__ */ React15.createElement(Box12, null, /* @__PURE__ */ React15.createElement(Text11, { color: meta.cursorColor, bold: true }, "\u203A "), /* @__PURE__ */ React15.createElement(Text11, null, value), /* @__PURE__ */ React15.createElement(Text11, { color: meta.cursorColor, bold: true }, cursorOn ? "\u258D" : " "))
13226
13305
  );
13227
13306
  }
13228
13307
 
13229
13308
  // src/cli/ui/PlanReviseConfirm.tsx
13230
- import { Box as Box12, Text as Text11 } from "ink";
13231
- import React15 from "react";
13309
+ import { Box as Box13, Text as Text12 } from "ink";
13310
+ import React16 from "react";
13232
13311
  function computeDiff(oldSteps, newSteps) {
13233
13312
  const oldIds = new Set(oldSteps.map((s) => s.id));
13234
13313
  const newIds = new Set(newSteps.map((s) => s.id));
@@ -13264,7 +13343,7 @@ function PlanReviseConfirmInner({
13264
13343
  const removedCount = rows.filter((r) => r.kind === "removed").length;
13265
13344
  const addedCount = rows.filter((r) => r.kind === "added").length;
13266
13345
  const keptCount = rows.filter((r) => r.kind === "kept").length;
13267
- return /* @__PURE__ */ React15.createElement(
13346
+ return /* @__PURE__ */ React16.createElement(
13268
13347
  ApprovalCard,
13269
13348
  {
13270
13349
  tone: "warn",
@@ -13272,17 +13351,17 @@ function PlanReviseConfirmInner({
13272
13351
  title: "plan revision proposed",
13273
13352
  metaRight: `\u2212${removedCount} +${addedCount} \xB7 ${keptCount} kept`
13274
13353
  },
13275
- /* @__PURE__ */ React15.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text11, null, reason)),
13276
- summary ? /* @__PURE__ */ React15.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text11, { dimColor: true }, `updated summary: ${summary}`)) : null,
13277
- /* @__PURE__ */ React15.createElement(Box12, { marginBottom: 1, flexDirection: "column" }, rows.map((row3) => {
13354
+ /* @__PURE__ */ React16.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text12, null, reason)),
13355
+ summary ? /* @__PURE__ */ React16.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text12, { dimColor: true }, `updated summary: ${summary}`)) : null,
13356
+ /* @__PURE__ */ React16.createElement(Box13, { marginBottom: 1, flexDirection: "column" }, rows.map((row3) => {
13278
13357
  const risk = riskDots(row3.step.risk);
13279
13358
  const prefix = row3.kind === "removed" ? "\u2212" : row3.kind === "added" ? "+" : " ";
13280
13359
  const prefixColor = row3.kind === "removed" ? "#f87171" : row3.kind === "added" ? "#4ade80" : "#94a3b8";
13281
13360
  const dim = row3.kind === "kept";
13282
13361
  const strike = row3.kind === "removed";
13283
- return /* @__PURE__ */ React15.createElement(Box12, { key: `${row3.kind}-${row3.step.id}` }, /* @__PURE__ */ React15.createElement(Text11, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React15.createElement(Text11, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React15.createElement(Text11, { dimColor: dim, strikethrough: strike }, ` ${row3.step.id} \xB7 ${row3.step.title}`));
13362
+ return /* @__PURE__ */ React16.createElement(Box13, { key: `${row3.kind}-${row3.step.id}` }, /* @__PURE__ */ React16.createElement(Text12, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React16.createElement(Text12, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React16.createElement(Text12, { dimColor: dim, strikethrough: strike }, ` ${row3.step.id} \xB7 ${row3.step.title}`));
13284
13363
  })),
13285
- /* @__PURE__ */ React15.createElement(
13364
+ /* @__PURE__ */ React16.createElement(
13286
13365
  SingleSelect,
13287
13366
  {
13288
13367
  initialValue: "accept",
@@ -13304,22 +13383,22 @@ function PlanReviseConfirmInner({
13304
13383
  )
13305
13384
  );
13306
13385
  }
13307
- var PlanReviseConfirm = React15.memo(PlanReviseConfirmInner);
13386
+ var PlanReviseConfirm = React16.memo(PlanReviseConfirmInner);
13308
13387
 
13309
13388
  // src/cli/ui/PlanReviseEditor.tsx
13310
- import { Box as Box13, Text as Text12 } from "ink";
13311
- import React16, { useState as useState6 } from "react";
13389
+ import { Box as Box14, Text as Text13 } from "ink";
13390
+ import React17, { useState as useState7 } from "react";
13312
13391
  function PlanReviseEditor({
13313
13392
  steps,
13314
13393
  completedStepIds,
13315
13394
  onAccept,
13316
13395
  onCancel
13317
13396
  }) {
13318
- const [rows, setRows] = useState6(
13397
+ const [rows, setRows] = useState7(
13319
13398
  () => steps.map((s) => ({ step: s, done: completedStepIds?.has(s.id) ?? false, skipped: false }))
13320
13399
  );
13321
13400
  const firstEditableIndex = rows.findIndex((r) => !r.done);
13322
- const [focus, setFocus] = useState6(firstEditableIndex < 0 ? 0 : firstEditableIndex);
13401
+ const [focus, setFocus] = useState7(firstEditableIndex < 0 ? 0 : firstEditableIndex);
13323
13402
  useKeystroke((ev) => {
13324
13403
  if (ev.paste) return;
13325
13404
  if (ev.escape) {
@@ -13380,7 +13459,7 @@ function PlanReviseEditor({
13380
13459
  return;
13381
13460
  }
13382
13461
  });
13383
- return /* @__PURE__ */ React16.createElement(
13462
+ return /* @__PURE__ */ React17.createElement(
13384
13463
  ApprovalCard,
13385
13464
  {
13386
13465
  tone: "accent",
@@ -13389,7 +13468,7 @@ function PlanReviseEditor({
13389
13468
  metaRight: `${rows.length} steps`,
13390
13469
  footerHint: "\u2191\u2193 focus \xB7 space toggle skip \xB7 k/j move \xB7 \u23CE accept \xB7 esc cancel"
13391
13470
  },
13392
- rows.map((r, i) => /* @__PURE__ */ React16.createElement(ReviseRow, { key: r.step.id, row: r, index: i, focused: i === focus }))
13471
+ rows.map((r, i) => /* @__PURE__ */ React17.createElement(ReviseRow, { key: r.step.id, row: r, index: i, focused: i === focus }))
13393
13472
  );
13394
13473
  }
13395
13474
  function ReviseRow({
@@ -13400,13 +13479,13 @@ function ReviseRow({
13400
13479
  const marker = row3.done ? "[\u2713]" : row3.skipped ? "[s]" : focused ? "[ ]" : "[ ]";
13401
13480
  const markerColor = row3.done ? TONE.ok : row3.skipped ? FG.faint : focused ? TONE.brand : FG.faint;
13402
13481
  const titleColor = row3.done ? FG.sub : row3.skipped ? FG.faint : focused ? FG.strong : FG.sub;
13403
- const focusGlyph = focused ? /* @__PURE__ */ React16.createElement(Text12, { color: TONE.brand }, "\u25B8 ") : /* @__PURE__ */ React16.createElement(Text12, null, " ");
13404
- return /* @__PURE__ */ React16.createElement(Box13, null, focusGlyph, /* @__PURE__ */ React16.createElement(Text12, { color: markerColor }, marker), /* @__PURE__ */ React16.createElement(Text12, { color: titleColor, bold: focused, italic: row3.skipped, strikethrough: row3.skipped }, ` ${index + 1}. ${row3.step.title}`), row3.skipped ? /* @__PURE__ */ React16.createElement(Text12, { color: TONE.warn }, " \u2190 skipped") : null);
13482
+ const focusGlyph = focused ? /* @__PURE__ */ React17.createElement(Text13, { color: TONE.brand }, "\u25B8 ") : /* @__PURE__ */ React17.createElement(Text13, null, " ");
13483
+ return /* @__PURE__ */ React17.createElement(Box14, null, focusGlyph, /* @__PURE__ */ React17.createElement(Text13, { color: markerColor }, marker), /* @__PURE__ */ React17.createElement(Text13, { color: titleColor, bold: focused, italic: row3.skipped, strikethrough: row3.skipped }, ` ${index + 1}. ${row3.step.title}`), row3.skipped ? /* @__PURE__ */ React17.createElement(Text13, { color: TONE.warn }, " \u2190 skipped") : null);
13405
13484
  }
13406
13485
 
13407
13486
  // src/cli/ui/PromptInput.tsx
13408
- import { Box as Box14, Text as Text13, useStdout as useStdout4 } from "ink";
13409
- import React17, { useRef as useRef2, useState as useState7 } from "react";
13487
+ import { Box as Box15, Text as Text14, useStdout as useStdout4 } from "ink";
13488
+ import React18, { useRef as useRef2, useState as useState8 } from "react";
13410
13489
 
13411
13490
  // src/cli/ui/key-normalize.ts
13412
13491
  var CSI_TAIL_TO_FLAGS = [
@@ -13812,7 +13891,7 @@ function PromptInput({
13812
13891
  onHistoryPrev,
13813
13892
  onHistoryNext
13814
13893
  }) {
13815
- const [cursor, setCursor] = useState7(value.length);
13894
+ const [cursor, setCursor] = useState8(value.length);
13816
13895
  const pastesRef = useRef2(/* @__PURE__ */ new Map());
13817
13896
  const nextPasteIdRef = useRef2(0);
13818
13897
  const lastLocalValueRef = useRef2(value);
@@ -13899,14 +13978,14 @@ function PromptInput({
13899
13978
  const { line: cursorLine, col: cursorCol } = lineAndColumn(value, cursor);
13900
13979
  const renderItems = collapseLinesForDisplay(lines, cursorLine);
13901
13980
  const showHugeBufferHints = lines.length > 20;
13902
- return /* @__PURE__ */ React17.createElement(Box14, { flexDirection: "column", paddingX: 1 }, (() => {
13981
+ return /* @__PURE__ */ React18.createElement(Box15, { flexDirection: "column", paddingX: 1 }, (() => {
13903
13982
  const rows = [];
13904
13983
  let firstRowEmitted = false;
13905
13984
  for (let renderIdx = 0; renderIdx < renderItems.length; renderIdx++) {
13906
13985
  const item = renderItems[renderIdx];
13907
13986
  if (item.kind === "skip") {
13908
13987
  rows.push(
13909
- /* @__PURE__ */ React17.createElement(Box14, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, continuationIndent), /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
13988
+ /* @__PURE__ */ React18.createElement(Box15, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, continuationIndent), /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
13910
13989
  );
13911
13990
  continue;
13912
13991
  }
@@ -13916,7 +13995,7 @@ function PromptInput({
13916
13995
  const showPlaceholder = i === 0 && value.length === 0;
13917
13996
  if (showPlaceholder) {
13918
13997
  rows.push(
13919
- /* @__PURE__ */ React17.createElement(
13998
+ /* @__PURE__ */ React18.createElement(
13920
13999
  PromptLine,
13921
14000
  {
13922
14001
  key: `ln-${i}-text-0`,
@@ -13947,7 +14026,7 @@ function PromptInput({
13947
14026
  if (seg.kind === "paste") {
13948
14027
  const cursorOnIt = isCursorLine && cursorCol >= seg.startOffset && cursorCol <= seg.startOffset + 1;
13949
14028
  rows.push(
13950
- /* @__PURE__ */ React17.createElement(
14029
+ /* @__PURE__ */ React18.createElement(
13951
14030
  PasteChipRow,
13952
14031
  {
13953
14032
  key: `ln-${i}-paste-${segIdx}`,
@@ -13964,7 +14043,7 @@ function PromptInput({
13964
14043
  }
13965
14044
  const segHasCursor = isCursorLine && cursorCol >= seg.startOffset && cursorCol <= seg.startOffset + seg.text.length;
13966
14045
  rows.push(
13967
- /* @__PURE__ */ React17.createElement(
14046
+ /* @__PURE__ */ React18.createElement(
13968
14047
  PromptLine,
13969
14048
  {
13970
14049
  key: `ln-${i}-text-${segIdx}`,
@@ -13989,7 +14068,7 @@ function PromptInput({
13989
14068
  const isFirst = !firstRowEmitted;
13990
14069
  firstRowEmitted = true;
13991
14070
  rows.push(
13992
- /* @__PURE__ */ React17.createElement(
14071
+ /* @__PURE__ */ React18.createElement(
13993
14072
  PromptLine,
13994
14073
  {
13995
14074
  key: `ln-${i}-empty`,
@@ -14012,7 +14091,7 @@ function PromptInput({
14012
14091
  }
14013
14092
  }
14014
14093
  return rows;
14015
- })(), showHugeBufferHints && !disabled ? /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, ` [${lines.length} lines \xB7 PgUp/PgDn jump \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled ? /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, " \u23CE send \xB7 shift/alt+\u23CE newline \xB7 \u2191\u2193 history \xB7 esc abort \xB7 ctrl-c quit")) : /* @__PURE__ */ React17.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, " esc to stop")));
14094
+ })(), showHugeBufferHints && !disabled ? /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, ` [${lines.length} lines \xB7 PgUp/PgDn jump \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled ? /* @__PURE__ */ React18.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, " \u23CE send \xB7 shift/alt+\u23CE newline \xB7 \u2191\u2193 history \xB7 esc abort \xB7 ctrl-c quit")) : /* @__PURE__ */ React18.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, " esc to stop")));
14016
14095
  }
14017
14096
  function splitLineByPastes(line) {
14018
14097
  const out = [];
@@ -14049,9 +14128,9 @@ function PasteChipRow({
14049
14128
  const leadColor = isFirst ? accentColor : FG.faint;
14050
14129
  const labelText = formatChipLabel(entry, pasteId, visibleCells - 6);
14051
14130
  if (active) {
14052
- return /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: leadColor }, lead), /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: accentColor }, "\u25B8 "), /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: "black", backgroundColor: accentColor }, ` ${labelText} `));
14131
+ return /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: leadColor }, lead), /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: accentColor }, "\u25B8 "), /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: "black", backgroundColor: accentColor }, ` ${labelText} `));
14053
14132
  }
14054
- return /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: leadColor }, lead), /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, " "), /* @__PURE__ */ React17.createElement(Text13, { color: FG.meta }, "\u250C "), /* @__PURE__ */ React17.createElement(Text13, { color: FG.body, backgroundColor: SURFACE.bgElev }, `${labelText} `), /* @__PURE__ */ React17.createElement(Text13, { color: FG.meta }, " \u2510"));
14133
+ return /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: leadColor }, lead), /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, " "), /* @__PURE__ */ React18.createElement(Text14, { color: FG.meta }, "\u250C "), /* @__PURE__ */ React18.createElement(Text14, { color: FG.body, backgroundColor: SURFACE.bgElev }, `${labelText} `), /* @__PURE__ */ React18.createElement(Text14, { color: FG.meta }, " \u2510"));
14055
14134
  }
14056
14135
  function formatChipLabel(entry, pasteId, budget3) {
14057
14136
  if (!entry) return `\u{1F4CB} paste #${pasteId + 1} \xB7 (missing)`;
@@ -14095,10 +14174,10 @@ function PromptLine({
14095
14174
  disabled
14096
14175
  }) {
14097
14176
  if (showPlaceholder) {
14098
- return /* @__PURE__ */ React17.createElement(Box14, null, /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: accentColor }, promptPrefix), !disabled ? /* @__PURE__ */ React17.createElement(Text13, { color: accentColor }, cursorVisible ? "\u258C" : " ") : null, /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, placeholderText));
14177
+ return /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: accentColor }, promptPrefix), !disabled ? /* @__PURE__ */ React18.createElement(Text14, { color: accentColor }, cursorVisible ? "\u258C" : " ") : null, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, placeholderText));
14099
14178
  }
14100
14179
  const viewport = buildViewport(line, isCursorLine ? cursorCol : null, visibleCells, pastes);
14101
- return /* @__PURE__ */ React17.createElement(Box14, null, isFirst ? /* @__PURE__ */ React17.createElement(Text13, { bold: true, color: accentColor }, promptPrefix) : /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, continuationIndent), viewport.hiddenLeft ? /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, "\u2039") : null, /* @__PURE__ */ React17.createElement(
14180
+ return /* @__PURE__ */ React18.createElement(Box15, null, isFirst ? /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: accentColor }, promptPrefix) : /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, continuationIndent), viewport.hiddenLeft ? /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, "\u2039") : null, /* @__PURE__ */ React18.createElement(
14102
14181
  ViewportContent,
14103
14182
  {
14104
14183
  segments: viewport.segments,
@@ -14106,7 +14185,7 @@ function PromptLine({
14106
14185
  accentColor,
14107
14186
  cursorVisible
14108
14187
  }
14109
- ), viewport.hiddenRight ? /* @__PURE__ */ React17.createElement(Text13, { color: FG.faint }, "\u203A") : null);
14188
+ ), viewport.hiddenRight ? /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, "\u203A") : null);
14110
14189
  }
14111
14190
  function ViewportContent({
14112
14191
  segments,
@@ -14115,7 +14194,7 @@ function ViewportContent({
14115
14194
  cursorVisible
14116
14195
  }) {
14117
14196
  if (cursorCell === null) {
14118
- return /* @__PURE__ */ React17.createElement(React17.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
14197
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
14119
14198
  }
14120
14199
  const out = [];
14121
14200
  let cells = 0;
@@ -14134,8 +14213,8 @@ function ViewportContent({
14134
14213
  }
14135
14214
  if (seg.kind === "paste") {
14136
14215
  out.push(
14137
- /* @__PURE__ */ React17.createElement(
14138
- Text13,
14216
+ /* @__PURE__ */ React18.createElement(
14217
+ Text14,
14139
14218
  {
14140
14219
  key: `p-${i}-cursor`,
14141
14220
  color: FG.body,
@@ -14152,29 +14231,29 @@ function ViewportContent({
14152
14231
  const offsetIntoSeg = cursorCell - cells;
14153
14232
  const split = splitTextByCells(seg.text, offsetIntoSeg);
14154
14233
  if (split.before.length > 0) {
14155
- out.push(/* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-b` }, split.before));
14234
+ out.push(/* @__PURE__ */ React18.createElement(Text14, { key: `t-${i}-b` }, split.before));
14156
14235
  }
14157
14236
  if (split.atCursor.length > 0) {
14158
14237
  out.push(
14159
- /* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-c`, inverse: cursorVisible, color: accentColor }, split.atCursor)
14238
+ /* @__PURE__ */ React18.createElement(Text14, { key: `t-${i}-c`, inverse: cursorVisible, color: accentColor }, split.atCursor)
14160
14239
  );
14161
14240
  } else {
14162
14241
  out.push(
14163
- /* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-c-eol`, color: accentColor }, cursorVisible ? "\u258C" : " ")
14242
+ /* @__PURE__ */ React18.createElement(Text14, { key: `t-${i}-c-eol`, color: accentColor }, cursorVisible ? "\u258C" : " ")
14164
14243
  );
14165
14244
  }
14166
14245
  if (split.after.length > 0) {
14167
- out.push(/* @__PURE__ */ React17.createElement(Text13, { key: `t-${i}-a` }, split.after));
14246
+ out.push(/* @__PURE__ */ React18.createElement(Text14, { key: `t-${i}-a` }, split.after));
14168
14247
  }
14169
14248
  placed = true;
14170
14249
  cells += segCells;
14171
14250
  }
14172
14251
  if (!placed) {
14173
14252
  out.push(
14174
- /* @__PURE__ */ React17.createElement(Text13, { key: "cursor-eol", color: accentColor }, cursorVisible ? "\u258C" : " ")
14253
+ /* @__PURE__ */ React18.createElement(Text14, { key: "cursor-eol", color: accentColor }, cursorVisible ? "\u258C" : " ")
14175
14254
  );
14176
14255
  }
14177
- return /* @__PURE__ */ React17.createElement(React17.Fragment, null, out);
14256
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, out);
14178
14257
  }
14179
14258
  function segmentCells(seg) {
14180
14259
  if (seg.kind === "paste") return seg.label.length;
@@ -14214,9 +14293,9 @@ function charCellsForText(ch) {
14214
14293
  }
14215
14294
  function renderSegment(seg, key, _inverse) {
14216
14295
  if (seg.kind === "text") {
14217
- return /* @__PURE__ */ React17.createElement(Text13, { key: `s-${key}` }, seg.text);
14296
+ return /* @__PURE__ */ React18.createElement(Text14, { key: `s-${key}` }, seg.text);
14218
14297
  }
14219
- return /* @__PURE__ */ React17.createElement(Text13, { key: `s-${key}`, backgroundColor: SURFACE.bgElev, color: FG.body }, seg.label);
14298
+ return /* @__PURE__ */ React18.createElement(Text14, { key: `s-${key}`, backgroundColor: SURFACE.bgElev, color: FG.body }, seg.label);
14220
14299
  }
14221
14300
  var COLLAPSE_THRESHOLD = 20;
14222
14301
  var COLLAPSE_HEAD_LINES = 3;
@@ -14243,16 +14322,16 @@ function collapseLinesForDisplay(lines, cursorLine) {
14243
14322
  }
14244
14323
 
14245
14324
  // src/cli/ui/SessionPicker.tsx
14246
- import { Box as Box15, Text as Text14, useStdout as useStdout5 } from "ink";
14247
- import React18, { useState as useState8 } from "react";
14325
+ import { Box as Box16, Text as Text15, useStdout as useStdout5 } from "ink";
14326
+ import React19, { useState as useState9 } from "react";
14248
14327
  var PAGE_MARGIN = 6;
14249
14328
  function SessionPicker({
14250
14329
  sessions: sessions2,
14251
14330
  workspace: workspace2,
14252
14331
  onChoose
14253
14332
  }) {
14254
- const [focus, setFocus] = useState8(0);
14255
- const [renaming, setRenaming] = useState8(null);
14333
+ const [focus, setFocus] = useState9(0);
14334
+ const [renaming, setRenaming] = useState9(null);
14256
14335
  const { stdout: stdout4 } = useStdout5();
14257
14336
  const rows = stdout4?.rows ?? 40;
14258
14337
  const visibleCount = Math.max(3, rows - PAGE_MARGIN);
@@ -14306,7 +14385,7 @@ function SessionPicker({
14306
14385
  const end = Math.min(sessions2.length, start + visibleCount);
14307
14386
  const shown = sessions2.slice(start, end);
14308
14387
  const hiddenBelow = sessions2.length - end;
14309
- return /* @__PURE__ */ React18.createElement(Box15, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: TONE.brand }, " \u25C8 REASONIX \xB7 pick a session "), /* @__PURE__ */ React18.createElement(Text14, { color: FG.meta }, ` \xB7 ${workspace2}`)), /* @__PURE__ */ React18.createElement(Box15, { height: 1 }), sessions2.length === 0 ? /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, " no saved sessions in this workspace yet \u2014 press "), /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: TONE.brand }, "\u23CE"), /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, " to start a new one")) : shown.map((s, i) => /* @__PURE__ */ React18.createElement(SessionRow, { key: s.name, info: s, focused: start + i === focus })), hiddenBelow > 0 ? /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, ` \u2026 ${hiddenBelow} more`)) : null, renaming ? /* @__PURE__ */ React18.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, ` rename "${renaming.from}" \u2192 `), /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: TONE.brand }, renaming.buf), /* @__PURE__ */ React18.createElement(Text14, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, /* @__PURE__ */ React18.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, renaming ? " \u23CE confirm rename \xB7 esc cancel" : sessions2.length === 0 ? " \u23CE new session \xB7 esc quit" : " \u2191\u2193 pick \xB7 \u23CE open \xB7 [n] new \xB7 [d] delete \xB7 [r] rename \xB7 esc quit")));
14388
+ return /* @__PURE__ */ React19.createElement(Box16, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React19.createElement(Box16, null, /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: TONE.brand }, " \u25C8 REASONIX \xB7 pick a session "), /* @__PURE__ */ React19.createElement(Text15, { color: FG.meta }, ` \xB7 ${workspace2}`)), /* @__PURE__ */ React19.createElement(Box16, { height: 1 }), sessions2.length === 0 ? /* @__PURE__ */ React19.createElement(Box16, null, /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, " no saved sessions in this workspace yet \u2014 press "), /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: TONE.brand }, "\u23CE"), /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, " to start a new one")) : shown.map((s, i) => /* @__PURE__ */ React19.createElement(SessionRow, { key: s.name, info: s, focused: start + i === focus })), hiddenBelow > 0 ? /* @__PURE__ */ React19.createElement(Box16, null, /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, ` \u2026 ${hiddenBelow} more`)) : null, renaming ? /* @__PURE__ */ React19.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, ` rename "${renaming.from}" \u2192 `), /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: TONE.brand }, renaming.buf), /* @__PURE__ */ React19.createElement(Text15, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, /* @__PURE__ */ React19.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, renaming ? " \u23CE confirm rename \xB7 esc cancel" : sessions2.length === 0 ? " \u23CE new session \xB7 esc quit" : " \u2191\u2193 pick \xB7 \u23CE open \xB7 [n] new \xB7 [d] delete \xB7 [r] rename \xB7 esc quit")));
14310
14389
  }
14311
14390
  function SessionRow({
14312
14391
  info,
@@ -14317,7 +14396,7 @@ function SessionRow({
14317
14396
  const turns = info.meta.turnCount ?? Math.ceil(info.messageCount / 2);
14318
14397
  const costCny = info.meta.totalCostUsd !== void 0 ? `\xA5${(info.meta.totalCostUsd * USD_TO_CNY).toFixed(2)}` : "";
14319
14398
  const time = relativeTime2(info.mtime);
14320
- return /* @__PURE__ */ React18.createElement(Box15, null, /* @__PURE__ */ React18.createElement(Text14, { color: focused ? TONE.brand : FG.faint }, focused ? " \u25B8 " : " "), /* @__PURE__ */ React18.createElement(Text14, { bold: focused, color: focused ? FG.strong : FG.sub }, info.name.padEnd(12)), /* @__PURE__ */ React18.createElement(Text14, { color: FG.meta }, ` \xB7 ${branch2.padEnd(8)} \xB7 `), /* @__PURE__ */ React18.createElement(Text14, { color: focused ? FG.body : FG.sub }, truncate2(summary, 40)), /* @__PURE__ */ React18.createElement(Box15, { flexGrow: 1 }), /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, `${time.padStart(11)} `), /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, `${turns} turns`), costCny ? /* @__PURE__ */ React18.createElement(Text14, { color: FG.faint }, ` \xB7 ${costCny}`) : null);
14399
+ return /* @__PURE__ */ React19.createElement(Box16, null, /* @__PURE__ */ React19.createElement(Text15, { color: focused ? TONE.brand : FG.faint }, focused ? " \u25B8 " : " "), /* @__PURE__ */ React19.createElement(Text15, { bold: focused, color: focused ? FG.strong : FG.sub }, info.name.padEnd(12)), /* @__PURE__ */ React19.createElement(Text15, { color: FG.meta }, ` \xB7 ${branch2.padEnd(8)} \xB7 `), /* @__PURE__ */ React19.createElement(Text15, { color: focused ? FG.body : FG.sub }, truncate2(summary, 40)), /* @__PURE__ */ React19.createElement(Box16, { flexGrow: 1 }), /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, `${time.padStart(11)} `), /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, `${turns} turns`), costCny ? /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, ` \xB7 ${costCny}`) : null);
14321
14400
  }
14322
14401
  function truncate2(s, max) {
14323
14402
  if (s.length <= max) return s;
@@ -14337,14 +14416,14 @@ function relativeTime2(date) {
14337
14416
  }
14338
14417
 
14339
14418
  // src/cli/ui/ShellConfirm.tsx
14340
- import { Box as Box16, Text as Text15 } from "ink";
14341
- import React19, { useState as useState9 } from "react";
14419
+ import { Box as Box17, Text as Text16 } from "ink";
14420
+ import React20, { useState as useState10 } from "react";
14342
14421
  function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
14343
14422
  const isBackground = kind === "run_background";
14344
14423
  const subtitle = isBackground ? "long-running process \u2014 keeps running after approval, /kill to stop" : "model wants to run a shell command";
14345
- const [phase, setPhase] = useState9("pick");
14424
+ const [phase, setPhase] = useState10("pick");
14346
14425
  if (phase === "deny") {
14347
- return /* @__PURE__ */ React19.createElement(
14426
+ return /* @__PURE__ */ React20.createElement(
14348
14427
  ApprovalCard,
14349
14428
  {
14350
14429
  tone: "error",
@@ -14353,7 +14432,7 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
14353
14432
  metaRight: "optional",
14354
14433
  footerHint: "\u23CE submit \xB7 esc skip (deny without reason)"
14355
14434
  },
14356
- /* @__PURE__ */ React19.createElement(
14435
+ /* @__PURE__ */ React20.createElement(
14357
14436
  DenyContextInput,
14358
14437
  {
14359
14438
  onSubmit: (context2) => onChoose("deny", context2 || void 0),
@@ -14362,7 +14441,7 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
14362
14441
  )
14363
14442
  );
14364
14443
  }
14365
- return /* @__PURE__ */ React19.createElement(
14444
+ return /* @__PURE__ */ React20.createElement(
14366
14445
  ApprovalCard,
14367
14446
  {
14368
14447
  tone: "warn",
@@ -14371,9 +14450,9 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
14371
14450
  metaRight: "awaiting",
14372
14451
  footerHint: "\u2191\u2193 pick \xB7 \u23CE confirm \xB7 esc cancel"
14373
14452
  },
14374
- /* @__PURE__ */ React19.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, subtitle)),
14375
- /* @__PURE__ */ React19.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: TONE.err }, "$ "), /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: FG.strong }, command)),
14376
- /* @__PURE__ */ React19.createElement(
14453
+ /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: FG.faint }, subtitle)),
14454
+ /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: TONE.err }, "$ "), /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: FG.strong }, command)),
14455
+ /* @__PURE__ */ React20.createElement(
14377
14456
  SingleSelect,
14378
14457
  {
14379
14458
  initialValue: "run_once",
@@ -14433,8 +14512,8 @@ function derivePrefix(command) {
14433
14512
  }
14434
14513
 
14435
14514
  // src/cli/ui/SlashArgPicker.tsx
14436
- import { Box as Box17, Text as Text16 } from "ink";
14437
- import React20 from "react";
14515
+ import { Box as Box18, Text as Text17 } from "ink";
14516
+ import React21 from "react";
14438
14517
  function SlashArgPicker({
14439
14518
  matches,
14440
14519
  selectedIndex,
@@ -14442,13 +14521,13 @@ function SlashArgPicker({
14442
14521
  kind,
14443
14522
  partial
14444
14523
  }) {
14445
- const headerRow = /* @__PURE__ */ React20.createElement(Box17, null, /* @__PURE__ */ React20.createElement(Text16, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React20.createElement(Text16, { color: COLOR.accent, bold: true }, `/${spec.cmd}`), spec.argsHint ? /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, ` ${spec.argsHint}`) : null, /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, ` ${spec.summary}`));
14524
+ const headerRow = /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.accent, bold: true }, `/${spec.cmd}`), spec.argsHint ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` ${spec.argsHint}`) : null, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` ${spec.summary}`));
14446
14525
  if (kind === "hint") {
14447
- return /* @__PURE__ */ React20.createElement(Box17, { paddingX: 1, marginTop: 1 }, headerRow);
14526
+ return /* @__PURE__ */ React21.createElement(Box18, { paddingX: 1, marginTop: 1 }, headerRow);
14448
14527
  }
14449
14528
  if (matches === null) return null;
14450
14529
  if (matches.length === 0) {
14451
- return /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, /* @__PURE__ */ React20.createElement(Box17, null, /* @__PURE__ */ React20.createElement(Text16, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React20.createElement(Text16, { color: COLOR.warn }, ` no match for "${partial}"`), /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, " \u2014 keep typing, or Backspace to edit")));
14530
+ return /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.warn }, ` no match for "${partial}"`), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " \u2014 keep typing, or Backspace to edit")));
14452
14531
  }
14453
14532
  const MAX = 8;
14454
14533
  const total = matches.length;
@@ -14456,22 +14535,22 @@ function SlashArgPicker({
14456
14535
  const shown = matches.slice(windowStart, windowStart + MAX);
14457
14536
  const hiddenAbove = windowStart;
14458
14537
  const hiddenBelow = total - windowStart - shown.length;
14459
- return /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, hiddenAbove > 0 ? /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null, shown.map((value, i) => /* @__PURE__ */ React20.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React20.createElement(Box17, { marginTop: 0 }, /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14538
+ return /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, hiddenAbove > 0 ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null, shown.map((value, i) => /* @__PURE__ */ React21.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React21.createElement(Box18, { marginTop: 0 }, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14460
14539
  }
14461
14540
  function ArgRow({ value, isSelected }) {
14462
- return /* @__PURE__ */ React20.createElement(Box17, null, /* @__PURE__ */ React20.createElement(Text16, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React20.createElement(Text16, { color: isSelected ? COLOR.user : COLOR.info, bold: isSelected, dimColor: !isSelected }, value));
14541
+ return /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text17, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React21.createElement(Text17, { color: isSelected ? COLOR.user : COLOR.info, bold: isSelected, dimColor: !isSelected }, value));
14463
14542
  }
14464
14543
 
14465
14544
  // src/cli/ui/SlashSuggestions.tsx
14466
- import { Box as Box18, Text as Text17 } from "ink";
14467
- import React21 from "react";
14545
+ import { Box as Box19, Text as Text18 } from "ink";
14546
+ import React22 from "react";
14468
14547
  function SlashSuggestions({
14469
14548
  matches,
14470
14549
  selectedIndex
14471
14550
  }) {
14472
14551
  if (matches === null) return null;
14473
14552
  if (matches.length === 0) {
14474
- return /* @__PURE__ */ React21.createElement(Box18, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.warn }, "no slash command matches that prefix"), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
14553
+ return /* @__PURE__ */ React22.createElement(Box19, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React22.createElement(Text18, null, " "), /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.warn }, "no slash command matches that prefix"), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
14475
14554
  }
14476
14555
  const MAX = 8;
14477
14556
  const total = matches.length;
@@ -14479,17 +14558,17 @@ function SlashSuggestions({
14479
14558
  const shown = matches.slice(windowStart, windowStart + MAX);
14480
14559
  const hiddenAbove = windowStart;
14481
14560
  const hiddenBelow = total - windowStart - shown.length;
14482
- return /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, `${total} command${total === 1 ? "" : "s"}`), hiddenAbove > 0 ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null), shown.map((spec, i) => /* @__PURE__ */ React21.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React21.createElement(Box18, { marginTop: 0 }, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14561
+ return /* @__PURE__ */ React22.createElement(Box19, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React22.createElement(Box19, null, /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, `${total} command${total === 1 ? "" : "s"}`), hiddenAbove > 0 ? /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null), shown.map((spec, i) => /* @__PURE__ */ React22.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React22.createElement(Box19, { marginTop: 0 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
14483
14562
  }
14484
14563
  function SuggestionRow({ spec, isSelected }) {
14485
14564
  const name = `/${spec.cmd}`;
14486
14565
  const argsSuffix = spec.argsHint ? spec.argsHint : "";
14487
- return /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text17, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.accent, bold: isSelected }, name.padEnd(14)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, argsSuffix.padEnd(14)), /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: isSelected ? COLOR.user : COLOR.info, dimColor: !isSelected }, spec.summary));
14566
+ return /* @__PURE__ */ React22.createElement(Box19, null, /* @__PURE__ */ React22.createElement(Text18, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React22.createElement(Text18, { color: COLOR.accent, bold: isSelected }, name.padEnd(14)), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, argsSuffix.padEnd(14)), /* @__PURE__ */ React22.createElement(Text18, null, " "), /* @__PURE__ */ React22.createElement(Text18, { color: isSelected ? COLOR.user : COLOR.info, dimColor: !isSelected }, spec.summary));
14488
14567
  }
14489
14568
 
14490
14569
  // src/cli/ui/WelcomeBanner.tsx
14491
- import { Box as Box19, Text as Text18, useStdout as useStdout6 } from "ink";
14492
- import React22 from "react";
14570
+ import { Box as Box20, Text as Text19, useStdout as useStdout6 } from "ink";
14571
+ import React23 from "react";
14493
14572
  var TAGLINE_CHAT = "DeepSeek-native agent";
14494
14573
  var TAGLINE_CODE = "DeepSeek-native coding agent";
14495
14574
  var TAGLINE_SUB = "cache-first \xB7 flash-first";
@@ -14510,22 +14589,22 @@ function WelcomeBanner({
14510
14589
  const hintsIndent = Math.max(2, Math.floor((cols - hintsRow.length) / 2));
14511
14590
  const startTextRaw = "type a message to start your session";
14512
14591
  const startIndent = Math.max(2, Math.floor((cols - startTextRaw.length) / 2));
14513
- return /* @__PURE__ */ React22.createElement(Box19, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand }, top)), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, "")), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: TONE.brand }, centerInside("\u25C8 REASONIX", BOX_INNER_WIDTH)))), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, "")), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, /* @__PURE__ */ React22.createElement(Text18, { color: FG.sub }, centerInside(tagline, BOX_INNER_WIDTH)))), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, /* @__PURE__ */ React22.createElement(Text18, { color: FG.meta }, centerInside(TAGLINE_SUB, BOX_INNER_WIDTH)))), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, "")), /* @__PURE__ */ React22.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand }, bot)), /* @__PURE__ */ React22.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, " ".repeat(startIndent)), /* @__PURE__ */ React22.createElement(Text18, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ React22.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, " ".repeat(hintsIndent)), HINTS.map((cmd, i) => /* @__PURE__ */ React22.createElement(React22.Fragment, { key: cmd }, /* @__PURE__ */ React22.createElement(Text18, { color: FG.meta }, cmd), i < HINTS.length - 1 && /* @__PURE__ */ React22.createElement(Text18, { color: FG.faint }, " \xB7 ")))), dashboardUrl ? /* @__PURE__ */ React22.createElement(Box19, { marginTop: 1, flexDirection: "row", justifyContent: "center" }, /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand, bold: true }, "\u25B8 web \xB7 "), /* @__PURE__ */ React22.createElement(Text18, { color: TONE.accent }, dashboardUrl)) : null);
14592
+ return /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand }, top)), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, "")), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: TONE.brand }, centerInside("\u25C8 REASONIX", BOX_INNER_WIDTH)))), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, "")), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, /* @__PURE__ */ React23.createElement(Text19, { color: FG.sub }, centerInside(tagline, BOX_INNER_WIDTH)))), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, /* @__PURE__ */ React23.createElement(Text19, { color: FG.meta }, centerInside(TAGLINE_SUB, BOX_INNER_WIDTH)))), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(BoxLine, { pad: BOX_INNER_WIDTH }, "")), /* @__PURE__ */ React23.createElement(BoxRow, { indent: boxIndent }, /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand }, bot)), /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, null, " ".repeat(startIndent)), /* @__PURE__ */ React23.createElement(Text19, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, null, " ".repeat(hintsIndent)), HINTS.map((cmd, i) => /* @__PURE__ */ React23.createElement(React23.Fragment, { key: cmd }, /* @__PURE__ */ React23.createElement(Text19, { color: FG.meta }, cmd), i < HINTS.length - 1 && /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, " \xB7 ")))), dashboardUrl ? /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center" }, /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand, bold: true }, "\u25B8 web \xB7 "), /* @__PURE__ */ React23.createElement(Text19, { color: TONE.accent }, dashboardUrl)) : null);
14514
14593
  }
14515
14594
  function BoxRow({
14516
14595
  indent,
14517
14596
  children
14518
14597
  }) {
14519
- return /* @__PURE__ */ React22.createElement(Box19, null, /* @__PURE__ */ React22.createElement(Text18, null, " ".repeat(indent)), children);
14598
+ return /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text19, null, " ".repeat(indent)), children);
14520
14599
  }
14521
14600
  function BoxLine({
14522
14601
  pad: pad3,
14523
14602
  children
14524
14603
  }) {
14525
14604
  if (children === "" || children === void 0) {
14526
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand }, "\u2551"), /* @__PURE__ */ React22.createElement(Text18, null, " ".repeat(pad3)), /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand }, "\u2551"));
14605
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand }, "\u2551"), /* @__PURE__ */ React23.createElement(Text19, null, " ".repeat(pad3)), /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand }, "\u2551"));
14527
14606
  }
14528
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand }, "\u2551"), children, /* @__PURE__ */ React22.createElement(Text18, { color: TONE.brand }, "\u2551"));
14607
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand }, "\u2551"), children, /* @__PURE__ */ React23.createElement(Text19, { color: TONE.brand }, "\u2551"));
14529
14608
  }
14530
14609
  function centerInside(text, pad3) {
14531
14610
  if (text.length >= pad3) return text.slice(0, pad3);
@@ -14547,12 +14626,12 @@ ${output}`;
14547
14626
  }
14548
14627
 
14549
14628
  // src/cli/ui/cards/PlanCard.tsx
14550
- import { Box as Box22, Text as Text21 } from "ink";
14551
- import React25 from "react";
14629
+ import { Box as Box23, Text as Text22 } from "ink";
14630
+ import React26 from "react";
14552
14631
 
14553
14632
  // src/cli/ui/primitives/BarRow.tsx
14554
- import { Box as Box20, Text as Text19 } from "ink";
14555
- import React23 from "react";
14633
+ import { Box as Box21, Text as Text20 } from "ink";
14634
+ import React24 from "react";
14556
14635
 
14557
14636
  // src/cli/ui/cards/glyphs.ts
14558
14637
  var STRUCT = {
@@ -14572,17 +14651,17 @@ function BarRow({
14572
14651
  children
14573
14652
  }) {
14574
14653
  const t2 = CARD[tone];
14575
- return /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "row" }, /* @__PURE__ */ React23.createElement(Text19, null, " "), /* @__PURE__ */ React23.createElement(Text19, { color: t2.color }, STRUCT.bar), glyph !== void 0 ? /* @__PURE__ */ React23.createElement(Text19, { bold: glyphBold, color: t2.color }, " ", glyph, indent === 3 ? " " : " ") : indent > 0 ? /* @__PURE__ */ React23.createElement(Text19, null, " ".repeat(indent + 1)) : null, children);
14654
+ return /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "row" }, /* @__PURE__ */ React24.createElement(Text20, null, " "), /* @__PURE__ */ React24.createElement(Text20, { color: t2.color }, STRUCT.bar), glyph !== void 0 ? /* @__PURE__ */ React24.createElement(Text20, { bold: glyphBold, color: t2.color }, " ", glyph, indent === 3 ? " " : " ") : indent > 0 ? /* @__PURE__ */ React24.createElement(Text20, null, " ".repeat(indent + 1)) : null, children);
14576
14655
  }
14577
14656
  function CursorBlock() {
14578
14657
  const tick = useTick();
14579
14658
  const on = Math.floor(tick / 4) % 2 === 0;
14580
- return /* @__PURE__ */ React23.createElement(Text19, { inverse: on, color: CARD.streaming.color }, " ");
14659
+ return /* @__PURE__ */ React24.createElement(Text20, { inverse: on, color: CARD.streaming.color }, " ");
14581
14660
  }
14582
14661
 
14583
14662
  // src/cli/ui/cards/CardHeader.tsx
14584
- import { Box as Box21, Text as Text20 } from "ink";
14585
- import React24 from "react";
14663
+ import { Box as Box22, Text as Text21 } from "ink";
14664
+ import React25 from "react";
14586
14665
  function CardHeader({
14587
14666
  tone,
14588
14667
  glyph,
@@ -14596,7 +14675,7 @@ function CardHeader({
14596
14675
  }) {
14597
14676
  const t2 = CARD[tone];
14598
14677
  const bar2 = barColor ?? t2.color;
14599
- return /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "row" }, /* @__PURE__ */ React24.createElement(Text20, null, " "), /* @__PURE__ */ React24.createElement(Text20, { color: bar2 }, STRUCT.bar), /* @__PURE__ */ React24.createElement(Text20, null, " "), /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: t2.color }, glyph), /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: titleColor ?? FG.strong }, ` ${title}`), inline2 && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(Text20, null, " "), inline2), subtitle && /* @__PURE__ */ React24.createElement(Text20, { color: FG.sub }, ` ${subtitle}`), /* @__PURE__ */ React24.createElement(Box21, { flexGrow: 1 }), meta && /* @__PURE__ */ React24.createElement(Text20, { color: FG.faint }, meta), trailing && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(Text20, null, " "), trailing));
14678
+ return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "row" }, /* @__PURE__ */ React25.createElement(Text21, null, " "), /* @__PURE__ */ React25.createElement(Text21, { color: bar2 }, STRUCT.bar), /* @__PURE__ */ React25.createElement(Text21, null, " "), /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: t2.color }, glyph), /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: titleColor ?? FG.strong }, ` ${title}`), inline2 && /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Text21, null, " "), inline2), subtitle && /* @__PURE__ */ React25.createElement(Text21, { color: FG.sub }, ` ${subtitle}`), /* @__PURE__ */ React25.createElement(Box22, { flexGrow: 1 }), meta && /* @__PURE__ */ React25.createElement(Text21, { color: FG.faint }, meta), trailing && /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Text21, null, " "), trailing));
14600
14679
  }
14601
14680
 
14602
14681
  // src/cli/ui/cards/PlanCard.tsx
@@ -14622,11 +14701,11 @@ function PlanCard({ card }) {
14622
14701
  const variantTag = card.variant === "resumed" ? " \xB7 resumed" : card.variant === "replay" ? " \xB7 \u23EA archive" : "";
14623
14702
  const meta = `${variantTag} \xB7 ${doneCount} of ${card.steps.length} done`;
14624
14703
  const showFooter = card.variant === "active";
14625
- return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column" }, /* @__PURE__ */ React25.createElement(CardHeader, { tone: "plan", glyph: "\u229E", title: card.title, meta }), /* @__PURE__ */ React25.createElement(BarRow, { tone: "plan", indent: 0 }), card.steps.map((step, i) => {
14704
+ return /* @__PURE__ */ React26.createElement(Box23, { flexDirection: "column" }, /* @__PURE__ */ React26.createElement(CardHeader, { tone: "plan", glyph: "\u229E", title: card.title, meta }), /* @__PURE__ */ React26.createElement(BarRow, { tone: "plan", indent: 0 }), card.steps.map((step, i) => {
14626
14705
  const isActive = step.status === "running";
14627
14706
  const titleColor = isActive ? FG.strong : step.status === "queued" ? FG.sub : FG.sub;
14628
- return /* @__PURE__ */ React25.createElement(BarRow, { key: step.id, tone: "plan" }, /* @__PURE__ */ React25.createElement(Text21, { color: STATUS_COLOR[step.status] }, `[${STATUS_GLYPH[step.status]}]`), /* @__PURE__ */ React25.createElement(Text21, { bold: isActive, color: titleColor }, ` ${i + 1}. ${step.title}`), isActive && /* @__PURE__ */ React25.createElement(Text21, { color: TONE.brand }, " \u2190 in progress"));
14629
- }), showFooter && /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(BarRow, { tone: "plan", indent: 0 }), /* @__PURE__ */ React25.createElement(BarRow, { tone: "plan" }, /* @__PURE__ */ React25.createElement(Text21, { color: FG.meta }, ACTIVE_PLAN_FOOTER))));
14707
+ return /* @__PURE__ */ React26.createElement(BarRow, { key: step.id, tone: "plan" }, /* @__PURE__ */ React26.createElement(Text22, { color: STATUS_COLOR[step.status] }, `[${STATUS_GLYPH[step.status]}]`), /* @__PURE__ */ React26.createElement(Text22, { bold: isActive, color: titleColor }, ` ${i + 1}. ${step.title}`), isActive && /* @__PURE__ */ React26.createElement(Text22, { color: TONE.brand }, " \u2190 in progress"));
14708
+ }), showFooter && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(BarRow, { tone: "plan", indent: 0 }), /* @__PURE__ */ React26.createElement(BarRow, { tone: "plan" }, /* @__PURE__ */ React26.createElement(Text22, { color: FG.meta }, ACTIVE_PLAN_FOOTER))));
14630
14709
  }
14631
14710
 
14632
14711
  // src/cli/ui/edit-history.ts
@@ -15069,7 +15148,7 @@ function useAgentSession({
15069
15148
  import { useMemo as useMemo3 } from "react";
15070
15149
 
15071
15150
  // src/cli/ui/state/provider.tsx
15072
- import React26 from "react";
15151
+ import React27 from "react";
15073
15152
 
15074
15153
  // src/cli/ui/state/reducer.ts
15075
15154
  function reduce(state, event) {
@@ -15408,26 +15487,26 @@ function createStore(session, initialCards) {
15408
15487
  }
15409
15488
 
15410
15489
  // src/cli/ui/state/provider.tsx
15411
- var StoreCtx = React26.createContext(null);
15490
+ var StoreCtx = React27.createContext(null);
15412
15491
  function AgentStoreProvider({
15413
15492
  session,
15414
15493
  initialCards,
15415
15494
  children
15416
15495
  }) {
15417
- const initialCardsRef = React26.useRef(initialCards);
15418
- const store = React26.useMemo(() => createStore(session, initialCardsRef.current), [session]);
15419
- return /* @__PURE__ */ React26.createElement(StoreCtx.Provider, { value: store }, children);
15496
+ const initialCardsRef = React27.useRef(initialCards);
15497
+ const store = React27.useMemo(() => createStore(session, initialCardsRef.current), [session]);
15498
+ return /* @__PURE__ */ React27.createElement(StoreCtx.Provider, { value: store }, children);
15420
15499
  }
15421
15500
  function useAgentStore() {
15422
- const store = React26.useContext(StoreCtx);
15501
+ const store = React27.useContext(StoreCtx);
15423
15502
  if (!store) throw new Error("useAgentStore must be used inside AgentStoreProvider");
15424
15503
  return store;
15425
15504
  }
15426
15505
  function useAgentState(selector) {
15427
15506
  const store = useAgentStore();
15428
- const subscribe = React26.useCallback((cb) => store.subscribe(cb), [store]);
15429
- const getSnapshot = React26.useCallback(() => selector(store.getState()), [store, selector]);
15430
- return React26.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
15507
+ const subscribe = React27.useCallback((cb) => store.subscribe(cb), [store]);
15508
+ const getSnapshot = React27.useCallback(() => selector(store.getState()), [store, selector]);
15509
+ return React27.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
15431
15510
  }
15432
15511
  function useDispatch() {
15433
15512
  return useAgentStore().dispatch;
@@ -15679,22 +15758,22 @@ function useSyntheticSubmit(deps) {
15679
15758
 
15680
15759
  // src/cli/ui/layout/CardStream.tsx
15681
15760
  import { Static } from "ink";
15682
- import React46 from "react";
15761
+ import React47 from "react";
15683
15762
 
15684
15763
  // src/cli/ui/cards/CardRenderer.tsx
15685
- import { Box as Box40, Text as Text40 } from "ink";
15686
- import React45 from "react";
15764
+ import { Box as Box41, Text as Text41 } from "ink";
15765
+ import React46 from "react";
15687
15766
 
15688
15767
  // src/cli/ui/cards/BranchCard.tsx
15689
- import { Text as Text22 } from "ink";
15690
- import { Box as Box23 } from "ink";
15691
- import React27 from "react";
15768
+ import { Text as Text23 } from "ink";
15769
+ import { Box as Box24 } from "ink";
15770
+ import React28 from "react";
15692
15771
  var BAR_CELLS = 28;
15693
15772
  function BranchCard({ card }) {
15694
15773
  const ratio = card.total > 0 ? card.completed / card.total : 0;
15695
15774
  const filled = Math.max(0, Math.min(BAR_CELLS, Math.round(ratio * BAR_CELLS)));
15696
15775
  const tone = card.done ? TONE.ok : CARD.streaming.color;
15697
- return /* @__PURE__ */ React27.createElement(Box23, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(
15776
+ return /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React28.createElement(
15698
15777
  CardHeader,
15699
15778
  {
15700
15779
  tone: "streaming",
@@ -15703,27 +15782,27 @@ function BranchCard({ card }) {
15703
15782
  meta: `\xB7 ${card.completed} of ${card.total} samples`,
15704
15783
  barColor: tone
15705
15784
  }
15706
- ), /* @__PURE__ */ React27.createElement(BarRow, { tone: "streaming", indent: 0 }), /* @__PURE__ */ React27.createElement(BarRow, { tone: "streaming" }, /* @__PURE__ */ React27.createElement(Text22, { color: tone }, "\u2588".repeat(filled)), /* @__PURE__ */ React27.createElement(Text22, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ React27.createElement(Text22, { color: FG.faint }, ` ${(ratio * 100).toFixed(0)}%`)), !card.done && card.completed > 0 && /* @__PURE__ */ React27.createElement(BarRow, { tone: "streaming" }, /* @__PURE__ */ React27.createElement(Text22, { color: FG.faint }, `latest: #${card.latestIndex} \xB7 T=${card.latestTemperature.toFixed(2)} \xB7 ${card.latestUncertainties} unc`)));
15785
+ ), /* @__PURE__ */ React28.createElement(BarRow, { tone: "streaming", indent: 0 }), /* @__PURE__ */ React28.createElement(BarRow, { tone: "streaming" }, /* @__PURE__ */ React28.createElement(Text23, { color: tone }, "\u2588".repeat(filled)), /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, ` ${(ratio * 100).toFixed(0)}%`)), !card.done && card.completed > 0 && /* @__PURE__ */ React28.createElement(BarRow, { tone: "streaming" }, /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, `latest: #${card.latestIndex} \xB7 T=${card.latestTemperature.toFixed(2)} \xB7 ${card.latestUncertainties} unc`)));
15707
15786
  }
15708
15787
 
15709
15788
  // src/cli/ui/cards/CtxCard.tsx
15710
- import { Box as Box24, Text as Text23 } from "ink";
15711
- import React28 from "react";
15789
+ import { Box as Box25, Text as Text24 } from "ink";
15790
+ import React29 from "react";
15712
15791
  var BAR_CELLS2 = 32;
15713
15792
  function row2(label, tokens, ratio, color2) {
15714
15793
  const filled = Math.max(0, Math.min(BAR_CELLS2, Math.round(ratio * BAR_CELLS2)));
15715
- return /* @__PURE__ */ React28.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React28.createElement(Text23, { color: FG.sub }, label.padEnd(8)), /* @__PURE__ */ React28.createElement(Text23, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, "\u2591".repeat(BAR_CELLS2 - filled)), /* @__PURE__ */ React28.createElement(Text23, { bold: true, color: FG.body }, ` ${tokens.toLocaleString()}`), /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, ` ${(ratio * 100).toFixed(1)}%`));
15794
+ return /* @__PURE__ */ React29.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React29.createElement(Text24, { color: FG.sub }, label.padEnd(8)), /* @__PURE__ */ React29.createElement(Text24, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, "\u2591".repeat(BAR_CELLS2 - filled)), /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: FG.body }, ` ${tokens.toLocaleString()}`), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, ` ${(ratio * 100).toFixed(1)}%`));
15716
15795
  }
15717
15796
  function CtxCard({ card }) {
15718
15797
  const cap = Math.max(1, card.ctxMax);
15719
15798
  const used = card.systemTokens + card.toolsTokens + card.logTokens + card.inputTokens;
15720
15799
  const usedPct = used / cap * 100;
15721
- return /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "row" }, /* @__PURE__ */ React28.createElement(Text23, null, " "), /* @__PURE__ */ React28.createElement(Text23, { bold: true, color: CARD.usage.color }, "\u2318 Context window"), /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, ` \xB7 ${used.toLocaleString()} / ${cap.toLocaleString()} (${usedPct.toFixed(1)}%)`)), /* @__PURE__ */ React28.createElement(BarRow, { tone: "usage", indent: 0 }), row2("system", card.systemTokens, card.systemTokens / cap, TONE.brand), row2("tools", card.toolsTokens, card.toolsTokens / cap, TONE.warn), row2("log", card.logTokens, card.logTokens / cap, TONE.ok), row2("input", card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React28.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, `top tools (${card.toolsCount} total \xB7 ${card.logMessages} log msgs):`)), card.topTools.slice(0, 5).map((t2) => /* @__PURE__ */ React28.createElement(BarRow, { key: `${t2.turn}-${t2.name}`, tone: "usage" }, /* @__PURE__ */ React28.createElement(Text23, { color: FG.sub }, ` ${t2.name}`), /* @__PURE__ */ React28.createElement(Text23, { color: FG.faint }, ` \xB7 turn ${t2.turn} \xB7 ${t2.tokens.toLocaleString()}`)))));
15800
+ return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "row" }, /* @__PURE__ */ React29.createElement(Text24, null, " "), /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: CARD.usage.color }, "\u2318 Context window"), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, ` \xB7 ${used.toLocaleString()} / ${cap.toLocaleString()} (${usedPct.toFixed(1)}%)`)), /* @__PURE__ */ React29.createElement(BarRow, { tone: "usage", indent: 0 }), row2("system", card.systemTokens, card.systemTokens / cap, TONE.brand), row2("tools", card.toolsTokens, card.toolsTokens / cap, TONE.warn), row2("log", card.logTokens, card.logTokens / cap, TONE.ok), row2("input", card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 && /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React29.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, `top tools (${card.toolsCount} total \xB7 ${card.logMessages} log msgs):`)), card.topTools.slice(0, 5).map((t2) => /* @__PURE__ */ React29.createElement(BarRow, { key: `${t2.turn}-${t2.name}`, tone: "usage" }, /* @__PURE__ */ React29.createElement(Text24, { color: FG.sub }, ` ${t2.name}`), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, ` \xB7 turn ${t2.turn} \xB7 ${t2.tokens.toLocaleString()}`)))));
15722
15801
  }
15723
15802
 
15724
15803
  // src/cli/ui/cards/DiffCard.tsx
15725
- import { Box as Box25, Text as Text24 } from "ink";
15726
- import React29 from "react";
15804
+ import { Box as Box26, Text as Text25 } from "ink";
15805
+ import React30 from "react";
15727
15806
  var LINE_COLOR = {
15728
15807
  ctx: FG.sub,
15729
15808
  add: TONE.ok,
@@ -15731,14 +15810,14 @@ var LINE_COLOR = {
15731
15810
  fold: FG.faint
15732
15811
  };
15733
15812
  function DiffCard({ card }) {
15734
- const meta = /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(Text24, { color: TONE.ok }, `+${card.stats.add}`), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, " / "), /* @__PURE__ */ React29.createElement(Text24, { color: TONE.err }, `-${card.stats.del}`));
15813
+ const meta = /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(Text25, { color: TONE.ok }, `+${card.stats.add}`), /* @__PURE__ */ React30.createElement(Text25, { color: FG.faint }, " / "), /* @__PURE__ */ React30.createElement(Text25, { color: TONE.err }, `-${card.stats.del}`));
15735
15814
  const showFooter = card.hunks.length > 0;
15736
- return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(CardHeader, { tone: "diff", glyph: "\xB1", title: "Edit", subtitle: card.file, trailing: meta }), card.hunks.map((hunk) => /* @__PURE__ */ React29.createElement(Box25, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ React29.createElement(BarRow, { tone: "diff", indent: 0 }), /* @__PURE__ */ React29.createElement(BarRow, { tone: "diff" }, /* @__PURE__ */ React29.createElement(Text24, { italic: true, color: FG.faint }, hunk.header)), hunk.lines.map((line, li) => /* @__PURE__ */ React29.createElement(BarRow, { key: `${card.id}:${hunk.header}:${li}`, tone: "diff" }, /* @__PURE__ */ React29.createElement(Text24, { color: LINE_COLOR[line.kind] }, line.text))))), showFooter && /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(BarRow, { tone: "diff", indent: 0 }), /* @__PURE__ */ React29.createElement(BarRow, { tone: "diff" }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: TONE.ok }, "[a] apply"), /* @__PURE__ */ React29.createElement(Text24, { color: FG.sub }, " [s] skip "), /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: TONE.err }, "[r] reject"))));
15815
+ return /* @__PURE__ */ React30.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(CardHeader, { tone: "diff", glyph: "\xB1", title: "Edit", subtitle: card.file, trailing: meta }), card.hunks.map((hunk) => /* @__PURE__ */ React30.createElement(Box26, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ React30.createElement(BarRow, { tone: "diff", indent: 0 }), /* @__PURE__ */ React30.createElement(BarRow, { tone: "diff" }, /* @__PURE__ */ React30.createElement(Text25, { italic: true, color: FG.faint }, hunk.header)), hunk.lines.map((line, li) => /* @__PURE__ */ React30.createElement(BarRow, { key: `${card.id}:${hunk.header}:${li}`, tone: "diff" }, /* @__PURE__ */ React30.createElement(Text25, { color: LINE_COLOR[line.kind] }, line.text))))), showFooter && /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(BarRow, { tone: "diff", indent: 0 }), /* @__PURE__ */ React30.createElement(BarRow, { tone: "diff" }, /* @__PURE__ */ React30.createElement(Text25, { bold: true, color: TONE.ok }, "[a] apply"), /* @__PURE__ */ React30.createElement(Text25, { color: FG.sub }, " [s] skip "), /* @__PURE__ */ React30.createElement(Text25, { bold: true, color: TONE.err }, "[r] reject"))));
15737
15816
  }
15738
15817
 
15739
15818
  // src/cli/ui/cards/DoctorCard.tsx
15740
- import { Box as Box26, Text as Text25 } from "ink";
15741
- import React30 from "react";
15819
+ import { Box as Box27, Text as Text26 } from "ink";
15820
+ import React31 from "react";
15742
15821
  var LEVEL_COLOR = {
15743
15822
  ok: TONE.ok,
15744
15823
  warn: TONE.warn,
@@ -15760,12 +15839,12 @@ function DoctorCard({ card }) {
15760
15839
  const fail = card.checks.filter((c) => c.level === "fail").length;
15761
15840
  const summary = `${card.checks.length} checks \xB7 ${ok} passed${warn > 0 ? ` \xB7 ${warn} warn` : ""}${fail > 0 ? ` \xB7 ${fail} fail` : ""}`;
15762
15841
  const labelWidth = card.checks.reduce((m, c) => Math.max(m, c.label.length), 0);
15763
- return /* @__PURE__ */ React30.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(CardHeader, { tone: "tool", glyph: "\u2695", title: "Doctor", meta: summary, barColor: CARD.tool.color }), /* @__PURE__ */ React30.createElement(BarRow, { tone: "tool", indent: 0 }), card.checks.map((c) => /* @__PURE__ */ React30.createElement(BarRow, { key: c.label, tone: "tool" }, /* @__PURE__ */ React30.createElement(Text25, { color: LEVEL_COLOR[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ React30.createElement(Text25, { bold: true, color: FG.body }, ` ${c.label.padEnd(labelWidth + 1)}`), /* @__PURE__ */ React30.createElement(Text25, { color: FG.sub }, c.detail), /* @__PURE__ */ React30.createElement(Text25, { color: LEVEL_COLOR[c.level] }, ` ${LEVEL_TAG[c.level]}`))));
15842
+ return /* @__PURE__ */ React31.createElement(Box27, { flexDirection: "column" }, /* @__PURE__ */ React31.createElement(CardHeader, { tone: "tool", glyph: "\u2695", title: "Doctor", meta: summary, barColor: CARD.tool.color }), /* @__PURE__ */ React31.createElement(BarRow, { tone: "tool", indent: 0 }), card.checks.map((c) => /* @__PURE__ */ React31.createElement(BarRow, { key: c.label, tone: "tool" }, /* @__PURE__ */ React31.createElement(Text26, { color: LEVEL_COLOR[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ React31.createElement(Text26, { bold: true, color: FG.body }, ` ${c.label.padEnd(labelWidth + 1)}`), /* @__PURE__ */ React31.createElement(Text26, { color: FG.sub }, c.detail), /* @__PURE__ */ React31.createElement(Text26, { color: LEVEL_COLOR[c.level] }, ` ${LEVEL_TAG[c.level]}`))));
15764
15843
  }
15765
15844
 
15766
15845
  // src/cli/ui/cards/ErrorCard.tsx
15767
- import { Box as Box27, Text as Text26 } from "ink";
15768
- import React31 from "react";
15846
+ import { Box as Box28, Text as Text27 } from "ink";
15847
+ import React32 from "react";
15769
15848
  var STACK_TAIL = 5;
15770
15849
  function ErrorCard({ card }) {
15771
15850
  const meta = card.retries !== void 0 && card.retries > 0 ? `\xB7 ${card.retries} retr${card.retries === 1 ? "y" : "ies"}` : void 0;
@@ -15774,16 +15853,16 @@ function ErrorCard({ card }) {
15774
15853
  const stackVisible = stackTrunc ? stackLines.slice(-STACK_TAIL) : stackLines;
15775
15854
  const stackHidden = stackTrunc ? stackLines.length - stackVisible.length : 0;
15776
15855
  const hasStack = stackVisible.length > 0;
15777
- return /* @__PURE__ */ React31.createElement(Box27, { flexDirection: "column" }, /* @__PURE__ */ React31.createElement(CardHeader, { tone: "error", glyph: "\u2716", title: "Error", subtitle: card.title, meta }), /* @__PURE__ */ React31.createElement(BarRow, { tone: "error", indent: 0 }), card.message.split("\n").map((line, i) => /* @__PURE__ */ React31.createElement(BarRow, { key: `${card.id}:msg:${i}`, tone: "error" }, /* @__PURE__ */ React31.createElement(Text26, { color: CARD.error.color }, line))), hasStack && /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(BarRow, { tone: "error", indent: 0 }), /* @__PURE__ */ React31.createElement(BarRow, { tone: "error" }, /* @__PURE__ */ React31.createElement(Text26, { color: FG.meta }, "stack trace")), stackHidden > 0 && /* @__PURE__ */ React31.createElement(BarRow, { tone: "error" }, /* @__PURE__ */ React31.createElement(Text26, { color: FG.faint }, `\u22EE ${stackHidden} earlier stack line${stackHidden === 1 ? "" : "s"} hidden`)), stackVisible.map((line, i) => /* @__PURE__ */ React31.createElement(BarRow, { key: `${card.id}:stk:${stackHidden + i}`, tone: "error" }, /* @__PURE__ */ React31.createElement(Text26, { color: FG.meta }, line)))), /* @__PURE__ */ React31.createElement(BarRow, { tone: "error", indent: 0 }), /* @__PURE__ */ React31.createElement(BarRow, { tone: "error" }, /* @__PURE__ */ React31.createElement(Text26, { bold: true, color: TONE.err }, "[r] retry"), /* @__PURE__ */ React31.createElement(Text26, { color: FG.sub }, " [s] skip")));
15856
+ return /* @__PURE__ */ React32.createElement(Box28, { flexDirection: "column" }, /* @__PURE__ */ React32.createElement(CardHeader, { tone: "error", glyph: "\u2716", title: "Error", subtitle: card.title, meta }), /* @__PURE__ */ React32.createElement(BarRow, { tone: "error", indent: 0 }), card.message.split("\n").map((line, i) => /* @__PURE__ */ React32.createElement(BarRow, { key: `${card.id}:msg:${i}`, tone: "error" }, /* @__PURE__ */ React32.createElement(Text27, { color: CARD.error.color }, line))), hasStack && /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(BarRow, { tone: "error", indent: 0 }), /* @__PURE__ */ React32.createElement(BarRow, { tone: "error" }, /* @__PURE__ */ React32.createElement(Text27, { color: FG.meta }, "stack trace")), stackHidden > 0 && /* @__PURE__ */ React32.createElement(BarRow, { tone: "error" }, /* @__PURE__ */ React32.createElement(Text27, { color: FG.faint }, `\u22EE ${stackHidden} earlier stack line${stackHidden === 1 ? "" : "s"} hidden`)), stackVisible.map((line, i) => /* @__PURE__ */ React32.createElement(BarRow, { key: `${card.id}:stk:${stackHidden + i}`, tone: "error" }, /* @__PURE__ */ React32.createElement(Text27, { color: FG.meta }, line)))), /* @__PURE__ */ React32.createElement(BarRow, { tone: "error", indent: 0 }), /* @__PURE__ */ React32.createElement(BarRow, { tone: "error" }, /* @__PURE__ */ React32.createElement(Text27, { bold: true, color: TONE.err }, "[r] retry"), /* @__PURE__ */ React32.createElement(Text27, { color: FG.sub }, " [s] skip")));
15778
15857
  }
15779
15858
 
15780
15859
  // src/cli/ui/cards/LiveCard.tsx
15781
- import { Box as Box28, Text as Text28 } from "ink";
15782
- import React33 from "react";
15860
+ import { Box as Box29, Text as Text29 } from "ink";
15861
+ import React34 from "react";
15783
15862
 
15784
15863
  // src/cli/ui/primitives/Spinner.tsx
15785
- import { Text as Text27 } from "ink";
15786
- import React32 from "react";
15864
+ import { Text as Text28 } from "ink";
15865
+ import React33 from "react";
15787
15866
  var FRAMES = {
15788
15867
  circle: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
15789
15868
  braille: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827"]
@@ -15794,12 +15873,12 @@ var CADENCE_MS = {
15794
15873
  };
15795
15874
  function Spinner({ kind = "circle", color: color2, bold }) {
15796
15875
  const frames = FRAMES[kind];
15797
- const [frame, setFrame] = React32.useState(0);
15798
- React32.useEffect(() => {
15876
+ const [frame, setFrame] = React33.useState(0);
15877
+ React33.useEffect(() => {
15799
15878
  const id = setInterval(() => setFrame((f) => (f + 1) % frames.length), CADENCE_MS[kind]);
15800
15879
  return () => clearInterval(id);
15801
15880
  }, [kind, frames.length]);
15802
- return /* @__PURE__ */ React32.createElement(Text27, { bold, color: color2 }, frames[frame]);
15881
+ return /* @__PURE__ */ React33.createElement(Text28, { bold, color: color2 }, frames[frame]);
15803
15882
  }
15804
15883
 
15805
15884
  // src/cli/ui/cards/LiveCard.tsx
@@ -15826,12 +15905,12 @@ var VARIANT_GLYPH = {
15826
15905
  function LiveCard({ card }) {
15827
15906
  const color2 = TONE_TO_COLOR[card.tone];
15828
15907
  const glyph = VARIANT_GLYPH[card.variant];
15829
- return /* @__PURE__ */ React33.createElement(Box28, { flexDirection: "row" }, /* @__PURE__ */ React33.createElement(Text28, null, " "), card.variant === "thinking" ? /* @__PURE__ */ React33.createElement(Spinner, { kind: "circle", color: color2, bold: true }) : /* @__PURE__ */ React33.createElement(Text28, { bold: true, color: color2 }, glyph), /* @__PURE__ */ React33.createElement(Text28, { color: FG.body }, ` ${card.text}`), card.meta !== void 0 && /* @__PURE__ */ React33.createElement(Text28, { color: FG.faint }, ` ${card.meta}`));
15908
+ return /* @__PURE__ */ React34.createElement(Box29, { flexDirection: "row" }, /* @__PURE__ */ React34.createElement(Text29, null, " "), card.variant === "thinking" ? /* @__PURE__ */ React34.createElement(Spinner, { kind: "circle", color: color2, bold: true }) : /* @__PURE__ */ React34.createElement(Text29, { bold: true, color: color2 }, glyph), /* @__PURE__ */ React34.createElement(Text29, { color: FG.body }, ` ${card.text}`), card.meta !== void 0 && /* @__PURE__ */ React34.createElement(Text29, { color: FG.faint }, ` ${card.meta}`));
15830
15909
  }
15831
15910
 
15832
15911
  // src/cli/ui/cards/MemoryCard.tsx
15833
- import { Box as Box29, Text as Text29 } from "ink";
15834
- import React34 from "react";
15912
+ import { Box as Box30, Text as Text30 } from "ink";
15913
+ import React35 from "react";
15835
15914
  var CATEGORY_ORDER = [
15836
15915
  "user",
15837
15916
  "feedback",
@@ -15860,7 +15939,7 @@ function MemoryCard({ card }) {
15860
15939
  const counts = countByCategory(card.entries);
15861
15940
  const summary = CATEGORY_ORDER.filter((c) => counts[c] > 0).map((c) => `${counts[c]} ${c}`).join(" \xB7 ");
15862
15941
  const tokens = card.tokens > 1024 ? `~${(card.tokens / 1024).toFixed(1)}K tok` : `~${card.tokens} tok`;
15863
- return /* @__PURE__ */ React34.createElement(Box29, { flexDirection: "column" }, /* @__PURE__ */ React34.createElement(
15942
+ return /* @__PURE__ */ React35.createElement(Box30, { flexDirection: "column" }, /* @__PURE__ */ React35.createElement(
15864
15943
  CardHeader,
15865
15944
  {
15866
15945
  tone: "memory",
@@ -15874,7 +15953,7 @@ function MemoryCard({ card }) {
15874
15953
  const all = card.entries.filter((e) => e.category === category);
15875
15954
  const shown = all.slice(0, 5);
15876
15955
  const remaining = all.length - shown.length;
15877
- return /* @__PURE__ */ React34.createElement(Box29, { key: category, flexDirection: "column" }, /* @__PURE__ */ React34.createElement(BarRow, { tone: "memory", indent: 0 }), /* @__PURE__ */ React34.createElement(BarRow, { tone: "memory" }, /* @__PURE__ */ React34.createElement(Text29, { color: FG.faint }, CATEGORY_LABEL[category], " (", counts[category], ")")), shown.map((entry) => /* @__PURE__ */ React34.createElement(BarRow, { key: `${category}:${entry.summary}`, tone: "memory" }, /* @__PURE__ */ React34.createElement(Text29, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category], " "), /* @__PURE__ */ React34.createElement(Text29, { color: FG.sub }, entry.summary))), remaining > 0 && /* @__PURE__ */ React34.createElement(BarRow, { tone: "memory" }, /* @__PURE__ */ React34.createElement(Text29, { color: FG.faint }, `\u22EE +${remaining} more`)));
15956
+ return /* @__PURE__ */ React35.createElement(Box30, { key: category, flexDirection: "column" }, /* @__PURE__ */ React35.createElement(BarRow, { tone: "memory", indent: 0 }), /* @__PURE__ */ React35.createElement(BarRow, { tone: "memory" }, /* @__PURE__ */ React35.createElement(Text30, { color: FG.faint }, CATEGORY_LABEL[category], " (", counts[category], ")")), shown.map((entry) => /* @__PURE__ */ React35.createElement(BarRow, { key: `${category}:${entry.summary}`, tone: "memory" }, /* @__PURE__ */ React35.createElement(Text30, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category], " "), /* @__PURE__ */ React35.createElement(Text30, { color: FG.sub }, entry.summary))), remaining > 0 && /* @__PURE__ */ React35.createElement(BarRow, { tone: "memory" }, /* @__PURE__ */ React35.createElement(Text30, { color: FG.faint }, `\u22EE +${remaining} more`)));
15878
15957
  }));
15879
15958
  }
15880
15959
  function countByCategory(entries) {
@@ -15889,8 +15968,8 @@ function countByCategory(entries) {
15889
15968
  }
15890
15969
 
15891
15970
  // src/cli/ui/cards/ReasoningCard.tsx
15892
- import { Box as Box30, Text as Text30, useStdout as useStdout7 } from "ink";
15893
- import React35 from "react";
15971
+ import { Box as Box31, Text as Text31, useStdout as useStdout7 } from "ink";
15972
+ import React36 from "react";
15894
15973
 
15895
15974
  // src/frame/width.ts
15896
15975
  import stringWidthLib from "string-width";
@@ -15939,19 +16018,19 @@ function ReasoningCard({
15939
16018
  const visible = overflows ? allLines.slice(-lineSlots) : allLines;
15940
16019
  const headDropped = overflows ? allLines.length - visible.length : 0;
15941
16020
  const showBody = expanded && allLines.length > 0;
15942
- return /* @__PURE__ */ React35.createElement(Box30, { flexDirection: "column" }, /* @__PURE__ */ React35.createElement(CardHeader, { tone: "reasoning", glyph: "\u25C6", title: "Reasoning", meta: `\xB7 ${meta}` }), showBody && /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(BarRow, { tone: "reasoning", indent: 0 }), headDropped > 0 && /* @__PURE__ */ React35.createElement(BarRow, { tone: "reasoning" }, /* @__PURE__ */ React35.createElement(Text30, { color: FG.faint }, card.streaming ? `\u2026 ${headDropped} earlier line${headDropped === 1 ? "" : "s"} (will appear in scrollback)` : `\u22EE ${headDropped} earlier line${headDropped === 1 ? "" : "s"}`)), visible.map((line, i) => {
16021
+ return /* @__PURE__ */ React36.createElement(Box31, { flexDirection: "column" }, /* @__PURE__ */ React36.createElement(CardHeader, { tone: "reasoning", glyph: "\u25C6", title: "Reasoning", meta: `\xB7 ${meta}` }), showBody && /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(BarRow, { tone: "reasoning", indent: 0 }), headDropped > 0 && /* @__PURE__ */ React36.createElement(BarRow, { tone: "reasoning" }, /* @__PURE__ */ React36.createElement(Text31, { color: FG.faint }, card.streaming ? `\u2026 ${headDropped} earlier line${headDropped === 1 ? "" : "s"} (will appear in scrollback)` : `\u22EE ${headDropped} earlier line${headDropped === 1 ? "" : "s"}`)), visible.map((line, i) => {
15943
16022
  const isLast = i === visible.length - 1;
15944
- return /* @__PURE__ */ React35.createElement(BarRow, { key: `${card.id}:${headDropped + i}`, tone: "reasoning" }, /* @__PURE__ */ React35.createElement(Text30, { italic: true, color: FG.meta }, clipToCells(line, lineCells)), isLast && card.streaming && /* @__PURE__ */ React35.createElement(CursorBlock, null));
16023
+ return /* @__PURE__ */ React36.createElement(BarRow, { key: `${card.id}:${headDropped + i}`, tone: "reasoning" }, /* @__PURE__ */ React36.createElement(Text31, { italic: true, color: FG.meta }, clipToCells(line, lineCells)), isLast && card.streaming && /* @__PURE__ */ React36.createElement(CursorBlock, null));
15945
16024
  })));
15946
16025
  }
15947
16026
 
15948
16027
  // src/cli/ui/cards/SearchCard.tsx
15949
- import { Box as Box31, Text as Text31 } from "ink";
15950
- import React36 from "react";
16028
+ import { Box as Box32, Text as Text32 } from "ink";
16029
+ import React37 from "react";
15951
16030
  function SearchCard({ card }) {
15952
16031
  const fileCount = new Set(card.hits.map((h) => h.file)).size;
15953
16032
  const meta = `${card.hits.length} hit${card.hits.length === 1 ? "" : "s"} in ${fileCount} file${fileCount === 1 ? "" : "s"} \xB7 ${(card.elapsedMs / 1e3).toFixed(2)}s`;
15954
- return /* @__PURE__ */ React36.createElement(Box31, { flexDirection: "column" }, /* @__PURE__ */ React36.createElement(CardHeader, { tone: "search", glyph: "\u2299", title: "Search", subtitle: `"${card.query}"`, meta }), card.hits.length > 0 && /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(BarRow, { tone: "search", indent: 0 }), groupByFile(card.hits.slice(0, 10)).map(([file, hits]) => /* @__PURE__ */ React36.createElement(Box31, { key: file, flexDirection: "column" }, /* @__PURE__ */ React36.createElement(BarRow, { tone: "search" }, /* @__PURE__ */ React36.createElement(Text31, { bold: true, color: FG.strong }, file)), hits.map((h, i) => /* @__PURE__ */ React36.createElement(BarRow, { key: `${file}:${h.line}:${i}`, tone: "search" }, /* @__PURE__ */ React36.createElement(Text31, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502 `), /* @__PURE__ */ React36.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 && /* @__PURE__ */ React36.createElement(BarRow, { tone: "search" }, /* @__PURE__ */ React36.createElement(Text31, { color: FG.faint }, `\u22EE +${card.hits.length - 10} more hits`))));
16033
+ return /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, /* @__PURE__ */ React37.createElement(CardHeader, { tone: "search", glyph: "\u2299", title: "Search", subtitle: `"${card.query}"`, meta }), card.hits.length > 0 && /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement(BarRow, { tone: "search", indent: 0 }), groupByFile(card.hits.slice(0, 10)).map(([file, hits]) => /* @__PURE__ */ React37.createElement(Box32, { key: file, flexDirection: "column" }, /* @__PURE__ */ React37.createElement(BarRow, { tone: "search" }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: FG.strong }, file)), hits.map((h, i) => /* @__PURE__ */ React37.createElement(BarRow, { key: `${file}:${h.line}:${i}`, tone: "search" }, /* @__PURE__ */ React37.createElement(Text32, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502 `), /* @__PURE__ */ React37.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 && /* @__PURE__ */ React37.createElement(BarRow, { tone: "search" }, /* @__PURE__ */ React37.createElement(Text32, { color: FG.faint }, `\u22EE +${card.hits.length - 10} more hits`))));
15955
16034
  }
15956
16035
  function HighlightedLine({
15957
16036
  text,
@@ -15959,9 +16038,9 @@ function HighlightedLine({
15959
16038
  end
15960
16039
  }) {
15961
16040
  if (start < 0 || end <= start || end > text.length) {
15962
- return /* @__PURE__ */ React36.createElement(Text31, { color: FG.sub }, text);
16041
+ return /* @__PURE__ */ React37.createElement(Text32, { color: FG.sub }, text);
15963
16042
  }
15964
- return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(Text31, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ React36.createElement(Text31, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ React36.createElement(Text31, { color: FG.sub }, text.slice(end)));
16043
+ return /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement(Text32, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ React37.createElement(Text32, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ React37.createElement(Text32, { color: FG.sub }, text.slice(end)));
15965
16044
  }
15966
16045
  function groupByFile(hits) {
15967
16046
  const map = /* @__PURE__ */ new Map();
@@ -15974,12 +16053,12 @@ function groupByFile(hits) {
15974
16053
  }
15975
16054
 
15976
16055
  // src/cli/ui/cards/StreamingCard.tsx
15977
- import { Box as Box33, Text as Text33, useStdout as useStdout8 } from "ink";
15978
- import React38 from "react";
16056
+ import { Box as Box34, Text as Text34, useStdout as useStdout8 } from "ink";
16057
+ import React39 from "react";
15979
16058
 
15980
16059
  // src/cli/ui/markdown.tsx
15981
16060
  import { highlight, supportsLanguage } from "cli-highlight";
15982
- import { Box as Box32, Text as Text32 } from "ink";
16061
+ import { Box as Box33, Text as Text33 } from "ink";
15983
16062
 
15984
16063
  // node_modules/marked/lib/marked.esm.js
15985
16064
  function _getDefaults() {
@@ -17991,7 +18070,7 @@ var parser = _Parser.parse;
17991
18070
  var lexer = _Lexer.lex;
17992
18071
 
17993
18072
  // src/cli/ui/markdown.tsx
17994
- import React37 from "react";
18073
+ import React38 from "react";
17995
18074
  import stringWidth from "string-width";
17996
18075
  function padToCells(text, cells) {
17997
18076
  const w = stringWidth(text);
@@ -18000,41 +18079,41 @@ function padToCells(text, cells) {
18000
18079
  }
18001
18080
  marked.setOptions({ gfm: true, breaks: false });
18002
18081
  function Markdown({ text }) {
18003
- const tokens = React37.useMemo(() => marked.lexer(text), [text]);
18004
- return /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ React37.createElement(BlockToken, { key: `${i}-${token.type}`, token })));
18082
+ const tokens = React38.useMemo(() => marked.lexer(text), [text]);
18083
+ return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ React38.createElement(BlockToken, { key: `${i}-${token.type}`, token })));
18005
18084
  }
18006
18085
  function BlockToken({ token }) {
18007
18086
  switch (token.type) {
18008
18087
  case "heading":
18009
- return /* @__PURE__ */ React37.createElement(Heading, { token });
18088
+ return /* @__PURE__ */ React38.createElement(Heading, { token });
18010
18089
  case "paragraph":
18011
- return /* @__PURE__ */ React37.createElement(Paragraph, { token });
18090
+ return /* @__PURE__ */ React38.createElement(Paragraph, { token });
18012
18091
  case "list":
18013
- return /* @__PURE__ */ React37.createElement(List, { token, depth: 0 });
18092
+ return /* @__PURE__ */ React38.createElement(List, { token, depth: 0 });
18014
18093
  case "code":
18015
- return /* @__PURE__ */ React37.createElement(CodeBlock, { token });
18094
+ return /* @__PURE__ */ React38.createElement(CodeBlock, { token });
18016
18095
  case "blockquote":
18017
- return /* @__PURE__ */ React37.createElement(Blockquote, { token });
18096
+ return /* @__PURE__ */ React38.createElement(Blockquote, { token });
18018
18097
  case "hr":
18019
- return /* @__PURE__ */ React37.createElement(HorizontalRule, null);
18098
+ return /* @__PURE__ */ React38.createElement(HorizontalRule, null);
18020
18099
  case "table":
18021
- return /* @__PURE__ */ React37.createElement(Table, { token });
18100
+ return /* @__PURE__ */ React38.createElement(Table, { token });
18022
18101
  case "html":
18023
- return /* @__PURE__ */ React37.createElement(Text32, { color: FG.body }, token.text);
18102
+ return /* @__PURE__ */ React38.createElement(Text33, { color: FG.body }, token.text);
18024
18103
  case "space":
18025
18104
  return null;
18026
18105
  default:
18027
- return /* @__PURE__ */ React37.createElement(Text32, { color: FG.body }, token.raw ?? "");
18106
+ return /* @__PURE__ */ React38.createElement(Text33, { color: FG.body }, token.raw ?? "");
18028
18107
  }
18029
18108
  }
18030
18109
  function Heading({ token }) {
18031
- return /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
18110
+ return /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text33, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
18032
18111
  }
18033
18112
  function Paragraph({ token }) {
18034
- return /* @__PURE__ */ React37.createElement(Text32, { color: FG.body }, /* @__PURE__ */ React37.createElement(Inline, { tokens: token.tokens ?? [] }));
18113
+ return /* @__PURE__ */ React38.createElement(Text33, { color: FG.body }, /* @__PURE__ */ React38.createElement(Inline, { tokens: token.tokens ?? [] }));
18035
18114
  }
18036
18115
  function List({ token, depth }) {
18037
- return /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ React37.createElement(
18116
+ return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ React38.createElement(
18038
18117
  ListItem,
18039
18118
  {
18040
18119
  key: `${i}-${item.text.slice(0, 24)}`,
@@ -18055,27 +18134,27 @@ function ListItem({
18055
18134
  const markerColor = item.task ? item.checked ? TONE.ok : FG.faint : FG.meta;
18056
18135
  const dim = item.task && item.checked === true;
18057
18136
  const indent = " ".repeat(depth + 1);
18058
- return /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, item.tokens.map((tok, i) => {
18137
+ return /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text33, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, item.tokens.map((tok, i) => {
18059
18138
  if (tok.type === "text") {
18060
18139
  const inner = tok.tokens;
18061
18140
  return (
18062
18141
  // biome-ignore lint/suspicious/noArrayIndexKey: list-item children are positional and stable per render
18063
- /* @__PURE__ */ React37.createElement(Text32, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ React37.createElement(Inline, { tokens: inner }) : tok.text)
18142
+ /* @__PURE__ */ React38.createElement(Text33, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ React38.createElement(Inline, { tokens: inner }) : tok.text)
18064
18143
  );
18065
18144
  }
18066
18145
  if (tok.type === "list") {
18067
- return /* @__PURE__ */ React37.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
18146
+ return /* @__PURE__ */ React38.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
18068
18147
  }
18069
- return /* @__PURE__ */ React37.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
18148
+ return /* @__PURE__ */ React38.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
18070
18149
  })));
18071
18150
  }
18072
18151
  function CodeBlock({ token }) {
18073
18152
  const lang = token.lang?.split(/\s+/)[0] ?? "";
18074
18153
  const colored = highlightCode(token.text, lang);
18075
18154
  const lines = colored.split("\n");
18076
- return /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, lang ? /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, lines.map((line, i) => (
18155
+ return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, lang ? /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text33, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, lines.map((line, i) => (
18077
18156
  // biome-ignore lint/suspicious/noArrayIndexKey: code lines are positional and stable per render
18078
- /* @__PURE__ */ React37.createElement(Text32, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
18157
+ /* @__PURE__ */ React38.createElement(Text33, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
18079
18158
  ))));
18080
18159
  }
18081
18160
  function highlightCode(source, lang) {
@@ -18088,10 +18167,10 @@ function highlightCode(source, lang) {
18088
18167
  }
18089
18168
  }
18090
18169
  function Blockquote({ token }) {
18091
- return /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ React37.createElement(Box32, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ React37.createElement(Text32, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ React37.createElement(Text32, { italic: true, color: FG.sub }, /* @__PURE__ */ React37.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ React37.createElement(BlockToken, { token: child })))));
18170
+ return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ React38.createElement(Box33, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ React38.createElement(Text33, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ React38.createElement(Text33, { italic: true, color: FG.sub }, /* @__PURE__ */ React38.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ React38.createElement(BlockToken, { token: child })))));
18092
18171
  }
18093
18172
  function HorizontalRule() {
18094
- return /* @__PURE__ */ React37.createElement(Text32, { color: FG.faint }, " \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");
18173
+ return /* @__PURE__ */ React38.createElement(Text33, { color: FG.faint }, " \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");
18095
18174
  }
18096
18175
  function Table({ token }) {
18097
18176
  const colCount = token.header.length;
@@ -18106,29 +18185,29 @@ function Table({ token }) {
18106
18185
  }
18107
18186
  const GAP = " ";
18108
18187
  const ruleRow = widths.map((w) => "\u2500".repeat(w)).join(GAP);
18109
- return /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, null, " "), headerCells.map((cell, i) => (
18188
+ return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text33, null, " "), headerCells.map((cell, i) => (
18110
18189
  // biome-ignore lint/suspicious/noArrayIndexKey: header cells positional
18111
- /* @__PURE__ */ React37.createElement(React37.Fragment, { key: `h-${i}` }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ React37.createElement(Text32, null, GAP) : null)
18112
- ))), /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, null, " "), /* @__PURE__ */ React37.createElement(Text32, { color: FG.faint }, ruleRow)), bodyCells.map((row3, ri) => (
18190
+ /* @__PURE__ */ React38.createElement(React38.Fragment, { key: `h-${i}` }, /* @__PURE__ */ React38.createElement(Text33, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ React38.createElement(Text33, null, GAP) : null)
18191
+ ))), /* @__PURE__ */ React38.createElement(Box33, null, /* @__PURE__ */ React38.createElement(Text33, null, " "), /* @__PURE__ */ React38.createElement(Text33, { color: FG.faint }, ruleRow)), bodyCells.map((row3, ri) => (
18113
18192
  // biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
18114
- /* @__PURE__ */ React37.createElement(Box32, { key: `tr-${ri}` }, /* @__PURE__ */ React37.createElement(Text32, null, " "), row3.map((cell, i) => (
18193
+ /* @__PURE__ */ React38.createElement(Box33, { key: `tr-${ri}` }, /* @__PURE__ */ React38.createElement(Text33, null, " "), row3.map((cell, i) => (
18115
18194
  // biome-ignore lint/suspicious/noArrayIndexKey: cells positional
18116
- /* @__PURE__ */ React37.createElement(React37.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ React37.createElement(Text32, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ React37.createElement(Text32, null, GAP) : null)
18195
+ /* @__PURE__ */ React38.createElement(React38.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ React38.createElement(Text33, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ React38.createElement(Text33, null, GAP) : null)
18117
18196
  )))
18118
18197
  )));
18119
18198
  }
18120
18199
  function Inline({ tokens }) {
18121
- return /* @__PURE__ */ React37.createElement(React37.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ React37.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
18200
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ React38.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
18122
18201
  }
18123
18202
  var FILE_REF_RE = /\b([A-Za-z0-9_./@\-]+\.[A-Za-z0-9]{1,6})(?::(\d+)(?:-(\d+))?)?\b/g;
18124
18203
  var MENTION_RE = /(?<![A-Za-z0-9_])@([A-Za-z0-9_./\-]+\.[A-Za-z0-9]{1,6})/g;
18125
18204
  function osc8(label, target, color2) {
18126
18205
  const open = `\x1B]8;;${target}\x07`;
18127
18206
  const close = "\x1B]8;;\x07";
18128
- return /* @__PURE__ */ React37.createElement(Text32, { color: color2, underline: true }, `${open}${label}${close}`);
18207
+ return /* @__PURE__ */ React38.createElement(Text33, { color: color2, underline: true }, `${open}${label}${close}`);
18129
18208
  }
18130
18209
  function renderInlineText(raw) {
18131
- if (!raw) return /* @__PURE__ */ React37.createElement(Text32, null, raw);
18210
+ if (!raw) return /* @__PURE__ */ React38.createElement(Text33, null, raw);
18132
18211
  const out = [];
18133
18212
  let cursor = 0;
18134
18213
  const hits = [];
@@ -18139,7 +18218,7 @@ function renderInlineText(raw) {
18139
18218
  hits.push({
18140
18219
  start,
18141
18220
  end,
18142
- node: /* @__PURE__ */ React37.createElement(Text32, { color: TONE.warn, underline: true }, `@${path5}`)
18221
+ node: /* @__PURE__ */ React38.createElement(Text33, { color: TONE.warn, underline: true }, `@${path5}`)
18143
18222
  });
18144
18223
  }
18145
18224
  for (const m of raw.matchAll(FILE_REF_RE)) {
@@ -18155,44 +18234,44 @@ function renderInlineText(raw) {
18155
18234
  let key = 0;
18156
18235
  for (const h of hits) {
18157
18236
  if (h.start > cursor) {
18158
- out.push(/* @__PURE__ */ React37.createElement(Text32, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
18237
+ out.push(/* @__PURE__ */ React38.createElement(Text33, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
18159
18238
  }
18160
- out.push(/* @__PURE__ */ React37.createElement(React37.Fragment, { key: `r-${key++}` }, h.node));
18239
+ out.push(/* @__PURE__ */ React38.createElement(React38.Fragment, { key: `r-${key++}` }, h.node));
18161
18240
  cursor = h.end;
18162
18241
  }
18163
- if (cursor < raw.length) out.push(/* @__PURE__ */ React37.createElement(Text32, { key: `t-${key++}` }, raw.slice(cursor)));
18164
- return /* @__PURE__ */ React37.createElement(React37.Fragment, null, out);
18242
+ if (cursor < raw.length) out.push(/* @__PURE__ */ React38.createElement(Text33, { key: `t-${key++}` }, raw.slice(cursor)));
18243
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, out);
18165
18244
  }
18166
18245
  function InlineToken({ token }) {
18167
18246
  switch (token.type) {
18168
18247
  case "text": {
18169
18248
  const t2 = token;
18170
- return t2.tokens ? /* @__PURE__ */ React37.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
18249
+ return t2.tokens ? /* @__PURE__ */ React38.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
18171
18250
  }
18172
18251
  case "strong":
18173
- return /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: FG.strong }, /* @__PURE__ */ React37.createElement(Inline, { tokens: token.tokens }));
18252
+ return /* @__PURE__ */ React38.createElement(Text33, { bold: true, color: FG.strong }, /* @__PURE__ */ React38.createElement(Inline, { tokens: token.tokens }));
18174
18253
  case "em":
18175
- return /* @__PURE__ */ React37.createElement(Text32, { italic: true }, /* @__PURE__ */ React37.createElement(Inline, { tokens: token.tokens }));
18254
+ return /* @__PURE__ */ React38.createElement(Text33, { italic: true }, /* @__PURE__ */ React38.createElement(Inline, { tokens: token.tokens }));
18176
18255
  case "codespan":
18177
- return /* @__PURE__ */ React37.createElement(Text32, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${token.text} `);
18256
+ return /* @__PURE__ */ React38.createElement(Text33, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${token.text} `);
18178
18257
  case "del":
18179
- return /* @__PURE__ */ React37.createElement(Text32, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ React37.createElement(Inline, { tokens: token.tokens }));
18258
+ return /* @__PURE__ */ React38.createElement(Text33, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ React38.createElement(Inline, { tokens: token.tokens }));
18180
18259
  case "link": {
18181
18260
  const l = token;
18182
- return /* @__PURE__ */ React37.createElement(Text32, { color: TONE.brand, underline: true }, /* @__PURE__ */ React37.createElement(Inline, { tokens: l.tokens }));
18261
+ return /* @__PURE__ */ React38.createElement(Text33, { color: TONE.brand, underline: true }, /* @__PURE__ */ React38.createElement(Inline, { tokens: l.tokens }));
18183
18262
  }
18184
18263
  case "image": {
18185
18264
  const im = token;
18186
- return /* @__PURE__ */ React37.createElement(Text32, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
18265
+ return /* @__PURE__ */ React38.createElement(Text33, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
18187
18266
  }
18188
18267
  case "br":
18189
- return /* @__PURE__ */ React37.createElement(Text32, null, "\n");
18268
+ return /* @__PURE__ */ React38.createElement(Text33, null, "\n");
18190
18269
  case "escape":
18191
- return /* @__PURE__ */ React37.createElement(Text32, null, token.text);
18270
+ return /* @__PURE__ */ React38.createElement(Text33, null, token.text);
18192
18271
  case "html":
18193
- return /* @__PURE__ */ React37.createElement(Text32, null, token.text);
18272
+ return /* @__PURE__ */ React38.createElement(Text33, null, token.text);
18194
18273
  default:
18195
- return /* @__PURE__ */ React37.createElement(Text32, null, token.raw ?? "");
18274
+ return /* @__PURE__ */ React38.createElement(Text33, null, token.raw ?? "");
18196
18275
  }
18197
18276
  }
18198
18277
  function plainText(tokens) {
@@ -18230,7 +18309,7 @@ var RESERVED_CHROME_ROWS = 14;
18230
18309
  var BODY_INDENT_CELLS2 = 5;
18231
18310
  function StreamingCard({ card }) {
18232
18311
  if (card.done && !card.aborted) {
18233
- return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column", paddingLeft: 3 }, /* @__PURE__ */ React38.createElement(Markdown, { text: card.text }));
18312
+ return /* @__PURE__ */ React39.createElement(Box34, { flexDirection: "column", paddingLeft: 3 }, /* @__PURE__ */ React39.createElement(Markdown, { text: card.text }));
18234
18313
  }
18235
18314
  const { stdout: stdout4 } = useStdout8();
18236
18315
  const rows = stdout4?.rows ?? 40;
@@ -18243,8 +18322,8 @@ function StreamingCard({ card }) {
18243
18322
  const overflows = !card.done && allLines.length > lineSlots;
18244
18323
  const visible = overflows ? allLines.slice(-lineSlots) : allLines;
18245
18324
  const headDropped = overflows ? allLines.length - visible.length : 0;
18246
- return /* @__PURE__ */ React38.createElement(Box33, { flexDirection: "column" }, card.aborted && /* @__PURE__ */ React38.createElement(BarRow, { tone: "streaming", glyph: "\u2014" }, /* @__PURE__ */ React38.createElement(Text33, { color: FG.faint, bold: true }, "\u2014 aborted \u2014"), /* @__PURE__ */ React38.createElement(Text33, { color: TONE.warn }, " stopped")), headDropped > 0 && /* @__PURE__ */ React38.createElement(BarRow, { tone: "streaming", glyph: "\u25BE" }, /* @__PURE__ */ React38.createElement(
18247
- Text33,
18325
+ return /* @__PURE__ */ React39.createElement(Box34, { flexDirection: "column" }, card.aborted && /* @__PURE__ */ React39.createElement(BarRow, { tone: "streaming", glyph: "\u2014" }, /* @__PURE__ */ React39.createElement(Text34, { color: FG.faint, bold: true }, "\u2014 aborted \u2014"), /* @__PURE__ */ React39.createElement(Text34, { color: TONE.warn }, " stopped")), headDropped > 0 && /* @__PURE__ */ React39.createElement(BarRow, { tone: "streaming", glyph: "\u25BE" }, /* @__PURE__ */ React39.createElement(
18326
+ Text34,
18248
18327
  {
18249
18328
  color: FG.faint
18250
18329
  },
@@ -18252,58 +18331,58 @@ function StreamingCard({ card }) {
18252
18331
  )), visible.map((line, i) => {
18253
18332
  const isLast = i === visible.length - 1;
18254
18333
  const isFirstRendered = !card.aborted && headDropped === 0 && i === 0;
18255
- return /* @__PURE__ */ React38.createElement(
18334
+ return /* @__PURE__ */ React39.createElement(
18256
18335
  BarRow,
18257
18336
  {
18258
18337
  key: `${card.id}:${headDropped + i}`,
18259
18338
  tone: "streaming",
18260
18339
  glyph: isFirstRendered ? "\u25B6" : void 0
18261
18340
  },
18262
- /* @__PURE__ */ React38.createElement(Text33, { color: card.aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)),
18263
- isLast && !card.done && /* @__PURE__ */ React38.createElement(CursorBlock, null)
18341
+ /* @__PURE__ */ React39.createElement(Text34, { color: card.aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)),
18342
+ isLast && !card.done && /* @__PURE__ */ React39.createElement(CursorBlock, null)
18264
18343
  );
18265
- }), card.aborted && /* @__PURE__ */ React38.createElement(BarRow, { tone: "streaming" }, /* @__PURE__ */ React38.createElement(Text33, { color: FG.faint }, "[truncated by esc]")));
18344
+ }), card.aborted && /* @__PURE__ */ React39.createElement(BarRow, { tone: "streaming" }, /* @__PURE__ */ React39.createElement(Text34, { color: FG.faint }, "[truncated by esc]")));
18266
18345
  }
18267
18346
 
18268
18347
  // src/cli/ui/cards/SubAgentCard.tsx
18269
- import { Box as Box34, Text as Text34 } from "ink";
18270
- import React39 from "react";
18348
+ import { Box as Box35, Text as Text35 } from "ink";
18349
+ import React40 from "react";
18271
18350
  var STATUS_COLOR2 = {
18272
18351
  running: TONE.violet,
18273
18352
  done: TONE.ok,
18274
18353
  failed: TONE.err
18275
18354
  };
18276
18355
  function SubAgentCard({ card }) {
18277
- return /* @__PURE__ */ React39.createElement(Box34, { flexDirection: "column" }, /* @__PURE__ */ React39.createElement(
18356
+ return /* @__PURE__ */ React40.createElement(Box35, { flexDirection: "column" }, /* @__PURE__ */ React40.createElement(
18278
18357
  CardHeader,
18279
18358
  {
18280
18359
  tone: "subagent",
18281
18360
  glyph: "\u232C",
18282
18361
  title: `Sub-agent \xB7 ${card.name}`,
18283
- trailing: /* @__PURE__ */ React39.createElement(Text34, { color: STATUS_COLOR2[card.status] }, card.status)
18362
+ trailing: /* @__PURE__ */ React40.createElement(Text35, { color: STATUS_COLOR2[card.status] }, card.status)
18284
18363
  }
18285
- ), /* @__PURE__ */ React39.createElement(BarRow, { tone: "subagent", indent: 0 }), /* @__PURE__ */ React39.createElement(BarRow, { tone: "subagent" }, /* @__PURE__ */ React39.createElement(Text34, { color: FG.faint }, "Task "), /* @__PURE__ */ React39.createElement(Text34, { color: FG.sub }, card.task)), card.tools && card.tools.length > 0 && /* @__PURE__ */ React39.createElement(BarRow, { tone: "subagent" }, /* @__PURE__ */ React39.createElement(Text34, { color: FG.faint }, "Tools "), /* @__PURE__ */ React39.createElement(Text34, { color: FG.sub }, card.tools.join(", "))), card.children.length > 0 && /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(BarRow, { tone: "subagent", indent: 0 }), /* @__PURE__ */ React39.createElement(BarRow, { tone: "subagent" }, /* @__PURE__ */ React39.createElement(Text34, { color: FG.meta }, "sub-agent stream")), card.children.map((child) => /* @__PURE__ */ React39.createElement(BarRow, { key: child.id, tone: "subagent" }, /* @__PURE__ */ React39.createElement(Text34, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React39.createElement(ChildSummary, { card: child })))));
18364
+ ), /* @__PURE__ */ React40.createElement(BarRow, { tone: "subagent", indent: 0 }), /* @__PURE__ */ React40.createElement(BarRow, { tone: "subagent" }, /* @__PURE__ */ React40.createElement(Text35, { color: FG.faint }, "Task "), /* @__PURE__ */ React40.createElement(Text35, { color: FG.sub }, card.task)), card.tools && card.tools.length > 0 && /* @__PURE__ */ React40.createElement(BarRow, { tone: "subagent" }, /* @__PURE__ */ React40.createElement(Text35, { color: FG.faint }, "Tools "), /* @__PURE__ */ React40.createElement(Text35, { color: FG.sub }, card.tools.join(", "))), card.children.length > 0 && /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(BarRow, { tone: "subagent", indent: 0 }), /* @__PURE__ */ React40.createElement(BarRow, { tone: "subagent" }, /* @__PURE__ */ React40.createElement(Text35, { color: FG.meta }, "sub-agent stream")), card.children.map((child) => /* @__PURE__ */ React40.createElement(BarRow, { key: child.id, tone: "subagent" }, /* @__PURE__ */ React40.createElement(Text35, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React40.createElement(ChildSummary, { card: child })))));
18286
18365
  }
18287
18366
  function ChildSummary({ card }) {
18288
18367
  switch (card.kind) {
18289
18368
  case "reasoning":
18290
- return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(Text34, { color: CARD.reasoning.color }, "\u25C6 "), /* @__PURE__ */ React39.createElement(Text34, { italic: true, color: FG.meta }, `Reasoning \xB7 ${card.paragraphs} paragraph${card.paragraphs === 1 ? "" : "s"}`));
18369
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(Text35, { color: CARD.reasoning.color }, "\u25C6 "), /* @__PURE__ */ React40.createElement(Text35, { italic: true, color: FG.meta }, `Reasoning \xB7 ${card.paragraphs} paragraph${card.paragraphs === 1 ? "" : "s"}`));
18291
18370
  case "tool":
18292
- return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(Text34, { color: CARD.tool.color }, "\u25A3 "), /* @__PURE__ */ React39.createElement(Text34, { bold: true, color: FG.body }, card.name), card.elapsedMs > 0 && /* @__PURE__ */ React39.createElement(Text34, { color: FG.faint }, ` ${(card.elapsedMs / 1e3).toFixed(2)}s`));
18371
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(Text35, { color: CARD.tool.color }, "\u25A3 "), /* @__PURE__ */ React40.createElement(Text35, { bold: true, color: FG.body }, card.name), card.elapsedMs > 0 && /* @__PURE__ */ React40.createElement(Text35, { color: FG.faint }, ` ${(card.elapsedMs / 1e3).toFixed(2)}s`));
18293
18372
  case "streaming":
18294
- return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(Text34, { color: CARD.streaming.color }, "\u25B6 "), /* @__PURE__ */ React39.createElement(Text34, { color: card.done ? FG.sub : TONE.brand }, card.done ? "response" : "streaming response \u2026"));
18373
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(Text35, { color: CARD.streaming.color }, "\u25B6 "), /* @__PURE__ */ React40.createElement(Text35, { color: card.done ? FG.sub : TONE.brand }, card.done ? "response" : "streaming response \u2026"));
18295
18374
  case "diff":
18296
- return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(Text34, { color: CARD.diff.color }, "\xB1 "), /* @__PURE__ */ React39.createElement(Text34, { color: FG.sub }, card.file));
18375
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(Text35, { color: CARD.diff.color }, "\xB1 "), /* @__PURE__ */ React40.createElement(Text35, { color: FG.sub }, card.file));
18297
18376
  case "error":
18298
- return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(Text34, { color: CARD.error.color }, "\u2716 "), /* @__PURE__ */ React39.createElement(Text34, { color: FG.sub }, card.title));
18377
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(Text35, { color: CARD.error.color }, "\u2716 "), /* @__PURE__ */ React40.createElement(Text35, { color: FG.sub }, card.title));
18299
18378
  default:
18300
- return /* @__PURE__ */ React39.createElement(Text34, { color: FG.faint }, `\xB7 ${card.kind}`);
18379
+ return /* @__PURE__ */ React40.createElement(Text35, { color: FG.faint }, `\xB7 ${card.kind}`);
18301
18380
  }
18302
18381
  }
18303
18382
 
18304
18383
  // src/cli/ui/cards/TaskCard.tsx
18305
- import { Box as Box35, Text as Text35 } from "ink";
18306
- import React40 from "react";
18384
+ import { Box as Box36, Text as Text36 } from "ink";
18385
+ import React41 from "react";
18307
18386
  var STEP_GLYPH = {
18308
18387
  queued: "\u25CB",
18309
18388
  running: "\u25B6",
@@ -18329,22 +18408,22 @@ var TASK_GLYPH = {
18329
18408
  function TaskCard({ card }) {
18330
18409
  const elapsed = `${(card.elapsedMs / 1e3).toFixed(1)}s`;
18331
18410
  const showSteps = card.steps.length > 0;
18332
- return /* @__PURE__ */ React40.createElement(Box35, { flexDirection: "column" }, /* @__PURE__ */ React40.createElement(
18411
+ return /* @__PURE__ */ React41.createElement(Box36, { flexDirection: "column" }, /* @__PURE__ */ React41.createElement(
18333
18412
  CardHeader,
18334
18413
  {
18335
18414
  tone: "task",
18336
18415
  glyph: TASK_GLYPH[card.status],
18337
18416
  title: `Step ${card.index} of ${card.total} \xB7 ${card.title}`,
18338
18417
  meta: `${elapsed} \xB7 `,
18339
- trailing: /* @__PURE__ */ React40.createElement(Text35, { color: TASK_COLOR[card.status] }, card.status),
18418
+ trailing: /* @__PURE__ */ React41.createElement(Text36, { color: TASK_COLOR[card.status] }, card.status),
18340
18419
  barColor: TASK_COLOR[card.status]
18341
18420
  }
18342
- ), showSteps && /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(BarRow, { tone: "task", indent: 0 }), card.steps.map((step) => /* @__PURE__ */ React40.createElement(BarRow, { key: step.id, tone: "task" }, /* @__PURE__ */ React40.createElement(Text35, { color: STEP_COLOR[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ React40.createElement(Text35, { bold: true, color: FG.body }, ` ${(step.toolName ?? "step").padEnd(7)} `), /* @__PURE__ */ React40.createElement(Text35, { color: FG.sub }, step.title), step.detail && /* @__PURE__ */ React40.createElement(Text35, { color: FG.faint }, ` ${step.detail}`), step.elapsedMs !== void 0 && /* @__PURE__ */ React40.createElement(Text35, { color: FG.faint }, ` ${(step.elapsedMs / 1e3).toFixed(2)}s`)))));
18421
+ ), showSteps && /* @__PURE__ */ React41.createElement(React41.Fragment, null, /* @__PURE__ */ React41.createElement(BarRow, { tone: "task", indent: 0 }), card.steps.map((step) => /* @__PURE__ */ React41.createElement(BarRow, { key: step.id, tone: "task" }, /* @__PURE__ */ React41.createElement(Text36, { color: STEP_COLOR[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ React41.createElement(Text36, { bold: true, color: FG.body }, ` ${(step.toolName ?? "step").padEnd(7)} `), /* @__PURE__ */ React41.createElement(Text36, { color: FG.sub }, step.title), step.detail && /* @__PURE__ */ React41.createElement(Text36, { color: FG.faint }, ` ${step.detail}`), step.elapsedMs !== void 0 && /* @__PURE__ */ React41.createElement(Text36, { color: FG.faint }, ` ${(step.elapsedMs / 1e3).toFixed(2)}s`)))));
18343
18422
  }
18344
18423
 
18345
18424
  // src/cli/ui/cards/ToolCard.tsx
18346
- import { Box as Box36, Text as Text36, useStdout as useStdout9 } from "ink";
18347
- import React41 from "react";
18425
+ import { Box as Box37, Text as Text37, useStdout as useStdout9 } from "ink";
18426
+ import React42 from "react";
18348
18427
  var READ_TAIL = 2;
18349
18428
  var OTHER_TAIL = 5;
18350
18429
  var BODY_INDENT_CELLS3 = 5;
@@ -18365,7 +18444,7 @@ function ToolCard({ card }) {
18365
18444
  const hidden = truncated ? allLines.length - visible.length : 0;
18366
18445
  const errColor = card.exitCode && card.exitCode !== 0 ? CARD.error.color : FG.sub;
18367
18446
  const showBody = visible.length > 0;
18368
- return /* @__PURE__ */ React41.createElement(Box36, { flexDirection: "column" }, /* @__PURE__ */ React41.createElement(
18447
+ return /* @__PURE__ */ React42.createElement(Box37, { flexDirection: "column" }, /* @__PURE__ */ React42.createElement(
18369
18448
  CardHeader,
18370
18449
  {
18371
18450
  tone: "tool",
@@ -18373,10 +18452,10 @@ function ToolCard({ card }) {
18373
18452
  title: card.name,
18374
18453
  subtitle: argsLabel || void 0,
18375
18454
  meta: meta || void 0,
18376
- inline: !card.done ? /* @__PURE__ */ React41.createElement(Spinner, { kind: "braille", color: CARD.tool.color, bold: true }) : void 0,
18377
- trailing: card.retry ? /* @__PURE__ */ React41.createElement(Text36, { color: TONE.warn, bold: true }, `\u21BB retry ${card.retry.attempt}/${card.retry.max}`) : void 0
18455
+ inline: !card.done ? /* @__PURE__ */ React42.createElement(Spinner, { kind: "braille", color: CARD.tool.color, bold: true }) : void 0,
18456
+ trailing: card.retry ? /* @__PURE__ */ React42.createElement(Text37, { color: TONE.warn, bold: true }, `\u21BB retry ${card.retry.attempt}/${card.retry.max}`) : void 0
18378
18457
  }
18379
- ), showBody && /* @__PURE__ */ React41.createElement(React41.Fragment, null, /* @__PURE__ */ React41.createElement(BarRow, { tone: "tool", indent: 0 }), hidden > 0 && /* @__PURE__ */ React41.createElement(BarRow, { tone: "tool" }, /* @__PURE__ */ React41.createElement(Text36, { color: FG.faint }, `\u22EE ${hidden} earlier line${hidden === 1 ? "" : "s"} (use /tool to read full)`)), visible.map((line, i) => /* @__PURE__ */ React41.createElement(BarRow, { key: `${card.id}:${hidden + i}`, tone: "tool" }, /* @__PURE__ */ React41.createElement(Text36, { color: errColor }, clipToCells(line, lineCells))))));
18458
+ ), showBody && /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(BarRow, { tone: "tool", indent: 0 }), hidden > 0 && /* @__PURE__ */ React42.createElement(BarRow, { tone: "tool" }, /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, `\u22EE ${hidden} earlier line${hidden === 1 ? "" : "s"} (use /tool to read full)`)), visible.map((line, i) => /* @__PURE__ */ React42.createElement(BarRow, { key: `${card.id}:${hidden + i}`, tone: "tool" }, /* @__PURE__ */ React42.createElement(Text37, { color: errColor }, clipToCells(line, lineCells))))));
18380
18459
  }
18381
18460
  function formatArgsSummary(args) {
18382
18461
  if (typeof args === "string") return args.length > 60 ? `${args.slice(0, 60)}\u2026` : args;
@@ -18408,8 +18487,8 @@ function formatMeta(card) {
18408
18487
  }
18409
18488
 
18410
18489
  // src/cli/ui/cards/UsageCard.tsx
18411
- import { Box as Box37, Text as Text37 } from "ink";
18412
- import React42 from "react";
18490
+ import { Box as Box38, Text as Text38 } from "ink";
18491
+ import React43 from "react";
18413
18492
  var BAR_CELLS3 = 30;
18414
18493
  function compactNum(n) {
18415
18494
  if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
@@ -18419,32 +18498,32 @@ function compactNum(n) {
18419
18498
  function bar(ratio, color2) {
18420
18499
  const filled = Math.max(0, Math.min(BAR_CELLS3, Math.round(ratio * BAR_CELLS3)));
18421
18500
  const empty = BAR_CELLS3 - filled;
18422
- return /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(Text37, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, "\u2591".repeat(empty)));
18501
+ return /* @__PURE__ */ React43.createElement(React43.Fragment, null, /* @__PURE__ */ React43.createElement(Text38, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, "\u2591".repeat(empty)));
18423
18502
  }
18424
18503
  function UsageCard({ card }) {
18425
- if (card.compact) return /* @__PURE__ */ React42.createElement(CompactUsageRow, { card });
18504
+ if (card.compact) return /* @__PURE__ */ React43.createElement(CompactUsageRow, { card });
18426
18505
  const cap = Math.max(1, card.tokens.promptCap);
18427
18506
  const promptRatio = card.tokens.prompt / cap;
18428
18507
  const reasonRatio = card.tokens.reason / cap;
18429
18508
  const outputRatio = card.tokens.output / cap;
18430
18509
  const elapsed = card.elapsedMs !== void 0 ? ` \xB7 ${(card.elapsedMs / 1e3).toFixed(1)}s` : "";
18431
18510
  const meta = `${formatCNY(card.cost)}${elapsed}`;
18432
- return /* @__PURE__ */ React42.createElement(Box37, { flexDirection: "column" }, /* @__PURE__ */ React42.createElement(CardHeader, { tone: "usage", glyph: "\u03A3", title: "Usage", subtitle: `turn ${card.turn}`, meta }), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React42.createElement(Text37, { color: FG.sub }, "prompt "), bar(promptRatio, TONE.brand), /* @__PURE__ */ React42.createElement(Text37, { bold: true, color: FG.body }, ` ${card.tokens.prompt.toLocaleString()}`), /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, ` / 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React42.createElement(Text37, { color: FG.sub }, "reason "), bar(reasonRatio, TONE.accent), /* @__PURE__ */ React42.createElement(Text37, { bold: true, color: FG.body }, ` ${card.tokens.reason.toLocaleString()}`)), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React42.createElement(Text37, { color: FG.sub }, "output "), bar(outputRatio, TONE.brand), /* @__PURE__ */ React42.createElement(Text37, { bold: true, color: FG.body }, ` ${card.tokens.output.toLocaleString()}`)), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React42.createElement(Text37, { color: FG.sub }, "cache hit "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ React42.createElement(Text37, { bold: true, color: TONE.ok }, ` ${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React42.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, "session "), /* @__PURE__ */ React42.createElement(Text37, { bold: true, color: FG.body }, `\u26C1 ${formatCNY(card.sessionCost, 3)}`), card.balance !== void 0 && /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(Text37, { color: FG.meta }, " \xB7 "), /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, "balance "), /* @__PURE__ */ React42.createElement(Text37, { bold: true, color: TONE.brand }, `\xA5${card.balance.toFixed(2)}`))));
18511
+ return /* @__PURE__ */ React43.createElement(Box38, { flexDirection: "column" }, /* @__PURE__ */ React43.createElement(CardHeader, { tone: "usage", glyph: "\u03A3", title: "Usage", subtitle: `turn ${card.turn}`, meta }), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React43.createElement(Text38, { color: FG.sub }, "prompt "), bar(promptRatio, TONE.brand), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: FG.body }, ` ${card.tokens.prompt.toLocaleString()}`), /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, ` / 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React43.createElement(Text38, { color: FG.sub }, "reason "), bar(reasonRatio, TONE.accent), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: FG.body }, ` ${card.tokens.reason.toLocaleString()}`)), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React43.createElement(Text38, { color: FG.sub }, "output "), bar(outputRatio, TONE.brand), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: FG.body }, ` ${card.tokens.output.toLocaleString()}`)), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React43.createElement(Text38, { color: FG.sub }, "cache hit "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: TONE.ok }, ` ${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage", indent: 0 }), /* @__PURE__ */ React43.createElement(BarRow, { tone: "usage" }, /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, "session "), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: FG.body }, `\u26C1 ${formatCNY(card.sessionCost, 3)}`), card.balance !== void 0 && /* @__PURE__ */ React43.createElement(React43.Fragment, null, /* @__PURE__ */ React43.createElement(Text38, { color: FG.meta }, " \xB7 "), /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, "balance "), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: TONE.brand }, `\xA5${card.balance.toFixed(2)}`))));
18433
18512
  }
18434
18513
  function CompactUsageRow({ card }) {
18435
18514
  const elapsed = card.elapsedMs !== void 0 ? ` \xB7 ${(card.elapsedMs / 1e3).toFixed(1)}s` : "";
18436
- return /* @__PURE__ */ React42.createElement(Box37, null, /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, ` \u03A3 turn ${card.turn} \xB7 `), /* @__PURE__ */ React42.createElement(
18437
- Text37,
18515
+ return /* @__PURE__ */ React43.createElement(Box38, null, /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, ` \u03A3 turn ${card.turn} \xB7 `), /* @__PURE__ */ React43.createElement(
18516
+ Text38,
18438
18517
  {
18439
18518
  color: FG.meta
18440
18519
  },
18441
18520
  `${compactNum(card.tokens.prompt)} prompt \xB7 ${compactNum(card.tokens.output)} out`
18442
- ), /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, " \xB7 cache "), /* @__PURE__ */ React42.createElement(Text37, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, ` \xB7 ${formatCNY(card.cost)}${elapsed}`), card.balance !== void 0 && /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(Text37, { color: FG.faint }, " \xB7 "), /* @__PURE__ */ React42.createElement(Text37, { color: TONE.brand }, `\xA5${card.balance.toFixed(2)}`)));
18521
+ ), /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, " \xB7 cache "), /* @__PURE__ */ React43.createElement(Text38, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, ` \xB7 ${formatCNY(card.cost)}${elapsed}`), card.balance !== void 0 && /* @__PURE__ */ React43.createElement(React43.Fragment, null, /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, " \xB7 "), /* @__PURE__ */ React43.createElement(Text38, { color: TONE.brand }, `\xA5${card.balance.toFixed(2)}`)));
18443
18522
  }
18444
18523
 
18445
18524
  // src/cli/ui/cards/UserCard.tsx
18446
- import { Box as Box38, Text as Text38 } from "ink";
18447
- import React43 from "react";
18525
+ import { Box as Box39, Text as Text39 } from "ink";
18526
+ import React44 from "react";
18448
18527
 
18449
18528
  // src/cli/ui/cards/time.ts
18450
18529
  function formatRelativeTime(ts, now = Date.now()) {
@@ -18461,15 +18540,15 @@ function formatRelativeTime(ts, now = Date.now()) {
18461
18540
 
18462
18541
  // src/cli/ui/cards/UserCard.tsx
18463
18542
  function UserCard({ card }) {
18464
- return /* @__PURE__ */ React43.createElement(Box38, { flexDirection: "column" }, /* @__PURE__ */ React43.createElement(Box38, { flexDirection: "row" }, /* @__PURE__ */ React43.createElement(Text38, null, " "), /* @__PURE__ */ React43.createElement(Text38, { color: FG.meta }, "\u25C7"), /* @__PURE__ */ React43.createElement(Text38, { bold: true, color: FG.sub }, " you"), /* @__PURE__ */ React43.createElement(Text38, { color: FG.faint }, ` \xB7 ${formatRelativeTime(card.ts)}`)), /* @__PURE__ */ React43.createElement(Box38, { flexDirection: "column", paddingLeft: 4 }, /* @__PURE__ */ React43.createElement(Markdown, { text: card.text })));
18543
+ return /* @__PURE__ */ React44.createElement(Box39, { flexDirection: "column" }, /* @__PURE__ */ React44.createElement(Box39, { flexDirection: "row" }, /* @__PURE__ */ React44.createElement(Text39, null, " "), /* @__PURE__ */ React44.createElement(Text39, { color: FG.meta }, "\u25C7"), /* @__PURE__ */ React44.createElement(Text39, { bold: true, color: FG.sub }, " you"), /* @__PURE__ */ React44.createElement(Text39, { color: FG.faint }, ` \xB7 ${formatRelativeTime(card.ts)}`)), /* @__PURE__ */ React44.createElement(Box39, { flexDirection: "column", paddingLeft: 4 }, /* @__PURE__ */ React44.createElement(Markdown, { text: card.text })));
18465
18544
  }
18466
18545
 
18467
18546
  // src/cli/ui/cards/WarnCard.tsx
18468
- import { Box as Box39, Text as Text39 } from "ink";
18469
- import React44 from "react";
18547
+ import { Box as Box40, Text as Text40 } from "ink";
18548
+ import React45 from "react";
18470
18549
  function WarnCard({ card }) {
18471
18550
  const showBody = card.message.length > 0;
18472
- return /* @__PURE__ */ React44.createElement(Box39, { flexDirection: "column" }, /* @__PURE__ */ React44.createElement(
18551
+ return /* @__PURE__ */ React45.createElement(Box40, { flexDirection: "column" }, /* @__PURE__ */ React45.createElement(
18473
18552
  CardHeader,
18474
18553
  {
18475
18554
  tone: "warn",
@@ -18477,7 +18556,7 @@ function WarnCard({ card }) {
18477
18556
  title: card.title,
18478
18557
  meta: card.detail ? `\xB7 ${card.detail}` : void 0
18479
18558
  }
18480
- ), showBody && /* @__PURE__ */ React44.createElement(React44.Fragment, null, /* @__PURE__ */ React44.createElement(BarRow, { tone: "warn", indent: 0 }), card.message.split("\n").map((line, i) => /* @__PURE__ */ React44.createElement(BarRow, { key: `${card.id}:${i}`, tone: "warn" }, /* @__PURE__ */ React44.createElement(Text39, { color: FG.body }, line)))));
18559
+ ), showBody && /* @__PURE__ */ React45.createElement(React45.Fragment, null, /* @__PURE__ */ React45.createElement(BarRow, { tone: "warn", indent: 0 }), card.message.split("\n").map((line, i) => /* @__PURE__ */ React45.createElement(BarRow, { key: `${card.id}:${i}`, tone: "warn" }, /* @__PURE__ */ React45.createElement(Text40, { color: FG.body }, line)))));
18481
18560
  }
18482
18561
 
18483
18562
  // src/cli/ui/cards/CardRenderer.tsx
@@ -18485,52 +18564,52 @@ function CardRenderer({ card }) {
18485
18564
  const contentStreaming = useAgentState(
18486
18565
  (s) => s.cards.some((c) => c.kind === "streaming" && c.text.length > 0 && !c.done)
18487
18566
  );
18488
- return /* @__PURE__ */ React45.createElement(Box40, { flexDirection: "column", marginTop: 1 }, renderCard(card, contentStreaming));
18567
+ return /* @__PURE__ */ React46.createElement(Box41, { flexDirection: "column", marginTop: 1 }, renderCard(card, contentStreaming));
18489
18568
  }
18490
18569
  function renderCard(card, contentStreaming) {
18491
18570
  switch (card.kind) {
18492
18571
  case "user":
18493
- return /* @__PURE__ */ React45.createElement(UserCard, { card });
18572
+ return /* @__PURE__ */ React46.createElement(UserCard, { card });
18494
18573
  case "reasoning":
18495
- return /* @__PURE__ */ React45.createElement(ReasoningCard, { card, expanded: !(card.streaming && contentStreaming) });
18574
+ return /* @__PURE__ */ React46.createElement(ReasoningCard, { card, expanded: !(card.streaming && contentStreaming) });
18496
18575
  case "streaming":
18497
- return /* @__PURE__ */ React45.createElement(StreamingCard, { card });
18576
+ return /* @__PURE__ */ React46.createElement(StreamingCard, { card });
18498
18577
  case "tool":
18499
- return /* @__PURE__ */ React45.createElement(ToolCard, { card });
18578
+ return /* @__PURE__ */ React46.createElement(ToolCard, { card });
18500
18579
  case "task":
18501
- return /* @__PURE__ */ React45.createElement(TaskCard, { card });
18580
+ return /* @__PURE__ */ React46.createElement(TaskCard, { card });
18502
18581
  case "plan":
18503
- return /* @__PURE__ */ React45.createElement(PlanCard, { card });
18582
+ return /* @__PURE__ */ React46.createElement(PlanCard, { card });
18504
18583
  case "diff":
18505
- return /* @__PURE__ */ React45.createElement(DiffCard, { card });
18584
+ return /* @__PURE__ */ React46.createElement(DiffCard, { card });
18506
18585
  case "error":
18507
- return /* @__PURE__ */ React45.createElement(ErrorCard, { card });
18586
+ return /* @__PURE__ */ React46.createElement(ErrorCard, { card });
18508
18587
  case "warn":
18509
- return /* @__PURE__ */ React45.createElement(WarnCard, { card });
18588
+ return /* @__PURE__ */ React46.createElement(WarnCard, { card });
18510
18589
  case "usage":
18511
- return /* @__PURE__ */ React45.createElement(UsageCard, { card });
18590
+ return /* @__PURE__ */ React46.createElement(UsageCard, { card });
18512
18591
  case "memory":
18513
- return /* @__PURE__ */ React45.createElement(MemoryCard, { card });
18592
+ return /* @__PURE__ */ React46.createElement(MemoryCard, { card });
18514
18593
  case "subagent":
18515
- return /* @__PURE__ */ React45.createElement(SubAgentCard, { card });
18594
+ return /* @__PURE__ */ React46.createElement(SubAgentCard, { card });
18516
18595
  case "search":
18517
- return /* @__PURE__ */ React45.createElement(SearchCard, { card });
18596
+ return /* @__PURE__ */ React46.createElement(SearchCard, { card });
18518
18597
  case "approval":
18519
- return /* @__PURE__ */ React45.createElement(FallbackCard, { card });
18598
+ return /* @__PURE__ */ React46.createElement(FallbackCard, { card });
18520
18599
  case "live":
18521
- return /* @__PURE__ */ React45.createElement(LiveCard, { card });
18600
+ return /* @__PURE__ */ React46.createElement(LiveCard, { card });
18522
18601
  case "ctx":
18523
- return /* @__PURE__ */ React45.createElement(CtxCard, { card });
18602
+ return /* @__PURE__ */ React46.createElement(CtxCard, { card });
18524
18603
  case "doctor":
18525
- return /* @__PURE__ */ React45.createElement(DoctorCard, { card });
18604
+ return /* @__PURE__ */ React46.createElement(DoctorCard, { card });
18526
18605
  case "branch":
18527
- return /* @__PURE__ */ React45.createElement(BranchCard, { card });
18606
+ return /* @__PURE__ */ React46.createElement(BranchCard, { card });
18528
18607
  default:
18529
- return /* @__PURE__ */ React45.createElement(FallbackCard, { card });
18608
+ return /* @__PURE__ */ React46.createElement(FallbackCard, { card });
18530
18609
  }
18531
18610
  }
18532
18611
  function FallbackCard({ card }) {
18533
- return /* @__PURE__ */ React45.createElement(Box40, { flexDirection: "row" }, /* @__PURE__ */ React45.createElement(Text40, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
18612
+ return /* @__PURE__ */ React46.createElement(Box41, { flexDirection: "row" }, /* @__PURE__ */ React46.createElement(Text41, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
18534
18613
  }
18535
18614
 
18536
18615
  // src/cli/ui/layout/CardStream.tsx
@@ -18561,16 +18640,16 @@ function CardStream({ excludeId } = {}) {
18561
18640
  }
18562
18641
  const committed = filtered.slice(0, cutoff);
18563
18642
  const live = filtered.slice(cutoff);
18564
- return /* @__PURE__ */ React46.createElement(React46.Fragment, null, /* @__PURE__ */ React46.createElement(Static, { items: committed }, (card) => /* @__PURE__ */ React46.createElement(CardRenderer, { key: card.id, card })), live.map((card) => /* @__PURE__ */ React46.createElement(CardRenderer, { key: card.id, card })));
18643
+ return /* @__PURE__ */ React47.createElement(React47.Fragment, null, /* @__PURE__ */ React47.createElement(Static, { items: committed }, (card) => /* @__PURE__ */ React47.createElement(CardRenderer, { key: card.id, card })), live.map((card) => /* @__PURE__ */ React47.createElement(CardRenderer, { key: card.id, card })));
18565
18644
  }
18566
18645
 
18567
18646
  // src/cli/ui/layout/LiveRows.tsx
18568
- import { Box as Box41, Text as Text41, useStdout as useStdout10 } from "ink";
18569
- import React47 from "react";
18647
+ import { Box as Box42, Text as Text42, useStdout as useStdout10 } from "ink";
18648
+ import React48 from "react";
18570
18649
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
18571
18650
  function ThinkingRow({ text }) {
18572
18651
  const elapsed = useElapsedSeconds();
18573
- return /* @__PURE__ */ React47.createElement(Box41, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React47.createElement(Spinner, { kind: "circle", color: TONE.brand, bold: true }), /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: TONE.brand }, text), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, ` \xB7 ${elapsed}s`));
18652
+ return /* @__PURE__ */ React48.createElement(Box42, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React48.createElement(Spinner, { kind: "circle", color: TONE.brand, bold: true }), /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: TONE.brand }, text), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, ` \xB7 ${elapsed}s`));
18574
18653
  }
18575
18654
  function ModeStatusBar({
18576
18655
  editMode,
@@ -18582,27 +18661,27 @@ function ModeStatusBar({
18582
18661
  }) {
18583
18662
  useSlowTick();
18584
18663
  const running = jobs2?.runningCount() ?? 0;
18585
- const jobsTag = running > 0 ? /* @__PURE__ */ React47.createElement(Text41, { color: TONE.warn, bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
18664
+ const jobsTag = running > 0 ? /* @__PURE__ */ React48.createElement(Text42, { color: TONE.warn, bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
18586
18665
  if (planMode) {
18587
- return /* @__PURE__ */ React47.createElement(ModeBarFrame, null, /* @__PURE__ */ React47.createElement(ModePill, { label: "PLAN MODE", color: TONE.err, flash }), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, " writes gated \xB7 /plan off to leave"), jobsTag);
18666
+ return /* @__PURE__ */ React48.createElement(ModeBarFrame, null, /* @__PURE__ */ React48.createElement(ModePill, { label: "PLAN MODE", color: TONE.err, flash }), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, " writes gated \xB7 /plan off to leave"), jobsTag);
18588
18667
  }
18589
18668
  const label = editMode === "yolo" ? "YOLO" : editMode === "auto" ? "AUTO" : "REVIEW";
18590
18669
  const pillColor = editMode === "yolo" ? TONE.err : editMode === "auto" ? TONE.accent : TONE.brand;
18591
18670
  const mid = editMode === "yolo" ? "edits + shell auto \xB7 /undo to roll back" : editMode === "auto" ? "edits land now \xB7 u to undo" : pendingCount > 0 ? `${pendingCount} queued \xB7 y apply \xB7 n discard` : "edits queued \xB7 y apply \xB7 n discard";
18592
- return /* @__PURE__ */ React47.createElement(ModeBarFrame, null, /* @__PURE__ */ React47.createElement(ModePill, { label, color: pillColor, flash }), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
18671
+ return /* @__PURE__ */ React48.createElement(ModeBarFrame, null, /* @__PURE__ */ React48.createElement(ModePill, { label, color: pillColor, flash }), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
18593
18672
  }
18594
18673
  function ModeBarFrame({ children }) {
18595
18674
  const { stdout: stdout4 } = useStdout10();
18596
18675
  const cols = stdout4?.columns ?? 80;
18597
18676
  const ruleWidth = Math.max(20, cols - 2);
18598
- return /* @__PURE__ */ React47.createElement(Box41, { flexDirection: "column" }, /* @__PURE__ */ React47.createElement(Box41, { paddingX: 1 }, /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, "\u254C".repeat(ruleWidth))), /* @__PURE__ */ React47.createElement(Box41, { paddingX: 1 }, children));
18677
+ return /* @__PURE__ */ React48.createElement(Box42, { flexDirection: "column" }, /* @__PURE__ */ React48.createElement(Box42, { paddingX: 1 }, /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, "\u254C".repeat(ruleWidth))), /* @__PURE__ */ React48.createElement(Box42, { paddingX: 1 }, children));
18599
18678
  }
18600
18679
  function ModePill({
18601
18680
  label,
18602
18681
  color: color2,
18603
18682
  flash
18604
18683
  }) {
18605
- return /* @__PURE__ */ React47.createElement(Text41, { color: color2, bold: true, inverse: flash }, `[${label}]`);
18684
+ return /* @__PURE__ */ React48.createElement(Text42, { color: color2, bold: true, inverse: flash }, `[${label}]`);
18606
18685
  }
18607
18686
  function UndoBanner({
18608
18687
  banner
@@ -18616,7 +18695,7 @@ function UndoBanner({
18616
18695
  const urgent = remainingSec <= 1;
18617
18696
  const pct2 = remainingMs / totalMs * 100;
18618
18697
  const tone = urgent ? TONE.err : TONE.accent;
18619
- return /* @__PURE__ */ React47.createElement(Box41, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React47.createElement(Text41, { backgroundColor: TONE.accent, color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, " press "), /* @__PURE__ */ React47.createElement(Text41, { backgroundColor: TONE.brand, color: "black", bold: true }, " u "), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, " to undo "), /* @__PURE__ */ React47.createElement(CharBar, { pct: pct2, width: 20, color: tone, showLabel: false }), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, " "), /* @__PURE__ */ React47.createElement(Text41, { color: tone, bold: urgent }, `${remainingSec}s`));
18698
+ return /* @__PURE__ */ React48.createElement(Box42, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React48.createElement(Text42, { backgroundColor: TONE.accent, color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, " press "), /* @__PURE__ */ React48.createElement(Text42, { backgroundColor: TONE.brand, color: "black", bold: true }, " u "), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, " to undo "), /* @__PURE__ */ React48.createElement(CharBar, { pct: pct2, width: 20, color: tone, showLabel: false }), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, " "), /* @__PURE__ */ React48.createElement(Text42, { color: tone, bold: urgent }, `${remainingSec}s`));
18620
18699
  }
18621
18700
  function subagentPhaseLabel(phase, iter, elapsedMs) {
18622
18701
  if (phase === "summarising") return "summarising findings\u2026";
@@ -18636,7 +18715,7 @@ function SubagentRow({
18636
18715
  const seconds = (activity.elapsedMs / 1e3).toFixed(1);
18637
18716
  const phase = subagentPhaseLabel(activity.phase, activity.iter, activity.elapsedMs);
18638
18717
  const last = activity.lastInner;
18639
- return /* @__PURE__ */ React47.createElement(Box41, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React47.createElement(Text41, { bold: true, color: CARD.subagent.color }, `\u232C ${subagentTitle(activity.skillName, activity.task)}`), /* @__PURE__ */ React47.createElement(Box41, { flexGrow: 1 }), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, `iter ${activity.iter} \xB7 ${seconds}s`), /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length])), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E")), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, "Task "), /* @__PURE__ */ React47.createElement(Text41, { color: FG.sub }, activity.task)), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, "Model "), /* @__PURE__ */ React47.createElement(Text41, { color: FG.sub }, activity.model ?? "\u2014")), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E")), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, "Last "), last ? /* @__PURE__ */ React47.createElement(React47.Fragment, null, /* @__PURE__ */ React47.createElement(Text41, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React47.createElement(Text41, { color: FG.body }, last.label), last.meta ? /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, "queued\u2026")), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E")), /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React47.createElement(Text41, { bold: true, color: TONE.brand }, "\u25B6 "), /* @__PURE__ */ React47.createElement(Text41, { color: TONE.brand }, phase)));
18718
+ return /* @__PURE__ */ React48.createElement(Box42, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React48.createElement(Text42, { bold: true, color: CARD.subagent.color }, `\u232C ${subagentTitle(activity.skillName, activity.task)}`), /* @__PURE__ */ React48.createElement(Box42, { flexGrow: 1 }), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, `iter ${activity.iter} \xB7 ${seconds}s`), /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length])), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E")), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, "Task "), /* @__PURE__ */ React48.createElement(Text42, { color: FG.sub }, activity.task)), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, "Model "), /* @__PURE__ */ React48.createElement(Text42, { color: FG.sub }, activity.model ?? "\u2014")), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E")), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, "Last "), last ? /* @__PURE__ */ React48.createElement(React48.Fragment, null, /* @__PURE__ */ React48.createElement(Text42, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React48.createElement(Text42, { color: FG.body }, last.label), last.meta ? /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, "queued\u2026")), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E")), /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.subagent.color }, "\u258E "), /* @__PURE__ */ React48.createElement(Text42, { bold: true, color: TONE.brand }, "\u25B6 "), /* @__PURE__ */ React48.createElement(Text42, { color: TONE.brand }, phase)));
18640
18719
  }
18641
18720
  function OngoingToolRow({
18642
18721
  tool: tool2,
@@ -18645,7 +18724,7 @@ function OngoingToolRow({
18645
18724
  const tick = useTick();
18646
18725
  const elapsed = useElapsedSeconds();
18647
18726
  const summary = summarizeToolArgs(tool2.name, tool2.args);
18648
- return /* @__PURE__ */ React47.createElement(Box41, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React47.createElement(Box41, null, /* @__PURE__ */ React47.createElement(Text41, { color: CARD.tool.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React47.createElement(Text41, null, " "), /* @__PURE__ */ React47.createElement(Text41, { color: CARD.tool.color, bold: true }, `\u25A3 ${tool2.name}`), /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React47.createElement(Box41, { paddingLeft: 3 }, /* @__PURE__ */ React47.createElement(Text41, { color: TONE.brand }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React47.createElement(Box41, { paddingLeft: 3 }, /* @__PURE__ */ React47.createElement(Text41, { color: FG.faint }, summary)) : null);
18727
+ return /* @__PURE__ */ React48.createElement(Box42, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React48.createElement(Box42, null, /* @__PURE__ */ React48.createElement(Text42, { color: CARD.tool.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React48.createElement(Text42, null, " "), /* @__PURE__ */ React48.createElement(Text42, { color: CARD.tool.color, bold: true }, `\u25A3 ${tool2.name}`), /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React48.createElement(Box42, { paddingLeft: 3 }, /* @__PURE__ */ React48.createElement(Text42, { color: TONE.brand }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React48.createElement(Box42, { paddingLeft: 3 }, /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, summary)) : null);
18649
18728
  }
18650
18729
  function renderProgressLine(p) {
18651
18730
  const msg = p.message ? ` ${p.message}` : "";
@@ -18701,16 +18780,16 @@ function summarizeToolArgs(name, args) {
18701
18780
  }
18702
18781
 
18703
18782
  // src/cli/ui/layout/StatusRow.tsx
18704
- import { Box as Box42, Text as Text43, useStdout as useStdout11 } from "ink";
18705
- import React49 from "react";
18783
+ import { Box as Box43, Text as Text44, useStdout as useStdout11 } from "ink";
18784
+ import React50 from "react";
18706
18785
 
18707
18786
  // src/cli/ui/primitives/Countdown.tsx
18708
- import { Text as Text42 } from "ink";
18709
- import React48 from "react";
18787
+ import { Text as Text43 } from "ink";
18788
+ import React49 from "react";
18710
18789
  function Countdown({ endsAt, color: color2 = TONE.brand }) {
18711
18790
  useSlowTick();
18712
18791
  const remainingSec = Math.max(0, Math.ceil((endsAt - Date.now()) / 1e3));
18713
- return /* @__PURE__ */ React48.createElement(Text42, { bold: true, color: color2 }, String(remainingSec));
18792
+ return /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: color2 }, String(remainingSec));
18714
18793
  }
18715
18794
 
18716
18795
  // src/cli/ui/layout/StatusRow.tsx
@@ -18730,7 +18809,7 @@ function StatusRow() {
18730
18809
  const turnCny = status3.cost * USD_TO_CNY;
18731
18810
  const sessionCny = status3.sessionCost * USD_TO_CNY;
18732
18811
  const hasTurn = status3.cost > 0;
18733
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "column" }, /* @__PURE__ */ React49.createElement(Box42, null, /* @__PURE__ */ React49.createElement(Text43, null, " "), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, null, " "), status3.recording ? /* @__PURE__ */ React49.createElement(RecordingPill, { rec: status3.recording }) : status3.countdownSeconds !== void 0 ? /* @__PURE__ */ React49.createElement(CountdownRow, { mode: status3.mode, secondsLeft: status3.countdownSeconds }) : /* @__PURE__ */ React49.createElement(ModePill2, { mode: status3.mode, network: status3.network, detail: status3.networkDetail }), /* @__PURE__ */ React49.createElement(Sep, null), /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React49.createElement(React49.Fragment, null, /* @__PURE__ */ React49.createElement(Sep, null), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: TONE.brand }, "\u25B8 "), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: FG.body }, `\xA5${turnCny.toFixed(4)} turn`)), /* @__PURE__ */ React49.createElement(Sep, null), /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, `\xA5${sessionCny.toFixed(3)} session`), status3.balance !== void 0 && /* @__PURE__ */ React49.createElement(React49.Fragment, null, /* @__PURE__ */ React49.createElement(Sep, null), /* @__PURE__ */ React49.createElement(Text43, { color: FG.faint }, "wallet "), /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: balanceColor(status3.balance) }, `\xA5${status3.balance.toFixed(2)}`)), /* @__PURE__ */ React49.createElement(Sep, null), /* @__PURE__ */ React49.createElement(Text43, { color: TONE.accent }, `cache ${Math.round(status3.cacheHit * 100)}%`)));
18812
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "column" }, /* @__PURE__ */ React50.createElement(Box43, null, /* @__PURE__ */ React50.createElement(Text44, null, " "), /* @__PURE__ */ React50.createElement(Text44, { color: FG.faint }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, null, " "), status3.recording ? /* @__PURE__ */ React50.createElement(RecordingPill, { rec: status3.recording }) : status3.countdownSeconds !== void 0 ? /* @__PURE__ */ React50.createElement(CountdownRow, { mode: status3.mode, secondsLeft: status3.countdownSeconds }) : /* @__PURE__ */ React50.createElement(ModePill2, { mode: status3.mode, network: status3.network, detail: status3.networkDetail }), /* @__PURE__ */ React50.createElement(Sep, null), /* @__PURE__ */ React50.createElement(Text44, { color: FG.sub }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React50.createElement(React50.Fragment, null, /* @__PURE__ */ React50.createElement(Sep, null), /* @__PURE__ */ React50.createElement(Text44, { bold: true, color: TONE.brand }, "\u25B8 "), /* @__PURE__ */ React50.createElement(Text44, { bold: true, color: FG.body }, `\xA5${turnCny.toFixed(4)} turn`)), /* @__PURE__ */ React50.createElement(Sep, null), /* @__PURE__ */ React50.createElement(Text44, { color: FG.sub }, `\xA5${sessionCny.toFixed(3)} session`), status3.balance !== void 0 && /* @__PURE__ */ React50.createElement(React50.Fragment, null, /* @__PURE__ */ React50.createElement(Sep, null), /* @__PURE__ */ React50.createElement(Text44, { color: FG.faint }, "wallet "), /* @__PURE__ */ React50.createElement(Text44, { bold: true, color: balanceColor(status3.balance) }, `\xA5${status3.balance.toFixed(2)}`)), /* @__PURE__ */ React50.createElement(Sep, null), /* @__PURE__ */ React50.createElement(Text44, { color: TONE.accent }, `cache ${Math.round(status3.cacheHit * 100)}%`)));
18734
18813
  }
18735
18814
  function ModePill2({
18736
18815
  mode: mode2,
@@ -18739,18 +18818,18 @@ function ModePill2({
18739
18818
  }) {
18740
18819
  if (network === "online") {
18741
18820
  const pill = modeGlyph(mode2);
18742
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, { color: pill.color }, pill.glyph), /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, ` ${mode2}`));
18821
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { color: pill.color }, pill.glyph), /* @__PURE__ */ React50.createElement(Text44, { color: FG.sub }, ` ${mode2}`));
18743
18822
  }
18744
18823
  const dot2 = networkDot(network);
18745
18824
  if (network === "slow") {
18746
18825
  const tail = detail ? ` \xB7 ${detail}` : "";
18747
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React49.createElement(Text43, { color: dot2.color }, ` ${mode2} \xB7 slow${tail}`));
18826
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React50.createElement(Text44, { color: dot2.color }, ` ${mode2} \xB7 slow${tail}`));
18748
18827
  }
18749
18828
  if (network === "disconnected") {
18750
18829
  const tail = detail ? ` \xB7 ${detail}` : "";
18751
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React49.createElement(Text43, { color: dot2.color }, ` disconnect${tail}`));
18830
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React50.createElement(Text44, { color: dot2.color }, ` disconnect${tail}`));
18752
18831
  }
18753
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React49.createElement(Text43, { color: dot2.color }, " reconnecting\u2026"));
18832
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React50.createElement(Text44, { color: dot2.color }, " reconnecting\u2026"));
18754
18833
  }
18755
18834
  function CountdownRow({
18756
18835
  mode: mode2,
@@ -18758,14 +18837,14 @@ function CountdownRow({
18758
18837
  }) {
18759
18838
  const pill = modeGlyph(mode2);
18760
18839
  const endsAt = Date.now() + secondsLeft * 1e3;
18761
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, { color: pill.color }, pill.glyph), /* @__PURE__ */ React49.createElement(Text43, { color: FG.sub }, ` ${mode2} \xB7 `), /* @__PURE__ */ React49.createElement(Text43, { color: TONE.warn }, "approving in "), /* @__PURE__ */ React49.createElement(Countdown, { endsAt }), /* @__PURE__ */ React49.createElement(Text43, { color: TONE.warn }, "s \xB7 esc to interrupt"));
18840
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { color: pill.color }, pill.glyph), /* @__PURE__ */ React50.createElement(Text44, { color: FG.sub }, ` ${mode2} \xB7 `), /* @__PURE__ */ React50.createElement(Text44, { color: TONE.warn }, "approving in "), /* @__PURE__ */ React50.createElement(Countdown, { endsAt }), /* @__PURE__ */ React50.createElement(Text44, { color: TONE.warn }, "s \xB7 esc to interrupt"));
18762
18841
  }
18763
18842
  function RecordingPill({ rec }) {
18764
18843
  const sizeMb = (rec.sizeBytes / (1024 * 1024)).toFixed(1);
18765
- return /* @__PURE__ */ React49.createElement(Box42, { flexDirection: "row" }, /* @__PURE__ */ React49.createElement(Text43, { bold: true, color: TONE.err }, "\u25CFREC"), /* @__PURE__ */ React49.createElement(Text43, { color: TONE.err }, ` ${sizeMb} MB \xB7 ${rec.events} evt`));
18844
+ return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { bold: true, color: TONE.err }, "\u25CFREC"), /* @__PURE__ */ React50.createElement(Text44, { color: TONE.err }, ` ${sizeMb} MB \xB7 ${rec.events} evt`));
18766
18845
  }
18767
18846
  function Sep() {
18768
- return /* @__PURE__ */ React49.createElement(Text43, { color: FG.meta }, " \xB7 ");
18847
+ return /* @__PURE__ */ React50.createElement(Text44, { color: FG.meta }, " \xB7 ");
18769
18848
  }
18770
18849
  function modeGlyph(mode2) {
18771
18850
  switch (mode2) {
@@ -18793,8 +18872,8 @@ function networkDot(state) {
18793
18872
  }
18794
18873
 
18795
18874
  // src/cli/ui/layout/ToastRail.tsx
18796
- import { Box as Box43, Text as Text44, useStdout as useStdout12 } from "ink";
18797
- import React50, { useEffect as useEffect3 } from "react";
18875
+ import { Box as Box44, Text as Text45, useStdout as useStdout12 } from "ink";
18876
+ import React51, { useEffect as useEffect3 } from "react";
18798
18877
  var TONE_COLOR = {
18799
18878
  ok: TONE.ok,
18800
18879
  info: TONE.brand,
@@ -18832,12 +18911,12 @@ function ToastRail() {
18832
18911
  }, [toasts, dispatch2]);
18833
18912
  const visible = toasts.filter((t2) => now - t2.bornAt < t2.ttlMs);
18834
18913
  if (visible.length === 0) return null;
18835
- return /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "column" }, visible.map((t2) => {
18914
+ return /* @__PURE__ */ React51.createElement(Box44, { flexDirection: "column" }, visible.map((t2) => {
18836
18915
  const color2 = TONE_COLOR[t2.tone];
18837
18916
  const glyph = TONE_GLYPH[t2.tone];
18838
18917
  const body = bodyColor(t2, now);
18839
18918
  const remainingSec = Math.max(0, Math.ceil((t2.ttlMs - (now - t2.bornAt)) / 1e3));
18840
- return /* @__PURE__ */ React50.createElement(Box43, { key: t2.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React50.createElement(Text44, { color: color2 }, rule), /* @__PURE__ */ React50.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React50.createElement(Text44, { color: color2 }, glyph), /* @__PURE__ */ React50.createElement(Text44, { bold: true, color: body }, ` ${t2.title}`), t2.detail !== void 0 && /* @__PURE__ */ React50.createElement(Text44, { color: FG.sub }, ` \xB7 ${t2.detail}`), /* @__PURE__ */ React50.createElement(Box43, { flexGrow: 1 }), /* @__PURE__ */ React50.createElement(Text44, { color: FG.faint }, `${remainingSec}s`)));
18919
+ return /* @__PURE__ */ React51.createElement(Box44, { key: t2.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React51.createElement(Text45, { color: color2 }, rule), /* @__PURE__ */ React51.createElement(Box44, { flexDirection: "row" }, /* @__PURE__ */ React51.createElement(Text45, { color: color2 }, glyph), /* @__PURE__ */ React51.createElement(Text45, { bold: true, color: body }, ` ${t2.title}`), t2.detail !== void 0 && /* @__PURE__ */ React51.createElement(Text45, { color: FG.sub }, ` \xB7 ${t2.detail}`), /* @__PURE__ */ React51.createElement(Box44, { flexGrow: 1 }), /* @__PURE__ */ React51.createElement(Text45, { color: FG.faint }, `${remainingSec}s`)));
18841
18920
  }));
18842
18921
  }
18843
18922
 
@@ -20519,15 +20598,23 @@ var handlers6 = {
20519
20598
  };
20520
20599
 
20521
20600
  // src/cli/ui/slash/handlers/mcp.ts
20522
- var mcp = (_args, loop2, ctx) => {
20601
+ var mcp = (args, loop2, ctx) => {
20523
20602
  const servers = ctx.mcpServers ?? [];
20524
20603
  const specs = ctx.mcpSpecs ?? [];
20525
20604
  const toolSpecs = loop2.prefix.toolSpecs ?? [];
20605
+ const sub = args[0];
20606
+ if (sub === "disable" || sub === "enable") {
20607
+ return toggleDisabled(sub, args[1], { servers, specs });
20608
+ }
20609
+ const wantsTextDump = sub === "text";
20526
20610
  if (servers.length === 0 && specs.length === 0 && toolSpecs.length === 0) {
20527
20611
  return {
20528
20612
  info: 'no MCP servers attached. Run `reasonix setup` to pick some, or launch with --mcp "<spec>". `reasonix mcp list` shows the catalog.'
20529
20613
  };
20530
20614
  }
20615
+ if (!wantsTextDump && servers.length > 0) {
20616
+ return { openMcpBrowser: true };
20617
+ }
20531
20618
  if (servers.length > 0) {
20532
20619
  const lines2 = [];
20533
20620
  let anyResources = false;
@@ -20536,7 +20623,7 @@ var mcp = (_args, loop2, ctx) => {
20536
20623
  const { report } = s;
20537
20624
  const serverName = report.serverInfo.name || "(unknown)";
20538
20625
  const serverVer = report.serverInfo.version ? ` v${report.serverInfo.version}` : "";
20539
- const health = healthBadge(report.elapsedMs);
20626
+ const health = healthBadge2(report.elapsedMs);
20540
20627
  lines2.push(`${health} [${s.label}] ${serverName}${serverVer} \u2014 ${s.spec}`);
20541
20628
  lines2.push(` tools ${s.toolCount}`);
20542
20629
  appendSection(lines2, "resources", report.resources);
@@ -20574,11 +20661,49 @@ var mcp = (_args, loop2, ctx) => {
20574
20661
  lines.push("To change this set, exit and run `reasonix setup`.");
20575
20662
  return { info: lines.join("\n") };
20576
20663
  };
20577
- function healthBadge(elapsedMs) {
20664
+ function healthBadge2(elapsedMs) {
20578
20665
  if (elapsedMs < 500) return `\u25CF healthy \xB7 ${elapsedMs}ms`;
20579
20666
  if (elapsedMs < 3e3) return `\u25CC slow \xB7 ${elapsedMs}ms`;
20580
20667
  return `\u2717 very slow \xB7 ${elapsedMs}ms`;
20581
20668
  }
20669
+ function toggleDisabled(action, rawName, ctx) {
20670
+ const name = rawName?.trim();
20671
+ if (!name) {
20672
+ return {
20673
+ info: `usage: /mcp ${action} <name> \xB7 pick a name shown in /mcp (anonymous servers can't be named-toggled).`
20674
+ };
20675
+ }
20676
+ const known = /* @__PURE__ */ new Set([
20677
+ ...ctx.servers.map((s) => s.label),
20678
+ ...ctx.specs.map((spec) => parseLabelFromSpec(spec)).filter((n) => n !== null)
20679
+ ]);
20680
+ if (!known.has(name)) {
20681
+ const list2 = [...known].sort().join(", ") || "(none)";
20682
+ return { info: `unknown MCP server "${name}". Known: ${list2}.` };
20683
+ }
20684
+ const cfg = readConfig();
20685
+ const current = new Set(cfg.mcpDisabled ?? []);
20686
+ if (action === "disable") {
20687
+ if (current.has(name)) {
20688
+ return { info: `\u25B8 ${name} is already disabled \u2014 restart to apply, or /mcp enable ${name}.` };
20689
+ }
20690
+ current.add(name);
20691
+ writeConfig({ ...cfg, mcpDisabled: [...current].sort() });
20692
+ return {
20693
+ info: `\u25B8 ${name} disabled \u2014 takes effect on next launch. /mcp enable ${name} to revert.`
20694
+ };
20695
+ }
20696
+ if (!current.has(name)) {
20697
+ return { info: `\u25B8 ${name} is not disabled.` };
20698
+ }
20699
+ current.delete(name);
20700
+ writeConfig({ ...cfg, mcpDisabled: current.size > 0 ? [...current].sort() : void 0 });
20701
+ return { info: `\u25B8 ${name} re-enabled \u2014 takes effect on next launch.` };
20702
+ }
20703
+ function parseLabelFromSpec(spec) {
20704
+ const match = spec.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=/);
20705
+ return match ? match[1] ?? null : null;
20706
+ }
20582
20707
  var handlers7 = { mcp };
20583
20708
 
20584
20709
  // src/cli/ui/slash/handlers/memory.ts
@@ -20919,17 +21044,17 @@ var handlers9 = {
20919
21044
  };
20920
21045
 
20921
21046
  // src/cli/ui/ctx-breakdown.tsx
20922
- import { Box as Box44, Text as Text46 } from "ink";
20923
- import React52 from "react";
21047
+ import { Box as Box45, Text as Text47 } from "ink";
21048
+ import React53 from "react";
20924
21049
 
20925
21050
  // src/cli/ui/primitives.tsx
20926
- import { Text as Text45, useStdout as useStdout13 } from "ink";
20927
- import React51 from "react";
21051
+ import { Text as Text46, useStdout as useStdout13 } from "ink";
21052
+ import React52 from "react";
20928
21053
  function ChromeRule() {
20929
21054
  const { stdout: stdout4 } = useStdout13();
20930
21055
  const cols = stdout4?.columns ?? 80;
20931
21056
  const w = Math.max(20, cols - 2);
20932
- return /* @__PURE__ */ React51.createElement(Text45, { dimColor: true }, "\u2500".repeat(w));
21057
+ return /* @__PURE__ */ React52.createElement(Text46, { dimColor: true }, "\u2500".repeat(w));
20933
21058
  }
20934
21059
  function Bar({
20935
21060
  ratio,
@@ -20938,7 +21063,7 @@ function Bar({
20938
21063
  dim
20939
21064
  }) {
20940
21065
  const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
20941
- return /* @__PURE__ */ React51.createElement(Text45, null, /* @__PURE__ */ React51.createElement(Text45, { color: color2, dimColor: dim }, "\u25B0".repeat(filled)), /* @__PURE__ */ React51.createElement(Text45, { dimColor: true }, "\u25B1".repeat(cells - filled)));
21066
+ return /* @__PURE__ */ React52.createElement(Text46, null, /* @__PURE__ */ React52.createElement(Text46, { color: color2, dimColor: dim }, "\u25B0".repeat(filled)), /* @__PURE__ */ React52.createElement(Text46, { dimColor: true }, "\u25B1".repeat(cells - filled)));
20942
21067
  }
20943
21068
 
20944
21069
  // src/cli/ui/ctx-breakdown.tsx
@@ -21957,7 +22082,7 @@ function hydrateCardsFromMessages(messages) {
21957
22082
  }
21958
22083
 
21959
22084
  // src/cli/ui/useCompletionPickers.ts
21960
- import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo5, useRef as useRef3, useState as useState10 } from "react";
22085
+ import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo5, useRef as useRef3, useState as useState11 } from "react";
21961
22086
  function useCompletionPickers({
21962
22087
  input,
21963
22088
  setInput,
@@ -21966,7 +22091,7 @@ function useCompletionPickers({
21966
22091
  models: models2,
21967
22092
  mcpServers
21968
22093
  }) {
21969
- const [slashSelected, setSlashSelected] = useState10(0);
22094
+ const [slashSelected, setSlashSelected] = useState11(0);
21970
22095
  const slashMatches = useMemo5(() => {
21971
22096
  if (!input.startsWith("/") || input.includes(" ")) return null;
21972
22097
  return suggestSlashCommands(input.slice(1), !!codeMode);
@@ -21978,8 +22103,8 @@ function useCompletionPickers({
21978
22103
  return prev;
21979
22104
  });
21980
22105
  }, [slashMatches]);
21981
- const [atSelected, setAtSelected] = useState10(0);
21982
- const [atFiles, setAtFiles] = useState10([]);
22106
+ const [atSelected, setAtSelected] = useState11(0);
22107
+ const [atFiles, setAtFiles] = useState11([]);
21983
22108
  useEffect4(() => {
21984
22109
  if (!codeMode) {
21985
22110
  setAtFiles([]);
@@ -22030,7 +22155,7 @@ function useCompletionPickers({
22030
22155
  },
22031
22156
  [atPicker, input, setInput]
22032
22157
  );
22033
- const [slashArgSelected, setSlashArgSelected] = useState10(0);
22158
+ const [slashArgSelected, setSlashArgSelected] = useState11(0);
22034
22159
  const slashArgContext = useMemo5(() => {
22035
22160
  if (!input.startsWith("/")) return null;
22036
22161
  if (slashMatches !== null) return null;
@@ -22110,12 +22235,12 @@ function useCompletionPickers({
22110
22235
  }
22111
22236
 
22112
22237
  // src/cli/ui/useEditHistory.ts
22113
- import { useCallback as useCallback3, useRef as useRef4, useState as useState11 } from "react";
22238
+ import { useCallback as useCallback3, useRef as useRef4, useState as useState12 } from "react";
22114
22239
  function useEditHistory(codeMode) {
22115
22240
  const editHistory = useRef4([]);
22116
22241
  const nextHistoryId = useRef4(1);
22117
22242
  const currentTurnEntry = useRef4(null);
22118
- const [undoBanner, setUndoBanner] = useState11(null);
22243
+ const [undoBanner, setUndoBanner] = useState12(null);
22119
22244
  const undoTimeoutRef = useRef4(null);
22120
22245
  const recordEdit = useCallback3(
22121
22246
  (source, blocks, results, snaps) => {
@@ -22320,11 +22445,11 @@ function useEditHistory(codeMode) {
22320
22445
  }
22321
22446
 
22322
22447
  // src/cli/ui/useSessionInfo.ts
22323
- import { useCallback as useCallback4, useEffect as useEffect5, useState as useState12 } from "react";
22448
+ import { useCallback as useCallback4, useEffect as useEffect5, useState as useState13 } from "react";
22324
22449
  function useSessionInfo(loop2) {
22325
- const [balance, setBalance] = useState12(null);
22326
- const [models2, setModels] = useState12(null);
22327
- const [latestVersion, setLatestVersion] = useState12(null);
22450
+ const [balance, setBalance] = useState13(null);
22451
+ const [models2, setModels] = useState13(null);
22452
+ const [latestVersion, setLatestVersion] = useState13(null);
22328
22453
  useEffect5(() => {
22329
22454
  let cancelled = false;
22330
22455
  void (async () => {
@@ -22393,7 +22518,7 @@ function useSessionInfo(loop2) {
22393
22518
  }
22394
22519
 
22395
22520
  // src/cli/ui/useSubagent.ts
22396
- import { useEffect as useEffect6, useRef as useRef5, useState as useState13 } from "react";
22521
+ import { useEffect as useEffect6, useRef as useRef5, useState as useState14 } from "react";
22397
22522
  function summariseInner(ev) {
22398
22523
  if (ev.role === "tool_start") {
22399
22524
  return {
@@ -22420,7 +22545,7 @@ function summariseInner(ev) {
22420
22545
  return null;
22421
22546
  }
22422
22547
  function useSubagent({ session, log }) {
22423
- const [activity, setActivity] = useState13(null);
22548
+ const [activity, setActivity] = useState14(null);
22424
22549
  const sinkRef = useRef5({ current: null });
22425
22550
  useEffect6(() => {
22426
22551
  sinkRef.current.current = (ev) => {
@@ -22503,13 +22628,13 @@ var PLAIN_UI = process.env.REASONIX_UI === "plain";
22503
22628
  function LoopStatusRow({
22504
22629
  loop: loop2
22505
22630
  }) {
22506
- const [, setTick] = React53.useState(0);
22507
- React53.useEffect(() => {
22631
+ const [, setTick] = React54.useState(0);
22632
+ React54.useEffect(() => {
22508
22633
  const id = setInterval(() => setTick((t2) => t2 + 1), 1e3);
22509
22634
  return () => clearInterval(id);
22510
22635
  }, []);
22511
22636
  const nextFireMs = Math.max(0, loop2.nextFireAt - Date.now());
22512
- return /* @__PURE__ */ React53.createElement(Box45, null, /* @__PURE__ */ React53.createElement(Text47, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
22637
+ return /* @__PURE__ */ React54.createElement(Box46, null, /* @__PURE__ */ React54.createElement(Text48, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
22513
22638
  }
22514
22639
  function App(props) {
22515
22640
  const session = useAgentSession({
@@ -22517,11 +22642,11 @@ function App(props) {
22517
22642
  model: props.model,
22518
22643
  workspace: props.codeMode?.rootDir ?? process.cwd()
22519
22644
  });
22520
- const initialCards = React53.useMemo(
22645
+ const initialCards = React54.useMemo(
22521
22646
  () => props.session ? hydrateCardsFromMessages(loadSessionMessages(props.session)) : [],
22522
22647
  [props.session]
22523
22648
  );
22524
- return /* @__PURE__ */ React53.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ React53.createElement(AppInner, { ...props }));
22649
+ return /* @__PURE__ */ React54.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ React54.createElement(AppInner, { ...props }));
22525
22650
  }
22526
22651
  function AppInner({
22527
22652
  model: model2,
@@ -22554,14 +22679,14 @@ function AppInner({
22554
22679
  }
22555
22680
  return null;
22556
22681
  });
22557
- const [input, setInput] = useState14("");
22558
- const [busy, setBusy] = useState14(false);
22682
+ const [input, setInput] = useState15("");
22683
+ const [busy, setBusy] = useState15(false);
22559
22684
  const abortedThisTurn = useRef6(false);
22560
22685
  useEffect7(() => {
22561
22686
  busyRef.current = busy;
22562
22687
  }, [busy]);
22563
- const [ongoingTool, setOngoingTool] = useState14(null);
22564
- const [toolProgress, setToolProgress] = useState14(null);
22688
+ const [ongoingTool, setOngoingTool] = useState15(null);
22689
+ const [toolProgress, setToolProgress] = useState15(null);
22565
22690
  const { stdout: stdout4 } = useStdout14();
22566
22691
  useEffect7(() => {
22567
22692
  if (!stdout4 || !stdout4.isTTY) return;
@@ -22572,7 +22697,7 @@ function AppInner({
22572
22697
  stdout4.write("\x1B[>4m");
22573
22698
  };
22574
22699
  }, [stdout4]);
22575
- const [isResizing, setIsResizing] = useState14(false);
22700
+ const [isResizing, setIsResizing] = useState15(false);
22576
22701
  useEffect7(() => {
22577
22702
  if (!stdout4 || !stdout4.isTTY) return;
22578
22703
  let timer = null;
@@ -22594,11 +22719,11 @@ function AppInner({
22594
22719
  session,
22595
22720
  log
22596
22721
  });
22597
- const [statusLine, setStatusLine] = useState14(null);
22598
- const [currentRootDir, setCurrentRootDir] = useState14(
22722
+ const [statusLine, setStatusLine] = useState15(null);
22723
+ const [currentRootDir, setCurrentRootDir] = useState15(
22599
22724
  () => codeMode?.rootDir ?? process.cwd()
22600
22725
  );
22601
- const [hookList, setHookList] = useState14(
22726
+ const [hookList, setHookList] = useState15(
22602
22727
  () => loadHooks({ projectRoot: codeMode?.rootDir })
22603
22728
  );
22604
22729
  const {
@@ -22613,13 +22738,13 @@ function AppInner({
22613
22738
  touchedPaths
22614
22739
  } = useEditHistory(codeMode);
22615
22740
  const pendingEdits = useRef6([]);
22616
- const [pendingCount, setPendingCount] = useState14(0);
22741
+ const [pendingCount, setPendingCount] = useState15(0);
22617
22742
  const syncPendingCount = useCallback5(() => {
22618
22743
  setPendingCount(pendingEdits.current.length);
22619
22744
  setPendingTick((t2) => t2 + 1);
22620
22745
  }, []);
22621
- const [editMode, setEditMode] = useState14(() => codeMode ? loadEditMode() : "review");
22622
- const [preset2, setPreset] = useState14(() => {
22746
+ const [editMode, setEditMode] = useState15(() => codeMode ? loadEditMode() : "review");
22747
+ const [preset2, setPreset] = useState15(() => {
22623
22748
  if (model2 === "deepseek-v4-pro") return "pro";
22624
22749
  return "auto";
22625
22750
  });
@@ -22631,12 +22756,12 @@ function AppInner({
22631
22756
  const planModeRef = useRef6(false);
22632
22757
  const currentRootDirRef = useRef6("");
22633
22758
  const latestVersionRef = useRef6(null);
22634
- const [pendingEditReview, setPendingEditReview] = useState14(null);
22635
- const [walkthroughActive, setWalkthroughActive] = useState14(false);
22636
- const [pendingTick, setPendingTick] = useState14(0);
22759
+ const [pendingEditReview, setPendingEditReview] = useState15(null);
22760
+ const [walkthroughActive, setWalkthroughActive] = useState15(false);
22761
+ const [pendingTick, setPendingTick] = useState15(0);
22637
22762
  const editReviewResolveRef = useRef6(null);
22638
22763
  const turnEditPolicyRef = useRef6("ask");
22639
- const [modeFlash, setModeFlash] = useState14(false);
22764
+ const [modeFlash, setModeFlash] = useState15(false);
22640
22765
  const modeFlashTimeoutRef = useRef6(null);
22641
22766
  const prevEditModeRef = useRef6(editMode);
22642
22767
  useEffect7(() => {
@@ -22649,26 +22774,27 @@ function AppInner({
22649
22774
  modeFlashTimeoutRef.current = null;
22650
22775
  }, 1200);
22651
22776
  }, [editMode]);
22652
- const [pendingShell, setPendingShell] = useState14(null);
22653
- const [pendingPlan, setPendingPlan] = useState14(null);
22654
- const [pendingReviseEditor, setPendingReviseEditor] = useState14(null);
22655
- const [pendingSessionsPicker, setPendingSessionsPicker] = useState14(false);
22656
- const [sessionsPickerList, setSessionsPickerList] = useState14([]);
22657
- const [stagedInput, setStagedInput] = useState14(null);
22658
- const [pendingCheckpoint, setPendingCheckpoint] = useState14(null);
22659
- const [stagedCheckpointRevise, setStagedCheckpointRevise] = useState14(null);
22660
- const [pendingRevision, setPendingRevision] = useState14(null);
22661
- const [pendingChoice, setPendingChoice] = useState14(null);
22662
- const [stagedChoiceCustom, setStagedChoiceCustom] = useState14(null);
22663
- const [planMode, setPlanMode] = useState14(false);
22664
- const [proArmed, setProArmed] = useState14(false);
22665
- const [turnOnPro, setTurnOnPro] = useState14(false);
22666
- const [queuedSubmit, setQueuedSubmit] = useState14(null);
22777
+ const [pendingShell, setPendingShell] = useState15(null);
22778
+ const [pendingPlan, setPendingPlan] = useState15(null);
22779
+ const [pendingReviseEditor, setPendingReviseEditor] = useState15(null);
22780
+ const [pendingSessionsPicker, setPendingSessionsPicker] = useState15(false);
22781
+ const [sessionsPickerList, setSessionsPickerList] = useState15([]);
22782
+ const [pendingMcpBrowser, setPendingMcpBrowser] = useState15(false);
22783
+ const [stagedInput, setStagedInput] = useState15(null);
22784
+ const [pendingCheckpoint, setPendingCheckpoint] = useState15(null);
22785
+ const [stagedCheckpointRevise, setStagedCheckpointRevise] = useState15(null);
22786
+ const [pendingRevision, setPendingRevision] = useState15(null);
22787
+ const [pendingChoice, setPendingChoice] = useState15(null);
22788
+ const [stagedChoiceCustom, setStagedChoiceCustom] = useState15(null);
22789
+ const [planMode, setPlanMode] = useState15(false);
22790
+ const [proArmed, setProArmed] = useState15(false);
22791
+ const [turnOnPro, setTurnOnPro] = useState15(false);
22792
+ const [queuedSubmit, setQueuedSubmit] = useState15(null);
22667
22793
  const promptHistory = useRef6([]);
22668
22794
  const historyCursor = useRef6(-1);
22669
22795
  const assistantIterCounter = useRef6(0);
22670
22796
  const atUrlCache = useRef6(/* @__PURE__ */ new Map());
22671
- const [activeLoop, setActiveLoop] = useState14(null);
22797
+ const [activeLoop, setActiveLoop] = useState15(null);
22672
22798
  const loopTimerRef = useRef6(null);
22673
22799
  const handleSubmitRef = useRef6(null);
22674
22800
  const busyRef = useRef6(false);
@@ -22698,7 +22824,7 @@ function AppInner({
22698
22824
  if (planSummaryRef.current) extras.summary = planSummaryRef.current;
22699
22825
  savePlanState(session, steps, completedStepIdsRef.current, extras);
22700
22826
  }, [session]);
22701
- const [summary, setSummary] = useState14({
22827
+ const [summary, setSummary] = useState15({
22702
22828
  turns: 0,
22703
22829
  totalCostUsd: 0,
22704
22830
  totalInputCostUsd: 0,
@@ -23053,7 +23179,7 @@ function AppInner({
23053
23179
  );
23054
23180
  return;
23055
23181
  }
23056
- if (codeMode && key.shift && key.tab && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !walkthroughActive && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision) {
23182
+ if (codeMode && key.shift && key.tab && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !walkthroughActive && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision) {
23057
23183
  const cur = editModeRef.current;
23058
23184
  const next = cur === "review" ? "auto" : cur === "auto" ? "yolo" : "review";
23059
23185
  setEditMode(next);
@@ -23061,7 +23187,7 @@ function AppInner({
23061
23187
  log.pushInfo(message);
23062
23188
  return;
23063
23189
  }
23064
- if (codeMode && input.length === 0 && (chKey === "u" || chKey === "U") && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !walkthroughActive && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision && // Fire when EITHER the banner is up OR there's any non-undone
23190
+ if (codeMode && input.length === 0 && (chKey === "u" || chKey === "U") && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !walkthroughActive && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision && // Fire when EITHER the banner is up OR there's any non-undone
23065
23191
  // history entry — the keybind is useful long after the 5-second
23066
23192
  // banner expires, which users rightly want.
23067
23193
  (undoBanner || hasUndoable())) {
@@ -23515,7 +23641,7 @@ function AppInner({
23515
23641
  const getDashboardUrl = useCallback5(() => {
23516
23642
  return dashboardRef.current?.url ?? null;
23517
23643
  }, []);
23518
- const [dashboardUrl, setDashboardUrlState] = useState14(null);
23644
+ const [dashboardUrl, setDashboardUrlState] = useState15(null);
23519
23645
  useEffect7(() => {
23520
23646
  if (noDashboard) return;
23521
23647
  if (dashboardRef.current) return;
@@ -23717,6 +23843,11 @@ function AppInner({
23717
23843
  promptHistory.current.push(text);
23718
23844
  return;
23719
23845
  }
23846
+ if (result.openMcpBrowser) {
23847
+ setPendingMcpBrowser(true);
23848
+ promptHistory.current.push(text);
23849
+ return;
23850
+ }
23720
23851
  const outcome = applySlashResult(result, {
23721
23852
  log,
23722
23853
  stdoutWrite: (chunk) => stdout4?.write(chunk),
@@ -24417,10 +24548,10 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24417
24548
  async (choice) => handleReviseConfirmRef.current(choice),
24418
24549
  []
24419
24550
  );
24420
- return /* @__PURE__ */ React53.createElement(React53.Fragment, null, /* @__PURE__ */ React53.createElement(
24551
+ return /* @__PURE__ */ React54.createElement(React54.Fragment, null, /* @__PURE__ */ React54.createElement(
24421
24552
  TickerProvider,
24422
24553
  {
24423
- disabled: PLAIN_UI || isResizing || !!pendingPlan || !!pendingReviseEditor || pendingSessionsPicker || !!pendingShell || !!pendingEditReview || walkthroughActive || !!pendingCheckpoint || !!stagedCheckpointRevise || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || // Idle gate: when nothing is actively happening, suspend the
24554
+ disabled: PLAIN_UI || isResizing || !!pendingPlan || !!pendingReviseEditor || pendingSessionsPicker || pendingMcpBrowser || !!pendingShell || !!pendingEditReview || walkthroughActive || !!pendingCheckpoint || !!stagedCheckpointRevise || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || // Idle gate: when nothing is actively happening, suspend the
24424
24555
  // 8Hz/1Hz heartbeats. The cursor blink, gradient pulse, and
24425
24556
  // spinner glyphs are pure cosmetics — running them at idle
24426
24557
  // forces Ink to repaint the screen ~8x/sec, which erases any
@@ -24430,28 +24561,28 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24430
24561
  // changes (incoming stream, key press, modal popup).
24431
24562
  !busy && !isStreaming
24432
24563
  },
24433
- /* @__PURE__ */ React53.createElement(Box45, { flexDirection: "column" }, /* @__PURE__ */ React53.createElement(Box45, { flexDirection: "column" }, /* @__PURE__ */ React53.createElement(CardStream, { excludeId: activePlanCard?.id }), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */ React53.createElement(WelcomeBanner, { inCodeMode: !!codeMode, dashboardUrl }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && ongoingTool ? /* @__PURE__ */ React53.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && subagentActivity ? /* @__PURE__ */ React53.createElement(SubagentRow, { activity: subagentActivity }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !ongoingTool && statusLine ? /* @__PURE__ */ React53.createElement(ThinkingRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision ? /* @__PURE__ */ React53.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && busy && !isStreaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React53.createElement(ThinkingRow, { text: "processing\u2026" }) : null, /* @__PURE__ */ React53.createElement(ToastRail, null)), !PLAIN_UI && activePlanCard ? /* @__PURE__ */ React53.createElement(Box45, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React53.createElement(PlanCard, { card: activePlanCard })) : null, stagedInput ? /* @__PURE__ */ React53.createElement(
24564
+ /* @__PURE__ */ React54.createElement(Box46, { flexDirection: "column" }, /* @__PURE__ */ React54.createElement(Box46, { flexDirection: "column" }, /* @__PURE__ */ React54.createElement(CardStream, { excludeId: activePlanCard?.id }), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */ React54.createElement(WelcomeBanner, { inCodeMode: !!codeMode, dashboardUrl }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && ongoingTool ? /* @__PURE__ */ React54.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && subagentActivity ? /* @__PURE__ */ React54.createElement(SubagentRow, { activity: subagentActivity }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !ongoingTool && statusLine ? /* @__PURE__ */ React54.createElement(ThinkingRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && !pendingChoice && !stagedChoiceCustom && !pendingRevision ? /* @__PURE__ */ React54.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpBrowser && !stagedInput && !pendingEditReview && !pendingCheckpoint && !stagedCheckpointRevise && busy && !isStreaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React54.createElement(ThinkingRow, { text: "processing\u2026" }) : null, /* @__PURE__ */ React54.createElement(ToastRail, null)), !PLAIN_UI && activePlanCard ? /* @__PURE__ */ React54.createElement(Box46, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React54.createElement(PlanCard, { card: activePlanCard })) : null, stagedInput ? /* @__PURE__ */ React54.createElement(
24434
24565
  PlanRefineInput,
24435
24566
  {
24436
24567
  mode: stagedInput.mode,
24437
24568
  onSubmit: handleStagedInputSubmit,
24438
24569
  onCancel: handleStagedInputCancel
24439
24570
  }
24440
- ) : stagedCheckpointRevise ? /* @__PURE__ */ React53.createElement(
24571
+ ) : stagedCheckpointRevise ? /* @__PURE__ */ React54.createElement(
24441
24572
  PlanRefineInput,
24442
24573
  {
24443
24574
  mode: "checkpoint-revise",
24444
24575
  onSubmit: handleCheckpointReviseSubmit,
24445
24576
  onCancel: handleCheckpointReviseCancel
24446
24577
  }
24447
- ) : stagedChoiceCustom ? /* @__PURE__ */ React53.createElement(
24578
+ ) : stagedChoiceCustom ? /* @__PURE__ */ React54.createElement(
24448
24579
  PlanRefineInput,
24449
24580
  {
24450
24581
  mode: "choice-custom",
24451
24582
  onSubmit: handleChoiceCustomSubmit,
24452
24583
  onCancel: handleChoiceCustomCancel
24453
24584
  }
24454
- ) : pendingChoice ? /* @__PURE__ */ React53.createElement(
24585
+ ) : pendingChoice ? /* @__PURE__ */ React54.createElement(
24455
24586
  ChoiceConfirm,
24456
24587
  {
24457
24588
  question: pendingChoice.question,
@@ -24459,7 +24590,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24459
24590
  allowCustom: pendingChoice.allowCustom,
24460
24591
  onChoose: stableHandleChoiceConfirm
24461
24592
  }
24462
- ) : pendingRevision ? /* @__PURE__ */ React53.createElement(
24593
+ ) : pendingRevision ? /* @__PURE__ */ React54.createElement(
24463
24594
  PlanReviseConfirm,
24464
24595
  {
24465
24596
  reason: pendingRevision.reason,
@@ -24470,7 +24601,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24470
24601
  summary: pendingRevision.summary,
24471
24602
  onChoose: stableHandleReviseConfirm
24472
24603
  }
24473
- ) : pendingCheckpoint ? /* @__PURE__ */ React53.createElement(
24604
+ ) : pendingCheckpoint ? /* @__PURE__ */ React54.createElement(
24474
24605
  PlanCheckpointConfirm,
24475
24606
  {
24476
24607
  stepId: pendingCheckpoint.stepId,
@@ -24481,7 +24612,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24481
24612
  completedStepIds: completedStepIdsRef.current,
24482
24613
  onChoose: stableHandleCheckpointConfirm
24483
24614
  }
24484
- ) : pendingSessionsPicker ? /* @__PURE__ */ React53.createElement(
24615
+ ) : pendingSessionsPicker ? /* @__PURE__ */ React54.createElement(
24485
24616
  SessionPicker,
24486
24617
  {
24487
24618
  sessions: sessionsPickerList,
@@ -24524,7 +24655,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24524
24655
  }
24525
24656
  }
24526
24657
  }
24527
- ) : pendingPlan ? /* @__PURE__ */ React53.createElement(
24658
+ ) : pendingMcpBrowser ? /* @__PURE__ */ React54.createElement(
24659
+ McpBrowser,
24660
+ {
24661
+ servers: mcpServers ?? [],
24662
+ configPath: defaultConfigPath(),
24663
+ onClose: () => setPendingMcpBrowser(false)
24664
+ }
24665
+ ) : pendingPlan ? /* @__PURE__ */ React54.createElement(
24528
24666
  PlanConfirm,
24529
24667
  {
24530
24668
  plan: pendingPlan,
@@ -24533,7 +24671,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24533
24671
  onChoose: stableHandlePlanConfirm,
24534
24672
  projectRoot: currentRootDir
24535
24673
  }
24536
- ) : pendingReviseEditor ? /* @__PURE__ */ React53.createElement(
24674
+ ) : pendingReviseEditor ? /* @__PURE__ */ React54.createElement(
24537
24675
  PlanReviseEditor,
24538
24676
  {
24539
24677
  steps: planStepsRef.current ?? [],
@@ -24552,7 +24690,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24552
24690
  setPendingPlan(planText);
24553
24691
  }
24554
24692
  }
24555
- ) : pendingShell ? /* @__PURE__ */ React53.createElement(
24693
+ ) : pendingShell ? /* @__PURE__ */ React54.createElement(
24556
24694
  ShellConfirm,
24557
24695
  {
24558
24696
  command: pendingShell.command,
@@ -24560,7 +24698,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24560
24698
  kind: pendingShell.kind,
24561
24699
  onChoose: handleShellConfirm
24562
24700
  }
24563
- ) : pendingEditReview ? /* @__PURE__ */ React53.createElement(
24701
+ ) : pendingEditReview ? /* @__PURE__ */ React54.createElement(
24564
24702
  EditConfirm,
24565
24703
  {
24566
24704
  block: pendingEditReview,
@@ -24572,14 +24710,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24572
24710
  }
24573
24711
  }
24574
24712
  }
24575
- ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React53.createElement(
24713
+ ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React54.createElement(
24576
24714
  EditConfirm,
24577
24715
  {
24578
24716
  key: `walk-${pendingTick}`,
24579
24717
  block: pendingEdits.current[0],
24580
24718
  onChoose: handleWalkChoice
24581
24719
  }
24582
- ) : /* @__PURE__ */ React53.createElement(React53.Fragment, null, codeMode ? /* @__PURE__ */ React53.createElement(
24720
+ ) : /* @__PURE__ */ React54.createElement(React54.Fragment, null, codeMode ? /* @__PURE__ */ React54.createElement(
24583
24721
  ModeStatusBar,
24584
24722
  {
24585
24723
  editMode,
@@ -24589,7 +24727,7 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24589
24727
  undoArmed: !!undoBanner || hasUndoable(),
24590
24728
  jobs: codeMode.jobs
24591
24729
  }
24592
- ) : null, activeLoop ? /* @__PURE__ */ React53.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React53.createElement(StatusRow, null), /* @__PURE__ */ React53.createElement(
24730
+ ) : null, activeLoop ? /* @__PURE__ */ React54.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React54.createElement(StatusRow, null), /* @__PURE__ */ React54.createElement(
24593
24731
  PromptInput,
24594
24732
  {
24595
24733
  value: input,
@@ -24599,14 +24737,14 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24599
24737
  onHistoryPrev: recallPrev,
24600
24738
  onHistoryNext: recallNext
24601
24739
  }
24602
- ), slashMatches !== null ? /* @__PURE__ */ React53.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }) : null, atMatches !== null ? /* @__PURE__ */ React53.createElement(
24740
+ ), slashMatches !== null ? /* @__PURE__ */ React54.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }) : null, atMatches !== null ? /* @__PURE__ */ React54.createElement(
24603
24741
  AtMentionSuggestions,
24604
24742
  {
24605
24743
  matches: atMatches,
24606
24744
  selectedIndex: atSelected,
24607
24745
  query: atPicker?.query ?? ""
24608
24746
  }
24609
- ) : null, slashArgContext ? /* @__PURE__ */ React53.createElement(
24747
+ ) : null, slashArgContext ? /* @__PURE__ */ React54.createElement(
24610
24748
  SlashArgPicker,
24611
24749
  {
24612
24750
  matches: slashArgMatches,
@@ -24620,12 +24758,12 @@ Continue executing from the next pending step. Call mark_step_complete after eac
24620
24758
  }
24621
24759
 
24622
24760
  // src/cli/ui/Setup.tsx
24623
- import { Box as Box46, Text as Text48, useApp } from "ink";
24761
+ import { Box as Box47, Text as Text49, useApp } from "ink";
24624
24762
  import TextInput from "ink-text-input";
24625
- import React54, { useState as useState15 } from "react";
24763
+ import React55, { useState as useState16 } from "react";
24626
24764
  function Setup({ onReady }) {
24627
- const [value, setValue] = useState15("");
24628
- const [error, setError] = useState15(null);
24765
+ const [value, setValue] = useState16("");
24766
+ const [error, setError] = useState16(null);
24629
24767
  const { exit: exit2 } = useApp();
24630
24768
  const handleSubmit2 = (raw) => {
24631
24769
  const trimmed = raw.trim();
@@ -24646,7 +24784,7 @@ function Setup({ onReady }) {
24646
24784
  }
24647
24785
  onReady(trimmed);
24648
24786
  };
24649
- return /* @__PURE__ */ React54.createElement(Box46, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React54.createElement(Box46, null, /* @__PURE__ */ React54.createElement(Text48, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React54.createElement(Text48, null, " "), /* @__PURE__ */ React54.createElement(Text48, { bold: true }, "Welcome to "), /* @__PURE__ */ React54.createElement(Text48, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React54.createElement(Box46, { marginTop: 1 }, /* @__PURE__ */ React54.createElement(Text48, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React54.createElement(Box46, null, /* @__PURE__ */ React54.createElement(Text48, { dimColor: true }, " free credit on signup \xB7 "), /* @__PURE__ */ React54.createElement(Text48, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React54.createElement(Box46, null, /* @__PURE__ */ React54.createElement(Text48, { dimColor: true }, " saved to "), /* @__PURE__ */ React54.createElement(Text48, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React54.createElement(Box46, { marginTop: 1 }, /* @__PURE__ */ React54.createElement(Text48, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React54.createElement(Text48, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React54.createElement(
24787
+ return /* @__PURE__ */ React55.createElement(Box47, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React55.createElement(Box47, null, /* @__PURE__ */ React55.createElement(Text49, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React55.createElement(Text49, null, " "), /* @__PURE__ */ React55.createElement(Text49, { bold: true }, "Welcome to "), /* @__PURE__ */ React55.createElement(Text49, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React55.createElement(Box47, { marginTop: 1 }, /* @__PURE__ */ React55.createElement(Text49, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React55.createElement(Box47, null, /* @__PURE__ */ React55.createElement(Text49, { dimColor: true }, " sign up at \xB7 "), /* @__PURE__ */ React55.createElement(Text49, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React55.createElement(Box47, null, /* @__PURE__ */ React55.createElement(Text49, { dimColor: true }, " saved to "), /* @__PURE__ */ React55.createElement(Text49, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React55.createElement(Box47, { marginTop: 1 }, /* @__PURE__ */ React55.createElement(Text49, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React55.createElement(Text49, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React55.createElement(
24650
24788
  TextInput,
24651
24789
  {
24652
24790
  value,
@@ -24655,7 +24793,40 @@ function Setup({ onReady }) {
24655
24793
  mask: "\u2022",
24656
24794
  placeholder: "sk-..."
24657
24795
  }
24658
- )), error ? /* @__PURE__ */ React54.createElement(Box46, { marginTop: 1 }, /* @__PURE__ */ React54.createElement(Text48, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React54.createElement(Text48, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React54.createElement(Box46, { marginTop: 1 }, /* @__PURE__ */ React54.createElement(Text48, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React54.createElement(Box46, { marginTop: 1 }, /* @__PURE__ */ React54.createElement(Text48, { dimColor: true }, " /exit to abort")));
24796
+ )), error ? /* @__PURE__ */ React55.createElement(Box47, { marginTop: 1 }, /* @__PURE__ */ React55.createElement(Text49, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React55.createElement(Text49, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React55.createElement(Box47, { marginTop: 1 }, /* @__PURE__ */ React55.createElement(Text49, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React55.createElement(Box47, { marginTop: 1 }, /* @__PURE__ */ React55.createElement(Text49, { dimColor: true }, " /exit to abort")));
24797
+ }
24798
+
24799
+ // src/cli/ui/mcp-lifecycle.ts
24800
+ var STATE = {
24801
+ handshake: { glyph: "\u21BB", label: "handshake\u2026" },
24802
+ connected: { glyph: "\u2713", label: "connected" },
24803
+ failed: { glyph: "\u2716", label: "failed" },
24804
+ disabled: { glyph: "\u25CB", label: "disabled" }
24805
+ };
24806
+ var NAME_COL = 22;
24807
+ var STATE_COL = 15;
24808
+ function formatMcpLifecycleEvent(ev) {
24809
+ const { glyph, label } = STATE[ev.state];
24810
+ const namePart = `MCP \xB7 ${ev.name}`;
24811
+ const namePad = " ".repeat(Math.max(1, NAME_COL - namePart.length));
24812
+ const stateField = `${glyph} ${label}`.padEnd(STATE_COL);
24813
+ return `\u2318 ${namePart}${namePad}${stateField}${describeDetail(ev)}`;
24814
+ }
24815
+ function describeDetail(ev) {
24816
+ if (ev.state === "handshake") return "initialise \u2192 tools/list \u2192 resources/list";
24817
+ if (ev.state === "failed") return ev.reason;
24818
+ if (ev.state === "disabled") return `via /mcp disable ${ev.name}`;
24819
+ const parts = [`${ev.tools} tools`];
24820
+ if (ev.resources && ev.resources > 0) parts.push(`${ev.resources} resources`);
24821
+ if (ev.prompts && ev.prompts > 0) parts.push(`${ev.prompts} prompts`);
24822
+ parts.push(`${ev.ms}ms`);
24823
+ return parts.join(" \xB7 ");
24824
+ }
24825
+
24826
+ // src/cli/ui/mcp-toast.ts
24827
+ function formatMcpSlowToast(t2) {
24828
+ const seconds = (t2.p95Ms / 1e3).toFixed(1);
24829
+ return `\u26A0 MCP \`${t2.name}\` slow \xB7 ${seconds}s p95 over the last ${t2.sampleSize} calls`;
24659
24830
  }
24660
24831
 
24661
24832
  // src/cli/commands/chat.tsx
@@ -24668,13 +24839,13 @@ function Root({
24668
24839
  showPicker,
24669
24840
  ...appProps
24670
24841
  }) {
24671
- const [key, setKey] = useState16(initialKey);
24672
- const [pickerOpen, setPickerOpen] = useState16(showPicker);
24673
- const [activeSession, setActiveSession] = useState16(appProps.session);
24842
+ const [key, setKey] = useState17(initialKey);
24843
+ const [pickerOpen, setPickerOpen] = useState17(showPicker);
24844
+ const [activeSession, setActiveSession] = useState17(appProps.session);
24674
24845
  const workspaceRoot = appProps.codeMode?.rootDir ?? process.cwd();
24675
- const [sessions2, setSessions] = useState16(() => listSessionsForWorkspace(workspaceRoot));
24846
+ const [sessions2, setSessions] = useState17(() => listSessionsForWorkspace(workspaceRoot));
24676
24847
  if (!key) {
24677
- return /* @__PURE__ */ React55.createElement(
24848
+ return /* @__PURE__ */ React56.createElement(
24678
24849
  Setup,
24679
24850
  {
24680
24851
  onReady: (k) => {
@@ -24686,7 +24857,7 @@ function Root({
24686
24857
  }
24687
24858
  process.env.DEEPSEEK_API_KEY = key;
24688
24859
  if (pickerOpen) {
24689
- return /* @__PURE__ */ React55.createElement(KeystrokeProvider, null, /* @__PURE__ */ React55.createElement(
24860
+ return /* @__PURE__ */ React56.createElement(KeystrokeProvider, null, /* @__PURE__ */ React56.createElement(
24690
24861
  SessionPicker,
24691
24862
  {
24692
24863
  sessions: sessions2,
@@ -24719,7 +24890,7 @@ function Root({
24719
24890
  }
24720
24891
  ));
24721
24892
  }
24722
- return /* @__PURE__ */ React55.createElement(KeystrokeProvider, null, /* @__PURE__ */ React55.createElement(
24893
+ return /* @__PURE__ */ React56.createElement(KeystrokeProvider, null, /* @__PURE__ */ React56.createElement(
24723
24894
  App,
24724
24895
  {
24725
24896
  key: activeSession ?? "__new__",
@@ -24750,11 +24921,22 @@ async function chatCommand(opts) {
24750
24921
  const mcpServers = [];
24751
24922
  const progressSink = { current: null };
24752
24923
  let tools = opts.seedTools;
24924
+ const disabledNames = new Set(readConfig().mcpDisabled ?? []);
24753
24925
  if (requestedSpecs.length > 0) {
24754
24926
  if (!tools) tools = new ToolRegistry();
24755
24927
  for (const raw of requestedSpecs) {
24928
+ let label = "anon";
24756
24929
  try {
24757
24930
  const spec = parseMcpSpec(raw);
24931
+ label = spec.name ?? "anon";
24932
+ if (spec.name && disabledNames.has(spec.name)) {
24933
+ process.stderr.write(`${formatMcpLifecycleEvent({ state: "disabled", name: label })}
24934
+ `);
24935
+ continue;
24936
+ }
24937
+ process.stderr.write(`${formatMcpLifecycleEvent({ state: "handshake", name: label })}
24938
+ `);
24939
+ const t0 = Date.now();
24758
24940
  const prefix = spec.name ? `${spec.name}_` : requestedSpecs.length === 1 && opts.mcpPrefix ? opts.mcpPrefix : "";
24759
24941
  const transport = spec.transport === "sse" ? new SseTransport({ url: spec.url }) : spec.transport === "streamable-http" ? new StreamableHttpTransport({ url: spec.url }) : new StdioTransport({ command: spec.command, args: spec.args });
24760
24942
  const mcp3 = new McpClient({ transport });
@@ -24762,7 +24944,12 @@ async function chatCommand(opts) {
24762
24944
  const bridge = await bridgeMcpTools(mcp3, {
24763
24945
  registry: tools,
24764
24946
  namePrefix: prefix,
24765
- onProgress: (info) => progressSink.current?.(info)
24947
+ serverName: label,
24948
+ onProgress: (info) => progressSink.current?.(info),
24949
+ onSlow: (info) => process.stderr.write(
24950
+ `${formatMcpSlowToast({ name: info.serverName, p95Ms: info.p95Ms, sampleSize: info.sampleSize })}
24951
+ `
24952
+ )
24766
24953
  });
24767
24954
  let report;
24768
24955
  try {
@@ -24778,10 +24965,18 @@ async function chatCommand(opts) {
24778
24965
  elapsedMs: 0
24779
24966
  };
24780
24967
  }
24781
- const label = spec.name ?? "anon";
24782
- const source = spec.transport === "sse" || spec.transport === "streamable-http" ? spec.url : `${spec.command} ${spec.args.join(" ")}`;
24968
+ const ms = Date.now() - t0;
24969
+ const resourceCount = report.resources.supported ? report.resources.items.length : 0;
24970
+ const promptCount = report.prompts.supported ? report.prompts.items.length : 0;
24783
24971
  process.stderr.write(
24784
- `\u25B8 MCP[${label}]: ${bridge.registeredNames.length} tool(s) from ${source}
24972
+ `${formatMcpLifecycleEvent({
24973
+ state: "connected",
24974
+ name: label,
24975
+ tools: bridge.registeredNames.length,
24976
+ resources: resourceCount,
24977
+ prompts: promptCount,
24978
+ ms
24979
+ })}
24785
24980
  `
24786
24981
  );
24787
24982
  clients.push(mcp3);
@@ -24797,8 +24992,8 @@ async function chatCommand(opts) {
24797
24992
  const reason = err.message;
24798
24993
  failedSpecs.push({ spec: raw, reason });
24799
24994
  process.stderr.write(
24800
- `\u25B8 MCP setup SKIPPED for "${raw}": ${reason}
24801
- \u2192 this server will not be available this session. Run \`reasonix setup\` to remove it, or fix the underlying issue (missing npm package, network, etc.).
24995
+ `${formatMcpLifecycleEvent({ state: "failed", name: label, reason })}
24996
+ \u2192 run \`reasonix setup\` to remove this entry, or fix the underlying issue (missing npm package, network, etc.).
24802
24997
  `
24803
24998
  );
24804
24999
  }
@@ -24825,7 +25020,7 @@ async function chatCommand(opts) {
24825
25020
  const launchWorkspace = opts.codeMode?.rootDir ?? process.cwd();
24826
25021
  const showPicker = !opts.session && !opts.forceResume && listSessionsForWorkspace(launchWorkspace).length > 0;
24827
25022
  const { waitUntilExit } = render(
24828
- /* @__PURE__ */ React55.createElement(
25023
+ /* @__PURE__ */ React56.createElement(
24829
25024
  Root,
24830
25025
  {
24831
25026
  initialKey,
@@ -24849,9 +25044,10 @@ async function chatCommand(opts) {
24849
25044
  }
24850
25045
 
24851
25046
  // src/cli/commands/code.tsx
25047
+ import { readFileSync as readFileSync23 } from "fs";
24852
25048
  import { basename as basename2, resolve as resolve9 } from "path";
24853
25049
  async function codeCommand(opts = {}) {
24854
- const { codeSystemPrompt: codeSystemPrompt2 } = await import("./prompt-P54FIQAH.js");
25050
+ const { codeSystemPrompt: codeSystemPrompt2 } = await import("./prompt-YUL7CYKY.js");
24855
25051
  const rootDir = resolve9(opts.dir ?? process.cwd());
24856
25052
  const session = opts.noSession ? void 0 : `code-${sanitizeName(basename2(rootDir))}`;
24857
25053
  const tools = new ToolRegistry();
@@ -24885,15 +25081,37 @@ async function codeCommand(opts = {}) {
24885
25081
  process.once("exit", () => {
24886
25082
  void jobs2.shutdown();
24887
25083
  });
25084
+ let systemAppendFileContents;
25085
+ if (opts.systemAppend !== void 0 && opts.systemAppend.trim().length === 0) {
25086
+ process.stderr.write("--system-append is empty \u2014 no prompt text will be appended\n");
25087
+ }
25088
+ if (opts.systemAppendFile) {
25089
+ const filePath = resolve9(opts.systemAppendFile);
25090
+ try {
25091
+ systemAppendFileContents = readFileSync23(filePath, "utf8");
25092
+ } catch (err) {
25093
+ const e = err;
25094
+ process.stderr.write(
25095
+ `Error: cannot read --system-append-file "${filePath}": ${e.code ? `[${e.code}] ` : ""}${e.message}
25096
+ `
25097
+ );
25098
+ process.exit(1);
25099
+ }
25100
+ }
24888
25101
  await chatCommand({
24889
25102
  model: opts.model ?? "deepseek-v4-flash",
24890
25103
  harvest: opts.harvest ?? false,
24891
25104
  budgetUsd: opts.budgetUsd,
24892
- system: codeSystemPrompt2(rootDir, { hasSemanticSearch: semantic2.enabled }),
25105
+ system: codeSystemPrompt2(rootDir, {
25106
+ hasSemanticSearch: semantic2.enabled,
25107
+ systemAppend: opts.systemAppend,
25108
+ systemAppendFile: systemAppendFileContents
25109
+ }),
24893
25110
  transcript: opts.transcript,
24894
25111
  session,
24895
25112
  seedTools: tools,
24896
25113
  codeMode: { rootDir, jobs: jobs2, reregisterTools: registerRootedTools },
25114
+ mcp: readConfig().mcp,
24897
25115
  forceResume: opts.forceResume,
24898
25116
  forceNew: opts.forceNew,
24899
25117
  noDashboard: opts.noDashboard
@@ -24902,7 +25120,7 @@ async function codeCommand(opts = {}) {
24902
25120
 
24903
25121
  // src/cli/commands/commit.ts
24904
25122
  import { spawn as spawn6, spawnSync as spawnSync4 } from "child_process";
24905
- import { mkdtempSync, readFileSync as readFileSync23, unlinkSync as unlinkSync6, writeFileSync as writeFileSync13 } from "fs";
25123
+ import { mkdtempSync, readFileSync as readFileSync24, unlinkSync as unlinkSync6, writeFileSync as writeFileSync13 } from "fs";
24906
25124
  import { tmpdir } from "os";
24907
25125
  import { join as join23 } from "path";
24908
25126
  import { stdin as stdin2, stdout } from "process";
@@ -25067,7 +25285,7 @@ function editInExternal(initial) {
25067
25285
  }
25068
25286
  let edited;
25069
25287
  try {
25070
- edited = readFileSync23(path5, "utf8");
25288
+ edited = readFileSync24(path5, "utf8");
25071
25289
  } catch {
25072
25290
  return null;
25073
25291
  } finally {
@@ -25178,19 +25396,19 @@ async function commitCommand(opts = {}) {
25178
25396
  import { writeFileSync as writeFileSync14 } from "fs";
25179
25397
  import { basename as basename3 } from "path";
25180
25398
  import { render as render2 } from "ink";
25181
- import React59 from "react";
25399
+ import React60 from "react";
25182
25400
 
25183
25401
  // src/cli/ui/DiffApp.tsx
25184
- import { Box as Box49, Static as Static2, Text as Text51, useApp as useApp2, useInput as useInput2 } from "ink";
25185
- import React58, { useState as useState17 } from "react";
25402
+ import { Box as Box50, Static as Static2, Text as Text52, useApp as useApp2, useInput as useInput2 } from "ink";
25403
+ import React59, { useState as useState18 } from "react";
25186
25404
 
25187
25405
  // src/cli/ui/RecordView.tsx
25188
- import { Box as Box48, Text as Text50 } from "ink";
25189
- import React57 from "react";
25406
+ import { Box as Box49, Text as Text51 } from "ink";
25407
+ import React58 from "react";
25190
25408
 
25191
25409
  // src/cli/ui/PlanStateBlock.tsx
25192
- import { Box as Box47, Text as Text49 } from "ink";
25193
- import React56 from "react";
25410
+ import { Box as Box48, Text as Text50 } from "ink";
25411
+ import React57 from "react";
25194
25412
  function PlanStateBlock({ planState }) {
25195
25413
  const fields = [];
25196
25414
  if (planState.subgoals.length)
@@ -25202,7 +25420,7 @@ function PlanStateBlock({ planState }) {
25202
25420
  if (planState.rejectedPaths.length)
25203
25421
  fields.push(["rejected", planState.rejectedPaths, COLOR.info, true]);
25204
25422
  if (fields.length === 0) return null;
25205
- return /* @__PURE__ */ React56.createElement(Box47, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color2, dim]) => /* @__PURE__ */ React56.createElement(Box47, { key: label }, /* @__PURE__ */ React56.createElement(Text49, { color: color2, bold: true, dimColor: dim }, label), /* @__PURE__ */ React56.createElement(Text49, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React56.createElement(Text49, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React56.createElement(Text49, { dimColor: dim, color: dim ? void 0 : COLOR.info }, items.join(" \xB7 ")))));
25423
+ return /* @__PURE__ */ React57.createElement(Box48, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color2, dim]) => /* @__PURE__ */ React57.createElement(Box48, { key: label }, /* @__PURE__ */ React57.createElement(Text50, { color: color2, bold: true, dimColor: dim }, label), /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React57.createElement(Text50, { dimColor: dim, color: dim ? void 0 : COLOR.info }, items.join(" \xB7 ")))));
25206
25424
  }
25207
25425
 
25208
25426
  // src/cli/ui/RecordView.tsx
@@ -25211,21 +25429,21 @@ function RecordView({ rec, compact: compact2 = false }) {
25211
25429
  const toolContentMax = compact2 ? 200 : 400;
25212
25430
  if (rec.role === "user") {
25213
25431
  const content = rec.content.includes("\n") ? rec.content.split("\n").join("\n ") : rec.content;
25214
- return /* @__PURE__ */ React57.createElement(Box48, { marginTop: 1 }, /* @__PURE__ */ React57.createElement(Text50, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React57.createElement(Text50, null, content));
25432
+ return /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1 }, /* @__PURE__ */ React58.createElement(Text51, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React58.createElement(Text51, null, content));
25215
25433
  }
25216
25434
  if (rec.role === "assistant_final") {
25217
- return /* @__PURE__ */ React57.createElement(Box48, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React57.createElement(Box48, null, /* @__PURE__ */ React57.createElement(Text50, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React57.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React57.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React57.createElement(Text50, null, rec.content) : /* @__PURE__ */ React57.createElement(Text50, { dimColor: true, italic: true }, "(tool-call response only)"));
25435
+ return /* @__PURE__ */ React58.createElement(Box49, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React58.createElement(Box49, null, /* @__PURE__ */ React58.createElement(Text51, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React58.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React58.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React58.createElement(Text51, null, rec.content) : /* @__PURE__ */ React58.createElement(Text51, { dimColor: true, italic: true }, "(tool-call response only)"));
25218
25436
  }
25219
25437
  if (rec.role === "tool") {
25220
- return /* @__PURE__ */ React57.createElement(Box48, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React57.createElement(Text50, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, " args: ", truncate3(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, " \u2192 ", truncate3(rec.content, toolContentMax)));
25438
+ return /* @__PURE__ */ React58.createElement(Box49, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React58.createElement(Text51, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " args: ", truncate3(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " \u2192 ", truncate3(rec.content, toolContentMax)));
25221
25439
  }
25222
25440
  if (rec.role === "error") {
25223
- return /* @__PURE__ */ React57.createElement(Box48, { marginTop: 1 }, /* @__PURE__ */ React57.createElement(Text50, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React57.createElement(Text50, { color: "red" }, rec.error ?? rec.content));
25441
+ return /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1 }, /* @__PURE__ */ React58.createElement(Text51, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React58.createElement(Text51, { color: "red" }, rec.error ?? rec.content));
25224
25442
  }
25225
25443
  if (rec.role === "done" || rec.role === "assistant_delta") {
25226
25444
  return null;
25227
25445
  }
25228
- return /* @__PURE__ */ React57.createElement(Box48, null, /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, "[", rec.role, "] ", rec.content));
25446
+ return /* @__PURE__ */ React58.createElement(Box49, null, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, "[", rec.role, "] ", rec.content));
25229
25447
  }
25230
25448
  function CacheBadge({ usage }) {
25231
25449
  const hit = usage.prompt_cache_hit_tokens ?? 0;
@@ -25234,7 +25452,7 @@ function CacheBadge({ usage }) {
25234
25452
  if (total === 0) return null;
25235
25453
  const pct2 = hit / total * 100;
25236
25454
  const color2 = pct2 >= 70 ? "green" : pct2 >= 40 ? "yellow" : "red";
25237
- return /* @__PURE__ */ React57.createElement(Text50, null, /* @__PURE__ */ React57.createElement(Text50, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React57.createElement(Text50, { color: color2 }, pct2.toFixed(1), "%"));
25455
+ return /* @__PURE__ */ React58.createElement(Text51, null, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React58.createElement(Text51, { color: color2 }, pct2.toFixed(1), "%"));
25238
25456
  }
25239
25457
  function truncate3(s, max) {
25240
25458
  return s.length <= max ? s : `${s.slice(0, max)}\u2026 (+${s.length - max} chars)`;
@@ -25245,7 +25463,7 @@ function DiffApp({ report }) {
25245
25463
  const { exit: exit2 } = useApp2();
25246
25464
  const maxIdx = Math.max(0, report.pairs.length - 1);
25247
25465
  const initialIdx = report.firstDivergenceTurn ? report.pairs.findIndex((p) => p.turn === report.firstDivergenceTurn) : 0;
25248
- const [idx, setIdx] = useState17(Math.max(0, initialIdx));
25466
+ const [idx, setIdx] = useState18(Math.max(0, initialIdx));
25249
25467
  useInput2((input, key) => {
25250
25468
  if (input === "q" || key.ctrl && input === "c") {
25251
25469
  exit2();
@@ -25268,7 +25486,7 @@ function DiffApp({ report }) {
25268
25486
  }
25269
25487
  });
25270
25488
  const pair = report.pairs[idx];
25271
- return /* @__PURE__ */ React58.createElement(Box49, { flexDirection: "column" }, /* @__PURE__ */ React58.createElement(DiffHeader, { report }), /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React58.createElement(Text51, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React58.createElement(Text51, null, pair ? /* @__PURE__ */ React58.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React58.createElement(Box49, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React58.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React58.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React58.createElement(Text51, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React58.createElement(Text51, null, pair.divergenceNote)) : null, /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "j"), "/", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "k"), "/", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "N"), "/", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "g"), "/", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React58.createElement(Text51, { bold: true }, "q"), " ", "quit")));
25489
+ return /* @__PURE__ */ React59.createElement(Box50, { flexDirection: "column" }, /* @__PURE__ */ React59.createElement(DiffHeader, { report }), /* @__PURE__ */ React59.createElement(Box50, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React59.createElement(Text52, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React59.createElement(Text52, null, pair ? /* @__PURE__ */ React59.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React59.createElement(Box50, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React59.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React59.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React59.createElement(Box50, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React59.createElement(Text52, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React59.createElement(Text52, null, pair.divergenceNote)) : null, /* @__PURE__ */ React59.createElement(Box50, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "j"), "/", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "k"), "/", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "N"), "/", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "g"), "/", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React59.createElement(Text52, { bold: true }, "q"), " ", "quit")));
25272
25490
  }
25273
25491
  function DiffHeader({ report }) {
25274
25492
  const a = report.a;
@@ -25286,15 +25504,15 @@ function DiffHeader({ report }) {
25286
25504
  } else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {
25287
25505
  prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}\u2026 \u2014 cache delta attributable to log stability, not prompt change.`;
25288
25506
  }
25289
- return /* @__PURE__ */ React58.createElement(Box49, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React58.createElement(Box49, { justifyContent: "space-between" }, /* @__PURE__ */ React58.createElement(Text51, null, /* @__PURE__ */ React58.createElement(Text51, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React58.createElement(Text51, { color: "blue" }, a.label), /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " vs B="), /* @__PURE__ */ React58.createElement(Text51, { color: "magenta" }, b.label)), /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React58.createElement(Text51, null, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, "cache "), /* @__PURE__ */ React58.createElement(Text51, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React58.createElement(Text51, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React58.createElement(Text51, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React58.createElement(Text51, null, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, "cost "), /* @__PURE__ */ React58.createElement(Text51, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React58.createElement(Text51, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React58.createElement(Text51, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React58.createElement(Text51, null, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true }, "model calls "), /* @__PURE__ */ React58.createElement(Text51, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1 }, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true, italic: true }, prefixLine)) : null);
25507
+ return /* @__PURE__ */ React59.createElement(Box50, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React59.createElement(Box50, { justifyContent: "space-between" }, /* @__PURE__ */ React59.createElement(Text52, null, /* @__PURE__ */ React59.createElement(Text52, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React59.createElement(Text52, { color: "blue" }, a.label), /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, " vs B="), /* @__PURE__ */ React59.createElement(Text52, { color: "magenta" }, b.label)), /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React59.createElement(Box50, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React59.createElement(Text52, null, /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, "cache "), /* @__PURE__ */ React59.createElement(Text52, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React59.createElement(Text52, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React59.createElement(Text52, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React59.createElement(Text52, null, /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, "cost "), /* @__PURE__ */ React59.createElement(Text52, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React59.createElement(Text52, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React59.createElement(Text52, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React59.createElement(Text52, null, /* @__PURE__ */ React59.createElement(Text52, { dimColor: true }, "model calls "), /* @__PURE__ */ React59.createElement(Text52, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React59.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React59.createElement(Text52, { dimColor: true, italic: true }, prefixLine)) : null);
25290
25508
  }
25291
25509
  function Pane({
25292
25510
  label,
25293
25511
  headerColor,
25294
25512
  records
25295
25513
  }) {
25296
- return /* @__PURE__ */ React58.createElement(
25297
- Box49,
25514
+ return /* @__PURE__ */ React59.createElement(
25515
+ Box50,
25298
25516
  {
25299
25517
  flexDirection: "column",
25300
25518
  flexGrow: 1,
@@ -25302,21 +25520,21 @@ function Pane({
25302
25520
  borderStyle: "single",
25303
25521
  borderColor: headerColor
25304
25522
  },
25305
- /* @__PURE__ */ React58.createElement(Text51, { color: headerColor, bold: true }, label),
25306
- records.length === 0 ? /* @__PURE__ */ React58.createElement(Box49, { marginTop: 1 }, /* @__PURE__ */ React58.createElement(Text51, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React58.createElement(Static2, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React58.createElement(RecordView, { key, rec, compact: true }))
25523
+ /* @__PURE__ */ React59.createElement(Text52, { color: headerColor, bold: true }, label),
25524
+ records.length === 0 ? /* @__PURE__ */ React59.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React59.createElement(Text52, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React59.createElement(Static2, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React59.createElement(RecordView, { key, rec, compact: true }))
25307
25525
  );
25308
25526
  }
25309
25527
  function KindBadge({ kind }) {
25310
25528
  if (kind === "match") {
25311
- return /* @__PURE__ */ React58.createElement(Text51, { color: "green" }, "\u2713 match");
25529
+ return /* @__PURE__ */ React59.createElement(Text52, { color: "green" }, "\u2713 match");
25312
25530
  }
25313
25531
  if (kind === "diverge") {
25314
- return /* @__PURE__ */ React58.createElement(Text51, { color: "yellow" }, "\u2605 diverge");
25532
+ return /* @__PURE__ */ React59.createElement(Text52, { color: "yellow" }, "\u2605 diverge");
25315
25533
  }
25316
25534
  if (kind === "only_in_a") {
25317
- return /* @__PURE__ */ React58.createElement(Text51, { color: "blue" }, "\u2190 only in A");
25535
+ return /* @__PURE__ */ React59.createElement(Text52, { color: "blue" }, "\u2190 only in A");
25318
25536
  }
25319
- return /* @__PURE__ */ React58.createElement(Text51, { color: "magenta" }, "\u2192 only in B");
25537
+ return /* @__PURE__ */ React59.createElement(Text52, { color: "magenta" }, "\u2192 only in B");
25320
25538
  }
25321
25539
  function paneRecords(pair, side) {
25322
25540
  if (!pair) return [];
@@ -25347,7 +25565,7 @@ markdown report written to ${opts.mdPath}`);
25347
25565
  return;
25348
25566
  }
25349
25567
  if (wantTui) {
25350
- const { waitUntilExit } = render2(React59.createElement(DiffApp, { report }), {
25568
+ const { waitUntilExit } = render2(React60.createElement(DiffApp, { report }), {
25351
25569
  exitOnCtrlC: true,
25352
25570
  patchConsole: false
25353
25571
  });
@@ -26018,16 +26236,16 @@ function pad2(s, width) {
26018
26236
 
26019
26237
  // src/cli/commands/replay.ts
26020
26238
  import { render as render3 } from "ink";
26021
- import React62 from "react";
26239
+ import React63 from "react";
26022
26240
 
26023
26241
  // src/cli/ui/ReplayApp.tsx
26024
- import { Box as Box51, Static as Static3, Text as Text53, useApp as useApp3, useInput as useInput3 } from "ink";
26025
- import React61, { useMemo as useMemo7, useState as useState18 } from "react";
26242
+ import { Box as Box52, Static as Static3, Text as Text54, useApp as useApp3, useInput as useInput3 } from "ink";
26243
+ import React62, { useMemo as useMemo7, useState as useState19 } from "react";
26026
26244
 
26027
26245
  // src/cli/ui/StatsPanel.tsx
26028
26246
  import { basename as basename4 } from "path";
26029
- import { Box as Box50, Text as Text52, useStdout as useStdout15 } from "ink";
26030
- import React60 from "react";
26247
+ import { Box as Box51, Text as Text53, useStdout as useStdout15 } from "ink";
26248
+ import React61 from "react";
26031
26249
  import stringWidth2 from "string-width";
26032
26250
  var COLD_START_TURNS = 3;
26033
26251
  function StatsPanel({
@@ -26043,7 +26261,7 @@ function StatsPanel({
26043
26261
  sessionName
26044
26262
  }) {
26045
26263
  const coldStart = summary.turns <= COLD_START_TURNS;
26046
- return /* @__PURE__ */ React60.createElement(Box50, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React60.createElement(
26264
+ return /* @__PURE__ */ React61.createElement(Box51, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React61.createElement(
26047
26265
  ChromeRow,
26048
26266
  {
26049
26267
  editMode,
@@ -26057,7 +26275,7 @@ function StatsPanel({
26057
26275
  updateAvailable,
26058
26276
  balance: balance ?? null
26059
26277
  }
26060
- ), /* @__PURE__ */ React60.createElement(ChromeRule, null), budgetUsd !== null && budgetUsd !== void 0 ? /* @__PURE__ */ React60.createElement(BudgetRow, { spent: summary.totalCostUsd, cap: budgetUsd }) : null);
26278
+ ), /* @__PURE__ */ React61.createElement(ChromeRule, null), budgetUsd !== null && budgetUsd !== void 0 ? /* @__PURE__ */ React61.createElement(BudgetRow, { spent: summary.totalCostUsd, cap: budgetUsd }) : null);
26061
26279
  }
26062
26280
  function ChromeRow({
26063
26281
  editMode,
@@ -26102,15 +26320,15 @@ function ChromeRow({
26102
26320
  if (showSession) budget3 -= sessionW;
26103
26321
  const showUpdate = updateW > 0 && budget3 >= updateW;
26104
26322
  if (showUpdate) budget3 -= updateW;
26105
- return /* @__PURE__ */ React60.createElement(Box50, null, /* @__PURE__ */ React60.createElement(Text52, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React60.createElement(Text52, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React60.createElement(Text52, null, projectName), showSession && sessionName ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React60.createElement(Text52, { color: COLOR.info }, sessionName)) : null) : null, /* @__PURE__ */ React60.createElement(Box50, { flexGrow: 1 }), showUpdate ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, { color: COLOR.warn, bold: true }, updateLabel), /* @__PURE__ */ React60.createElement(Text52, null, " ")) : null, modePill ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, { color: modePill.color, bold: true }, `[${modePill.label}]`), /* @__PURE__ */ React60.createElement(Text52, null, " ")) : null, proPill ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React60.createElement(Text52, null, " ")) : null, /* @__PURE__ */ React60.createElement(
26106
- Text52,
26323
+ return /* @__PURE__ */ React61.createElement(Box51, null, /* @__PURE__ */ React61.createElement(Text53, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React61.createElement(Text53, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React61.createElement(Text53, null, projectName), showSession && sessionName ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React61.createElement(Text53, { color: COLOR.info }, sessionName)) : null) : null, /* @__PURE__ */ React61.createElement(Box51, { flexGrow: 1 }), showUpdate ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, { color: COLOR.warn, bold: true }, updateLabel), /* @__PURE__ */ React61.createElement(Text53, null, " ")) : null, modePill ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, { color: modePill.color, bold: true }, `[${modePill.label}]`), /* @__PURE__ */ React61.createElement(Text53, null, " ")) : null, proPill ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React61.createElement(Text53, null, " ")) : null, /* @__PURE__ */ React61.createElement(
26324
+ Text53,
26107
26325
  {
26108
26326
  color: summary.turns === 0 || coldStart ? COLOR.info : sessionCostColor(summary.totalCostUsd),
26109
26327
  bold: summary.turns > 0 && !coldStart,
26110
26328
  dimColor: summary.turns === 0 || coldStart
26111
26329
  },
26112
26330
  costLabel
26113
- ), showBalance && balance ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, null, " "), /* @__PURE__ */ React60.createElement(Text52, { color: balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok }, balanceLabel)) : null, showCache ? /* @__PURE__ */ React60.createElement(React60.Fragment, null, /* @__PURE__ */ React60.createElement(Text52, null, " "), /* @__PURE__ */ React60.createElement(Text52, { dimColor: true }, "["), /* @__PURE__ */ React60.createElement(Text52, { dimColor: true }, "c "), /* @__PURE__ */ React60.createElement(
26331
+ ), showBalance && balance ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, null, " "), /* @__PURE__ */ React61.createElement(Text53, { color: balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok }, balanceLabel)) : null, showCache ? /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(Text53, null, " "), /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, "["), /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, "c "), /* @__PURE__ */ React61.createElement(
26114
26332
  Bar,
26115
26333
  {
26116
26334
  ratio: summary.cacheHitRatio,
@@ -26118,7 +26336,7 @@ function ChromeRow({
26118
26336
  cells: 6,
26119
26337
  dim: coldStart
26120
26338
  }
26121
- ), /* @__PURE__ */ React60.createElement(Text52, null, " "), /* @__PURE__ */ React60.createElement(Text52, { color: coldStart ? void 0 : cacheColor, dimColor: coldStart }, coldStart && summary.turns === 0 ? "\u2014" : `${cachePct}%`), /* @__PURE__ */ React60.createElement(Text52, { dimColor: true }, "]")) : null);
26339
+ ), /* @__PURE__ */ React61.createElement(Text53, null, " "), /* @__PURE__ */ React61.createElement(Text53, { color: coldStart ? void 0 : cacheColor, dimColor: coldStart }, coldStart && summary.turns === 0 ? "\u2014" : `${cachePct}%`), /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, "]")) : null);
26122
26340
  }
26123
26341
  function pickModePill(planMode, editMode) {
26124
26342
  if (planMode) return { label: "PLAN", color: COLOR.err };
@@ -26130,7 +26348,7 @@ function pickModePill(planMode, editMode) {
26130
26348
  function BudgetRow({ spent, cap }) {
26131
26349
  const pct2 = Math.max(0, spent / cap * 100);
26132
26350
  const color2 = pct2 >= 100 ? "#f87171" : pct2 >= 80 ? "#fbbf24" : "#94a3b8";
26133
- return /* @__PURE__ */ React60.createElement(Box50, null, /* @__PURE__ */ React60.createElement(Text52, { dimColor: true }, " budget "), /* @__PURE__ */ React60.createElement(Text52, { color: color2 }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React60.createElement(Text52, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
26351
+ return /* @__PURE__ */ React61.createElement(Box51, null, /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, " budget "), /* @__PURE__ */ React61.createElement(Text53, { color: color2 }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
26134
26352
  }
26135
26353
  function sessionCostColor(cost2) {
26136
26354
  if (cost2 <= 0) return void 0;
@@ -26143,7 +26361,7 @@ function sessionCostColor(cost2) {
26143
26361
  function ReplayApp({ meta, pages }) {
26144
26362
  const { exit: exit2 } = useApp3();
26145
26363
  const maxIdx = Math.max(0, pages.length - 1);
26146
- const [idx, setIdx] = useState18(maxIdx);
26364
+ const [idx, setIdx] = useState19(maxIdx);
26147
26365
  useInput3((input, key) => {
26148
26366
  if (input === "q" || key.ctrl && input === "c") {
26149
26367
  exit2();
@@ -26179,7 +26397,7 @@ function ReplayApp({ meta, pages }) {
26179
26397
  const prefixHash = cumStats.prefixHashes.length === 1 ? cumStats.prefixHashes[0].slice(0, 16) : cumStats.prefixHashes.length === 0 ? "(untracked)" : `(churned \xD7${cumStats.prefixHashes.length})`;
26180
26398
  const currentPage = pages[idx];
26181
26399
  const progressLabel = pages.length === 0 ? "empty transcript" : `turn ${idx + 1} / ${pages.length}`;
26182
- return /* @__PURE__ */ React61.createElement(Box51, { flexDirection: "column" }, /* @__PURE__ */ React61.createElement(StatsPanel, { summary }), /* @__PURE__ */ React61.createElement(Box51, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React61.createElement(Box51, { justifyContent: "space-between" }, /* @__PURE__ */ React61.createElement(Text53, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React61.createElement(Static3, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React61.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React61.createElement(Text53, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React61.createElement(Box51, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React61.createElement(Text53, { dimColor: true }, /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "j"), "/", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "k"), "/", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React61.createElement(Text53, { bold: true }, "q"), " quit")));
26400
+ return /* @__PURE__ */ React62.createElement(Box52, { flexDirection: "column" }, /* @__PURE__ */ React62.createElement(StatsPanel, { summary }), /* @__PURE__ */ React62.createElement(Box52, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React62.createElement(Box52, { justifyContent: "space-between" }, /* @__PURE__ */ React62.createElement(Text54, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React62.createElement(Static3, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React62.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React62.createElement(Text54, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React62.createElement(Box52, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React62.createElement(Text54, { dimColor: true }, /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "j"), "/", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "k"), "/", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React62.createElement(Text54, { bold: true }, "q"), " quit")));
26183
26401
  }
26184
26402
 
26185
26403
  // src/cli/commands/replay.ts
@@ -26191,7 +26409,7 @@ async function replayCommand(opts) {
26191
26409
  }
26192
26410
  const { parsed } = replayFromFile(opts.path);
26193
26411
  const pages = groupRecordsByTurn(parsed.records);
26194
- const { waitUntilExit } = render3(React62.createElement(ReplayApp, { meta: parsed.meta, pages }), {
26412
+ const { waitUntilExit } = render3(React63.createElement(ReplayApp, { meta: parsed.meta, pages }), {
26195
26413
  exitOnCtrlC: true,
26196
26414
  patchConsole: false
26197
26415
  });
@@ -26326,26 +26544,49 @@ async function runCommand2(opts) {
26326
26544
  const clients = [];
26327
26545
  let tools;
26328
26546
  let successCount = 0;
26547
+ const disabledNames = new Set(readConfig().mcpDisabled ?? []);
26329
26548
  if (requestedSpecs.length > 0) {
26330
26549
  tools = new ToolRegistry();
26331
26550
  for (const raw of requestedSpecs) {
26551
+ let label = "anon";
26332
26552
  try {
26333
26553
  const spec = parseMcpSpec(raw);
26554
+ label = spec.name ?? "anon";
26555
+ if (spec.name && disabledNames.has(spec.name)) {
26556
+ process.stderr.write(`${formatMcpLifecycleEvent({ state: "disabled", name: label })}
26557
+ `);
26558
+ continue;
26559
+ }
26560
+ process.stderr.write(`${formatMcpLifecycleEvent({ state: "handshake", name: label })}
26561
+ `);
26562
+ const t0 = Date.now();
26334
26563
  const prefix2 = spec.name ? `${spec.name}_` : requestedSpecs.length === 1 && opts.mcpPrefix ? opts.mcpPrefix : "";
26335
26564
  const transport = spec.transport === "sse" ? new SseTransport({ url: spec.url }) : spec.transport === "streamable-http" ? new StreamableHttpTransport({ url: spec.url }) : new StdioTransport({ command: spec.command, args: spec.args });
26336
26565
  const mcp3 = new McpClient({ transport });
26337
26566
  await mcp3.initialize();
26338
- const bridge = await bridgeMcpTools(mcp3, { registry: tools, namePrefix: prefix2 });
26339
- const source = spec.transport === "sse" || spec.transport === "streamable-http" ? spec.url : `${spec.command} ${spec.args.join(" ")}`;
26567
+ const bridge = await bridgeMcpTools(mcp3, {
26568
+ registry: tools,
26569
+ namePrefix: prefix2,
26570
+ serverName: label,
26571
+ onSlow: (info) => process.stderr.write(
26572
+ `${formatMcpSlowToast({ name: info.serverName, p95Ms: info.p95Ms, sampleSize: info.sampleSize })}
26573
+ `
26574
+ )
26575
+ });
26340
26576
  process.stderr.write(
26341
- `\u25B8 MCP[${spec.name ?? "anon"}]: ${bridge.registeredNames.length} tool(s) from ${source}
26577
+ `${formatMcpLifecycleEvent({
26578
+ state: "connected",
26579
+ name: label,
26580
+ tools: bridge.registeredNames.length,
26581
+ ms: Date.now() - t0
26582
+ })}
26342
26583
  `
26343
26584
  );
26344
26585
  clients.push(mcp3);
26345
26586
  successCount++;
26346
26587
  } catch (err) {
26347
26588
  process.stderr.write(
26348
- `\u25B8 MCP setup SKIPPED for "${raw}": ${err.message}
26589
+ `${formatMcpLifecycleEvent({ state: "failed", name: label, reason: err.message })}
26349
26590
  \u2192 run \`reasonix setup\` to remove broken entries from your saved config.
26350
26591
  `
26351
26592
  );
@@ -26497,28 +26738,28 @@ function truncate5(s, max) {
26497
26738
 
26498
26739
  // src/cli/commands/setup.tsx
26499
26740
  import { render as render4 } from "ink";
26500
- import React64 from "react";
26741
+ import React65 from "react";
26501
26742
 
26502
26743
  // src/cli/ui/Wizard.tsx
26503
- import { Box as Box52, Text as Text54, useApp as useApp4, useInput as useInput4 } from "ink";
26744
+ import { Box as Box53, Text as Text55, useApp as useApp4, useInput as useInput4 } from "ink";
26504
26745
  import TextInput2 from "ink-text-input";
26505
- import React63, { useState as useState19 } from "react";
26746
+ import React64, { useState as useState20 } from "react";
26506
26747
  var CATALOG_BY_NAME = new Map(MCP_CATALOG.map((e) => [e.name, e]));
26507
26748
  function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26508
26749
  const { exit: exit2 } = useApp4();
26509
- const [step, setStep] = useState19(existingApiKey ? "preset" : "apiKey");
26510
- const [data, setData] = useState19({
26750
+ const [step, setStep] = useState20(existingApiKey ? "preset" : "apiKey");
26751
+ const [data, setData] = useState20({
26511
26752
  apiKey: existingApiKey ?? "",
26512
26753
  preset: initial?.preset ?? "auto",
26513
26754
  selectedCatalog: deriveInitialCatalog(initial?.mcp ?? []),
26514
26755
  catalogArgs: {}
26515
26756
  });
26516
- const [error, setError] = useState19(null);
26757
+ const [error, setError] = useState20(null);
26517
26758
  useInput4((_input, key) => {
26518
26759
  if (key.escape && step !== "saved" && onCancel) onCancel();
26519
26760
  });
26520
26761
  if (step === "apiKey") {
26521
- return /* @__PURE__ */ React63.createElement(
26762
+ return /* @__PURE__ */ React64.createElement(
26522
26763
  ApiKeyStep,
26523
26764
  {
26524
26765
  onSubmit: (key) => {
@@ -26532,7 +26773,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26532
26773
  );
26533
26774
  }
26534
26775
  if (step === "preset") {
26535
- return /* @__PURE__ */ React63.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React63.createElement(
26776
+ return /* @__PURE__ */ React64.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React64.createElement(
26536
26777
  SingleSelect,
26537
26778
  {
26538
26779
  items: presetItems(),
@@ -26542,10 +26783,10 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26542
26783
  setStep("mcp");
26543
26784
  }
26544
26785
  }
26545
- ), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
26786
+ ), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
26546
26787
  }
26547
26788
  if (step === "mcp") {
26548
- return /* @__PURE__ */ React63.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React63.createElement(
26789
+ return /* @__PURE__ */ React64.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React64.createElement(
26549
26790
  MultiSelect,
26550
26791
  {
26551
26792
  items: mcpItems(),
@@ -26570,7 +26811,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26570
26811
  }
26571
26812
  const currentName = pending[0];
26572
26813
  const entry = CATALOG_BY_NAME.get(currentName);
26573
- return /* @__PURE__ */ React63.createElement(
26814
+ return /* @__PURE__ */ React64.createElement(
26574
26815
  McpArgsStep,
26575
26816
  {
26576
26817
  entry,
@@ -26588,7 +26829,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26588
26829
  }
26589
26830
  if (step === "review") {
26590
26831
  const specs = data.selectedCatalog.map((name) => buildSpec(name, data.catalogArgs));
26591
- return /* @__PURE__ */ React63.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React63.createElement(Box52, { flexDirection: "column" }, /* @__PURE__ */ React63.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React63.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React63.createElement(
26832
+ return /* @__PURE__ */ React64.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React64.createElement(Box53, { flexDirection: "column" }, /* @__PURE__ */ React64.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React64.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React64.createElement(
26592
26833
  SummaryLine,
26593
26834
  {
26594
26835
  label: "MCP",
@@ -26596,8 +26837,8 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26596
26837
  }
26597
26838
  ), specs.map((spec, i) => (
26598
26839
  // biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
26599
- /* @__PURE__ */ React63.createElement(Box52, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "\xB7 ", spec))
26600
- )), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { color: "red" }, error)) : null, /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React63.createElement(
26840
+ /* @__PURE__ */ React64.createElement(Box53, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "\xB7 ", spec))
26841
+ )), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: "red" }, error)) : null, /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React64.createElement(
26601
26842
  ReviewConfirm,
26602
26843
  {
26603
26844
  onConfirm: () => {
@@ -26623,15 +26864,15 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
26623
26864
  }
26624
26865
  ));
26625
26866
  }
26626
- return /* @__PURE__ */ React63.createElement(Box52, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React63.createElement(Text54, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React63.createElement(ExitOnEnter, { onExit: exit2 }));
26867
+ return /* @__PURE__ */ React64.createElement(Box53, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React64.createElement(ExitOnEnter, { onExit: exit2 }));
26627
26868
  }
26628
26869
  function ApiKeyStep({
26629
26870
  onSubmit,
26630
26871
  error,
26631
26872
  onError
26632
26873
  }) {
26633
- const [value, setValue] = useState19("");
26634
- return /* @__PURE__ */ React63.createElement(Box52, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React63.createElement(Text54, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React63.createElement(
26874
+ const [value, setValue] = useState20("");
26875
+ return /* @__PURE__ */ React64.createElement(Box53, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "Get one at: https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React64.createElement(
26635
26876
  TextInput2,
26636
26877
  {
26637
26878
  value,
@@ -26648,7 +26889,7 @@ function ApiKeyStep({
26648
26889
  mask: "\u2022",
26649
26890
  placeholder: "sk-..."
26650
26891
  }
26651
- )), error ? /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { color: "red" }, error)) : value ? /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "preview: ", redactKey(value))) : null);
26892
+ )), error ? /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: "red" }, error)) : value ? /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "preview: ", redactKey(value))) : null);
26652
26893
  }
26653
26894
  function McpArgsStep({
26654
26895
  entry,
@@ -26656,8 +26897,8 @@ function McpArgsStep({
26656
26897
  onSubmit,
26657
26898
  onError
26658
26899
  }) {
26659
- const [value, setValue] = useState19("");
26660
- return /* @__PURE__ */ React63.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React63.createElement(Box52, { flexDirection: "column" }, /* @__PURE__ */ React63.createElement(Text54, null, entry.summary), entry.note ? /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, null, "Required parameter: "), /* @__PURE__ */ React63.createElement(Text54, { bold: true }, entry.userArgs)), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React63.createElement(
26900
+ const [value, setValue] = useState20("");
26901
+ return /* @__PURE__ */ React64.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React64.createElement(Box53, { flexDirection: "column" }, /* @__PURE__ */ React64.createElement(Text55, null, entry.summary), entry.note ? /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, null, "Required parameter: "), /* @__PURE__ */ React64.createElement(Text55, { bold: true }, entry.userArgs)), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React64.createElement(
26661
26902
  TextInput2,
26662
26903
  {
26663
26904
  value,
@@ -26673,7 +26914,7 @@ function McpArgsStep({
26673
26914
  },
26674
26915
  placeholder: placeholderFor(entry)
26675
26916
  }
26676
- )), error ? /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React63.createElement(Text54, { color: "red" }, error)) : null));
26917
+ )), error ? /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: "red" }, error)) : null));
26677
26918
  }
26678
26919
  function ReviewConfirm({ onConfirm }) {
26679
26920
  useInput4((_i, key) => {
@@ -26693,10 +26934,10 @@ function StepFrame({
26693
26934
  total,
26694
26935
  children
26695
26936
  }) {
26696
- return /* @__PURE__ */ React63.createElement(Box52, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React63.createElement(Box52, null, /* @__PURE__ */ React63.createElement(Text54, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React63.createElement(Text54, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React63.createElement(Box52, { marginTop: 1, flexDirection: "column" }, children));
26937
+ return /* @__PURE__ */ React64.createElement(Box53, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React64.createElement(Box53, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React64.createElement(Box53, { marginTop: 1, flexDirection: "column" }, children));
26697
26938
  }
26698
26939
  function SummaryLine({ label, value }) {
26699
- return /* @__PURE__ */ React63.createElement(Box52, null, /* @__PURE__ */ React63.createElement(Text54, null, label.padEnd(12)), /* @__PURE__ */ React63.createElement(Text54, { bold: true }, value));
26940
+ return /* @__PURE__ */ React64.createElement(Box53, null, /* @__PURE__ */ React64.createElement(Text55, null, label.padEnd(12)), /* @__PURE__ */ React64.createElement(Text55, { bold: true }, value));
26700
26941
  }
26701
26942
  function presetItems() {
26702
26943
  return ["auto", "flash", "pro"].map((name) => ({
@@ -26752,7 +26993,7 @@ async function setupCommand(_opts = {}) {
26752
26993
  const existingKey = loadApiKey();
26753
26994
  const existing = readConfig();
26754
26995
  const { waitUntilExit, unmount } = render4(
26755
- /* @__PURE__ */ React64.createElement(
26996
+ /* @__PURE__ */ React65.createElement(
26756
26997
  Wizard,
26757
26998
  {
26758
26999
  existingApiKey: existingKey,
@@ -26976,6 +27217,12 @@ program.command("code [dir]").description(
26976
27217
  ).option(
26977
27218
  "--no-dashboard",
26978
27219
  "Suppress the auto-launched embedded web dashboard. Default behavior boots it on TUI mount and shows the URL in the status bar (clickable in OSC-8-aware terminals)."
27220
+ ).option(
27221
+ "--system-append <prompt>",
27222
+ "Append instructions to the code system prompt. Does NOT replace the default prompt \u2014 adds after it."
27223
+ ).option(
27224
+ "--system-append-file <path>",
27225
+ "Append file contents to the code system prompt. Does NOT replace the default prompt. UTF-8, relative to cwd or absolute."
26979
27226
  ).action(async (dir, opts) => {
26980
27227
  await codeCommand({
26981
27228
  dir,
@@ -26986,7 +27233,9 @@ program.command("code [dir]").description(
26986
27233
  forceNew: !!opts.new,
26987
27234
  harvest: !!opts.harvest,
26988
27235
  budgetUsd: parseBudgetFlag(opts.budget),
26989
- noDashboard: opts.dashboard === false
27236
+ noDashboard: opts.dashboard === false,
27237
+ systemAppend: opts.systemAppend,
27238
+ systemAppendFile: opts.systemAppendFile
26990
27239
  });
26991
27240
  });
26992
27241
  program.command("chat").description("Interactive Ink TUI with live cache/cost panel.").option("-m, --model <id>", "DeepSeek model id (overrides preset)").option("-s, --system <prompt>", "System prompt (pinned in the immutable prefix)", DEFAULT_SYSTEM).option("--transcript <path>", "Write a JSONL transcript to this path").option(