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