reasonix 0.36.0 → 0.36.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/README.zh-CN.md +17 -0
- package/dashboard/dist/app.js +405 -196
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{chat-RGMYAOY2.js → chat-QSM6JKUA.js} +7 -7
- package/dist/cli/{chunk-ZU45XW3P.js → chunk-4D6TT2IB.js} +10 -2
- package/dist/cli/chunk-4D6TT2IB.js.map +1 -0
- package/dist/cli/{chunk-2MCYGFLK.js → chunk-C5543CRX.js} +17 -16
- package/dist/cli/chunk-C5543CRX.js.map +1 -0
- package/dist/cli/{chunk-KJQIA4US.js → chunk-K6W64QVE.js} +48 -29
- package/dist/cli/chunk-K6W64QVE.js.map +1 -0
- package/dist/cli/{chunk-EN4LAZW5.js → chunk-NHV5YGTB.js} +761 -642
- package/dist/cli/chunk-NHV5YGTB.js.map +1 -0
- package/dist/cli/{chunk-QRUQ2BFT.js → chunk-RNSZYYGB.js} +109 -41
- package/dist/cli/chunk-RNSZYYGB.js.map +1 -0
- package/dist/cli/{chunk-QPNZWUZF.js → chunk-S4GF3HPO.js} +26 -1
- package/dist/cli/chunk-S4GF3HPO.js.map +1 -0
- package/dist/cli/{code-KJB3WDU6.js → code-6C5A2CY3.js} +17 -9
- package/dist/cli/code-6C5A2CY3.js.map +1 -0
- package/dist/cli/index.js +10 -10
- package/dist/cli/{prompt-YEKXMNNV.js → prompt-QSEB7HNQ.js} +3 -3
- package/dist/cli/{run-FK5UBIIM.js → run-AG4Y45X7.js} +5 -5
- package/dist/cli/{server-W4XJK4GX.js → server-GNHR5K3N.js} +4 -4
- package/dist/cli/{sessions-YZXWMIWW.js → sessions-MHRF3GU4.js} +5 -5
- package/dist/cli/{version-DWD6RLIU.js → version-7AL4JZ63.js} +5 -5
- package/dist/index.d.ts +29 -1
- package/dist/index.js +146 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-2MCYGFLK.js.map +0 -1
- package/dist/cli/chunk-EN4LAZW5.js.map +0 -1
- package/dist/cli/chunk-KJQIA4US.js.map +0 -1
- package/dist/cli/chunk-QPNZWUZF.js.map +0 -1
- package/dist/cli/chunk-QRUQ2BFT.js.map +0 -1
- package/dist/cli/chunk-ZU45XW3P.js.map +0 -1
- package/dist/cli/code-KJB3WDU6.js.map +0 -1
- /package/dist/cli/{chat-RGMYAOY2.js.map → chat-QSM6JKUA.js.map} +0 -0
- /package/dist/cli/{prompt-YEKXMNNV.js.map → prompt-QSEB7HNQ.js.map} +0 -0
- /package/dist/cli/{run-FK5UBIIM.js.map → run-AG4Y45X7.js.map} +0 -0
- /package/dist/cli/{server-W4XJK4GX.js.map → server-GNHR5K3N.js.map} +0 -0
- /package/dist/cli/{sessions-YZXWMIWW.js.map → sessions-MHRF3GU4.js.map} +0 -0
- /package/dist/cli/{version-DWD6RLIU.js.map → version-7AL4JZ63.js.map} +0 -0
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
toWholeFileEditBlock,
|
|
35
35
|
walkFilesStream,
|
|
36
36
|
webFetch
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-RNSZYYGB.js";
|
|
38
38
|
import {
|
|
39
39
|
McpClient,
|
|
40
40
|
SseTransport,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
} from "./chunk-XHQIK7B6.js";
|
|
51
51
|
import {
|
|
52
52
|
MemoryStore
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-4D6TT2IB.js";
|
|
54
54
|
import {
|
|
55
55
|
KeystrokeProvider,
|
|
56
56
|
SingleSelect,
|
|
@@ -101,7 +101,7 @@ import {
|
|
|
101
101
|
resolveSlashAlias,
|
|
102
102
|
savePlanState,
|
|
103
103
|
suggestSlashCommands
|
|
104
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-C5543CRX.js";
|
|
105
105
|
import {
|
|
106
106
|
fetchSmitheryDetail,
|
|
107
107
|
loadMorePages,
|
|
@@ -117,13 +117,13 @@ import {
|
|
|
117
117
|
formatCommandResult,
|
|
118
118
|
pauseGate,
|
|
119
119
|
runCommand
|
|
120
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-S4GF3HPO.js";
|
|
121
121
|
import {
|
|
122
122
|
PROJECT_MEMORY_FILE,
|
|
123
123
|
SkillStore,
|
|
124
124
|
memoryEnabled,
|
|
125
125
|
readProjectMemory
|
|
126
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-K6W64QVE.js";
|
|
127
127
|
import {
|
|
128
128
|
HOOK_EVENTS,
|
|
129
129
|
formatHookOutcomeMessage,
|
|
@@ -214,7 +214,7 @@ import {
|
|
|
214
214
|
|
|
215
215
|
// src/cli/commands/chat.tsx
|
|
216
216
|
import { render } from "ink";
|
|
217
|
-
import
|
|
217
|
+
import React65, { useState as useState22 } from "react";
|
|
218
218
|
|
|
219
219
|
// src/mcp/summary.ts
|
|
220
220
|
function buildMcpServerSummary(opts) {
|
|
@@ -237,8 +237,8 @@ function buildMcpServerSummary(opts) {
|
|
|
237
237
|
// src/cli/ui/App.tsx
|
|
238
238
|
import { statSync } from "fs";
|
|
239
239
|
import { resolve as resolve2 } from "path";
|
|
240
|
-
import { Box as
|
|
241
|
-
import
|
|
240
|
+
import { Box as Box50, Text as Text53, useStdout as useStdout15 } from "ink";
|
|
241
|
+
import React62, { useCallback as useCallback11, useEffect as useEffect12, useMemo as useMemo9, useRef as useRef9, useState as useState20 } from "react";
|
|
242
242
|
|
|
243
243
|
// src/code/checkpoints.ts
|
|
244
244
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
@@ -6552,9 +6552,42 @@ function truncateCells(value, maxCells) {
|
|
|
6552
6552
|
return `${value.slice(0, maxCells - 1)}\u2026`;
|
|
6553
6553
|
}
|
|
6554
6554
|
|
|
6555
|
-
// src/cli/ui/
|
|
6555
|
+
// src/cli/ui/ThemePicker.tsx
|
|
6556
6556
|
import { Box as Box24, Text as Text24 } from "ink";
|
|
6557
6557
|
import React28 from "react";
|
|
6558
|
+
function ThemePicker({
|
|
6559
|
+
currentPreference,
|
|
6560
|
+
activeTheme,
|
|
6561
|
+
onChoose
|
|
6562
|
+
}) {
|
|
6563
|
+
const choices = ["auto", ...listThemeNames()];
|
|
6564
|
+
const items = choices.map((value) => ({
|
|
6565
|
+
value,
|
|
6566
|
+
label: value,
|
|
6567
|
+
hint: describeTheme(value, currentPreference, activeTheme)
|
|
6568
|
+
}));
|
|
6569
|
+
return /* @__PURE__ */ React28.createElement(Box24, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React28.createElement(Text24, { bold: true }, "Theme"), /* @__PURE__ */ React28.createElement(
|
|
6570
|
+
SingleSelect,
|
|
6571
|
+
{
|
|
6572
|
+
items,
|
|
6573
|
+
initialValue: currentPreference,
|
|
6574
|
+
onSubmit: (value) => onChoose({ kind: "select", value }),
|
|
6575
|
+
onCancel: () => onChoose({ kind: "quit" }),
|
|
6576
|
+
footer: "\u2191\u2193 pick \xB7 \u23CE confirm \xB7 esc cancel"
|
|
6577
|
+
}
|
|
6578
|
+
));
|
|
6579
|
+
}
|
|
6580
|
+
function describeTheme(value, currentPreference, activeTheme) {
|
|
6581
|
+
const tags = [];
|
|
6582
|
+
if (value === currentPreference) tags.push("current preference");
|
|
6583
|
+
if (value === activeTheme) tags.push("active now");
|
|
6584
|
+
if (value === "auto") tags.push("use REASONIX_THEME or default");
|
|
6585
|
+
return tags.join(" \xB7 ");
|
|
6586
|
+
}
|
|
6587
|
+
|
|
6588
|
+
// src/cli/ui/WelcomeBanner.tsx
|
|
6589
|
+
import { Box as Box25, Text as Text25 } from "ink";
|
|
6590
|
+
import React29 from "react";
|
|
6558
6591
|
var HINTS = ["/help", "/init", "/memory", "/cost"];
|
|
6559
6592
|
function WelcomeBanner({
|
|
6560
6593
|
inCodeMode,
|
|
@@ -6564,8 +6597,8 @@ function WelcomeBanner({
|
|
|
6564
6597
|
const tagline = inCodeMode ? t("ui.taglineCode") : t("ui.taglineChat");
|
|
6565
6598
|
const taglineSub = t("ui.taglineSub");
|
|
6566
6599
|
const startTextRaw = t("ui.startSessionHint");
|
|
6567
|
-
return /* @__PURE__ */
|
|
6568
|
-
|
|
6600
|
+
return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", alignItems: "center", marginY: 1 }, /* @__PURE__ */ React29.createElement(
|
|
6601
|
+
Box25,
|
|
6569
6602
|
{
|
|
6570
6603
|
flexDirection: "column",
|
|
6571
6604
|
alignItems: "center",
|
|
@@ -6574,9 +6607,9 @@ function WelcomeBanner({
|
|
|
6574
6607
|
paddingX: 4,
|
|
6575
6608
|
paddingY: 1
|
|
6576
6609
|
},
|
|
6577
|
-
/* @__PURE__ */
|
|
6578
|
-
/* @__PURE__ */
|
|
6579
|
-
), /* @__PURE__ */
|
|
6610
|
+
/* @__PURE__ */ React29.createElement(Box25, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React29.createElement(Text25, { color: TONE.brand, bold: true }, "REASONIX"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, "\xD7"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text25, null, "\u{1F40B}"), /* @__PURE__ */ React29.createElement(Text25, { color: TONE.accent, bold: true }, "DeepSeek"))),
|
|
6611
|
+
/* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "column", alignItems: "center" }, /* @__PURE__ */ React29.createElement(Text25, { color: FG.body }, tagline), /* @__PURE__ */ React29.createElement(Text25, { color: FG.meta }, taglineSub))
|
|
6612
|
+
), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "row", gap: 3 }, HINTS.map((cmd) => /* @__PURE__ */ React29.createElement(Text25, { key: cmd, color: FG.meta }, cmd))), inCodeMode && workspaceRoot ? /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: TONE.brand }, "\u25B8 workspace"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.body }, workspaceRoot), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, " (relaunch with --dir <path> to switch)")) : null, dashboardUrl ? /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text25, { color: TONE.brand, bold: true }, "\u25B8 web"), /* @__PURE__ */ React29.createElement(Text25, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React29.createElement(Text25, { color: TONE.accent }, dashboardUrl)) : null);
|
|
6580
6613
|
}
|
|
6581
6614
|
|
|
6582
6615
|
// src/cli/ui/bang.ts
|
|
@@ -6774,6 +6807,7 @@ function applySlashResult(result, ctx) {
|
|
|
6774
6807
|
return { kind: "consumed" };
|
|
6775
6808
|
}
|
|
6776
6809
|
if (result.clear) {
|
|
6810
|
+
ctx.resetPendingModals?.();
|
|
6777
6811
|
ctx.stdoutWrite("\x1B[2J\x1B[3J\x1B[H");
|
|
6778
6812
|
ctx.log.reset();
|
|
6779
6813
|
if (result.info) ctx.log.pushInfo(result.info);
|
|
@@ -6879,7 +6913,7 @@ function handleToolStart(ev, ctx) {
|
|
|
6879
6913
|
ctx.setOngoingTool({ name: ev.toolName ?? "?", args: ev.toolArgs });
|
|
6880
6914
|
ctx.setToolProgress(null);
|
|
6881
6915
|
ctx.toolStartedAtRef.current = Date.now();
|
|
6882
|
-
ctx.translator.toolStart(ev.toolName ?? "?", parseJsonOrRaw(ev.toolArgs));
|
|
6916
|
+
ctx.translator.toolStart(ev.toolName ?? "?", parseJsonOrRaw(ev.toolArgs), ev.callId);
|
|
6883
6917
|
if (!ctx.codeModeOn || !ev.toolArgs) return;
|
|
6884
6918
|
try {
|
|
6885
6919
|
const parsed = JSON.parse(ev.toolArgs);
|
|
@@ -6894,6 +6928,10 @@ function handleToolStart(ev, ctx) {
|
|
|
6894
6928
|
}
|
|
6895
6929
|
}
|
|
6896
6930
|
function handleErrorEvent(ev, ctx) {
|
|
6931
|
+
ctx.setOngoingTool(null);
|
|
6932
|
+
ctx.setToolProgress(null);
|
|
6933
|
+
ctx.toolStartedAtRef.current = null;
|
|
6934
|
+
ctx.translator.toolAbort(ev.error ?? ev.content);
|
|
6897
6935
|
ctx.log.pushError("tool error", ev.error ?? ev.content);
|
|
6898
6936
|
}
|
|
6899
6937
|
function handleWarningEvent(ev, ctx) {
|
|
@@ -6935,274 +6973,8 @@ function handleToolEvent(ev, ctx) {
|
|
|
6935
6973
|
}
|
|
6936
6974
|
}
|
|
6937
6975
|
|
|
6938
|
-
// src/cli/ui/hooks/useAgentSession.ts
|
|
6939
|
-
import { useMemo as useMemo6 } from "react";
|
|
6940
|
-
function useAgentSession({
|
|
6941
|
-
sessionId,
|
|
6942
|
-
model: model2,
|
|
6943
|
-
workspace,
|
|
6944
|
-
branch
|
|
6945
|
-
}) {
|
|
6946
|
-
return useMemo6(
|
|
6947
|
-
() => ({
|
|
6948
|
-
id: sessionId ?? "default",
|
|
6949
|
-
branch: branch ?? "main",
|
|
6950
|
-
workspace,
|
|
6951
|
-
model: model2
|
|
6952
|
-
}),
|
|
6953
|
-
[sessionId, branch, workspace, model2]
|
|
6954
|
-
);
|
|
6955
|
-
}
|
|
6956
|
-
|
|
6957
|
-
// src/cli/ui/hooks/useChatScroll.ts
|
|
6958
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState14 } from "react";
|
|
6959
|
-
var SCROLL_PAGE_ROWS = 3;
|
|
6960
|
-
var COALESCE_MS = 16;
|
|
6961
|
-
function useChatScroll() {
|
|
6962
|
-
const [scrollRows, setScrollRows] = useState14(0);
|
|
6963
|
-
const [pinned, setPinned] = useState14(true);
|
|
6964
|
-
const [maxScroll, setMaxScrollState] = useState14(0);
|
|
6965
|
-
const maxScrollRef = useRef2(0);
|
|
6966
|
-
const pendingDelta = useRef2(0);
|
|
6967
|
-
const flushTimer = useRef2(null);
|
|
6968
|
-
const flush = useCallback2(() => {
|
|
6969
|
-
flushTimer.current = null;
|
|
6970
|
-
const d = pendingDelta.current;
|
|
6971
|
-
pendingDelta.current = 0;
|
|
6972
|
-
if (d === 0) return;
|
|
6973
|
-
if (d < 0) setPinned(false);
|
|
6974
|
-
setScrollRows((o) => {
|
|
6975
|
-
const next = Math.max(0, Math.min(maxScrollRef.current, o + d));
|
|
6976
|
-
if (next >= maxScrollRef.current) setPinned(true);
|
|
6977
|
-
return next;
|
|
6978
|
-
});
|
|
6979
|
-
}, []);
|
|
6980
|
-
const schedule = useCallback2(
|
|
6981
|
-
(delta) => {
|
|
6982
|
-
pendingDelta.current += delta;
|
|
6983
|
-
if (flushTimer.current !== null) return;
|
|
6984
|
-
flushTimer.current = setTimeout(flush, COALESCE_MS);
|
|
6985
|
-
},
|
|
6986
|
-
[flush]
|
|
6987
|
-
);
|
|
6988
|
-
useEffect4(() => {
|
|
6989
|
-
return () => {
|
|
6990
|
-
if (flushTimer.current !== null) {
|
|
6991
|
-
clearTimeout(flushTimer.current);
|
|
6992
|
-
flushTimer.current = null;
|
|
6993
|
-
}
|
|
6994
|
-
};
|
|
6995
|
-
}, []);
|
|
6996
|
-
useEffect4(() => {
|
|
6997
|
-
if (pinned) setScrollRows(maxScroll);
|
|
6998
|
-
}, [pinned, maxScroll]);
|
|
6999
|
-
useEffect4(() => {
|
|
7000
|
-
if (scrollRows > maxScroll) setScrollRows(maxScroll);
|
|
7001
|
-
}, [scrollRows, maxScroll]);
|
|
7002
|
-
const scrollUp = useCallback2(() => schedule(-SCROLL_PAGE_ROWS), [schedule]);
|
|
7003
|
-
const scrollDown = useCallback2(() => schedule(SCROLL_PAGE_ROWS), [schedule]);
|
|
7004
|
-
const jumpToBottom = useCallback2(() => {
|
|
7005
|
-
pendingDelta.current = 0;
|
|
7006
|
-
if (flushTimer.current !== null) {
|
|
7007
|
-
clearTimeout(flushTimer.current);
|
|
7008
|
-
flushTimer.current = null;
|
|
7009
|
-
}
|
|
7010
|
-
setPinned(true);
|
|
7011
|
-
}, []);
|
|
7012
|
-
const setMaxScroll = useCallback2((rows) => {
|
|
7013
|
-
maxScrollRef.current = rows;
|
|
7014
|
-
setMaxScrollState(rows);
|
|
7015
|
-
}, []);
|
|
7016
|
-
return { scrollRows, pinned, scrollUp, scrollDown, jumpToBottom, setMaxScroll };
|
|
7017
|
-
}
|
|
7018
|
-
|
|
7019
|
-
// src/cli/ui/hooks/useCodeMode.ts
|
|
7020
|
-
import { useCallback as useCallback3 } from "react";
|
|
7021
|
-
function useCodeMode(opts) {
|
|
7022
|
-
const { codeMode, pendingEdits, currentRootDir, session, syncPendingCount, recordEdit } = opts;
|
|
7023
|
-
const codeApply = useCallback3(
|
|
7024
|
-
(indices) => {
|
|
7025
|
-
if (!codeMode) return "not in code mode";
|
|
7026
|
-
const blocks = pendingEdits.current;
|
|
7027
|
-
if (blocks.length === 0) {
|
|
7028
|
-
return "nothing pending \u2014 the model hasn't proposed edits since the last /apply or /discard.";
|
|
7029
|
-
}
|
|
7030
|
-
const useSubset = indices !== void 0 && indices.length > 0;
|
|
7031
|
-
const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
|
|
7032
|
-
if (selected.length === 0) {
|
|
7033
|
-
return "\u25B8 no edits matched those indices \u2014 nothing applied. Use /apply with no args to commit them all.";
|
|
7034
|
-
}
|
|
7035
|
-
const snaps = snapshotBeforeEdits(selected, currentRootDir);
|
|
7036
|
-
const results = applyEditBlocks(selected, currentRootDir);
|
|
7037
|
-
const anyApplied = results.some((r) => r.status === "applied" || r.status === "created");
|
|
7038
|
-
if (anyApplied) recordEdit("review-apply", selected, results, snaps);
|
|
7039
|
-
pendingEdits.current = remaining;
|
|
7040
|
-
if (remaining.length === 0) clearPendingEdits(session ?? null);
|
|
7041
|
-
else savePendingEdits(session ?? null, remaining);
|
|
7042
|
-
syncPendingCount();
|
|
7043
|
-
const tail = remaining.length > 0 ? `
|
|
7044
|
-
\u25B8 ${remaining.length} edit block(s) still pending \u2014 /apply or /discard to clear them.` : "";
|
|
7045
|
-
return formatEditResults(results) + tail;
|
|
7046
|
-
},
|
|
7047
|
-
[codeMode, currentRootDir, session, syncPendingCount, recordEdit, pendingEdits]
|
|
7048
|
-
);
|
|
7049
|
-
const codeDiscard = useCallback3(
|
|
7050
|
-
(indices) => {
|
|
7051
|
-
const blocks = pendingEdits.current;
|
|
7052
|
-
if (blocks.length === 0) return "nothing pending to discard.";
|
|
7053
|
-
const useSubset = indices !== void 0 && indices.length > 0;
|
|
7054
|
-
const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
|
|
7055
|
-
if (selected.length === 0) {
|
|
7056
|
-
return "\u25B8 no edits matched those indices \u2014 nothing discarded.";
|
|
7057
|
-
}
|
|
7058
|
-
pendingEdits.current = remaining;
|
|
7059
|
-
if (remaining.length === 0) clearPendingEdits(session ?? null);
|
|
7060
|
-
else savePendingEdits(session ?? null, remaining);
|
|
7061
|
-
syncPendingCount();
|
|
7062
|
-
const tail = remaining.length > 0 ? ` (${remaining.length} block(s) still pending)` : ". Nothing was written to disk.";
|
|
7063
|
-
return `\u25B8 discarded ${selected.length} pending edit block(s)${tail}`;
|
|
7064
|
-
},
|
|
7065
|
-
[session, syncPendingCount, pendingEdits]
|
|
7066
|
-
);
|
|
7067
|
-
return { codeApply, codeDiscard };
|
|
7068
|
-
}
|
|
7069
|
-
|
|
7070
|
-
// src/cli/ui/hooks/useInputRecall.ts
|
|
7071
|
-
import { useCallback as useCallback4, useRef as useRef3 } from "react";
|
|
7072
|
-
function useInputRecall(setInput) {
|
|
7073
|
-
const promptHistory = useRef3([]);
|
|
7074
|
-
const historyCursor = useRef3(-1);
|
|
7075
|
-
const recallPrev = useCallback4(() => {
|
|
7076
|
-
const hist = promptHistory.current;
|
|
7077
|
-
if (hist.length === 0) return;
|
|
7078
|
-
const nextCursor = Math.min(historyCursor.current + 1, hist.length - 1);
|
|
7079
|
-
historyCursor.current = nextCursor;
|
|
7080
|
-
setInput(hist[hist.length - 1 - nextCursor] ?? "");
|
|
7081
|
-
}, [setInput]);
|
|
7082
|
-
const recallNext = useCallback4(() => {
|
|
7083
|
-
if (historyCursor.current < 0) return;
|
|
7084
|
-
const hist = promptHistory.current;
|
|
7085
|
-
const nextCursor = historyCursor.current - 1;
|
|
7086
|
-
historyCursor.current = nextCursor;
|
|
7087
|
-
setInput(nextCursor < 0 ? "" : hist[hist.length - 1 - nextCursor] ?? "");
|
|
7088
|
-
}, [setInput]);
|
|
7089
|
-
const pushHistory = useCallback4((text) => {
|
|
7090
|
-
promptHistory.current.push(text);
|
|
7091
|
-
}, []);
|
|
7092
|
-
const resetCursor = useCallback4(() => {
|
|
7093
|
-
historyCursor.current = -1;
|
|
7094
|
-
}, []);
|
|
7095
|
-
return { recallPrev, recallNext, pushHistory, resetCursor };
|
|
7096
|
-
}
|
|
7097
|
-
|
|
7098
|
-
// src/cli/ui/hooks/useLoopMode.ts
|
|
7099
|
-
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef4, useState as useState15 } from "react";
|
|
7100
|
-
function useLoopMode(opts) {
|
|
7101
|
-
const { log, busyRef, handleSubmitRef } = opts;
|
|
7102
|
-
const [activeLoop, setActiveLoop] = useState15(null);
|
|
7103
|
-
const activeLoopRef = useRef4(null);
|
|
7104
|
-
const loopTimerRef = useRef4(null);
|
|
7105
|
-
const loopFiringRef = useRef4(false);
|
|
7106
|
-
useEffect5(() => {
|
|
7107
|
-
activeLoopRef.current = activeLoop;
|
|
7108
|
-
}, [activeLoop]);
|
|
7109
|
-
const stopLoop = useCallback5(() => {
|
|
7110
|
-
if (loopTimerRef.current) {
|
|
7111
|
-
clearTimeout(loopTimerRef.current);
|
|
7112
|
-
loopTimerRef.current = null;
|
|
7113
|
-
}
|
|
7114
|
-
const cur = activeLoopRef.current;
|
|
7115
|
-
if (!cur) return;
|
|
7116
|
-
setActiveLoop(null);
|
|
7117
|
-
log.pushInfo(`\u25B8 loop stopped (after ${cur.iter} iter${cur.iter === 1 ? "" : "s"}).`);
|
|
7118
|
-
}, [log]);
|
|
7119
|
-
const startLoop = useCallback5((intervalMs, prompt) => {
|
|
7120
|
-
if (loopTimerRef.current) {
|
|
7121
|
-
clearTimeout(loopTimerRef.current);
|
|
7122
|
-
loopTimerRef.current = null;
|
|
7123
|
-
}
|
|
7124
|
-
setActiveLoop({
|
|
7125
|
-
prompt,
|
|
7126
|
-
intervalMs,
|
|
7127
|
-
nextFireAt: Date.now() + intervalMs,
|
|
7128
|
-
iter: 0
|
|
7129
|
-
});
|
|
7130
|
-
}, []);
|
|
7131
|
-
const getLoopStatus = useCallback5(() => {
|
|
7132
|
-
const cur = activeLoopRef.current;
|
|
7133
|
-
if (!cur) return null;
|
|
7134
|
-
return {
|
|
7135
|
-
prompt: cur.prompt,
|
|
7136
|
-
intervalMs: cur.intervalMs,
|
|
7137
|
-
iter: cur.iter,
|
|
7138
|
-
nextFireMs: Math.max(0, cur.nextFireAt - Date.now())
|
|
7139
|
-
};
|
|
7140
|
-
}, []);
|
|
7141
|
-
const isLoopActive = useCallback5(() => activeLoopRef.current !== null, []);
|
|
7142
|
-
const isLoopFiring = useCallback5(() => loopFiringRef.current, []);
|
|
7143
|
-
const clearFiringFlag = useCallback5(() => {
|
|
7144
|
-
loopFiringRef.current = false;
|
|
7145
|
-
}, []);
|
|
7146
|
-
useEffect5(() => {
|
|
7147
|
-
if (!activeLoop) return;
|
|
7148
|
-
const delay = Math.max(0, activeLoop.nextFireAt - Date.now());
|
|
7149
|
-
const timer = setTimeout(async () => {
|
|
7150
|
-
loopTimerRef.current = null;
|
|
7151
|
-
if (busyRef.current) {
|
|
7152
|
-
setActiveLoop((cur2) => cur2 ? { ...cur2, nextFireAt: Date.now() + 1e3 } : cur2);
|
|
7153
|
-
return;
|
|
7154
|
-
}
|
|
7155
|
-
const cur = activeLoopRef.current;
|
|
7156
|
-
if (!cur) return;
|
|
7157
|
-
const nextIter = cur.iter + 1;
|
|
7158
|
-
setActiveLoop(
|
|
7159
|
-
(c) => c ? { ...c, iter: nextIter, nextFireAt: Date.now() + cur.intervalMs } : c
|
|
7160
|
-
);
|
|
7161
|
-
log.pushInfo(`\u25B8 /loop iter ${nextIter} \u2192 ${cur.prompt}`);
|
|
7162
|
-
loopFiringRef.current = true;
|
|
7163
|
-
try {
|
|
7164
|
-
await handleSubmitRef.current?.(cur.prompt);
|
|
7165
|
-
} catch {
|
|
7166
|
-
stopLoop();
|
|
7167
|
-
} finally {
|
|
7168
|
-
loopFiringRef.current = false;
|
|
7169
|
-
}
|
|
7170
|
-
}, delay);
|
|
7171
|
-
loopTimerRef.current = timer;
|
|
7172
|
-
return () => clearTimeout(timer);
|
|
7173
|
-
}, [activeLoop, stopLoop, log, busyRef, handleSubmitRef]);
|
|
7174
|
-
return {
|
|
7175
|
-
startLoop,
|
|
7176
|
-
stopLoop,
|
|
7177
|
-
getLoopStatus,
|
|
7178
|
-
isLoopActive,
|
|
7179
|
-
isLoopFiring,
|
|
7180
|
-
clearFiringFlag,
|
|
7181
|
-
activeLoop
|
|
7182
|
-
};
|
|
7183
|
-
}
|
|
7184
|
-
|
|
7185
|
-
// src/cli/ui/hooks/useQuit.ts
|
|
7186
|
-
import { useCallback as useCallback6, useEffect as useEffect6 } from "react";
|
|
7187
|
-
function useQuit(transcriptRef) {
|
|
7188
|
-
const quitProcess = useCallback6(() => {
|
|
7189
|
-
transcriptRef.current?.end();
|
|
7190
|
-
process.exit(0);
|
|
7191
|
-
}, [transcriptRef]);
|
|
7192
|
-
useEffect6(() => {
|
|
7193
|
-
process.on("SIGINT", quitProcess);
|
|
7194
|
-
return () => {
|
|
7195
|
-
process.off("SIGINT", quitProcess);
|
|
7196
|
-
};
|
|
7197
|
-
}, [quitProcess]);
|
|
7198
|
-
return quitProcess;
|
|
7199
|
-
}
|
|
7200
|
-
|
|
7201
|
-
// src/cli/ui/hooks/useScrollback.ts
|
|
7202
|
-
import { useMemo as useMemo7 } from "react";
|
|
7203
|
-
|
|
7204
6976
|
// src/cli/ui/state/provider.tsx
|
|
7205
|
-
import
|
|
6977
|
+
import React30 from "react";
|
|
7206
6978
|
|
|
7207
6979
|
// src/cli/ui/state/reducer.ts
|
|
7208
6980
|
function reduce(state, event) {
|
|
@@ -7536,62 +7308,337 @@ function initialState(session, cards = []) {
|
|
|
7536
7308
|
};
|
|
7537
7309
|
}
|
|
7538
7310
|
|
|
7539
|
-
// src/cli/ui/state/store.ts
|
|
7540
|
-
function createStore(session, initialCards) {
|
|
7541
|
-
let state = initialState(session, initialCards);
|
|
7542
|
-
const stateListeners = /* @__PURE__ */ new Set();
|
|
7543
|
-
const eventListeners = /* @__PURE__ */ new Set();
|
|
7544
|
-
return {
|
|
7545
|
-
getState() {
|
|
7546
|
-
return state;
|
|
7547
|
-
},
|
|
7548
|
-
dispatch(event) {
|
|
7549
|
-
state = reduce(state, event);
|
|
7550
|
-
for (const listener of stateListeners) listener();
|
|
7551
|
-
for (const listener of eventListeners) listener(event);
|
|
7552
|
-
},
|
|
7553
|
-
subscribe(listener) {
|
|
7554
|
-
stateListeners.add(listener);
|
|
7555
|
-
return () => {
|
|
7556
|
-
stateListeners.delete(listener);
|
|
7557
|
-
};
|
|
7558
|
-
},
|
|
7559
|
-
onEvent(listener) {
|
|
7560
|
-
eventListeners.add(listener);
|
|
7561
|
-
return () => {
|
|
7562
|
-
eventListeners.delete(listener);
|
|
7563
|
-
};
|
|
7311
|
+
// src/cli/ui/state/store.ts
|
|
7312
|
+
function createStore(session, initialCards) {
|
|
7313
|
+
let state = initialState(session, initialCards);
|
|
7314
|
+
const stateListeners = /* @__PURE__ */ new Set();
|
|
7315
|
+
const eventListeners = /* @__PURE__ */ new Set();
|
|
7316
|
+
return {
|
|
7317
|
+
getState() {
|
|
7318
|
+
return state;
|
|
7319
|
+
},
|
|
7320
|
+
dispatch(event) {
|
|
7321
|
+
state = reduce(state, event);
|
|
7322
|
+
for (const listener of stateListeners) listener();
|
|
7323
|
+
for (const listener of eventListeners) listener(event);
|
|
7324
|
+
},
|
|
7325
|
+
subscribe(listener) {
|
|
7326
|
+
stateListeners.add(listener);
|
|
7327
|
+
return () => {
|
|
7328
|
+
stateListeners.delete(listener);
|
|
7329
|
+
};
|
|
7330
|
+
},
|
|
7331
|
+
onEvent(listener) {
|
|
7332
|
+
eventListeners.add(listener);
|
|
7333
|
+
return () => {
|
|
7334
|
+
eventListeners.delete(listener);
|
|
7335
|
+
};
|
|
7336
|
+
}
|
|
7337
|
+
};
|
|
7338
|
+
}
|
|
7339
|
+
|
|
7340
|
+
// src/cli/ui/state/provider.tsx
|
|
7341
|
+
var StoreCtx = React30.createContext(null);
|
|
7342
|
+
function AgentStoreProvider({
|
|
7343
|
+
session,
|
|
7344
|
+
initialCards,
|
|
7345
|
+
children
|
|
7346
|
+
}) {
|
|
7347
|
+
const initialCardsRef = React30.useRef(initialCards);
|
|
7348
|
+
const store = React30.useMemo(() => createStore(session, initialCardsRef.current), [session]);
|
|
7349
|
+
return /* @__PURE__ */ React30.createElement(StoreCtx.Provider, { value: store }, children);
|
|
7350
|
+
}
|
|
7351
|
+
function useAgentStore() {
|
|
7352
|
+
const store = React30.useContext(StoreCtx);
|
|
7353
|
+
if (!store) throw new Error("useAgentStore must be used inside AgentStoreProvider");
|
|
7354
|
+
return store;
|
|
7355
|
+
}
|
|
7356
|
+
function useAgentState(selector) {
|
|
7357
|
+
const store = useAgentStore();
|
|
7358
|
+
const subscribe = React30.useCallback((cb) => store.subscribe(cb), [store]);
|
|
7359
|
+
const getSnapshot = React30.useCallback(() => selector(store.getState()), [store, selector]);
|
|
7360
|
+
return React30.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
7361
|
+
}
|
|
7362
|
+
function useDispatch() {
|
|
7363
|
+
return useAgentStore().dispatch;
|
|
7364
|
+
}
|
|
7365
|
+
|
|
7366
|
+
// src/cli/ui/hooks/useActivityPhase.ts
|
|
7367
|
+
function deriveActivityLabel(cards) {
|
|
7368
|
+
if (cards.some((c) => c.kind === "reasoning" && c.streaming)) return "thinking\u2026";
|
|
7369
|
+
const last = cards[cards.length - 1];
|
|
7370
|
+
if (!last || last.kind === "user") return "waiting for model\u2026";
|
|
7371
|
+
return "processing\u2026";
|
|
7372
|
+
}
|
|
7373
|
+
function useActivityLabel() {
|
|
7374
|
+
return useAgentState((s) => deriveActivityLabel(s.cards));
|
|
7375
|
+
}
|
|
7376
|
+
|
|
7377
|
+
// src/cli/ui/hooks/useAgentSession.ts
|
|
7378
|
+
import { useMemo as useMemo6 } from "react";
|
|
7379
|
+
function useAgentSession({
|
|
7380
|
+
sessionId,
|
|
7381
|
+
model: model2,
|
|
7382
|
+
workspace,
|
|
7383
|
+
branch
|
|
7384
|
+
}) {
|
|
7385
|
+
return useMemo6(
|
|
7386
|
+
() => ({
|
|
7387
|
+
id: sessionId ?? "default",
|
|
7388
|
+
branch: branch ?? "main",
|
|
7389
|
+
workspace,
|
|
7390
|
+
model: model2
|
|
7391
|
+
}),
|
|
7392
|
+
[sessionId, branch, workspace, model2]
|
|
7393
|
+
);
|
|
7394
|
+
}
|
|
7395
|
+
|
|
7396
|
+
// src/cli/ui/hooks/useChatScroll.ts
|
|
7397
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState14 } from "react";
|
|
7398
|
+
var SCROLL_PAGE_ROWS = 3;
|
|
7399
|
+
var COALESCE_MS = 16;
|
|
7400
|
+
function useChatScroll() {
|
|
7401
|
+
const [scrollRows, setScrollRows] = useState14(0);
|
|
7402
|
+
const [pinned, setPinned] = useState14(true);
|
|
7403
|
+
const [maxScroll, setMaxScrollState] = useState14(0);
|
|
7404
|
+
const maxScrollRef = useRef2(0);
|
|
7405
|
+
const pendingDelta = useRef2(0);
|
|
7406
|
+
const flushTimer = useRef2(null);
|
|
7407
|
+
const flush = useCallback2(() => {
|
|
7408
|
+
flushTimer.current = null;
|
|
7409
|
+
const d = pendingDelta.current;
|
|
7410
|
+
pendingDelta.current = 0;
|
|
7411
|
+
if (d === 0) return;
|
|
7412
|
+
if (d < 0) setPinned(false);
|
|
7413
|
+
setScrollRows((o) => {
|
|
7414
|
+
const next = Math.max(0, Math.min(maxScrollRef.current, o + d));
|
|
7415
|
+
if (next >= maxScrollRef.current) setPinned(true);
|
|
7416
|
+
return next;
|
|
7417
|
+
});
|
|
7418
|
+
}, []);
|
|
7419
|
+
const schedule = useCallback2(
|
|
7420
|
+
(delta) => {
|
|
7421
|
+
pendingDelta.current += delta;
|
|
7422
|
+
if (flushTimer.current !== null) return;
|
|
7423
|
+
flushTimer.current = setTimeout(flush, COALESCE_MS);
|
|
7424
|
+
},
|
|
7425
|
+
[flush]
|
|
7426
|
+
);
|
|
7427
|
+
useEffect4(() => {
|
|
7428
|
+
return () => {
|
|
7429
|
+
if (flushTimer.current !== null) {
|
|
7430
|
+
clearTimeout(flushTimer.current);
|
|
7431
|
+
flushTimer.current = null;
|
|
7432
|
+
}
|
|
7433
|
+
};
|
|
7434
|
+
}, []);
|
|
7435
|
+
useEffect4(() => {
|
|
7436
|
+
if (pinned) setScrollRows(maxScroll);
|
|
7437
|
+
}, [pinned, maxScroll]);
|
|
7438
|
+
useEffect4(() => {
|
|
7439
|
+
if (scrollRows > maxScroll) setScrollRows(maxScroll);
|
|
7440
|
+
}, [scrollRows, maxScroll]);
|
|
7441
|
+
const scrollUp = useCallback2(() => schedule(-SCROLL_PAGE_ROWS), [schedule]);
|
|
7442
|
+
const scrollDown = useCallback2(() => schedule(SCROLL_PAGE_ROWS), [schedule]);
|
|
7443
|
+
const jumpToBottom = useCallback2(() => {
|
|
7444
|
+
pendingDelta.current = 0;
|
|
7445
|
+
if (flushTimer.current !== null) {
|
|
7446
|
+
clearTimeout(flushTimer.current);
|
|
7447
|
+
flushTimer.current = null;
|
|
7448
|
+
}
|
|
7449
|
+
setPinned(true);
|
|
7450
|
+
}, []);
|
|
7451
|
+
const setMaxScroll = useCallback2((rows) => {
|
|
7452
|
+
maxScrollRef.current = rows;
|
|
7453
|
+
setMaxScrollState(rows);
|
|
7454
|
+
}, []);
|
|
7455
|
+
return { scrollRows, pinned, scrollUp, scrollDown, jumpToBottom, setMaxScroll };
|
|
7456
|
+
}
|
|
7457
|
+
|
|
7458
|
+
// src/cli/ui/hooks/useCodeMode.ts
|
|
7459
|
+
import { useCallback as useCallback3 } from "react";
|
|
7460
|
+
function useCodeMode(opts) {
|
|
7461
|
+
const { codeMode, pendingEdits, currentRootDir, session, syncPendingCount, recordEdit } = opts;
|
|
7462
|
+
const codeApply = useCallback3(
|
|
7463
|
+
(indices) => {
|
|
7464
|
+
if (!codeMode) return "not in code mode";
|
|
7465
|
+
const blocks = pendingEdits.current;
|
|
7466
|
+
if (blocks.length === 0) {
|
|
7467
|
+
return "nothing pending \u2014 the model hasn't proposed edits since the last /apply or /discard.";
|
|
7468
|
+
}
|
|
7469
|
+
const useSubset = indices !== void 0 && indices.length > 0;
|
|
7470
|
+
const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
|
|
7471
|
+
if (selected.length === 0) {
|
|
7472
|
+
return "\u25B8 no edits matched those indices \u2014 nothing applied. Use /apply with no args to commit them all.";
|
|
7473
|
+
}
|
|
7474
|
+
const snaps = snapshotBeforeEdits(selected, currentRootDir);
|
|
7475
|
+
const results = applyEditBlocks(selected, currentRootDir);
|
|
7476
|
+
const anyApplied = results.some((r) => r.status === "applied" || r.status === "created");
|
|
7477
|
+
if (anyApplied) recordEdit("review-apply", selected, results, snaps);
|
|
7478
|
+
pendingEdits.current = remaining;
|
|
7479
|
+
if (remaining.length === 0) clearPendingEdits(session ?? null);
|
|
7480
|
+
else savePendingEdits(session ?? null, remaining);
|
|
7481
|
+
syncPendingCount();
|
|
7482
|
+
const tail = remaining.length > 0 ? `
|
|
7483
|
+
\u25B8 ${remaining.length} edit block(s) still pending \u2014 /apply or /discard to clear them.` : "";
|
|
7484
|
+
return formatEditResults(results) + tail;
|
|
7485
|
+
},
|
|
7486
|
+
[codeMode, currentRootDir, session, syncPendingCount, recordEdit, pendingEdits]
|
|
7487
|
+
);
|
|
7488
|
+
const codeDiscard = useCallback3(
|
|
7489
|
+
(indices) => {
|
|
7490
|
+
const blocks = pendingEdits.current;
|
|
7491
|
+
if (blocks.length === 0) return "nothing pending to discard.";
|
|
7492
|
+
const useSubset = indices !== void 0 && indices.length > 0;
|
|
7493
|
+
const { selected, remaining } = useSubset ? partitionEdits(blocks, indices) : { selected: blocks, remaining: [] };
|
|
7494
|
+
if (selected.length === 0) {
|
|
7495
|
+
return "\u25B8 no edits matched those indices \u2014 nothing discarded.";
|
|
7496
|
+
}
|
|
7497
|
+
pendingEdits.current = remaining;
|
|
7498
|
+
if (remaining.length === 0) clearPendingEdits(session ?? null);
|
|
7499
|
+
else savePendingEdits(session ?? null, remaining);
|
|
7500
|
+
syncPendingCount();
|
|
7501
|
+
const tail = remaining.length > 0 ? ` (${remaining.length} block(s) still pending)` : ". Nothing was written to disk.";
|
|
7502
|
+
return `\u25B8 discarded ${selected.length} pending edit block(s)${tail}`;
|
|
7503
|
+
},
|
|
7504
|
+
[session, syncPendingCount, pendingEdits]
|
|
7505
|
+
);
|
|
7506
|
+
return { codeApply, codeDiscard };
|
|
7507
|
+
}
|
|
7508
|
+
|
|
7509
|
+
// src/cli/ui/hooks/useInputRecall.ts
|
|
7510
|
+
import { useCallback as useCallback4, useRef as useRef3 } from "react";
|
|
7511
|
+
function useInputRecall(setInput) {
|
|
7512
|
+
const promptHistory = useRef3([]);
|
|
7513
|
+
const historyCursor = useRef3(-1);
|
|
7514
|
+
const recallPrev = useCallback4(() => {
|
|
7515
|
+
const hist = promptHistory.current;
|
|
7516
|
+
if (hist.length === 0) return;
|
|
7517
|
+
const nextCursor = Math.min(historyCursor.current + 1, hist.length - 1);
|
|
7518
|
+
historyCursor.current = nextCursor;
|
|
7519
|
+
setInput(hist[hist.length - 1 - nextCursor] ?? "");
|
|
7520
|
+
}, [setInput]);
|
|
7521
|
+
const recallNext = useCallback4(() => {
|
|
7522
|
+
if (historyCursor.current < 0) return;
|
|
7523
|
+
const hist = promptHistory.current;
|
|
7524
|
+
const nextCursor = historyCursor.current - 1;
|
|
7525
|
+
historyCursor.current = nextCursor;
|
|
7526
|
+
setInput(nextCursor < 0 ? "" : hist[hist.length - 1 - nextCursor] ?? "");
|
|
7527
|
+
}, [setInput]);
|
|
7528
|
+
const pushHistory = useCallback4((text) => {
|
|
7529
|
+
promptHistory.current.push(text);
|
|
7530
|
+
}, []);
|
|
7531
|
+
const resetCursor = useCallback4(() => {
|
|
7532
|
+
historyCursor.current = -1;
|
|
7533
|
+
}, []);
|
|
7534
|
+
return { recallPrev, recallNext, pushHistory, resetCursor };
|
|
7535
|
+
}
|
|
7536
|
+
|
|
7537
|
+
// src/cli/ui/hooks/useLoopMode.ts
|
|
7538
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef4, useState as useState15 } from "react";
|
|
7539
|
+
function useLoopMode(opts) {
|
|
7540
|
+
const { log, busyRef, handleSubmitRef } = opts;
|
|
7541
|
+
const [activeLoop, setActiveLoop] = useState15(null);
|
|
7542
|
+
const activeLoopRef = useRef4(null);
|
|
7543
|
+
const loopTimerRef = useRef4(null);
|
|
7544
|
+
const loopFiringRef = useRef4(false);
|
|
7545
|
+
useEffect5(() => {
|
|
7546
|
+
activeLoopRef.current = activeLoop;
|
|
7547
|
+
}, [activeLoop]);
|
|
7548
|
+
const stopLoop = useCallback5(() => {
|
|
7549
|
+
if (loopTimerRef.current) {
|
|
7550
|
+
clearTimeout(loopTimerRef.current);
|
|
7551
|
+
loopTimerRef.current = null;
|
|
7552
|
+
}
|
|
7553
|
+
const cur = activeLoopRef.current;
|
|
7554
|
+
if (!cur) return;
|
|
7555
|
+
setActiveLoop(null);
|
|
7556
|
+
log.pushInfo(`\u25B8 loop stopped (after ${cur.iter} iter${cur.iter === 1 ? "" : "s"}).`);
|
|
7557
|
+
}, [log]);
|
|
7558
|
+
const startLoop = useCallback5((intervalMs, prompt) => {
|
|
7559
|
+
if (loopTimerRef.current) {
|
|
7560
|
+
clearTimeout(loopTimerRef.current);
|
|
7561
|
+
loopTimerRef.current = null;
|
|
7564
7562
|
}
|
|
7563
|
+
setActiveLoop({
|
|
7564
|
+
prompt,
|
|
7565
|
+
intervalMs,
|
|
7566
|
+
nextFireAt: Date.now() + intervalMs,
|
|
7567
|
+
iter: 0
|
|
7568
|
+
});
|
|
7569
|
+
}, []);
|
|
7570
|
+
const getLoopStatus = useCallback5(() => {
|
|
7571
|
+
const cur = activeLoopRef.current;
|
|
7572
|
+
if (!cur) return null;
|
|
7573
|
+
return {
|
|
7574
|
+
prompt: cur.prompt,
|
|
7575
|
+
intervalMs: cur.intervalMs,
|
|
7576
|
+
iter: cur.iter,
|
|
7577
|
+
nextFireMs: Math.max(0, cur.nextFireAt - Date.now())
|
|
7578
|
+
};
|
|
7579
|
+
}, []);
|
|
7580
|
+
const isLoopActive = useCallback5(() => activeLoopRef.current !== null, []);
|
|
7581
|
+
const isLoopFiring = useCallback5(() => loopFiringRef.current, []);
|
|
7582
|
+
const clearFiringFlag = useCallback5(() => {
|
|
7583
|
+
loopFiringRef.current = false;
|
|
7584
|
+
}, []);
|
|
7585
|
+
useEffect5(() => {
|
|
7586
|
+
if (!activeLoop) return;
|
|
7587
|
+
const delay = Math.max(0, activeLoop.nextFireAt - Date.now());
|
|
7588
|
+
const timer = setTimeout(async () => {
|
|
7589
|
+
loopTimerRef.current = null;
|
|
7590
|
+
if (busyRef.current) {
|
|
7591
|
+
setActiveLoop((cur2) => cur2 ? { ...cur2, nextFireAt: Date.now() + 1e3 } : cur2);
|
|
7592
|
+
return;
|
|
7593
|
+
}
|
|
7594
|
+
const cur = activeLoopRef.current;
|
|
7595
|
+
if (!cur) return;
|
|
7596
|
+
const nextIter = cur.iter + 1;
|
|
7597
|
+
setActiveLoop(
|
|
7598
|
+
(c) => c ? { ...c, iter: nextIter, nextFireAt: Date.now() + cur.intervalMs } : c
|
|
7599
|
+
);
|
|
7600
|
+
log.pushInfo(`\u25B8 /loop iter ${nextIter} \u2192 ${cur.prompt}`);
|
|
7601
|
+
loopFiringRef.current = true;
|
|
7602
|
+
try {
|
|
7603
|
+
await handleSubmitRef.current?.(cur.prompt);
|
|
7604
|
+
} catch {
|
|
7605
|
+
stopLoop();
|
|
7606
|
+
} finally {
|
|
7607
|
+
loopFiringRef.current = false;
|
|
7608
|
+
}
|
|
7609
|
+
}, delay);
|
|
7610
|
+
loopTimerRef.current = timer;
|
|
7611
|
+
return () => clearTimeout(timer);
|
|
7612
|
+
}, [activeLoop, stopLoop, log, busyRef, handleSubmitRef]);
|
|
7613
|
+
return {
|
|
7614
|
+
startLoop,
|
|
7615
|
+
stopLoop,
|
|
7616
|
+
getLoopStatus,
|
|
7617
|
+
isLoopActive,
|
|
7618
|
+
isLoopFiring,
|
|
7619
|
+
clearFiringFlag,
|
|
7620
|
+
activeLoop
|
|
7565
7621
|
};
|
|
7566
7622
|
}
|
|
7567
7623
|
|
|
7568
|
-
// src/cli/ui/
|
|
7569
|
-
|
|
7570
|
-
function
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
})
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
return store;
|
|
7583
|
-
}
|
|
7584
|
-
function useAgentState(selector) {
|
|
7585
|
-
const store = useAgentStore();
|
|
7586
|
-
const subscribe = React29.useCallback((cb) => store.subscribe(cb), [store]);
|
|
7587
|
-
const getSnapshot = React29.useCallback(() => selector(store.getState()), [store, selector]);
|
|
7588
|
-
return React29.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
7589
|
-
}
|
|
7590
|
-
function useDispatch() {
|
|
7591
|
-
return useAgentStore().dispatch;
|
|
7624
|
+
// src/cli/ui/hooks/useQuit.ts
|
|
7625
|
+
import { useCallback as useCallback6, useEffect as useEffect6 } from "react";
|
|
7626
|
+
function useQuit(transcriptRef) {
|
|
7627
|
+
const quitProcess = useCallback6(() => {
|
|
7628
|
+
transcriptRef.current?.end();
|
|
7629
|
+
process.exit(0);
|
|
7630
|
+
}, [transcriptRef]);
|
|
7631
|
+
useEffect6(() => {
|
|
7632
|
+
process.on("SIGINT", quitProcess);
|
|
7633
|
+
return () => {
|
|
7634
|
+
process.off("SIGINT", quitProcess);
|
|
7635
|
+
};
|
|
7636
|
+
}, [quitProcess]);
|
|
7637
|
+
return quitProcess;
|
|
7592
7638
|
}
|
|
7593
7639
|
|
|
7594
7640
|
// src/cli/ui/hooks/useScrollback.ts
|
|
7641
|
+
import { useMemo as useMemo7 } from "react";
|
|
7595
7642
|
var seq = 0;
|
|
7596
7643
|
function nextId2(prefix) {
|
|
7597
7644
|
seq += 1;
|
|
@@ -7771,8 +7818,8 @@ ${stack}` : message
|
|
|
7771
7818
|
endStreaming(id, aborted) {
|
|
7772
7819
|
dispatch({ type: "streaming.end", id, aborted });
|
|
7773
7820
|
},
|
|
7774
|
-
startTool(name, args) {
|
|
7775
|
-
const id = nextId2("tool");
|
|
7821
|
+
startTool(name, args, presetId) {
|
|
7822
|
+
const id = presetId ?? nextId2("tool");
|
|
7776
7823
|
dispatch({ type: "tool.start", id, name, args });
|
|
7777
7824
|
return id;
|
|
7778
7825
|
},
|
|
@@ -7830,21 +7877,21 @@ function useTranscriptWriter(transcriptRef, model2, prefixHash) {
|
|
|
7830
7877
|
}
|
|
7831
7878
|
|
|
7832
7879
|
// src/cli/ui/layout/CardStream.tsx
|
|
7833
|
-
import { Box as
|
|
7834
|
-
import
|
|
7880
|
+
import { Box as Box45, Text as Text47, useBoxMetrics } from "ink";
|
|
7881
|
+
import React55, { useEffect as useEffect7, useRef as useRef5 } from "react";
|
|
7835
7882
|
|
|
7836
7883
|
// src/cli/ui/cards/CardRenderer.tsx
|
|
7837
|
-
import { Box as
|
|
7838
|
-
import
|
|
7884
|
+
import { Box as Box44, Text as Text46 } from "ink";
|
|
7885
|
+
import React54 from "react";
|
|
7839
7886
|
|
|
7840
7887
|
// src/cli/ui/cards/CtxCard.tsx
|
|
7841
|
-
import { Box as
|
|
7842
|
-
import
|
|
7888
|
+
import { Box as Box28, Text as Text27 } from "ink";
|
|
7889
|
+
import React33 from "react";
|
|
7843
7890
|
|
|
7844
7891
|
// src/cli/ui/primitives/Card.tsx
|
|
7845
|
-
import { Box as
|
|
7846
|
-
import
|
|
7847
|
-
var ActiveCardContext =
|
|
7892
|
+
import { Box as Box26 } from "ink";
|
|
7893
|
+
import React31, { useContext as useContext3 } from "react";
|
|
7894
|
+
var ActiveCardContext = React31.createContext(true);
|
|
7848
7895
|
var STRIPE_BORDER = {
|
|
7849
7896
|
topLeft: " ",
|
|
7850
7897
|
top: " ",
|
|
@@ -7858,10 +7905,10 @@ var STRIPE_BORDER = {
|
|
|
7858
7905
|
function Card({ tone, children }) {
|
|
7859
7906
|
const active = useContext3(ActiveCardContext);
|
|
7860
7907
|
if (!active) {
|
|
7861
|
-
return /* @__PURE__ */
|
|
7908
|
+
return /* @__PURE__ */ React31.createElement(Box26, { flexDirection: "column" }, children);
|
|
7862
7909
|
}
|
|
7863
|
-
return /* @__PURE__ */
|
|
7864
|
-
|
|
7910
|
+
return /* @__PURE__ */ React31.createElement(
|
|
7911
|
+
Box26,
|
|
7865
7912
|
{
|
|
7866
7913
|
flexDirection: "column",
|
|
7867
7914
|
borderStyle: STRIPE_BORDER,
|
|
@@ -7878,8 +7925,8 @@ function Card({ tone, children }) {
|
|
|
7878
7925
|
}
|
|
7879
7926
|
|
|
7880
7927
|
// src/cli/ui/primitives/CardHeader.tsx
|
|
7881
|
-
import { Box as
|
|
7882
|
-
import
|
|
7928
|
+
import { Box as Box27, Text as Text26 } from "ink";
|
|
7929
|
+
import React32, { useContext as useContext4 } from "react";
|
|
7883
7930
|
function CardHeader({
|
|
7884
7931
|
glyph,
|
|
7885
7932
|
tone,
|
|
@@ -7892,13 +7939,13 @@ function CardHeader({
|
|
|
7892
7939
|
}) {
|
|
7893
7940
|
const active = useContext4(ActiveCardContext);
|
|
7894
7941
|
const visibleMeta = active ? meta : meta?.filter((item) => typeof item !== "string");
|
|
7895
|
-
return /* @__PURE__ */
|
|
7942
|
+
return /* @__PURE__ */ React32.createElement(Box27, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React32.createElement(Text26, { color: tone }, glyph), titleBg ? /* @__PURE__ */ React32.createElement(Text26, { backgroundColor: titleBg, color: titleColor ?? tone, bold: true }, ` ${title} `) : /* @__PURE__ */ React32.createElement(Text26, { bold: true, color: titleColor ?? tone }, title), subtitle ? /* @__PURE__ */ React32.createElement(Text26, { color: FG.body }, subtitle) : null, visibleMeta?.map((item, i) => {
|
|
7896
7943
|
const isStr = typeof item === "string";
|
|
7897
7944
|
const text = isStr ? item : item.text;
|
|
7898
7945
|
const color = isStr ? FG.faint : item.color;
|
|
7899
7946
|
return (
|
|
7900
7947
|
// biome-ignore lint/suspicious/noArrayIndexKey: meta items are positional
|
|
7901
|
-
/* @__PURE__ */
|
|
7948
|
+
/* @__PURE__ */ React32.createElement(React32.Fragment, { key: `m-${i}` }, /* @__PURE__ */ React32.createElement(Text26, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React32.createElement(Text26, { color }, text))
|
|
7902
7949
|
);
|
|
7903
7950
|
}), active ? right : null);
|
|
7904
7951
|
}
|
|
@@ -7907,13 +7954,13 @@ function CardHeader({
|
|
|
7907
7954
|
var BAR_CELLS = 32;
|
|
7908
7955
|
function row(label, tokens, ratio, color) {
|
|
7909
7956
|
const filled = Math.max(0, Math.min(BAR_CELLS, Math.round(ratio * BAR_CELLS)));
|
|
7910
|
-
return /* @__PURE__ */
|
|
7957
|
+
return /* @__PURE__ */ React33.createElement(Box28, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React33.createElement(Text27, { color: FG.sub }, label.padEnd(7)), /* @__PURE__ */ React33.createElement(Text27, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ React33.createElement(Text27, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ React33.createElement(Text27, { bold: true, color: FG.body }, tokens.toLocaleString()), /* @__PURE__ */ React33.createElement(Text27, { color: FG.faint }, `\xB7 ${(ratio * 100).toFixed(1)}%`));
|
|
7911
7958
|
}
|
|
7912
7959
|
function CtxCard({ card }) {
|
|
7913
7960
|
const cap = Math.max(1, card.ctxMax);
|
|
7914
7961
|
const used = card.systemTokens + card.toolsTokens + card.logTokens + card.inputTokens;
|
|
7915
7962
|
const usedPct = used / cap * 100;
|
|
7916
|
-
return /* @__PURE__ */
|
|
7963
|
+
return /* @__PURE__ */ React33.createElement(Card, { tone: TONE.brand }, /* @__PURE__ */ React33.createElement(
|
|
7917
7964
|
CardHeader,
|
|
7918
7965
|
{
|
|
7919
7966
|
glyph: "\u2318",
|
|
@@ -7921,8 +7968,8 @@ function CtxCard({ card }) {
|
|
|
7921
7968
|
title: t("cardTitles.context"),
|
|
7922
7969
|
meta: [`${used.toLocaleString()} / ${cap.toLocaleString()} (${usedPct.toFixed(1)}%)`]
|
|
7923
7970
|
}
|
|
7924
|
-
), row(t("cardLabels.system"), card.systemTokens, card.systemTokens / cap, TONE.brand), row(t("cardLabels.tools"), card.toolsTokens, card.toolsTokens / cap, TONE.warn), row(t("cardLabels.log"), card.logTokens, card.logTokens / cap, TONE.ok), row(t("cardLabels.input"), card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */
|
|
7925
|
-
|
|
7971
|
+
), row(t("cardLabels.system"), card.systemTokens, card.systemTokens / cap, TONE.brand), row(t("cardLabels.tools"), card.toolsTokens, card.toolsTokens / cap, TONE.warn), row(t("cardLabels.log"), card.logTokens, card.logTokens / cap, TONE.ok), row(t("cardLabels.input"), card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(Text27, { color: FG.faint }, `${t("cardLabels.topTools")} \xB7 ${card.toolsCount} ${t("cardLabels.tools")} \xB7 ${card.logMessages} ${t("cardLabels.logMsgs")}`), card.topTools.slice(0, 5).map((tool) => /* @__PURE__ */ React33.createElement(Box28, { key: `${tool.turn}-${tool.name}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React33.createElement(Text27, { color: FG.sub }, tool.name), /* @__PURE__ */ React33.createElement(
|
|
7972
|
+
Text27,
|
|
7926
7973
|
{
|
|
7927
7974
|
color: FG.faint
|
|
7928
7975
|
},
|
|
@@ -7931,8 +7978,8 @@ function CtxCard({ card }) {
|
|
|
7931
7978
|
}
|
|
7932
7979
|
|
|
7933
7980
|
// src/cli/ui/cards/DiffCard.tsx
|
|
7934
|
-
import { Box as
|
|
7935
|
-
import
|
|
7981
|
+
import { Box as Box29, Text as Text28 } from "ink";
|
|
7982
|
+
import React34 from "react";
|
|
7936
7983
|
var LINE_COLOR = {
|
|
7937
7984
|
ctx: FG.sub,
|
|
7938
7985
|
add: TONE.ok,
|
|
@@ -7947,7 +7994,7 @@ var LINE_GLYPH = {
|
|
|
7947
7994
|
};
|
|
7948
7995
|
function DiffCard({ card }) {
|
|
7949
7996
|
const showFooter = card.hunks.length > 0;
|
|
7950
|
-
return /* @__PURE__ */
|
|
7997
|
+
return /* @__PURE__ */ React34.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React34.createElement(
|
|
7951
7998
|
CardHeader,
|
|
7952
7999
|
{
|
|
7953
8000
|
glyph: "\xB1",
|
|
@@ -7959,12 +8006,12 @@ function DiffCard({ card }) {
|
|
|
7959
8006
|
{ text: `-${card.stats.del}`, color: TONE.err }
|
|
7960
8007
|
]
|
|
7961
8008
|
}
|
|
7962
|
-
), card.hunks.map((hunk) => /* @__PURE__ */
|
|
8009
|
+
), card.hunks.map((hunk) => /* @__PURE__ */ React34.createElement(Box29, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ React34.createElement(Text28, { italic: true, color: FG.faint }, hunk.header), hunk.lines.map((line, li) => /* @__PURE__ */ React34.createElement(Box29, { key: `${card.id}:${hunk.header}:${li}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React34.createElement(Text28, { color: LINE_COLOR[line.kind] }, LINE_GLYPH[line.kind]), /* @__PURE__ */ React34.createElement(Text28, { color: LINE_COLOR[line.kind], dimColor: line.kind === "ctx" }, line.text))))), showFooter && /* @__PURE__ */ React34.createElement(Box29, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React34.createElement(Text28, { bold: true, color: TONE.ok }, "[a] apply"), /* @__PURE__ */ React34.createElement(Text28, { color: FG.sub }, "[s] skip"), /* @__PURE__ */ React34.createElement(Text28, { bold: true, color: TONE.err }, "[r] reject")));
|
|
7963
8010
|
}
|
|
7964
8011
|
|
|
7965
8012
|
// src/cli/ui/cards/DoctorCard.tsx
|
|
7966
|
-
import { Box as
|
|
7967
|
-
import
|
|
8013
|
+
import { Box as Box30, Text as Text29 } from "ink";
|
|
8014
|
+
import React35 from "react";
|
|
7968
8015
|
var LEVEL_GLYPH = {
|
|
7969
8016
|
ok: "\u2713",
|
|
7970
8017
|
warn: "\u26A0",
|
|
@@ -7987,12 +8034,12 @@ function DoctorCard({ card }) {
|
|
|
7987
8034
|
const fail = card.checks.filter((c) => c.level === "fail").length;
|
|
7988
8035
|
const labelWidth = card.checks.reduce((m, c) => Math.max(m, c.label.length), 0);
|
|
7989
8036
|
const summary = `${card.checks.length} checks \xB7 ${ok} passed${warn > 0 ? ` \xB7 ${warn} warn` : ""}${fail > 0 ? ` \xB7 ${fail} fail` : ""}`;
|
|
7990
|
-
return /* @__PURE__ */
|
|
8037
|
+
return /* @__PURE__ */ React35.createElement(Card, { tone: CARD.tool.color }, /* @__PURE__ */ React35.createElement(CardHeader, { glyph: "\u2695", tone: CARD.tool.color, title: "doctor", meta: [summary] }), card.checks.map((c) => /* @__PURE__ */ React35.createElement(Box30, { key: c.label, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React35.createElement(Text29, { color: levelColor[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ React35.createElement(Text29, { bold: true, color: fg.body }, c.label.padEnd(labelWidth + 1)), /* @__PURE__ */ React35.createElement(Text29, { color: fg.sub }, c.detail), /* @__PURE__ */ React35.createElement(Text29, { color: levelColor[c.level] }, LEVEL_TAG[c.level]))));
|
|
7991
8038
|
}
|
|
7992
8039
|
|
|
7993
8040
|
// src/cli/ui/cards/ErrorCard.tsx
|
|
7994
|
-
import { Box as
|
|
7995
|
-
import
|
|
8041
|
+
import { Box as Box31, Text as Text30 } from "ink";
|
|
8042
|
+
import React36 from "react";
|
|
7996
8043
|
var STACK_TAIL = 5;
|
|
7997
8044
|
function ErrorCard({ card }) {
|
|
7998
8045
|
const retryNote = card.retries !== void 0 && card.retries > 0 ? `${card.retries} ${t("cardLabels.retries")}` : null;
|
|
@@ -8002,7 +8049,7 @@ function ErrorCard({ card }) {
|
|
|
8002
8049
|
const stackHidden = stackTrunc ? stackLines.length - stackVisible.length : 0;
|
|
8003
8050
|
const hasStack = stackVisible.length > 0;
|
|
8004
8051
|
const messageLines = card.message.split("\n");
|
|
8005
|
-
return /* @__PURE__ */
|
|
8052
|
+
return /* @__PURE__ */ React36.createElement(Card, { tone: TONE.err }, /* @__PURE__ */ React36.createElement(
|
|
8006
8053
|
CardHeader,
|
|
8007
8054
|
{
|
|
8008
8055
|
glyph: "\u2716",
|
|
@@ -8010,19 +8057,19 @@ function ErrorCard({ card }) {
|
|
|
8010
8057
|
title: card.title || t("cardTitles.error"),
|
|
8011
8058
|
meta: retryNote ? [retryNote] : void 0
|
|
8012
8059
|
}
|
|
8013
|
-
), messageLines.map((line, i) => /* @__PURE__ */
|
|
8060
|
+
), messageLines.map((line, i) => /* @__PURE__ */ React36.createElement(Text30, { key: `${card.id}:msg:${i}`, color: TONE.err }, line || " ")), hasStack ? /* @__PURE__ */ React36.createElement(Box31, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React36.createElement(Text30, { color: FG.meta }, t("cardLabels.stackTrace")), stackHidden > 0 ? /* @__PURE__ */ React36.createElement(Text30, { color: FG.faint }, t(
|
|
8014
8061
|
stackHidden === 1 ? "cardLabels.earlierStackLine" : "cardLabels.earlierStackLines",
|
|
8015
8062
|
{ count: stackHidden }
|
|
8016
|
-
)) : null, stackVisible.map((line, i) => /* @__PURE__ */
|
|
8063
|
+
)) : null, stackVisible.map((line, i) => /* @__PURE__ */ React36.createElement(Text30, { key: `${card.id}:stk:${stackHidden + i}`, color: FG.meta }, line || " "))) : null);
|
|
8017
8064
|
}
|
|
8018
8065
|
|
|
8019
8066
|
// src/cli/ui/cards/LiveCard.tsx
|
|
8020
|
-
import { Box as
|
|
8021
|
-
import
|
|
8067
|
+
import { Box as Box32, Text as Text32 } from "ink";
|
|
8068
|
+
import React38 from "react";
|
|
8022
8069
|
|
|
8023
8070
|
// src/cli/ui/primitives/Spinner.tsx
|
|
8024
|
-
import { Text as
|
|
8025
|
-
import
|
|
8071
|
+
import { Text as Text31 } from "ink";
|
|
8072
|
+
import React37 from "react";
|
|
8026
8073
|
var FRAMES = {
|
|
8027
8074
|
circle: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
|
|
8028
8075
|
braille: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827"]
|
|
@@ -8031,7 +8078,7 @@ function Spinner({ kind = "circle", color, bold }) {
|
|
|
8031
8078
|
const frames = FRAMES[kind];
|
|
8032
8079
|
const tick = useTick();
|
|
8033
8080
|
const frame = tick % frames.length;
|
|
8034
|
-
return /* @__PURE__ */
|
|
8081
|
+
return /* @__PURE__ */ React37.createElement(Text31, { bold, color }, frames[frame]);
|
|
8035
8082
|
}
|
|
8036
8083
|
|
|
8037
8084
|
// src/cli/ui/cards/LiveCard.tsx
|
|
@@ -8058,12 +8105,12 @@ var VARIANT_GLYPH = {
|
|
|
8058
8105
|
function LiveCard({ card }) {
|
|
8059
8106
|
const color = TONE_TO_COLOR[card.tone];
|
|
8060
8107
|
const glyph = VARIANT_GLYPH[card.variant];
|
|
8061
|
-
return /* @__PURE__ */
|
|
8108
|
+
return /* @__PURE__ */ React38.createElement(Box32, { paddingLeft: 2, flexDirection: "row", gap: 1 }, card.variant === "thinking" ? /* @__PURE__ */ React38.createElement(Spinner, { kind: "circle", color, bold: true }) : /* @__PURE__ */ React38.createElement(Text32, { bold: true, color }, glyph), /* @__PURE__ */ React38.createElement(Text32, { color: FG.body }, card.text), card.meta !== void 0 ? /* @__PURE__ */ React38.createElement(Text32, { color: FG.faint }, `\xB7 ${card.meta}`) : null);
|
|
8062
8109
|
}
|
|
8063
8110
|
|
|
8064
8111
|
// src/cli/ui/cards/MemoryCard.tsx
|
|
8065
|
-
import { Box as
|
|
8066
|
-
import
|
|
8112
|
+
import { Box as Box33, Text as Text33 } from "ink";
|
|
8113
|
+
import React39 from "react";
|
|
8067
8114
|
var CATEGORY_ORDER = [
|
|
8068
8115
|
"user",
|
|
8069
8116
|
"feedback",
|
|
@@ -8092,7 +8139,7 @@ function MemoryCard({ card }) {
|
|
|
8092
8139
|
const counts = countByCategory(card.entries);
|
|
8093
8140
|
const summary = CATEGORY_ORDER.filter((c) => counts[c] > 0).map((c) => `${counts[c]} ${c}`).join(" \xB7 ");
|
|
8094
8141
|
const tokens = card.tokens > 1024 ? `~${(card.tokens / 1024).toFixed(1)}K tok` : `~${card.tokens} tok`;
|
|
8095
|
-
return /* @__PURE__ */
|
|
8142
|
+
return /* @__PURE__ */ React39.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React39.createElement(
|
|
8096
8143
|
CardHeader,
|
|
8097
8144
|
{
|
|
8098
8145
|
glyph: "\u2311",
|
|
@@ -8105,7 +8152,7 @@ function MemoryCard({ card }) {
|
|
|
8105
8152
|
const all = card.entries.filter((e) => e.category === category);
|
|
8106
8153
|
const shown = all.slice(0, 5);
|
|
8107
8154
|
const remaining = all.length - shown.length;
|
|
8108
|
-
return /* @__PURE__ */
|
|
8155
|
+
return /* @__PURE__ */ React39.createElement(Box33, { key: category, flexDirection: "column" }, /* @__PURE__ */ React39.createElement(Text33, { color: FG.faint }, `${CATEGORY_LABEL[category]} (${counts[category]})`), shown.map((entry) => /* @__PURE__ */ React39.createElement(Box33, { key: `${category}:${entry.summary}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React39.createElement(Text33, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category]), /* @__PURE__ */ React39.createElement(Text33, { color: FG.sub }, entry.summary))), remaining > 0 ? /* @__PURE__ */ React39.createElement(Text33, { color: FG.faint }, `\u22EE +${remaining} more`) : null);
|
|
8109
8156
|
}));
|
|
8110
8157
|
}
|
|
8111
8158
|
function countByCategory(entries) {
|
|
@@ -8120,8 +8167,8 @@ function countByCategory(entries) {
|
|
|
8120
8167
|
}
|
|
8121
8168
|
|
|
8122
8169
|
// src/cli/ui/cards/PlanCard.tsx
|
|
8123
|
-
import { Box as
|
|
8124
|
-
import
|
|
8170
|
+
import { Box as Box34, Text as Text34 } from "ink";
|
|
8171
|
+
import React40 from "react";
|
|
8125
8172
|
var STATUS_GLYPH = {
|
|
8126
8173
|
queued: "\u25CB",
|
|
8127
8174
|
running: "\u25B6",
|
|
@@ -8147,11 +8194,11 @@ function PlanCard({ card }) {
|
|
|
8147
8194
|
const hasRunning = card.steps.some((s) => s.status === "running");
|
|
8148
8195
|
const cardTone = hasRunning ? toneActive.accent : tone.accent;
|
|
8149
8196
|
const window = pickWindow(card.steps);
|
|
8150
|
-
return /* @__PURE__ */
|
|
8197
|
+
return /* @__PURE__ */ React40.createElement(Card, { tone: cardTone }, /* @__PURE__ */ React40.createElement(CardHeader, { glyph: "\u229E", tone: cardTone, title: card.title, meta: [progress] }), window.hiddenBefore > 0 ? /* @__PURE__ */ React40.createElement(Box34, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text34, { color: tone.ok }, "\u2713"), /* @__PURE__ */ React40.createElement(Text34, { color: fg.faint }, `\u22EF ${window.hiddenBefore} done`)) : null, window.steps.map((step) => {
|
|
8151
8198
|
const isActive = step.status === "running";
|
|
8152
8199
|
const titleColor = isActive ? fg.strong : fg.sub;
|
|
8153
|
-
return /* @__PURE__ */
|
|
8154
|
-
}), window.hiddenAfter > 0 ? /* @__PURE__ */
|
|
8200
|
+
return /* @__PURE__ */ React40.createElement(Box34, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text34, { color: statusColor[step.status] }, STATUS_GLYPH[step.status]), /* @__PURE__ */ React40.createElement(Text34, { bold: isActive, color: titleColor }, `${step.indexLabel}. ${step.title}`), isActive ? /* @__PURE__ */ React40.createElement(Text34, { color: toneActive.brand }, "\u2190 in progress") : null);
|
|
8201
|
+
}), window.hiddenAfter > 0 ? /* @__PURE__ */ React40.createElement(Box34, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text34, { color: fg.faint }, "\u25CB"), /* @__PURE__ */ React40.createElement(Text34, { color: fg.faint }, `\u22EF ${window.hiddenAfter} upcoming`)) : null);
|
|
8155
8202
|
}
|
|
8156
8203
|
function pickWindow(steps) {
|
|
8157
8204
|
if (steps.length <= VISIBLE_WINDOW) {
|
|
@@ -8179,8 +8226,8 @@ function anchorIndex(steps) {
|
|
|
8179
8226
|
}
|
|
8180
8227
|
|
|
8181
8228
|
// src/cli/ui/cards/ReasoningCard.tsx
|
|
8182
|
-
import { Box as
|
|
8183
|
-
import
|
|
8229
|
+
import { Box as Box35, Text as Text36, useStdout as useStdout9 } from "ink";
|
|
8230
|
+
import React42 from "react";
|
|
8184
8231
|
|
|
8185
8232
|
// src/frame/width.ts
|
|
8186
8233
|
import stringWidthLib from "string-width";
|
|
@@ -8231,12 +8278,12 @@ function wrapToCells(s, maxCells) {
|
|
|
8231
8278
|
}
|
|
8232
8279
|
|
|
8233
8280
|
// src/cli/ui/primitives/CursorBlock.tsx
|
|
8234
|
-
import { Text as
|
|
8235
|
-
import
|
|
8281
|
+
import { Text as Text35 } from "ink";
|
|
8282
|
+
import React41 from "react";
|
|
8236
8283
|
function CursorBlock() {
|
|
8237
8284
|
const tick = useTick();
|
|
8238
8285
|
const on = Math.floor(tick / 4) % 2 === 0;
|
|
8239
|
-
return /* @__PURE__ */
|
|
8286
|
+
return /* @__PURE__ */ React41.createElement(Text35, { inverse: on, color: CARD.streaming.color }, " ");
|
|
8240
8287
|
}
|
|
8241
8288
|
|
|
8242
8289
|
// src/cli/ui/cards/ReasoningCard.tsx
|
|
@@ -8252,7 +8299,7 @@ function ReasoningCard({
|
|
|
8252
8299
|
const allLines = card.text.length > 0 ? card.text.split("\n") : [];
|
|
8253
8300
|
const showBody = expanded && (allLines.length > 0 || card.streaming);
|
|
8254
8301
|
const tone = card.aborted ? TONE.err : card.streaming ? TONE_ACTIVE.accent : TONE.accent;
|
|
8255
|
-
return /* @__PURE__ */
|
|
8302
|
+
return /* @__PURE__ */ React42.createElement(Card, { tone }, /* @__PURE__ */ React42.createElement(ReasoningHeader, { card }), showBody && (card.streaming ? /* @__PURE__ */ React42.createElement(StreamingPreview, { card, allLines, lineCells }) : /* @__PURE__ */ React42.createElement(SettledPreview, { card, allLines, lineCells })));
|
|
8256
8303
|
}
|
|
8257
8304
|
function ReasoningHeader({ card }) {
|
|
8258
8305
|
const streamingActive = card.streaming && !card.aborted;
|
|
@@ -8265,7 +8312,7 @@ function ReasoningHeader({ card }) {
|
|
|
8265
8312
|
const duration = headerDuration(card);
|
|
8266
8313
|
if (duration) meta.push(duration);
|
|
8267
8314
|
const modelBadge = card.model ? modelBadgeFor(card.model) : null;
|
|
8268
|
-
return /* @__PURE__ */
|
|
8315
|
+
return /* @__PURE__ */ React42.createElement(
|
|
8269
8316
|
CardHeader,
|
|
8270
8317
|
{
|
|
8271
8318
|
glyph,
|
|
@@ -8274,7 +8321,7 @@ function ReasoningHeader({ card }) {
|
|
|
8274
8321
|
titleColor: PILL_SECTION.reason.fg,
|
|
8275
8322
|
titleBg: PILL_SECTION.reason.bg,
|
|
8276
8323
|
meta: meta.length > 0 ? meta : void 0,
|
|
8277
|
-
right: /* @__PURE__ */
|
|
8324
|
+
right: /* @__PURE__ */ React42.createElement(React42.Fragment, null, streamingActive ? /* @__PURE__ */ React42.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.accent }) : null, modelBadge ? /* @__PURE__ */ React42.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null)
|
|
8278
8325
|
}
|
|
8279
8326
|
);
|
|
8280
8327
|
}
|
|
@@ -8295,13 +8342,13 @@ function headerDuration(card) {
|
|
|
8295
8342
|
function StreamingPreview({ card, allLines, lineCells }) {
|
|
8296
8343
|
const visualLines = allLines.flatMap((l) => wrapToCells(l, lineCells));
|
|
8297
8344
|
const visible = visualLines.slice(-STREAMING_PREVIEW_LINES);
|
|
8298
|
-
return /* @__PURE__ */
|
|
8345
|
+
return /* @__PURE__ */ React42.createElement(BodyLines, { card, lines: visible, lineCells, cursorOnLast: true });
|
|
8299
8346
|
}
|
|
8300
8347
|
function SettledPreview({ card, allLines, lineCells }) {
|
|
8301
8348
|
const visualLines = allLines.flatMap((l) => wrapToCells(l, lineCells));
|
|
8302
8349
|
const visible = visualLines.slice(-SETTLED_TAIL_LINES);
|
|
8303
8350
|
const droppedLines = Math.max(0, visualLines.length - visible.length);
|
|
8304
|
-
return /* @__PURE__ */
|
|
8351
|
+
return /* @__PURE__ */ React42.createElement(React42.Fragment, null, droppedLines > 0 ? /* @__PURE__ */ React42.createElement(ElisionHint, { droppedLines, card }) : null, /* @__PURE__ */ React42.createElement(BodyLines, { card, lines: visible, lineCells, indexOffset: droppedLines }));
|
|
8305
8352
|
}
|
|
8306
8353
|
function BodyLines({
|
|
8307
8354
|
card,
|
|
@@ -8310,9 +8357,9 @@ function BodyLines({
|
|
|
8310
8357
|
cursorOnLast = false,
|
|
8311
8358
|
indexOffset = 0
|
|
8312
8359
|
}) {
|
|
8313
|
-
return /* @__PURE__ */
|
|
8360
|
+
return /* @__PURE__ */ React42.createElement(React42.Fragment, null, lines.map((line, i) => {
|
|
8314
8361
|
const isLast = i === lines.length - 1;
|
|
8315
|
-
return /* @__PURE__ */
|
|
8362
|
+
return /* @__PURE__ */ React42.createElement(Box35, { key: `${card.id}:b:${indexOffset + i}`, flexDirection: "row" }, /* @__PURE__ */ React42.createElement(Text36, { italic: true, color: FG.meta }, clipToCells(line, lineCells)), isLast && cursorOnLast && /* @__PURE__ */ React42.createElement(CursorBlock, null));
|
|
8316
8363
|
}));
|
|
8317
8364
|
}
|
|
8318
8365
|
function ElisionHint({
|
|
@@ -8326,12 +8373,12 @@ function ElisionHint({
|
|
|
8326
8373
|
parts.push(`${droppedLines} line${droppedLines === 1 ? "" : "s"}`);
|
|
8327
8374
|
}
|
|
8328
8375
|
if (card.tokens > 0) parts.push(`${card.tokens.toLocaleString()} tok`);
|
|
8329
|
-
return /* @__PURE__ */
|
|
8376
|
+
return /* @__PURE__ */ React42.createElement(Text36, { color: FG.faint }, `\u22EF ${parts.join(" \xB7 ")} above \xB7 /reasoning last`);
|
|
8330
8377
|
}
|
|
8331
8378
|
|
|
8332
8379
|
// src/cli/ui/cards/SearchCard.tsx
|
|
8333
|
-
import { Box as
|
|
8334
|
-
import
|
|
8380
|
+
import { Box as Box36, Text as Text37 } from "ink";
|
|
8381
|
+
import React43 from "react";
|
|
8335
8382
|
function SearchCard({ card }) {
|
|
8336
8383
|
const fileCount = new Set(card.hits.map((h) => h.file)).size;
|
|
8337
8384
|
const elapsed = `${(card.elapsedMs / 1e3).toFixed(2)}s`;
|
|
@@ -8340,7 +8387,7 @@ function SearchCard({ card }) {
|
|
|
8340
8387
|
files: fileCount
|
|
8341
8388
|
});
|
|
8342
8389
|
const grouped = groupByFile(card.hits.slice(0, 10));
|
|
8343
|
-
return /* @__PURE__ */
|
|
8390
|
+
return /* @__PURE__ */ React43.createElement(Card, { tone: TONE.info }, /* @__PURE__ */ React43.createElement(
|
|
8344
8391
|
CardHeader,
|
|
8345
8392
|
{
|
|
8346
8393
|
glyph: "\u2299",
|
|
@@ -8349,7 +8396,7 @@ function SearchCard({ card }) {
|
|
|
8349
8396
|
subtitle: `"${card.query}"`,
|
|
8350
8397
|
meta: [stats2, elapsed]
|
|
8351
8398
|
}
|
|
8352
|
-
), grouped.map(([file, hits]) => /* @__PURE__ */
|
|
8399
|
+
), grouped.map(([file, hits]) => /* @__PURE__ */ React43.createElement(Box36, { key: file, flexDirection: "column" }, /* @__PURE__ */ React43.createElement(Text37, { bold: true, color: FG.strong }, file), hits.map((h, i) => /* @__PURE__ */ React43.createElement(Box36, { key: `${file}:${h.line}:${i}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React43.createElement(Text37, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502`), /* @__PURE__ */ React43.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 ? /* @__PURE__ */ React43.createElement(Text37, { color: FG.faint }, t(
|
|
8353
8400
|
card.hits.length - 10 === 1 ? "cardLabels.moreHitSingular" : "cardLabels.moreHitsPlural",
|
|
8354
8401
|
{ count: card.hits.length - 10 }
|
|
8355
8402
|
)) : null);
|
|
@@ -8360,9 +8407,9 @@ function HighlightedLine({
|
|
|
8360
8407
|
end
|
|
8361
8408
|
}) {
|
|
8362
8409
|
if (start < 0 || end <= start || end > text.length) {
|
|
8363
|
-
return /* @__PURE__ */
|
|
8410
|
+
return /* @__PURE__ */ React43.createElement(Text37, { color: FG.sub }, text);
|
|
8364
8411
|
}
|
|
8365
|
-
return /* @__PURE__ */
|
|
8412
|
+
return /* @__PURE__ */ React43.createElement(React43.Fragment, null, /* @__PURE__ */ React43.createElement(Text37, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ React43.createElement(Text37, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ React43.createElement(Text37, { color: FG.sub }, text.slice(end)));
|
|
8366
8413
|
}
|
|
8367
8414
|
function groupByFile(hits) {
|
|
8368
8415
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -8375,8 +8422,8 @@ function groupByFile(hits) {
|
|
|
8375
8422
|
}
|
|
8376
8423
|
|
|
8377
8424
|
// src/cli/ui/cards/StreamingCard.tsx
|
|
8378
|
-
import { Box as
|
|
8379
|
-
import
|
|
8425
|
+
import { Box as Box38, Text as Text39, useStdout as useStdout11 } from "ink";
|
|
8426
|
+
import React45, { useContext as useContext5 } from "react";
|
|
8380
8427
|
|
|
8381
8428
|
// src/cli/ui/layout/LiveExpandContext.ts
|
|
8382
8429
|
import { createContext as createContext3 } from "react";
|
|
@@ -8384,54 +8431,54 @@ var LiveExpandContext = createContext3(false);
|
|
|
8384
8431
|
|
|
8385
8432
|
// src/cli/ui/markdown.tsx
|
|
8386
8433
|
import { highlight, supportsLanguage } from "cli-highlight";
|
|
8387
|
-
import { Box as
|
|
8388
|
-
import
|
|
8434
|
+
import { Box as Box37, Text as Text38, useStdout as useStdout10 } from "ink";
|
|
8435
|
+
import React44 from "react";
|
|
8389
8436
|
import stringWidth from "string-width";
|
|
8390
8437
|
var BODY_LEFT_CELLS = 7;
|
|
8391
|
-
var MarkdownWidthCtx =
|
|
8438
|
+
var MarkdownWidthCtx = React44.createContext(void 0);
|
|
8392
8439
|
function useWidth() {
|
|
8393
|
-
const ctx =
|
|
8440
|
+
const ctx = React44.useContext(MarkdownWidthCtx);
|
|
8394
8441
|
if (ctx !== void 0) return ctx;
|
|
8395
8442
|
return (useStdout10()?.stdout?.columns ?? process.stdout.columns ?? 80) - BODY_LEFT_CELLS;
|
|
8396
8443
|
}
|
|
8397
8444
|
marked.setOptions({ gfm: true, breaks: false });
|
|
8398
8445
|
function Markdown({ text, width }) {
|
|
8399
|
-
const tokens =
|
|
8446
|
+
const tokens = React44.useMemo(() => marked.lexer(text), [text]);
|
|
8400
8447
|
const ctxWidth = width !== void 0 ? Math.max(1, width) : void 0;
|
|
8401
|
-
return /* @__PURE__ */
|
|
8448
|
+
return /* @__PURE__ */ React44.createElement(MarkdownWidthCtx.Provider, { value: ctxWidth }, /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ React44.createElement(BlockToken, { key: `${i}-${token.type}`, token }))));
|
|
8402
8449
|
}
|
|
8403
8450
|
function BlockToken({ token }) {
|
|
8404
8451
|
switch (token.type) {
|
|
8405
8452
|
case "heading":
|
|
8406
|
-
return /* @__PURE__ */
|
|
8453
|
+
return /* @__PURE__ */ React44.createElement(Heading, { token });
|
|
8407
8454
|
case "paragraph":
|
|
8408
|
-
return /* @__PURE__ */
|
|
8455
|
+
return /* @__PURE__ */ React44.createElement(Paragraph, { token });
|
|
8409
8456
|
case "list":
|
|
8410
|
-
return /* @__PURE__ */
|
|
8457
|
+
return /* @__PURE__ */ React44.createElement(List, { token, depth: 0 });
|
|
8411
8458
|
case "code":
|
|
8412
|
-
return /* @__PURE__ */
|
|
8459
|
+
return /* @__PURE__ */ React44.createElement(CodeBlock2, { token });
|
|
8413
8460
|
case "blockquote":
|
|
8414
|
-
return /* @__PURE__ */
|
|
8461
|
+
return /* @__PURE__ */ React44.createElement(Blockquote, { token });
|
|
8415
8462
|
case "hr":
|
|
8416
|
-
return /* @__PURE__ */
|
|
8463
|
+
return /* @__PURE__ */ React44.createElement(HorizontalRule, null);
|
|
8417
8464
|
case "table":
|
|
8418
|
-
return /* @__PURE__ */
|
|
8465
|
+
return /* @__PURE__ */ React44.createElement(Table, { token });
|
|
8419
8466
|
case "html":
|
|
8420
|
-
return /* @__PURE__ */
|
|
8467
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, token.text);
|
|
8421
8468
|
case "space":
|
|
8422
8469
|
return null;
|
|
8423
8470
|
default:
|
|
8424
|
-
return /* @__PURE__ */
|
|
8471
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, token.raw ?? "");
|
|
8425
8472
|
}
|
|
8426
8473
|
}
|
|
8427
8474
|
function Heading({ token }) {
|
|
8428
|
-
return /* @__PURE__ */
|
|
8475
|
+
return /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
|
|
8429
8476
|
}
|
|
8430
8477
|
function Paragraph({ token }) {
|
|
8431
|
-
return /* @__PURE__ */
|
|
8478
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens ?? [] }));
|
|
8432
8479
|
}
|
|
8433
8480
|
function List({ token, depth }) {
|
|
8434
|
-
return /* @__PURE__ */
|
|
8481
|
+
return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ React44.createElement(
|
|
8435
8482
|
ListItem,
|
|
8436
8483
|
{
|
|
8437
8484
|
key: `${i}-${item.text.slice(0, 24)}`,
|
|
@@ -8452,27 +8499,27 @@ function ListItem({
|
|
|
8452
8499
|
const markerColor = item.task ? item.checked ? TONE.ok : FG.faint : FG.meta;
|
|
8453
8500
|
const dim = item.task && item.checked === true;
|
|
8454
8501
|
const indent = " ".repeat(depth + 1);
|
|
8455
|
-
return /* @__PURE__ */
|
|
8502
|
+
return /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, item.tokens.map((tok, i) => {
|
|
8456
8503
|
if (tok.type === "text") {
|
|
8457
8504
|
const inner = tok.tokens;
|
|
8458
8505
|
return (
|
|
8459
8506
|
// biome-ignore lint/suspicious/noArrayIndexKey: list-item children are positional and stable per render
|
|
8460
|
-
/* @__PURE__ */
|
|
8507
|
+
/* @__PURE__ */ React44.createElement(Text38, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ React44.createElement(Inline, { tokens: inner }) : tok.text)
|
|
8461
8508
|
);
|
|
8462
8509
|
}
|
|
8463
8510
|
if (tok.type === "list") {
|
|
8464
|
-
return /* @__PURE__ */
|
|
8511
|
+
return /* @__PURE__ */ React44.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
|
|
8465
8512
|
}
|
|
8466
|
-
return /* @__PURE__ */
|
|
8513
|
+
return /* @__PURE__ */ React44.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
|
|
8467
8514
|
})));
|
|
8468
8515
|
}
|
|
8469
8516
|
function CodeBlock2({ token }) {
|
|
8470
8517
|
const lang = token.lang?.split(/\s+/)[0] ?? "";
|
|
8471
8518
|
const colored = highlightCode(token.text, lang);
|
|
8472
8519
|
const lines = colored.split("\n");
|
|
8473
|
-
return /* @__PURE__ */
|
|
8520
|
+
return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, lang ? /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, lines.map((line, i) => (
|
|
8474
8521
|
// biome-ignore lint/suspicious/noArrayIndexKey: code lines are positional and stable per render
|
|
8475
|
-
/* @__PURE__ */
|
|
8522
|
+
/* @__PURE__ */ React44.createElement(Text38, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
|
|
8476
8523
|
))));
|
|
8477
8524
|
}
|
|
8478
8525
|
function highlightCode(source, lang) {
|
|
@@ -8485,7 +8532,7 @@ function highlightCode(source, lang) {
|
|
|
8485
8532
|
}
|
|
8486
8533
|
}
|
|
8487
8534
|
function Blockquote({ token }) {
|
|
8488
|
-
return /* @__PURE__ */
|
|
8535
|
+
return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ React44.createElement(Box37, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ React44.createElement(Text38, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ React44.createElement(Text38, { italic: true, color: FG.sub }, /* @__PURE__ */ React44.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ React44.createElement(BlockToken, { token: child })))));
|
|
8489
8536
|
}
|
|
8490
8537
|
function padToCells(text, cells) {
|
|
8491
8538
|
const w = stringWidth(text);
|
|
@@ -8495,7 +8542,7 @@ function padToCells(text, cells) {
|
|
|
8495
8542
|
function HorizontalRule() {
|
|
8496
8543
|
const width = useWidth();
|
|
8497
8544
|
const rule = "\u2500".repeat(Math.max(width, 1));
|
|
8498
|
-
return /* @__PURE__ */
|
|
8545
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: FG.faint }, ` ${rule}`);
|
|
8499
8546
|
}
|
|
8500
8547
|
function tableLayout(headerCells, bodyCells, availableWidth) {
|
|
8501
8548
|
const colCount = headerCells.length;
|
|
@@ -8523,7 +8570,7 @@ function Table({ token }) {
|
|
|
8523
8570
|
const bodyCells = token.rows.map((row2) => row2.map((c) => plainText(c.tokens)));
|
|
8524
8571
|
const layout = tableLayout(headerCells, bodyCells, width);
|
|
8525
8572
|
if (!layout.fallback)
|
|
8526
|
-
return /* @__PURE__ */
|
|
8573
|
+
return /* @__PURE__ */ React44.createElement(
|
|
8527
8574
|
ColumnarTable,
|
|
8528
8575
|
{
|
|
8529
8576
|
headerCells,
|
|
@@ -8533,7 +8580,7 @@ function Table({ token }) {
|
|
|
8533
8580
|
gap: layout.gap
|
|
8534
8581
|
}
|
|
8535
8582
|
);
|
|
8536
|
-
return /* @__PURE__ */
|
|
8583
|
+
return /* @__PURE__ */ React44.createElement(
|
|
8537
8584
|
FallbackTable,
|
|
8538
8585
|
{
|
|
8539
8586
|
headerCells,
|
|
@@ -8551,14 +8598,14 @@ function ColumnarTable({
|
|
|
8551
8598
|
gap
|
|
8552
8599
|
}) {
|
|
8553
8600
|
const ruleRow = widths.map((w) => "\u2500".repeat(w)).join(gap);
|
|
8554
|
-
return /* @__PURE__ */
|
|
8601
|
+
return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, null, " "), headerCells.map((cell, i) => (
|
|
8555
8602
|
// biome-ignore lint/suspicious/noArrayIndexKey: header cells positional
|
|
8556
|
-
/* @__PURE__ */
|
|
8557
|
-
))), /* @__PURE__ */
|
|
8603
|
+
/* @__PURE__ */ React44.createElement(React44.Fragment, { key: `h-${i}` }, /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ React44.createElement(Text38, null, gap) : null)
|
|
8604
|
+
))), /* @__PURE__ */ React44.createElement(Box37, null, /* @__PURE__ */ React44.createElement(Text38, null, " "), /* @__PURE__ */ React44.createElement(Text38, { color: FG.faint }, ruleRow)), bodyCells.map((row2, ri) => (
|
|
8558
8605
|
// biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
|
|
8559
|
-
/* @__PURE__ */
|
|
8606
|
+
/* @__PURE__ */ React44.createElement(Box37, { key: `tr-${ri}` }, /* @__PURE__ */ React44.createElement(Text38, null, " "), row2.map((cell, i) => (
|
|
8560
8607
|
// biome-ignore lint/suspicious/noArrayIndexKey: cells positional
|
|
8561
|
-
/* @__PURE__ */
|
|
8608
|
+
/* @__PURE__ */ React44.createElement(React44.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ React44.createElement(Text38, null, gap) : null)
|
|
8562
8609
|
)))
|
|
8563
8610
|
)));
|
|
8564
8611
|
}
|
|
@@ -8568,20 +8615,20 @@ function FallbackTable({
|
|
|
8568
8615
|
labelPad,
|
|
8569
8616
|
valueCells
|
|
8570
8617
|
}) {
|
|
8571
|
-
return /* @__PURE__ */
|
|
8618
|
+
return /* @__PURE__ */ React44.createElement(Box37, { flexDirection: "column" }, bodyCells.map((row2, ri) => (
|
|
8572
8619
|
// biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
|
|
8573
|
-
/* @__PURE__ */
|
|
8620
|
+
/* @__PURE__ */ React44.createElement(Box37, { key: `fr-${ri}`, flexDirection: "column" }, ri > 0 ? /* @__PURE__ */ React44.createElement(Text38, null, " ") : null, headerCells.map((h, ci) => {
|
|
8574
8621
|
const label = `${padToCells(h, labelPad - 2)}: `;
|
|
8575
8622
|
const lines = wrapToCells(row2[ci] ?? "", valueCells);
|
|
8576
8623
|
return lines.map((line, li) => (
|
|
8577
8624
|
// biome-ignore lint/suspicious/noArrayIndexKey: fallback table lines are positional
|
|
8578
|
-
/* @__PURE__ */
|
|
8625
|
+
/* @__PURE__ */ React44.createElement(Box37, { key: `fc-${ri}-${ci}-${li}` }, li === 0 ? /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.sub }, label) : /* @__PURE__ */ React44.createElement(Text38, null, padToCells("", labelPad)), /* @__PURE__ */ React44.createElement(Text38, { color: FG.body }, line))
|
|
8579
8626
|
));
|
|
8580
8627
|
}))
|
|
8581
8628
|
)));
|
|
8582
8629
|
}
|
|
8583
8630
|
function Inline({ tokens }) {
|
|
8584
|
-
return /* @__PURE__ */
|
|
8631
|
+
return /* @__PURE__ */ React44.createElement(React44.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ React44.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
|
|
8585
8632
|
}
|
|
8586
8633
|
var FILE_REF_RE2 = /\b([A-Za-z0-9_./@\-]+\.[A-Za-z0-9]{1,6})(?::(\d+)(?:-(\d+))?)?\b/g;
|
|
8587
8634
|
var MENTION_RE = /(?<![A-Za-z0-9_])@([A-Za-z0-9_./\-]+\.[A-Za-z0-9]{1,6})/g;
|
|
@@ -8592,10 +8639,10 @@ function looksLikeFileRef(path, hasLine) {
|
|
|
8592
8639
|
return ext.length >= 2;
|
|
8593
8640
|
}
|
|
8594
8641
|
function osc8(label, _target, color) {
|
|
8595
|
-
return /* @__PURE__ */
|
|
8642
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color, underline: true }, label);
|
|
8596
8643
|
}
|
|
8597
8644
|
function renderInlineText(raw) {
|
|
8598
|
-
if (!raw) return /* @__PURE__ */
|
|
8645
|
+
if (!raw) return /* @__PURE__ */ React44.createElement(Text38, null, raw);
|
|
8599
8646
|
const out = [];
|
|
8600
8647
|
let cursor = 0;
|
|
8601
8648
|
const hits = [];
|
|
@@ -8606,7 +8653,7 @@ function renderInlineText(raw) {
|
|
|
8606
8653
|
hits.push({
|
|
8607
8654
|
start,
|
|
8608
8655
|
end,
|
|
8609
|
-
node: /* @__PURE__ */
|
|
8656
|
+
node: /* @__PURE__ */ React44.createElement(Text38, { color: TONE.warn, underline: true }, `@${path}`)
|
|
8610
8657
|
});
|
|
8611
8658
|
}
|
|
8612
8659
|
for (const m of raw.matchAll(FILE_REF_RE2)) {
|
|
@@ -8623,44 +8670,44 @@ function renderInlineText(raw) {
|
|
|
8623
8670
|
let key = 0;
|
|
8624
8671
|
for (const h of hits) {
|
|
8625
8672
|
if (h.start > cursor) {
|
|
8626
|
-
out.push(/* @__PURE__ */
|
|
8673
|
+
out.push(/* @__PURE__ */ React44.createElement(Text38, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
|
|
8627
8674
|
}
|
|
8628
|
-
out.push(/* @__PURE__ */
|
|
8675
|
+
out.push(/* @__PURE__ */ React44.createElement(React44.Fragment, { key: `r-${key++}` }, h.node));
|
|
8629
8676
|
cursor = h.end;
|
|
8630
8677
|
}
|
|
8631
|
-
if (cursor < raw.length) out.push(/* @__PURE__ */
|
|
8632
|
-
return /* @__PURE__ */
|
|
8678
|
+
if (cursor < raw.length) out.push(/* @__PURE__ */ React44.createElement(Text38, { key: `t-${key++}` }, raw.slice(cursor)));
|
|
8679
|
+
return /* @__PURE__ */ React44.createElement(React44.Fragment, null, out);
|
|
8633
8680
|
}
|
|
8634
8681
|
function InlineToken({ token }) {
|
|
8635
8682
|
switch (token.type) {
|
|
8636
8683
|
case "text": {
|
|
8637
8684
|
const t2 = token;
|
|
8638
|
-
return t2.tokens ? /* @__PURE__ */
|
|
8685
|
+
return t2.tokens ? /* @__PURE__ */ React44.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
|
|
8639
8686
|
}
|
|
8640
8687
|
case "strong":
|
|
8641
|
-
return /* @__PURE__ */
|
|
8688
|
+
return /* @__PURE__ */ React44.createElement(Text38, { bold: true, color: FG.strong }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens }));
|
|
8642
8689
|
case "em":
|
|
8643
|
-
return /* @__PURE__ */
|
|
8690
|
+
return /* @__PURE__ */ React44.createElement(Text38, { italic: true }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens }));
|
|
8644
8691
|
case "codespan":
|
|
8645
|
-
return /* @__PURE__ */
|
|
8692
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${token.text} `);
|
|
8646
8693
|
case "del":
|
|
8647
|
-
return /* @__PURE__ */
|
|
8694
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ React44.createElement(Inline, { tokens: token.tokens }));
|
|
8648
8695
|
case "link": {
|
|
8649
8696
|
const l = token;
|
|
8650
|
-
return /* @__PURE__ */
|
|
8697
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: TONE.brand, underline: true }, /* @__PURE__ */ React44.createElement(Inline, { tokens: l.tokens }));
|
|
8651
8698
|
}
|
|
8652
8699
|
case "image": {
|
|
8653
8700
|
const im = token;
|
|
8654
|
-
return /* @__PURE__ */
|
|
8701
|
+
return /* @__PURE__ */ React44.createElement(Text38, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
|
|
8655
8702
|
}
|
|
8656
8703
|
case "br":
|
|
8657
|
-
return /* @__PURE__ */
|
|
8704
|
+
return /* @__PURE__ */ React44.createElement(Text38, null, "\n");
|
|
8658
8705
|
case "escape":
|
|
8659
|
-
return /* @__PURE__ */
|
|
8706
|
+
return /* @__PURE__ */ React44.createElement(Text38, null, token.text);
|
|
8660
8707
|
case "html":
|
|
8661
|
-
return /* @__PURE__ */
|
|
8708
|
+
return /* @__PURE__ */ React44.createElement(Text38, null, token.text);
|
|
8662
8709
|
default:
|
|
8663
|
-
return /* @__PURE__ */
|
|
8710
|
+
return /* @__PURE__ */ React44.createElement(Text38, null, token.raw ?? "");
|
|
8664
8711
|
}
|
|
8665
8712
|
}
|
|
8666
8713
|
function plainText(tokens) {
|
|
@@ -8723,19 +8770,19 @@ function StreamingCard({ card }) {
|
|
|
8723
8770
|
});
|
|
8724
8771
|
useSlowTick();
|
|
8725
8772
|
const modelBadge = card.model ? modelBadgeFor(card.model) : null;
|
|
8726
|
-
const modelPill = modelBadge ? /* @__PURE__ */
|
|
8773
|
+
const modelPill = modelBadge ? /* @__PURE__ */ React45.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null;
|
|
8727
8774
|
if (card.done && !card.aborted) {
|
|
8728
8775
|
const { tokens, tps } = tokenRate(card.text, card.ts, card.endedAt ?? Date.now());
|
|
8729
|
-
const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */
|
|
8730
|
-
return /* @__PURE__ */
|
|
8776
|
+
const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */ React45.createElement(Pill, { label: `${formatTokenCount(tokens)} tok \xB7 ${tps} t/s`, ...PILL_RATE, bold: false }) : null;
|
|
8777
|
+
return /* @__PURE__ */ React45.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React45.createElement(
|
|
8731
8778
|
CardHeader,
|
|
8732
8779
|
{
|
|
8733
8780
|
glyph: "\u2039",
|
|
8734
8781
|
tone: TONE.ok,
|
|
8735
8782
|
title: t("cardTitles.reply"),
|
|
8736
|
-
right: /* @__PURE__ */
|
|
8783
|
+
right: /* @__PURE__ */ React45.createElement(React45.Fragment, null, ratePill, modelPill)
|
|
8737
8784
|
}
|
|
8738
|
-
), /* @__PURE__ */
|
|
8785
|
+
), /* @__PURE__ */ React45.createElement(Markdown, { text: card.text }));
|
|
8739
8786
|
}
|
|
8740
8787
|
const lineCells = Math.max(20, cols - 4);
|
|
8741
8788
|
const allLines = card.text.length > 0 ? card.text.split("\n") : [""];
|
|
@@ -8748,24 +8795,24 @@ function StreamingCard({ card }) {
|
|
|
8748
8795
|
const glyph = aborted ? "\u2039" : "\u25C8";
|
|
8749
8796
|
const headLabel = aborted ? t("cardLabels.aborted") : t("cardLabels.writing");
|
|
8750
8797
|
const { tokens: liveTokens, tps: liveTps } = tokenRate(card.text, card.ts, Date.now());
|
|
8751
|
-
const liveRatePill = !aborted && liveTokens >= MIN_TOKENS_FOR_RATE && liveTps !== null ? /* @__PURE__ */
|
|
8752
|
-
const expandPill = !aborted ? /* @__PURE__ */
|
|
8753
|
-
return /* @__PURE__ */
|
|
8798
|
+
const liveRatePill = !aborted && liveTokens >= MIN_TOKENS_FOR_RATE && liveTps !== null ? /* @__PURE__ */ React45.createElement(Pill, { label: `${liveTps} t/s`, ...PILL_RATE, bold: false }) : null;
|
|
8799
|
+
const expandPill = !aborted ? /* @__PURE__ */ React45.createElement(Pill, { label: expanded ? "expanded \u2303o" : "preview \u2303o", ...PILL_RATE, bold: false }) : null;
|
|
8800
|
+
return /* @__PURE__ */ React45.createElement(Card, { tone: headColor }, /* @__PURE__ */ React45.createElement(
|
|
8754
8801
|
CardHeader,
|
|
8755
8802
|
{
|
|
8756
8803
|
glyph,
|
|
8757
8804
|
tone: headColor,
|
|
8758
8805
|
title: headLabel,
|
|
8759
|
-
right: /* @__PURE__ */
|
|
8806
|
+
right: /* @__PURE__ */ React45.createElement(React45.Fragment, null, liveRatePill, expandPill, aborted ? null : /* @__PURE__ */ React45.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand }), modelPill)
|
|
8760
8807
|
}
|
|
8761
|
-
), expanded && droppedAbove > 0 ? /* @__PURE__ */
|
|
8808
|
+
), expanded && droppedAbove > 0 ? /* @__PURE__ */ React45.createElement(Text39, { color: FG.faint }, t(droppedAbove === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
|
|
8762
8809
|
count: droppedAbove
|
|
8763
|
-
})) : null, visible.map((line, i) => /* @__PURE__ */
|
|
8810
|
+
})) : null, visible.map((line, i) => /* @__PURE__ */ React45.createElement(Box38, { key: `${card.id}:${visualLines.length - visible.length + i}`, flexDirection: "row" }, /* @__PURE__ */ React45.createElement(Text39, { color: aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)))), aborted ? /* @__PURE__ */ React45.createElement(Text39, { color: FG.faint }, t("cardLabels.truncatedByEsc")) : null);
|
|
8764
8811
|
}
|
|
8765
8812
|
|
|
8766
8813
|
// src/cli/ui/cards/SubAgentCard.tsx
|
|
8767
|
-
import { Box as
|
|
8768
|
-
import
|
|
8814
|
+
import { Box as Box39, Text as Text40 } from "ink";
|
|
8815
|
+
import React46, { useContext as useContext6 } from "react";
|
|
8769
8816
|
function SubAgentCard({ card }) {
|
|
8770
8817
|
const { fg, tone, toneActive } = useThemeTokens();
|
|
8771
8818
|
const statusColor = {
|
|
@@ -8779,7 +8826,7 @@ function SubAgentCard({ card }) {
|
|
|
8779
8826
|
const isRunning = card.status === "running";
|
|
8780
8827
|
const inLive = useContext6(ActiveCardContext);
|
|
8781
8828
|
const headerMeta2 = isRunning ? runningChildren > 0 ? [`${runningChildren} ${t("cardLabels.runningLabel")}`] : [t("cardLabels.workingLabel")] : [{ text: card.status, color: headColor }];
|
|
8782
|
-
return /* @__PURE__ */
|
|
8829
|
+
return /* @__PURE__ */ React46.createElement(Card, { tone: headColor }, /* @__PURE__ */ React46.createElement(
|
|
8783
8830
|
CardHeader,
|
|
8784
8831
|
{
|
|
8785
8832
|
glyph: headGlyph,
|
|
@@ -8789,7 +8836,7 @@ function SubAgentCard({ card }) {
|
|
|
8789
8836
|
subtitle: card.task,
|
|
8790
8837
|
meta: headerMeta2
|
|
8791
8838
|
}
|
|
8792
|
-
), card.name ? /* @__PURE__ */
|
|
8839
|
+
), card.name ? /* @__PURE__ */ React46.createElement(Text40, { color: fg.faint }, `${t("cardLabels.agent")} \xB7 ${card.name}`) : null, card.tools && card.tools.length > 0 && /* @__PURE__ */ React46.createElement(Text40, { color: fg.faint }, `${t("cardLabels.tools")} \xB7 ${card.tools.join(", ")}`), card.children.map((child) => /* @__PURE__ */ React46.createElement(Box39, { key: child.id, flexDirection: "row", gap: 1 }, inLive ? null : /* @__PURE__ */ React46.createElement(Text40, { color: tone.violet }, "\u258E"), /* @__PURE__ */ React46.createElement(ChildRow, { card: child }))));
|
|
8793
8840
|
}
|
|
8794
8841
|
function isChildDone(card) {
|
|
8795
8842
|
switch (card.kind) {
|
|
@@ -8806,16 +8853,16 @@ function ChildRow({ card }) {
|
|
|
8806
8853
|
const { fg, tone } = useThemeTokens();
|
|
8807
8854
|
const v = childVisual(card, tone.ok, tone.err, fg.faint);
|
|
8808
8855
|
const isDone = isChildDone(card);
|
|
8809
|
-
return /* @__PURE__ */
|
|
8856
|
+
return /* @__PURE__ */ React46.createElement(React46.Fragment, null, v.statusGlyph, /* @__PURE__ */ React46.createElement(Text40, { color: v.kindColor }, v.kindGlyph), /* @__PURE__ */ React46.createElement(Text40, { dimColor: isDone, color: fg.body }, v.text));
|
|
8810
8857
|
}
|
|
8811
8858
|
function runningGlyph(color) {
|
|
8812
|
-
return /* @__PURE__ */
|
|
8859
|
+
return /* @__PURE__ */ React46.createElement(Spinner, { kind: "circle", color });
|
|
8813
8860
|
}
|
|
8814
8861
|
function doneGlyph(color) {
|
|
8815
|
-
return /* @__PURE__ */
|
|
8862
|
+
return /* @__PURE__ */ React46.createElement(Text40, { color }, "\u2713");
|
|
8816
8863
|
}
|
|
8817
8864
|
function failedGlyph(color) {
|
|
8818
|
-
return /* @__PURE__ */
|
|
8865
|
+
return /* @__PURE__ */ React46.createElement(Text40, { color }, "\u2716");
|
|
8819
8866
|
}
|
|
8820
8867
|
function childVisual(card, doneColor, failedColor, fallbackColor) {
|
|
8821
8868
|
switch (card.kind) {
|
|
@@ -8860,7 +8907,7 @@ function childVisual(card, doneColor, failedColor, fallbackColor) {
|
|
|
8860
8907
|
};
|
|
8861
8908
|
default:
|
|
8862
8909
|
return {
|
|
8863
|
-
statusGlyph: /* @__PURE__ */
|
|
8910
|
+
statusGlyph: /* @__PURE__ */ React46.createElement(Text40, { color: fallbackColor }, "\xB7"),
|
|
8864
8911
|
kindGlyph: "\xB7",
|
|
8865
8912
|
kindColor: fallbackColor,
|
|
8866
8913
|
text: card.kind
|
|
@@ -8869,8 +8916,8 @@ function childVisual(card, doneColor, failedColor, fallbackColor) {
|
|
|
8869
8916
|
}
|
|
8870
8917
|
|
|
8871
8918
|
// src/cli/ui/cards/TaskCard.tsx
|
|
8872
|
-
import { Box as
|
|
8873
|
-
import
|
|
8919
|
+
import { Box as Box40, Text as Text41 } from "ink";
|
|
8920
|
+
import React47 from "react";
|
|
8874
8921
|
var STEP_GLYPH = {
|
|
8875
8922
|
queued: "\u25CB",
|
|
8876
8923
|
running: "\u25B6",
|
|
@@ -8896,7 +8943,7 @@ function TaskCard({ card }) {
|
|
|
8896
8943
|
failed: tone.err
|
|
8897
8944
|
};
|
|
8898
8945
|
const elapsed = `${(card.elapsedMs / 1e3).toFixed(1)}s`;
|
|
8899
|
-
return /* @__PURE__ */
|
|
8946
|
+
return /* @__PURE__ */ React47.createElement(Card, { tone: taskColor[card.status] }, /* @__PURE__ */ React47.createElement(
|
|
8900
8947
|
CardHeader,
|
|
8901
8948
|
{
|
|
8902
8949
|
glyph: TASK_GLYPH[card.status],
|
|
@@ -8905,12 +8952,12 @@ function TaskCard({ card }) {
|
|
|
8905
8952
|
subtitle: card.title,
|
|
8906
8953
|
meta: [elapsed, card.status]
|
|
8907
8954
|
}
|
|
8908
|
-
), card.steps.map((step) => /* @__PURE__ */
|
|
8955
|
+
), card.steps.map((step) => /* @__PURE__ */ React47.createElement(Box40, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React47.createElement(Text41, { color: stepColor[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ React47.createElement(Text41, { bold: true, color: fg.body }, (step.toolName ?? "step").padEnd(7)), /* @__PURE__ */ React47.createElement(Text41, { color: fg.sub }, step.title), step.detail ? /* @__PURE__ */ React47.createElement(Text41, { color: fg.faint }, step.detail) : null, step.elapsedMs !== void 0 ? /* @__PURE__ */ React47.createElement(Text41, { color: fg.faint }, `${(step.elapsedMs / 1e3).toFixed(2)}s`) : null)));
|
|
8909
8956
|
}
|
|
8910
8957
|
|
|
8911
8958
|
// src/cli/ui/cards/TipCard.tsx
|
|
8912
|
-
import { Box as
|
|
8913
|
-
import
|
|
8959
|
+
import { Box as Box41, Text as Text42 } from "ink";
|
|
8960
|
+
import React48 from "react";
|
|
8914
8961
|
import stringWidth2 from "string-width";
|
|
8915
8962
|
var KEY_GUTTER = 4;
|
|
8916
8963
|
function TipCard({ card }) {
|
|
@@ -8918,7 +8965,7 @@ function TipCard({ card }) {
|
|
|
8918
8965
|
(max, sec) => sec.rows.reduce((m, r) => Math.max(m, stringWidth2(r.key)), max),
|
|
8919
8966
|
0
|
|
8920
8967
|
);
|
|
8921
|
-
return /* @__PURE__ */
|
|
8968
|
+
return /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "column", paddingLeft: 2, marginY: 1 }, /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React48.createElement(Text42, { color: TONE.accent, bold: true }, "\u24D8"), /* @__PURE__ */ React48.createElement(Text42, { color: FG.body, bold: true }, card.topic)), card.oneTime ? /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, t("ui.tipShownOnce")) : null), card.sections.map((section, i) => /* @__PURE__ */ React48.createElement(Box41, { key: section.title ?? `section-${i}`, flexDirection: "column", marginTop: 1 }, section.title ? /* @__PURE__ */ React48.createElement(Box41, { marginBottom: 0 }, /* @__PURE__ */ React48.createElement(Text42, { color: FG.sub }, section.title)) : null, section.rows.map((row2) => /* @__PURE__ */ React48.createElement(
|
|
8922
8969
|
TipRowRender,
|
|
8923
8970
|
{
|
|
8924
8971
|
key: row2.key,
|
|
@@ -8926,7 +8973,7 @@ function TipCard({ card }) {
|
|
|
8926
8973
|
keyWidth,
|
|
8927
8974
|
indent: section.title ? 2 : 0
|
|
8928
8975
|
}
|
|
8929
|
-
)))), card.footer ? /* @__PURE__ */
|
|
8976
|
+
)))), card.footer ? /* @__PURE__ */ React48.createElement(Box41, { marginTop: 1 }, /* @__PURE__ */ React48.createElement(Text42, { color: FG.faint }, card.footer)) : null);
|
|
8930
8977
|
}
|
|
8931
8978
|
function TipRowRender({
|
|
8932
8979
|
row: row2,
|
|
@@ -8935,12 +8982,34 @@ function TipRowRender({
|
|
|
8935
8982
|
}) {
|
|
8936
8983
|
const pad = " ".repeat(Math.max(0, keyWidth - stringWidth2(row2.key) + KEY_GUTTER));
|
|
8937
8984
|
const lead = indent > 0 ? " ".repeat(indent) : "";
|
|
8938
|
-
return /* @__PURE__ */
|
|
8985
|
+
return /* @__PURE__ */ React48.createElement(Box41, { flexDirection: "row" }, lead ? /* @__PURE__ */ React48.createElement(Text42, null, lead) : null, /* @__PURE__ */ React48.createElement(Text42, { color: TONE.accent }, row2.key), /* @__PURE__ */ React48.createElement(Text42, null, pad), /* @__PURE__ */ React48.createElement(Text42, { color: FG.body }, row2.text));
|
|
8939
8986
|
}
|
|
8940
8987
|
|
|
8941
8988
|
// src/cli/ui/cards/ToolCard.tsx
|
|
8942
|
-
import { Text as
|
|
8943
|
-
import
|
|
8989
|
+
import { Text as Text43, useStdout as useStdout12 } from "ink";
|
|
8990
|
+
import React50 from "react";
|
|
8991
|
+
|
|
8992
|
+
// src/cli/ui/state/inflight-context.tsx
|
|
8993
|
+
import React49, { createContext as createContext4, useContext as useContext7, useSyncExternalStore } from "react";
|
|
8994
|
+
var Ctx = createContext4(null);
|
|
8995
|
+
function InflightProvider({
|
|
8996
|
+
inflight,
|
|
8997
|
+
children
|
|
8998
|
+
}) {
|
|
8999
|
+
return /* @__PURE__ */ React49.createElement(Ctx.Provider, { value: inflight }, children);
|
|
9000
|
+
}
|
|
9001
|
+
function useIsInflight(id) {
|
|
9002
|
+
const inflight = useContext7(Ctx);
|
|
9003
|
+
return useSyncExternalStore(
|
|
9004
|
+
(cb) => inflight ? inflight.subscribe(cb) : noop,
|
|
9005
|
+
() => inflight ? inflight.has(id) : false,
|
|
9006
|
+
() => false
|
|
9007
|
+
);
|
|
9008
|
+
}
|
|
9009
|
+
var noop = () => {
|
|
9010
|
+
};
|
|
9011
|
+
|
|
9012
|
+
// src/cli/ui/cards/ToolCard.tsx
|
|
8944
9013
|
var READ_TAIL = 2;
|
|
8945
9014
|
var OTHER_TAIL = 5;
|
|
8946
9015
|
function tailLinesFor(name) {
|
|
@@ -8958,7 +9027,8 @@ function ToolCard({ card }) {
|
|
|
8958
9027
|
const truncated = allLines.length > tail;
|
|
8959
9028
|
const visible = truncated ? allLines.slice(-tail) : allLines;
|
|
8960
9029
|
const hidden = truncated ? allLines.length - visible.length : 0;
|
|
8961
|
-
const
|
|
9030
|
+
const isInflight = useIsInflight(card.id);
|
|
9031
|
+
const status2 = toolStatus(card, isInflight);
|
|
8962
9032
|
const headColor = headerColorFor(status2);
|
|
8963
9033
|
const errColor = card.exitCode && card.exitCode !== 0 ? TONE.err : FG.sub;
|
|
8964
9034
|
const showBody = !card.rejected && (subagentMarkdown !== null || visible.length > 0);
|
|
@@ -8970,7 +9040,7 @@ function ToolCard({ card }) {
|
|
|
8970
9040
|
meta.push({ text: t("cardLabels.rejected"), color: TONE.err });
|
|
8971
9041
|
}
|
|
8972
9042
|
for (const part of metaTrail(card)) meta.push(part);
|
|
8973
|
-
return /* @__PURE__ */
|
|
9043
|
+
return /* @__PURE__ */ React50.createElement(Card, { tone: headColor }, /* @__PURE__ */ React50.createElement(
|
|
8974
9044
|
CardHeader,
|
|
8975
9045
|
{
|
|
8976
9046
|
glyph: statusGlyph2(status2),
|
|
@@ -8978,12 +9048,12 @@ function ToolCard({ card }) {
|
|
|
8978
9048
|
title: card.name,
|
|
8979
9049
|
subtitle: argsLabel || void 0,
|
|
8980
9050
|
meta: meta.length > 0 ? meta : void 0,
|
|
8981
|
-
right: status2 === "running" ? /* @__PURE__ */
|
|
9051
|
+
right: status2 === "running" ? /* @__PURE__ */ React50.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand, bold: true }) : void 0
|
|
8982
9052
|
}
|
|
8983
|
-
), showBody && (subagentMarkdown !== null ? /* @__PURE__ */
|
|
9053
|
+
), showBody && (subagentMarkdown !== null ? /* @__PURE__ */ React50.createElement(Markdown, { text: subagentMarkdown, width: lineCells }) : /* @__PURE__ */ React50.createElement(React50.Fragment, null, hidden > 0 ? /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, t(hidden === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
|
|
8984
9054
|
count: hidden
|
|
8985
|
-
})) : null, visible.map((line, i) => /* @__PURE__ */
|
|
8986
|
-
|
|
9055
|
+
})) : null, visible.map((line, i) => /* @__PURE__ */ React50.createElement(
|
|
9056
|
+
Text43,
|
|
8987
9057
|
{
|
|
8988
9058
|
key: `${card.id}:${hidden + i}`,
|
|
8989
9059
|
color: errColor,
|
|
@@ -9006,10 +9076,10 @@ function unwrapSubagentMarkdown(card) {
|
|
|
9006
9076
|
return null;
|
|
9007
9077
|
}
|
|
9008
9078
|
}
|
|
9009
|
-
function toolStatus(card) {
|
|
9079
|
+
function toolStatus(card, isInflight) {
|
|
9080
|
+
if (isInflight) return "running";
|
|
9010
9081
|
if (card.rejected) return "rejected";
|
|
9011
9082
|
if (card.aborted) return "aborted";
|
|
9012
|
-
if (!card.done) return "running";
|
|
9013
9083
|
if (card.exitCode !== void 0 && card.exitCode !== 0) return "error";
|
|
9014
9084
|
return "ok";
|
|
9015
9085
|
}
|
|
@@ -9084,8 +9154,8 @@ function formatBytes(n) {
|
|
|
9084
9154
|
}
|
|
9085
9155
|
|
|
9086
9156
|
// src/cli/ui/cards/UsageCard.tsx
|
|
9087
|
-
import { Box as
|
|
9088
|
-
import
|
|
9157
|
+
import { Box as Box43, Text as Text44 } from "ink";
|
|
9158
|
+
import React51 from "react";
|
|
9089
9159
|
var BAR_CELLS2 = 30;
|
|
9090
9160
|
function compactNum(n) {
|
|
9091
9161
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -9095,10 +9165,10 @@ function compactNum(n) {
|
|
|
9095
9165
|
function bar(ratio, color) {
|
|
9096
9166
|
const filled = Math.max(0, Math.min(BAR_CELLS2, Math.round(ratio * BAR_CELLS2)));
|
|
9097
9167
|
const empty = BAR_CELLS2 - filled;
|
|
9098
|
-
return /* @__PURE__ */
|
|
9168
|
+
return /* @__PURE__ */ React51.createElement(React51.Fragment, null, /* @__PURE__ */ React51.createElement(Text44, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, "\u2591".repeat(empty)));
|
|
9099
9169
|
}
|
|
9100
9170
|
function UsageCard({ card }) {
|
|
9101
|
-
if (card.compact) return /* @__PURE__ */
|
|
9171
|
+
if (card.compact) return /* @__PURE__ */ React51.createElement(CompactUsageRow, { card });
|
|
9102
9172
|
const cap = Math.max(1, card.tokens.promptCap);
|
|
9103
9173
|
const promptRatio = card.tokens.prompt / cap;
|
|
9104
9174
|
const reasonRatio = card.tokens.reason / cap;
|
|
@@ -9108,15 +9178,15 @@ function UsageCard({ card }) {
|
|
|
9108
9178
|
formatCost(card.cost, card.balanceCurrency)
|
|
9109
9179
|
];
|
|
9110
9180
|
if (card.elapsedMs !== void 0) headerMeta2.push(`${(card.elapsedMs / 1e3).toFixed(1)}s`);
|
|
9111
|
-
return /* @__PURE__ */
|
|
9181
|
+
return /* @__PURE__ */ React51.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React51.createElement(CardHeader, { glyph: "\u03A3", tone: FG.meta, title: t("cardTitles.usage"), meta: headerMeta2 }), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.prompt")), bar(promptRatio, TONE.brand), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, card.tokens.prompt.toLocaleString()), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `/ 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.reason")), bar(reasonRatio, TONE.accent), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, card.tokens.reason.toLocaleString())), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.output")), bar(outputRatio, TONE.brand), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, card.tokens.output.toLocaleString())), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.sub }, t("cardLabels.cache"), " "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: TONE.ok }, `${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, t("cardLabels.session")), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: FG.body }, `\u26C1 ${formatCost(card.sessionCost, card.balanceCurrency, 3)}`), card.balance !== void 0 ? /* @__PURE__ */ React51.createElement(React51.Fragment, null, /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `\xB7 ${t("cardLabels.balance")}`), /* @__PURE__ */ React51.createElement(Text44, { bold: true, color: TONE.brand }, formatBalance(card.balance, card.balanceCurrency))) : null));
|
|
9112
9182
|
}
|
|
9113
9183
|
function CompactUsageRow({ card }) {
|
|
9114
9184
|
const elapsed = card.elapsedMs !== void 0 ? ` \xB7 ${(card.elapsedMs / 1e3).toFixed(1)}s` : "";
|
|
9115
|
-
return /* @__PURE__ */
|
|
9185
|
+
return /* @__PURE__ */ React51.createElement(Box43, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ React51.createElement(Text44, { color: FG.meta }, "\u03A3"), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `${t("cardLabels.turn")} ${card.turn}`), /* @__PURE__ */ React51.createElement(Text44, { color: FG.meta }, `\xB7 ${compactNum(card.tokens.prompt)} ${t("cardLabels.prompt")} \xB7 ${compactNum(card.tokens.output)} ${t("cardLabels.output")}`), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `\xB7 ${t("cardLabels.cache")}`), /* @__PURE__ */ React51.createElement(Text44, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ React51.createElement(Text44, { color: FG.faint }, `\xB7 ${formatCost(card.cost, card.balanceCurrency)}${elapsed}`), card.balance !== void 0 ? /* @__PURE__ */ React51.createElement(Text44, { color: TONE.brand }, `\xB7 ${formatBalance(card.balance, card.balanceCurrency)}`) : null);
|
|
9116
9186
|
}
|
|
9117
9187
|
|
|
9118
9188
|
// src/cli/ui/cards/UserCard.tsx
|
|
9119
|
-
import
|
|
9189
|
+
import React52 from "react";
|
|
9120
9190
|
|
|
9121
9191
|
// src/cli/ui/cards/time.ts
|
|
9122
9192
|
function formatRelativeTime(ts, now = Date.now()) {
|
|
@@ -9133,7 +9203,7 @@ function formatRelativeTime(ts, now = Date.now()) {
|
|
|
9133
9203
|
|
|
9134
9204
|
// src/cli/ui/cards/UserCard.tsx
|
|
9135
9205
|
function UserCard({ card }) {
|
|
9136
|
-
return /* @__PURE__ */
|
|
9206
|
+
return /* @__PURE__ */ React52.createElement(Card, { tone: TONE.accent }, /* @__PURE__ */ React52.createElement(
|
|
9137
9207
|
CardHeader,
|
|
9138
9208
|
{
|
|
9139
9209
|
glyph: "\u203A",
|
|
@@ -9142,15 +9212,15 @@ function UserCard({ card }) {
|
|
|
9142
9212
|
titleColor: FG.sub,
|
|
9143
9213
|
meta: [formatRelativeTime(card.ts)]
|
|
9144
9214
|
}
|
|
9145
|
-
), /* @__PURE__ */
|
|
9215
|
+
), /* @__PURE__ */ React52.createElement(Markdown, { text: card.text }));
|
|
9146
9216
|
}
|
|
9147
9217
|
|
|
9148
9218
|
// src/cli/ui/cards/WarnCard.tsx
|
|
9149
|
-
import { Text as
|
|
9150
|
-
import
|
|
9219
|
+
import { Text as Text45 } from "ink";
|
|
9220
|
+
import React53 from "react";
|
|
9151
9221
|
function WarnCard({ card }) {
|
|
9152
9222
|
const messageLines = card.message.length > 0 ? card.message.split("\n") : [];
|
|
9153
|
-
return /* @__PURE__ */
|
|
9223
|
+
return /* @__PURE__ */ React53.createElement(Card, { tone: TONE.warn }, /* @__PURE__ */ React53.createElement(
|
|
9154
9224
|
CardHeader,
|
|
9155
9225
|
{
|
|
9156
9226
|
glyph: "\u26A0",
|
|
@@ -9158,57 +9228,57 @@ function WarnCard({ card }) {
|
|
|
9158
9228
|
title: card.title,
|
|
9159
9229
|
meta: card.detail ? [card.detail] : void 0
|
|
9160
9230
|
}
|
|
9161
|
-
), messageLines.map((line, i) => /* @__PURE__ */
|
|
9231
|
+
), messageLines.map((line, i) => /* @__PURE__ */ React53.createElement(Text45, { key: `${card.id}:${i}`, color: FG.body }, line || " ")));
|
|
9162
9232
|
}
|
|
9163
9233
|
|
|
9164
9234
|
// src/cli/ui/cards/CardRenderer.tsx
|
|
9165
|
-
var CardRenderer =
|
|
9235
|
+
var CardRenderer = React54.memo(function CardRenderer2({
|
|
9166
9236
|
card
|
|
9167
9237
|
}) {
|
|
9168
|
-
return /* @__PURE__ */
|
|
9238
|
+
return /* @__PURE__ */ React54.createElement(Box44, { flexDirection: "column" }, renderCard(card));
|
|
9169
9239
|
});
|
|
9170
9240
|
function renderCard(card) {
|
|
9171
9241
|
switch (card.kind) {
|
|
9172
9242
|
case "user":
|
|
9173
|
-
return /* @__PURE__ */
|
|
9243
|
+
return /* @__PURE__ */ React54.createElement(UserCard, { card });
|
|
9174
9244
|
case "reasoning":
|
|
9175
|
-
return /* @__PURE__ */
|
|
9245
|
+
return /* @__PURE__ */ React54.createElement(ReasoningCard, { card, expanded: true });
|
|
9176
9246
|
case "streaming":
|
|
9177
|
-
return /* @__PURE__ */
|
|
9247
|
+
return /* @__PURE__ */ React54.createElement(StreamingCard, { card });
|
|
9178
9248
|
case "tool":
|
|
9179
|
-
return /* @__PURE__ */
|
|
9249
|
+
return /* @__PURE__ */ React54.createElement(ToolCard, { card });
|
|
9180
9250
|
case "task":
|
|
9181
|
-
return /* @__PURE__ */
|
|
9251
|
+
return /* @__PURE__ */ React54.createElement(TaskCard, { card });
|
|
9182
9252
|
case "plan":
|
|
9183
|
-
return /* @__PURE__ */
|
|
9253
|
+
return /* @__PURE__ */ React54.createElement(PlanCard, { card });
|
|
9184
9254
|
case "diff":
|
|
9185
|
-
return /* @__PURE__ */
|
|
9255
|
+
return /* @__PURE__ */ React54.createElement(DiffCard, { card });
|
|
9186
9256
|
case "error":
|
|
9187
|
-
return /* @__PURE__ */
|
|
9257
|
+
return /* @__PURE__ */ React54.createElement(ErrorCard, { card });
|
|
9188
9258
|
case "warn":
|
|
9189
|
-
return /* @__PURE__ */
|
|
9259
|
+
return /* @__PURE__ */ React54.createElement(WarnCard, { card });
|
|
9190
9260
|
case "usage":
|
|
9191
|
-
return /* @__PURE__ */
|
|
9261
|
+
return /* @__PURE__ */ React54.createElement(UsageCard, { card });
|
|
9192
9262
|
case "memory":
|
|
9193
|
-
return /* @__PURE__ */
|
|
9263
|
+
return /* @__PURE__ */ React54.createElement(MemoryCard, { card });
|
|
9194
9264
|
case "subagent":
|
|
9195
|
-
return /* @__PURE__ */
|
|
9265
|
+
return /* @__PURE__ */ React54.createElement(SubAgentCard, { card });
|
|
9196
9266
|
case "search":
|
|
9197
|
-
return /* @__PURE__ */
|
|
9267
|
+
return /* @__PURE__ */ React54.createElement(SearchCard, { card });
|
|
9198
9268
|
case "live":
|
|
9199
|
-
return /* @__PURE__ */
|
|
9269
|
+
return /* @__PURE__ */ React54.createElement(LiveCard, { card });
|
|
9200
9270
|
case "tip":
|
|
9201
|
-
return /* @__PURE__ */
|
|
9271
|
+
return /* @__PURE__ */ React54.createElement(TipCard, { card });
|
|
9202
9272
|
case "ctx":
|
|
9203
|
-
return /* @__PURE__ */
|
|
9273
|
+
return /* @__PURE__ */ React54.createElement(CtxCard, { card });
|
|
9204
9274
|
case "doctor":
|
|
9205
|
-
return /* @__PURE__ */
|
|
9275
|
+
return /* @__PURE__ */ React54.createElement(DoctorCard, { card });
|
|
9206
9276
|
default:
|
|
9207
|
-
return /* @__PURE__ */
|
|
9277
|
+
return /* @__PURE__ */ React54.createElement(FallbackCard, { card });
|
|
9208
9278
|
}
|
|
9209
9279
|
}
|
|
9210
9280
|
function FallbackCard({ card }) {
|
|
9211
|
-
return /* @__PURE__ */
|
|
9281
|
+
return /* @__PURE__ */ React54.createElement(Box44, { flexDirection: "row" }, /* @__PURE__ */ React54.createElement(Text46, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
|
|
9212
9282
|
}
|
|
9213
9283
|
|
|
9214
9284
|
// src/cli/ui/layout/CardStream.tsx
|
|
@@ -9230,7 +9300,7 @@ function CardStream({
|
|
|
9230
9300
|
if (suppressLive && cards.length > 0 && !isFullySettled(cards[cards.length - 1])) {
|
|
9231
9301
|
visible = cards.slice(0, -1);
|
|
9232
9302
|
}
|
|
9233
|
-
return /* @__PURE__ */
|
|
9303
|
+
return /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Box45, { height: 1, flexShrink: 0 }, scrollRows > 0 ? /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, " \u2191 earlier \u2014 PgUp / wheel / \u2191") : null), /* @__PURE__ */ React55.createElement(Box45, { ref: outerRef, flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ React55.createElement(Box45, { ref: innerRef, flexDirection: "column", marginTop: -scrollRows, flexShrink: 0 }, visible.map((card) => /* @__PURE__ */ React55.createElement(CardRenderer, { key: card.id, card })))));
|
|
9234
9304
|
}
|
|
9235
9305
|
function isFullySettled(card) {
|
|
9236
9306
|
switch (card.kind) {
|
|
@@ -9250,13 +9320,13 @@ function isFullySettled(card) {
|
|
|
9250
9320
|
}
|
|
9251
9321
|
|
|
9252
9322
|
// src/cli/ui/layout/LiveRows.tsx
|
|
9253
|
-
import { Box as
|
|
9254
|
-
import
|
|
9323
|
+
import { Box as Box46, Text as Text48 } from "ink";
|
|
9324
|
+
import React56 from "react";
|
|
9255
9325
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
9256
9326
|
function ThinkingRow({ text }) {
|
|
9257
9327
|
const elapsed = useElapsedSeconds();
|
|
9258
9328
|
const { fg, tone } = useThemeTokens();
|
|
9259
|
-
return /* @__PURE__ */
|
|
9329
|
+
return /* @__PURE__ */ React56.createElement(Box46, { marginY: 1, paddingX: 1, gap: 1 }, /* @__PURE__ */ React56.createElement(Spinner, { kind: "circle", color: TONE.accent }), /* @__PURE__ */ React56.createElement(Text48, { italic: true, color: FG.sub }, text), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, `${elapsed}s`));
|
|
9260
9330
|
}
|
|
9261
9331
|
function ModeStatusBar({
|
|
9262
9332
|
editMode,
|
|
@@ -9268,24 +9338,24 @@ function ModeStatusBar({
|
|
|
9268
9338
|
}) {
|
|
9269
9339
|
useSlowTick();
|
|
9270
9340
|
const running = jobs2?.runningCount() ?? 0;
|
|
9271
|
-
const jobsTag = running > 0 ? /* @__PURE__ */
|
|
9341
|
+
const jobsTag = running > 0 ? /* @__PURE__ */ React56.createElement(Text48, { color: TONE.warn, bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
|
|
9272
9342
|
if (planMode) {
|
|
9273
|
-
return /* @__PURE__ */
|
|
9343
|
+
return /* @__PURE__ */ React56.createElement(ModeBarFrame, null, /* @__PURE__ */ React56.createElement(ModePill, { label: "PLAN MODE", color: TONE.err, flash }), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, " writes gated \xB7 /plan off to leave"), jobsTag);
|
|
9274
9344
|
}
|
|
9275
9345
|
const label = editMode === "yolo" ? "YOLO" : editMode === "auto" ? "AUTO" : "REVIEW";
|
|
9276
9346
|
const pillColor = editMode === "yolo" ? TONE.err : editMode === "auto" ? TONE.accent : TONE.brand;
|
|
9277
9347
|
const mid = editMode === "yolo" ? "edits + shell auto \xB7 /undo to roll back" : editMode === "auto" ? "edits land now \xB7 u to undo" : pendingCount > 0 ? `${pendingCount} queued \xB7 y apply \xB7 n discard` : "edits queued \xB7 y apply \xB7 n discard";
|
|
9278
|
-
return /* @__PURE__ */
|
|
9348
|
+
return /* @__PURE__ */ React56.createElement(ModeBarFrame, null, /* @__PURE__ */ React56.createElement(ModePill, { label, color: pillColor, flash }), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
|
|
9279
9349
|
}
|
|
9280
9350
|
function ModeBarFrame({ children }) {
|
|
9281
|
-
return /* @__PURE__ */
|
|
9351
|
+
return /* @__PURE__ */ React56.createElement(Box46, { paddingX: 1 }, children);
|
|
9282
9352
|
}
|
|
9283
9353
|
function ModePill({
|
|
9284
9354
|
label,
|
|
9285
9355
|
color,
|
|
9286
9356
|
flash
|
|
9287
9357
|
}) {
|
|
9288
|
-
return /* @__PURE__ */
|
|
9358
|
+
return /* @__PURE__ */ React56.createElement(Text48, { color, bold: true, inverse: flash }, `[${label}]`);
|
|
9289
9359
|
}
|
|
9290
9360
|
function UndoBanner({
|
|
9291
9361
|
banner
|
|
@@ -9300,7 +9370,7 @@ function UndoBanner({
|
|
|
9300
9370
|
const urgent = !paused && remainingSec <= 1;
|
|
9301
9371
|
const pct = remainingMs / totalMs * 100;
|
|
9302
9372
|
const tone = paused ? TONE.warn : urgent ? TONE.err : TONE.accent;
|
|
9303
|
-
return /* @__PURE__ */
|
|
9373
|
+
return /* @__PURE__ */ React56.createElement(Box46, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React56.createElement(Text48, { backgroundColor: TONE.accent, color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, " press "), /* @__PURE__ */ React56.createElement(Text48, { backgroundColor: TONE.brand, color: "black", bold: true }, " u "), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, paused ? " to undo \xB7 " : " to undo \xB7 "), /* @__PURE__ */ React56.createElement(Text48, { backgroundColor: paused ? TONE.warn : FG.faint, color: "black", bold: true }, " space "), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, paused ? " to resume " : " to pause "), /* @__PURE__ */ React56.createElement(CharBar, { pct, width: 20, color: tone, showLabel: false }), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, " "), /* @__PURE__ */ React56.createElement(Text48, { color: tone, bold: urgent || paused }, paused ? `${remainingSec}s \xB7 paused` : `${remainingSec}s`));
|
|
9304
9374
|
}
|
|
9305
9375
|
function subagentPhaseLabel(phase, iter, elapsedMs) {
|
|
9306
9376
|
if (phase === "summarising") return "summarising findings\u2026";
|
|
@@ -9315,7 +9385,7 @@ function SubagentRow({ activity }) {
|
|
|
9315
9385
|
const last = activity.lastInner;
|
|
9316
9386
|
const subtitle = activity.skillName ?? truncate2(activity.task, 48);
|
|
9317
9387
|
const modelBadge = activity.model ? modelBadgeFor(activity.model) : null;
|
|
9318
|
-
return /* @__PURE__ */
|
|
9388
|
+
return /* @__PURE__ */ React56.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React56.createElement(
|
|
9319
9389
|
CardHeader,
|
|
9320
9390
|
{
|
|
9321
9391
|
glyph: "\u232C",
|
|
@@ -9325,9 +9395,9 @@ function SubagentRow({ activity }) {
|
|
|
9325
9395
|
titleBg: PILL_SECTION.plan.bg,
|
|
9326
9396
|
subtitle,
|
|
9327
9397
|
meta: [`iter ${activity.iter}`, `${seconds}s`],
|
|
9328
|
-
right: /* @__PURE__ */
|
|
9398
|
+
right: /* @__PURE__ */ React56.createElement(React56.Fragment, null, modelBadge ? /* @__PURE__ */ React56.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null, /* @__PURE__ */ React56.createElement(Spinner, { kind: "braille", color: CARD.subagent.color }))
|
|
9329
9399
|
}
|
|
9330
|
-
), /* @__PURE__ */
|
|
9400
|
+
), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "task ", /* @__PURE__ */ React56.createElement(Text48, { color: FG.sub }, activity.task)), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "last ", last ? /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Text48, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.body }, last.label), last.meta ? /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "queued\u2026")), /* @__PURE__ */ React56.createElement(Text48, { color: TONE.brand }, "\u25B6 ", phase));
|
|
9331
9401
|
}
|
|
9332
9402
|
function SubagentLiveStack({
|
|
9333
9403
|
activities,
|
|
@@ -9335,13 +9405,13 @@ function SubagentLiveStack({
|
|
|
9335
9405
|
}) {
|
|
9336
9406
|
const tick = useTick();
|
|
9337
9407
|
if (activities.length === 0) return null;
|
|
9338
|
-
if (activities.length === 1) return /* @__PURE__ */
|
|
9408
|
+
if (activities.length === 1) return /* @__PURE__ */ React56.createElement(SubagentRow, { activity: activities[0] });
|
|
9339
9409
|
const visible = activities.slice(0, max);
|
|
9340
9410
|
const overflow = activities.length - visible.length;
|
|
9341
9411
|
const summarising = activities.filter((a) => a.phase === "summarising").length;
|
|
9342
9412
|
const metaParts = [`${activities.length} running`];
|
|
9343
9413
|
if (summarising > 0) metaParts.push(`${summarising} summarising`);
|
|
9344
|
-
return /* @__PURE__ */
|
|
9414
|
+
return /* @__PURE__ */ React56.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React56.createElement(
|
|
9345
9415
|
CardHeader,
|
|
9346
9416
|
{
|
|
9347
9417
|
glyph: "\u232C",
|
|
@@ -9350,9 +9420,9 @@ function SubagentLiveStack({
|
|
|
9350
9420
|
titleColor: PILL_SECTION.plan.fg,
|
|
9351
9421
|
titleBg: PILL_SECTION.plan.bg,
|
|
9352
9422
|
subtitle: metaParts.join(" \xB7 "),
|
|
9353
|
-
right: /* @__PURE__ */
|
|
9423
|
+
right: /* @__PURE__ */ React56.createElement(Spinner, { kind: "braille", color: CARD.subagent.color })
|
|
9354
9424
|
}
|
|
9355
|
-
), visible.map((a, i) => /* @__PURE__ */
|
|
9425
|
+
), visible.map((a, i) => /* @__PURE__ */ React56.createElement(CompactSubagentLine, { key: a.runId, activity: a, tick, index: i })), overflow > 0 ? /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` +${overflow} more running\u2026`) : null);
|
|
9356
9426
|
}
|
|
9357
9427
|
function CompactSubagentLine({
|
|
9358
9428
|
activity,
|
|
@@ -9367,7 +9437,7 @@ function CompactSubagentLine({
|
|
|
9367
9437
|
const title = activity.skillName ?? truncate2(activity.task, 28);
|
|
9368
9438
|
const titlePadded = title.padEnd(28);
|
|
9369
9439
|
const last = activity.lastInner;
|
|
9370
|
-
return /* @__PURE__ */
|
|
9440
|
+
return /* @__PURE__ */ React56.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React56.createElement(Text48, { color: glyphColor, bold: true }, ` ${glyph} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.body }, titlePadded), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` iter ${String(activity.iter).padStart(2)} \xB7 ${seconds}s \xB7 `), last ? /* @__PURE__ */ React56.createElement(React56.Fragment, null, /* @__PURE__ */ React56.createElement(Text48, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React56.createElement(Text48, { color: FG.body }, truncate2(last.label, 18)), last.meta ? /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, "queued\u2026"));
|
|
9371
9441
|
}
|
|
9372
9442
|
function truncate2(text, max) {
|
|
9373
9443
|
return text.length > max ? `${text.slice(0, max)}\u2026` : text;
|
|
@@ -9379,7 +9449,7 @@ function OngoingToolRow({
|
|
|
9379
9449
|
const tick = useTick();
|
|
9380
9450
|
const elapsed = useElapsedSeconds();
|
|
9381
9451
|
const summary = summarizeToolArgs(tool.name, tool.args);
|
|
9382
|
-
return /* @__PURE__ */
|
|
9452
|
+
return /* @__PURE__ */ React56.createElement(Box46, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React56.createElement(Box46, null, /* @__PURE__ */ React56.createElement(Text48, { color: CARD.tool.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React56.createElement(Text48, null, " "), /* @__PURE__ */ React56.createElement(Text48, { color: CARD.tool.color, bold: true }, `\u25A3 ${tool.name}`), /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React56.createElement(Box46, { paddingLeft: 3 }, /* @__PURE__ */ React56.createElement(Text48, { color: TONE.brand }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React56.createElement(Box46, { paddingLeft: 3 }, /* @__PURE__ */ React56.createElement(Text48, { color: FG.faint }, summary)) : null);
|
|
9383
9453
|
}
|
|
9384
9454
|
function renderProgressLine(p) {
|
|
9385
9455
|
const msg = p.message ? ` ${p.message}` : "";
|
|
@@ -9435,16 +9505,16 @@ function summarizeToolArgs(name, args) {
|
|
|
9435
9505
|
}
|
|
9436
9506
|
|
|
9437
9507
|
// src/cli/ui/layout/StatusRow.tsx
|
|
9438
|
-
import { Box as
|
|
9439
|
-
import
|
|
9508
|
+
import { Box as Box47, Text as Text50, useStdout as useStdout13 } from "ink";
|
|
9509
|
+
import React58 from "react";
|
|
9440
9510
|
|
|
9441
9511
|
// src/cli/ui/primitives/Countdown.tsx
|
|
9442
|
-
import { Text as
|
|
9443
|
-
import
|
|
9512
|
+
import { Text as Text49 } from "ink";
|
|
9513
|
+
import React57 from "react";
|
|
9444
9514
|
function Countdown({ endsAt, color = TONE.brand }) {
|
|
9445
9515
|
useSlowTick();
|
|
9446
9516
|
const remainingSec = Math.max(0, Math.ceil((endsAt - Date.now()) / 1e3));
|
|
9447
|
-
return /* @__PURE__ */
|
|
9517
|
+
return /* @__PURE__ */ React57.createElement(Text49, { bold: true, color }, String(remainingSec));
|
|
9448
9518
|
}
|
|
9449
9519
|
|
|
9450
9520
|
// src/cli/ui/layout/StatusRow.tsx
|
|
@@ -9463,21 +9533,21 @@ function StatusRow() {
|
|
|
9463
9533
|
const hasSession = status2.sessionCost > 0;
|
|
9464
9534
|
const hasBalance = typeof status2.balance === "number";
|
|
9465
9535
|
const showWallet = cols >= WALLET_MIN_COLS && (hasSession || hasBalance);
|
|
9466
|
-
return /* @__PURE__ */
|
|
9467
|
-
|
|
9536
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Box47, { height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, null, " "), /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, minHeight: 1, flexWrap: "nowrap", flexShrink: 0 }, /* @__PURE__ */ React58.createElement(Text50, { wrap: "truncate" }, " "), status2.recording ? /* @__PURE__ */ React58.createElement(RecordingPill, { rec: status2.recording }) : status2.countdownSeconds !== void 0 ? /* @__PURE__ */ React58.createElement(CountdownRow, { mode: status2.mode, secondsLeft: status2.countdownSeconds }) : /* @__PURE__ */ React58.createElement(ModePill2, { mode: status2.mode, network: status2.network, detail: status2.networkDetail }), /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: TONE.brand, wrap: "truncate" }, "\u25B8 "), /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: FG.body, wrap: "truncate" }, `${formatCost(status2.cost, status2.balanceCurrency)} turn`)), /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(
|
|
9537
|
+
Text50,
|
|
9468
9538
|
{
|
|
9469
9539
|
color: TONE.accent,
|
|
9470
9540
|
wrap: "truncate"
|
|
9471
9541
|
},
|
|
9472
9542
|
`cache ${Math.round(status2.cacheHit * 100)}%`
|
|
9473
|
-
), showWallet && /* @__PURE__ */
|
|
9543
|
+
), showWallet && /* @__PURE__ */ React58.createElement(
|
|
9474
9544
|
WalletPill,
|
|
9475
9545
|
{
|
|
9476
9546
|
sessionCostUsd: status2.sessionCost,
|
|
9477
9547
|
balance: status2.balance,
|
|
9478
9548
|
currency: status2.balanceCurrency
|
|
9479
9549
|
}
|
|
9480
|
-
), cols >= VERSION_MIN_COLS && /* @__PURE__ */
|
|
9550
|
+
), cols >= VERSION_MIN_COLS && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, `v${VERSION}`), cols >= FEEDBACK_HINT_MIN_COLS && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, " \xB7 "), /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, "\u2691 "), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, "/feedback")))));
|
|
9481
9551
|
}
|
|
9482
9552
|
function WalletPill({
|
|
9483
9553
|
sessionCostUsd,
|
|
@@ -9486,14 +9556,14 @@ function WalletPill({
|
|
|
9486
9556
|
}) {
|
|
9487
9557
|
const showSpent = sessionCostUsd > 0;
|
|
9488
9558
|
const showBalance = typeof balance === "number";
|
|
9489
|
-
return /* @__PURE__ */
|
|
9490
|
-
|
|
9559
|
+
return /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(Sep, null), /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, "\u26C1 "), showSpent && /* @__PURE__ */ React58.createElement(
|
|
9560
|
+
Text50,
|
|
9491
9561
|
{
|
|
9492
9562
|
color: FG.body,
|
|
9493
9563
|
wrap: "truncate"
|
|
9494
9564
|
},
|
|
9495
9565
|
`${formatCost(sessionCostUsd, currency, 2)} spent`
|
|
9496
|
-
), showSpent && showBalance && /* @__PURE__ */
|
|
9566
|
+
), showSpent && showBalance && /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, " / "), showBalance && /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: balanceColor(balance, currency), wrap: "truncate" }, formatBalance(balance, currency, { fractionDigits: 2 })), showBalance && /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint, wrap: "truncate" }, " left"));
|
|
9497
9567
|
}
|
|
9498
9568
|
function ModePill2({
|
|
9499
9569
|
mode: mode2,
|
|
@@ -9502,18 +9572,18 @@ function ModePill2({
|
|
|
9502
9572
|
}) {
|
|
9503
9573
|
if (network === "online") {
|
|
9504
9574
|
const pill = modeGlyph(mode2);
|
|
9505
|
-
return /* @__PURE__ */
|
|
9575
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: pill.color, wrap: "truncate" }, pill.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, ` ${mode2}`));
|
|
9506
9576
|
}
|
|
9507
9577
|
const dot = networkDot(network);
|
|
9508
9578
|
if (network === "slow") {
|
|
9509
9579
|
const tail = detail ? ` \xB7 ${detail}` : "";
|
|
9510
|
-
return /* @__PURE__ */
|
|
9580
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, ` ${mode2} \xB7 slow${tail}`));
|
|
9511
9581
|
}
|
|
9512
9582
|
if (network === "disconnected") {
|
|
9513
9583
|
const tail = detail ? ` \xB7 ${detail}` : "";
|
|
9514
|
-
return /* @__PURE__ */
|
|
9584
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, ` disconnect${tail}`));
|
|
9515
9585
|
}
|
|
9516
|
-
return /* @__PURE__ */
|
|
9586
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, dot.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: dot.color, wrap: "truncate" }, " reconnecting\u2026"));
|
|
9517
9587
|
}
|
|
9518
9588
|
function CountdownRow({
|
|
9519
9589
|
mode: mode2,
|
|
@@ -9521,14 +9591,14 @@ function CountdownRow({
|
|
|
9521
9591
|
}) {
|
|
9522
9592
|
const pill = modeGlyph(mode2);
|
|
9523
9593
|
const endsAt = Date.now() + secondsLeft * 1e3;
|
|
9524
|
-
return /* @__PURE__ */
|
|
9594
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { color: pill.color, wrap: "truncate" }, pill.glyph), /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub, wrap: "truncate" }, ` ${mode2} \xB7 `), /* @__PURE__ */ React58.createElement(Text50, { color: TONE.warn, wrap: "truncate" }, "approving in "), /* @__PURE__ */ React58.createElement(Countdown, { endsAt }), /* @__PURE__ */ React58.createElement(Text50, { color: TONE.warn, wrap: "truncate" }, "s \xB7 esc to interrupt"));
|
|
9525
9595
|
}
|
|
9526
9596
|
function RecordingPill({ rec }) {
|
|
9527
9597
|
const sizeMb = (rec.sizeBytes / (1024 * 1024)).toFixed(1);
|
|
9528
|
-
return /* @__PURE__ */
|
|
9598
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row", height: 1, flexWrap: "nowrap" }, /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: TONE.err, wrap: "truncate" }, "\u25CFREC"), /* @__PURE__ */ React58.createElement(Text50, { color: TONE.err, wrap: "truncate" }, ` ${sizeMb} MB \xB7 ${rec.events} evt`));
|
|
9529
9599
|
}
|
|
9530
9600
|
function Sep() {
|
|
9531
|
-
return /* @__PURE__ */
|
|
9601
|
+
return /* @__PURE__ */ React58.createElement(Text50, { color: FG.meta, wrap: "truncate" }, " \xB7 ");
|
|
9532
9602
|
}
|
|
9533
9603
|
function modeGlyph(mode2) {
|
|
9534
9604
|
switch (mode2) {
|
|
@@ -9556,8 +9626,8 @@ function networkDot(state) {
|
|
|
9556
9626
|
}
|
|
9557
9627
|
|
|
9558
9628
|
// src/cli/ui/layout/ToastRail.tsx
|
|
9559
|
-
import { Box as
|
|
9560
|
-
import
|
|
9629
|
+
import { Box as Box48, Text as Text51, useStdout as useStdout14 } from "ink";
|
|
9630
|
+
import React59, { useEffect as useEffect8 } from "react";
|
|
9561
9631
|
var TONE_COLOR = {
|
|
9562
9632
|
ok: TONE.ok,
|
|
9563
9633
|
info: TONE.brand,
|
|
@@ -9595,17 +9665,17 @@ function ToastRail() {
|
|
|
9595
9665
|
}, [toasts, dispatch]);
|
|
9596
9666
|
const visible = toasts.filter((t2) => now - t2.bornAt < t2.ttlMs);
|
|
9597
9667
|
if (visible.length === 0) return null;
|
|
9598
|
-
return /* @__PURE__ */
|
|
9668
|
+
return /* @__PURE__ */ React59.createElement(Box48, { flexDirection: "column" }, visible.map((t2) => {
|
|
9599
9669
|
const color = TONE_COLOR[t2.tone];
|
|
9600
9670
|
const glyph = TONE_GLYPH[t2.tone];
|
|
9601
9671
|
const body = bodyColor(t2, now);
|
|
9602
9672
|
const remainingSec = Math.max(0, Math.ceil((t2.ttlMs - (now - t2.bornAt)) / 1e3));
|
|
9603
|
-
return /* @__PURE__ */
|
|
9673
|
+
return /* @__PURE__ */ React59.createElement(Box48, { key: t2.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React59.createElement(Text51, { color }, rule), /* @__PURE__ */ React59.createElement(Box48, { flexDirection: "row" }, /* @__PURE__ */ React59.createElement(Text51, { color }, glyph), /* @__PURE__ */ React59.createElement(Text51, { bold: true, color: body }, ` ${t2.title}`), t2.detail !== void 0 && /* @__PURE__ */ React59.createElement(Text51, { color: FG.sub }, ` \xB7 ${t2.detail}`), /* @__PURE__ */ React59.createElement(Box48, { flexGrow: 1 }), /* @__PURE__ */ React59.createElement(Text51, { color: FG.faint }, `${remainingSec}s`)));
|
|
9604
9674
|
}));
|
|
9605
9675
|
}
|
|
9606
9676
|
|
|
9607
9677
|
// src/cli/ui/layout/plan-live-row.tsx
|
|
9608
|
-
import
|
|
9678
|
+
import React60 from "react";
|
|
9609
9679
|
function isActivePlanInFlight(card) {
|
|
9610
9680
|
if (card.kind !== "plan") return false;
|
|
9611
9681
|
if (card.variant !== "active") return false;
|
|
@@ -9620,7 +9690,7 @@ function PlanLiveRow() {
|
|
|
9620
9690
|
return null;
|
|
9621
9691
|
});
|
|
9622
9692
|
if (!planCard) return null;
|
|
9623
|
-
return /* @__PURE__ */
|
|
9693
|
+
return /* @__PURE__ */ React60.createElement(PlanCard, { card: planCard });
|
|
9624
9694
|
}
|
|
9625
9695
|
|
|
9626
9696
|
// src/cli/ui/loop.ts
|
|
@@ -11109,8 +11179,8 @@ function writeClipboard(text) {
|
|
|
11109
11179
|
}
|
|
11110
11180
|
|
|
11111
11181
|
// src/cli/ui/ctx-breakdown.tsx
|
|
11112
|
-
import { Box as
|
|
11113
|
-
import
|
|
11182
|
+
import { Box as Box49, Text as Text52 } from "ink";
|
|
11183
|
+
import React61 from "react";
|
|
11114
11184
|
function computeCtxBreakdown(loop2) {
|
|
11115
11185
|
const systemTokens = countTokens(loop2.prefix.system);
|
|
11116
11186
|
const toolsTokens = countTokens(JSON.stringify(loop2.prefix.toolSpecs));
|
|
@@ -11765,23 +11835,12 @@ var handlers15 = {
|
|
|
11765
11835
|
|
|
11766
11836
|
// src/cli/ui/slash/handlers/theme.ts
|
|
11767
11837
|
var themeChoices = ["auto", ...listThemeNames()];
|
|
11768
|
-
function formatThemeStatus() {
|
|
11769
|
-
const configured = loadTheme();
|
|
11770
|
-
const active = resolveThemePreference(configured, process.env.REASONIX_THEME);
|
|
11771
|
-
const source = configured && configured !== "auto" ? "config" : "env/default";
|
|
11772
|
-
return [
|
|
11773
|
-
`theme: ${active} (${source})`,
|
|
11774
|
-
`configured: ${configured ?? "unset"}`,
|
|
11775
|
-
`available: ${themeChoices.join(", ")}`,
|
|
11776
|
-
"usage: /theme <name|auto>"
|
|
11777
|
-
].join("\n");
|
|
11778
|
-
}
|
|
11779
11838
|
function isThemeChoice(value) {
|
|
11780
11839
|
return value === "auto" || isThemeName(value);
|
|
11781
11840
|
}
|
|
11782
11841
|
var theme = (args) => {
|
|
11783
11842
|
const next = args[0];
|
|
11784
|
-
if (!next) return {
|
|
11843
|
+
if (!next) return { openThemePicker: true };
|
|
11785
11844
|
if (!isThemeChoice(next)) {
|
|
11786
11845
|
return { info: `unknown theme: ${next}
|
|
11787
11846
|
available: ${themeChoices.join(", ")}` };
|
|
@@ -11908,9 +11967,9 @@ var TurnTranslator = class {
|
|
|
11908
11967
|
this.log.appendStreaming(this.streamingCardId, contentChunk);
|
|
11909
11968
|
}
|
|
11910
11969
|
}
|
|
11911
|
-
toolStart(name, args) {
|
|
11970
|
+
toolStart(name, args, callId) {
|
|
11912
11971
|
this.toolStartedAt = Date.now();
|
|
11913
|
-
this.toolCardId = this.log.startTool(name, args);
|
|
11972
|
+
this.toolCardId = this.log.startTool(name, args, callId);
|
|
11914
11973
|
}
|
|
11915
11974
|
toolEnd(output) {
|
|
11916
11975
|
if (this.toolCardId) {
|
|
@@ -11921,6 +11980,16 @@ var TurnTranslator = class {
|
|
|
11921
11980
|
this.toolCardId = null;
|
|
11922
11981
|
}
|
|
11923
11982
|
}
|
|
11983
|
+
toolAbort(output) {
|
|
11984
|
+
if (this.toolCardId) {
|
|
11985
|
+
this.log.endTool(this.toolCardId, {
|
|
11986
|
+
output,
|
|
11987
|
+
elapsedMs: Date.now() - this.toolStartedAt,
|
|
11988
|
+
aborted: true
|
|
11989
|
+
});
|
|
11990
|
+
this.toolCardId = null;
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11924
11993
|
toolRetry(attempt, max) {
|
|
11925
11994
|
if (this.toolCardId) this.log.retryTool(this.toolCardId, attempt, max);
|
|
11926
11995
|
}
|
|
@@ -12814,13 +12883,13 @@ var PLAIN_UI = process.env.REASONIX_UI === "plain";
|
|
|
12814
12883
|
function LoopStatusRow({
|
|
12815
12884
|
loop: loop2
|
|
12816
12885
|
}) {
|
|
12817
|
-
const [, setTick] =
|
|
12818
|
-
|
|
12886
|
+
const [, setTick] = React62.useState(0);
|
|
12887
|
+
React62.useEffect(() => {
|
|
12819
12888
|
const id = setInterval(() => setTick((t2) => t2 + 1), 1e3);
|
|
12820
12889
|
return () => clearInterval(id);
|
|
12821
12890
|
}, []);
|
|
12822
12891
|
const nextFireMs = Math.max(0, loop2.nextFireAt - Date.now());
|
|
12823
|
-
return /* @__PURE__ */
|
|
12892
|
+
return /* @__PURE__ */ React62.createElement(Box50, null, /* @__PURE__ */ React62.createElement(Text53, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
|
|
12824
12893
|
}
|
|
12825
12894
|
function App(props) {
|
|
12826
12895
|
markPhase("app_render_start");
|
|
@@ -12829,12 +12898,14 @@ function App(props) {
|
|
|
12829
12898
|
model: props.model,
|
|
12830
12899
|
workspace: props.codeMode?.rootDir ?? process.cwd()
|
|
12831
12900
|
});
|
|
12832
|
-
const initialCards =
|
|
12901
|
+
const initialCards = React62.useMemo(
|
|
12833
12902
|
() => props.session ? hydrateCardsFromMessages(loadSessionMessages(props.session)) : [],
|
|
12834
12903
|
[props.session]
|
|
12835
12904
|
);
|
|
12836
|
-
const themeName =
|
|
12837
|
-
|
|
12905
|
+
const [themeName, setThemeName] = React62.useState(
|
|
12906
|
+
() => resolveThemePreference(loadTheme(), process.env.REASONIX_THEME)
|
|
12907
|
+
);
|
|
12908
|
+
return /* @__PURE__ */ React62.createElement(ThemeProvider, { name: themeName }, /* @__PURE__ */ React62.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ React62.createElement(AppInner, { ...props, themeName, setThemeName })));
|
|
12838
12909
|
}
|
|
12839
12910
|
function AppInner({
|
|
12840
12911
|
model: model2,
|
|
@@ -12850,7 +12921,9 @@ function AppInner({
|
|
|
12850
12921
|
codeMode,
|
|
12851
12922
|
noDashboard,
|
|
12852
12923
|
onSwitchSession,
|
|
12853
|
-
mouse = true
|
|
12924
|
+
mouse = true,
|
|
12925
|
+
themeName,
|
|
12926
|
+
setThemeName
|
|
12854
12927
|
}) {
|
|
12855
12928
|
markPhase("app_inner_start");
|
|
12856
12929
|
const log = useScrollback();
|
|
@@ -12859,6 +12932,7 @@ function AppInner({
|
|
|
12859
12932
|
(s) => s.cards.some((c) => c.kind === "user" || c.kind === "streaming")
|
|
12860
12933
|
);
|
|
12861
12934
|
const isStreaming = useAgentState((s) => s.cards.some((c) => c.kind === "streaming" && !c.done));
|
|
12935
|
+
const activityLabel = useActivityLabel();
|
|
12862
12936
|
const chatScroll = useChatScroll();
|
|
12863
12937
|
const [input, setInput] = useState20("");
|
|
12864
12938
|
const [busy, setBusy] = useState20(false);
|
|
@@ -12965,13 +13039,14 @@ function AppInner({
|
|
|
12965
13039
|
const [checkpointPickerList, setCheckpointPickerList] = useState20([]);
|
|
12966
13040
|
const [pendingMcpHub, setPendingMcpHub] = useState20(null);
|
|
12967
13041
|
const [pendingModelPicker, setPendingModelPicker] = useState20(false);
|
|
13042
|
+
const [pendingThemePicker, setPendingThemePicker] = useState20(false);
|
|
12968
13043
|
const [stagedInput, setStagedInput] = useState20(null);
|
|
12969
13044
|
const [pendingCheckpoint, setPendingCheckpoint] = useState20(null);
|
|
12970
13045
|
const [stagedCheckpointRevise, setStagedCheckpointRevise] = useState20(null);
|
|
12971
13046
|
const [pendingRevision, setPendingRevision] = useState20(null);
|
|
12972
13047
|
const [pendingChoice, setPendingChoice] = useState20(null);
|
|
12973
13048
|
const [stagedChoiceCustom, setStagedChoiceCustom] = useState20(null);
|
|
12974
|
-
const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingCheckpointPicker || !!pendingMcpHub || pendingModelPicker || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
|
|
13049
|
+
const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingCheckpointPicker || !!pendingMcpHub || pendingModelPicker || pendingThemePicker || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
|
|
12975
13050
|
const [planMode, setPlanMode] = useState20(false);
|
|
12976
13051
|
const [proArmed, setProArmed] = useState20(false);
|
|
12977
13052
|
const [turnOnPro, setTurnOnPro] = useState20(false);
|
|
@@ -13382,12 +13457,7 @@ function AppInner({
|
|
|
13382
13457
|
if (key.escape && busy) {
|
|
13383
13458
|
if (abortedThisTurn.current) return;
|
|
13384
13459
|
abortedThisTurn.current = true;
|
|
13385
|
-
|
|
13386
|
-
if (resolve3) {
|
|
13387
|
-
editReviewResolveRef.current = null;
|
|
13388
|
-
setPendingEditReview(null);
|
|
13389
|
-
resolve3({ choice: "reject" });
|
|
13390
|
-
}
|
|
13460
|
+
resetPendingModals();
|
|
13391
13461
|
if (isLoopActive()) stopLoop();
|
|
13392
13462
|
loop2.abort();
|
|
13393
13463
|
return;
|
|
@@ -13582,7 +13652,7 @@ function AppInner({
|
|
|
13582
13652
|
if (dashboardRef.current) return dashboardRef.current.url;
|
|
13583
13653
|
if (dashboardStartingRef.current) return dashboardStartingRef.current;
|
|
13584
13654
|
const startup = (async () => {
|
|
13585
|
-
const { startDashboardServer } = await import("./server-
|
|
13655
|
+
const { startDashboardServer } = await import("./server-GNHR5K3N.js");
|
|
13586
13656
|
const handle = await startDashboardServer({
|
|
13587
13657
|
mode: "attached",
|
|
13588
13658
|
configPath: defaultConfigPath(),
|
|
@@ -13906,7 +13976,7 @@ function AppInner({
|
|
|
13906
13976
|
}
|
|
13907
13977
|
if (text.startsWith("/") && !text.includes(" ")) {
|
|
13908
13978
|
const typed = text.slice(1).toLowerCase();
|
|
13909
|
-
const matches = suggestSlashCommands(typed, !!codeMode);
|
|
13979
|
+
const matches = suggestSlashCommands(typed, !!codeMode, slashUsage);
|
|
13910
13980
|
const exact = matches.find((m) => m.cmd === typed);
|
|
13911
13981
|
if (!exact && matches.length > 0) {
|
|
13912
13982
|
const chosen = matches[slashSelected] ?? matches[0];
|
|
@@ -14103,6 +14173,11 @@ function AppInner({
|
|
|
14103
14173
|
pushHistory(text);
|
|
14104
14174
|
return;
|
|
14105
14175
|
}
|
|
14176
|
+
if (result.openThemePicker) {
|
|
14177
|
+
setPendingThemePicker(true);
|
|
14178
|
+
pushHistory(text);
|
|
14179
|
+
return;
|
|
14180
|
+
}
|
|
14106
14181
|
if (result.openArgPickerFor) {
|
|
14107
14182
|
pushHistory(text);
|
|
14108
14183
|
setInput(`/${result.openArgPickerFor} `);
|
|
@@ -14135,6 +14210,7 @@ function AppInner({
|
|
|
14135
14210
|
stopLoop,
|
|
14136
14211
|
quitProcess,
|
|
14137
14212
|
pushHistory,
|
|
14213
|
+
resetPendingModals,
|
|
14138
14214
|
text
|
|
14139
14215
|
});
|
|
14140
14216
|
if (outcome.kind === "resubmit") {
|
|
@@ -14346,7 +14422,13 @@ function AppInner({
|
|
|
14346
14422
|
codeModeOn: !!codeMode
|
|
14347
14423
|
});
|
|
14348
14424
|
} else if (ev.role === "error") {
|
|
14349
|
-
handleErrorEvent(ev, {
|
|
14425
|
+
handleErrorEvent(ev, {
|
|
14426
|
+
log,
|
|
14427
|
+
setOngoingTool,
|
|
14428
|
+
setToolProgress,
|
|
14429
|
+
toolStartedAtRef,
|
|
14430
|
+
translator
|
|
14431
|
+
});
|
|
14350
14432
|
} else if (ev.role === "warning") {
|
|
14351
14433
|
handleWarningEvent(ev, { log, setTurnOnPro });
|
|
14352
14434
|
}
|
|
@@ -14400,6 +14482,7 @@ function AppInner({
|
|
|
14400
14482
|
planMode,
|
|
14401
14483
|
session,
|
|
14402
14484
|
slashSelected,
|
|
14485
|
+
slashUsage,
|
|
14403
14486
|
atState,
|
|
14404
14487
|
atSelected,
|
|
14405
14488
|
pickAtMention,
|
|
@@ -14469,6 +14552,24 @@ function AppInner({
|
|
|
14469
14552
|
[pendingShell, codeMode, currentRootDir, log]
|
|
14470
14553
|
);
|
|
14471
14554
|
const pendingGateIdRef = useRef9(null);
|
|
14555
|
+
const resetPendingModals = useCallback11(() => {
|
|
14556
|
+
const editResolve = editReviewResolveRef.current;
|
|
14557
|
+
if (editResolve) {
|
|
14558
|
+
editReviewResolveRef.current = null;
|
|
14559
|
+
setPendingEditReview(null);
|
|
14560
|
+
editResolve({ choice: "reject" });
|
|
14561
|
+
}
|
|
14562
|
+
setPendingShell(null);
|
|
14563
|
+
setPendingPlan(null);
|
|
14564
|
+
setPendingCheckpoint(null);
|
|
14565
|
+
setPendingRevision(null);
|
|
14566
|
+
setPendingChoice(null);
|
|
14567
|
+
setStagedInput(null);
|
|
14568
|
+
setStagedChoiceCustom(null);
|
|
14569
|
+
setStagedCheckpointRevise(null);
|
|
14570
|
+
pendingGateIdRef.current = null;
|
|
14571
|
+
pauseGate.cancelAll();
|
|
14572
|
+
}, []);
|
|
14472
14573
|
useEffect12(() => {
|
|
14473
14574
|
if (!busy && queuedSubmit !== null) {
|
|
14474
14575
|
const text = queuedSubmit;
|
|
@@ -14844,14 +14945,14 @@ function AppInner({
|
|
|
14844
14945
|
[]
|
|
14845
14946
|
);
|
|
14846
14947
|
const tickerSuspended = PLAIN_UI || modalOpen || !busy && !isStreaming;
|
|
14847
|
-
return /* @__PURE__ */
|
|
14948
|
+
return /* @__PURE__ */ React62.createElement(React62.Fragment, null, /* @__PURE__ */ React62.createElement(TickerProvider, { disabled: tickerSuspended }, /* @__PURE__ */ React62.createElement(ViewportBudgetProvider, null, /* @__PURE__ */ React62.createElement(InflightProvider, { inflight: loop2.inflight }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "row", height: stdout?.rows ?? 24 }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React62.createElement(LiveExpandContext.Provider, { value: liveExpand }, /* @__PURE__ */ React62.createElement(
|
|
14848
14949
|
CardStream,
|
|
14849
14950
|
{
|
|
14850
14951
|
suppressLive: modalOpen,
|
|
14851
14952
|
scrollRows: chatScroll.scrollRows,
|
|
14852
14953
|
onMaxScrollChange: chatScroll.setMaxScroll
|
|
14853
14954
|
}
|
|
14854
|
-
)), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */
|
|
14955
|
+
)), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */ React62.createElement(
|
|
14855
14956
|
WelcomeBanner,
|
|
14856
14957
|
{
|
|
14857
14958
|
inCodeMode: !!codeMode,
|
|
@@ -14859,7 +14960,7 @@ function AppInner({
|
|
|
14859
14960
|
dashboardUrl,
|
|
14860
14961
|
languageVersion
|
|
14861
14962
|
}
|
|
14862
|
-
) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && ongoingTool ? /* @__PURE__ */
|
|
14963
|
+
) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && ongoingTool ? /* @__PURE__ */ React62.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && subagentActivities.length > 0 ? /* @__PURE__ */ React62.createElement(SubagentLiveStack, { activities: subagentActivities, max: 3 }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !ongoingTool && statusLine ? /* @__PURE__ */ React62.createElement(ThinkingRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !pendingChoice && !stagedChoiceCustom && !pendingRevision && !stagedCheckpointRevise && !pendingCheckpoint ? /* @__PURE__ */ React62.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && busy && !isStreaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React62.createElement(ThinkingRow, { text: activityLabel }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview ? /* @__PURE__ */ React62.createElement(PlanLiveRow, null) : null, /* @__PURE__ */ React62.createElement(ToastRail, null)), stagedInput ? /* @__PURE__ */ React62.createElement(
|
|
14863
14964
|
PlanRefineInput,
|
|
14864
14965
|
{
|
|
14865
14966
|
mode: stagedInput.mode,
|
|
@@ -14867,21 +14968,21 @@ function AppInner({
|
|
|
14867
14968
|
onSubmit: handleStagedInputSubmit,
|
|
14868
14969
|
onCancel: handleStagedInputCancel
|
|
14869
14970
|
}
|
|
14870
|
-
) : stagedChoiceCustom ? /* @__PURE__ */
|
|
14971
|
+
) : stagedChoiceCustom ? /* @__PURE__ */ React62.createElement(
|
|
14871
14972
|
PlanRefineInput,
|
|
14872
14973
|
{
|
|
14873
14974
|
mode: "choice-custom",
|
|
14874
14975
|
onSubmit: handleChoiceCustomSubmit,
|
|
14875
14976
|
onCancel: handleChoiceCustomCancel
|
|
14876
14977
|
}
|
|
14877
|
-
) : stagedCheckpointRevise ? /* @__PURE__ */
|
|
14978
|
+
) : stagedCheckpointRevise ? /* @__PURE__ */ React62.createElement(
|
|
14878
14979
|
PlanRefineInput,
|
|
14879
14980
|
{
|
|
14880
14981
|
mode: "checkpoint-revise",
|
|
14881
14982
|
onSubmit: (text) => handleCheckpointReviseSubmit(text, stagedCheckpointRevise),
|
|
14882
14983
|
onCancel: handleCheckpointReviseCancel
|
|
14883
14984
|
}
|
|
14884
|
-
) : pendingChoice ? /* @__PURE__ */
|
|
14985
|
+
) : pendingChoice ? /* @__PURE__ */ React62.createElement(
|
|
14885
14986
|
ChoiceConfirm,
|
|
14886
14987
|
{
|
|
14887
14988
|
question: pendingChoice.question,
|
|
@@ -14889,7 +14990,7 @@ function AppInner({
|
|
|
14889
14990
|
allowCustom: pendingChoice.allowCustom,
|
|
14890
14991
|
onChoose: stableHandleChoiceConfirm
|
|
14891
14992
|
}
|
|
14892
|
-
) : pendingRevision ? /* @__PURE__ */
|
|
14993
|
+
) : pendingRevision ? /* @__PURE__ */ React62.createElement(
|
|
14893
14994
|
PlanReviseConfirm,
|
|
14894
14995
|
{
|
|
14895
14996
|
reason: pendingRevision.reason,
|
|
@@ -14900,7 +15001,7 @@ function AppInner({
|
|
|
14900
15001
|
summary: pendingRevision.summary,
|
|
14901
15002
|
onChoose: stableHandleReviseConfirm
|
|
14902
15003
|
}
|
|
14903
|
-
) : pendingCheckpoint ? /* @__PURE__ */
|
|
15004
|
+
) : pendingCheckpoint ? /* @__PURE__ */ React62.createElement(
|
|
14904
15005
|
PlanCheckpointConfirm,
|
|
14905
15006
|
{
|
|
14906
15007
|
stepId: pendingCheckpoint.stepId,
|
|
@@ -14911,7 +15012,7 @@ function AppInner({
|
|
|
14911
15012
|
completedStepIds: completedStepIdsRef.current,
|
|
14912
15013
|
onChoose: stableHandleCheckpointConfirm
|
|
14913
15014
|
}
|
|
14914
|
-
) : pendingCheckpointPicker ? /* @__PURE__ */
|
|
15015
|
+
) : pendingCheckpointPicker ? /* @__PURE__ */ React62.createElement(
|
|
14915
15016
|
CheckpointPicker,
|
|
14916
15017
|
{
|
|
14917
15018
|
checkpoints: checkpointPickerList,
|
|
@@ -14956,7 +15057,7 @@ function AppInner({
|
|
|
14956
15057
|
}
|
|
14957
15058
|
}
|
|
14958
15059
|
}
|
|
14959
|
-
) : pendingSessionsPicker ? /* @__PURE__ */
|
|
15060
|
+
) : pendingSessionsPicker ? /* @__PURE__ */ React62.createElement(
|
|
14960
15061
|
SessionPicker,
|
|
14961
15062
|
{
|
|
14962
15063
|
sessions: sessionsPickerList,
|
|
@@ -15001,7 +15102,25 @@ function AppInner({
|
|
|
15001
15102
|
}
|
|
15002
15103
|
}
|
|
15003
15104
|
}
|
|
15004
|
-
) :
|
|
15105
|
+
) : pendingThemePicker ? /* @__PURE__ */ React62.createElement(
|
|
15106
|
+
ThemePicker,
|
|
15107
|
+
{
|
|
15108
|
+
currentPreference: loadTheme() ?? "auto",
|
|
15109
|
+
activeTheme: themeName,
|
|
15110
|
+
onChoose: (outcome) => {
|
|
15111
|
+
setPendingThemePicker(false);
|
|
15112
|
+
if (outcome.kind === "quit") return;
|
|
15113
|
+
saveTheme(outcome.value);
|
|
15114
|
+
const active = resolveThemePreference(
|
|
15115
|
+
outcome.value,
|
|
15116
|
+
process.env.REASONIX_THEME
|
|
15117
|
+
);
|
|
15118
|
+
setThemeName(active);
|
|
15119
|
+
log.pushInfo(`\u25B8 theme saved: ${outcome.value}
|
|
15120
|
+
active now: ${active}`);
|
|
15121
|
+
}
|
|
15122
|
+
}
|
|
15123
|
+
) : pendingModelPicker ? /* @__PURE__ */ React62.createElement(
|
|
15005
15124
|
ModelPicker,
|
|
15006
15125
|
{
|
|
15007
15126
|
models,
|
|
@@ -15033,7 +15152,7 @@ function AppInner({
|
|
|
15033
15152
|
}
|
|
15034
15153
|
}
|
|
15035
15154
|
}
|
|
15036
|
-
) : pendingMcpHub ? /* @__PURE__ */
|
|
15155
|
+
) : pendingMcpHub ? /* @__PURE__ */ React62.createElement(
|
|
15037
15156
|
McpHub,
|
|
15038
15157
|
{
|
|
15039
15158
|
initialTab: pendingMcpHub.tab,
|
|
@@ -15053,7 +15172,7 @@ function AppInner({
|
|
|
15053
15172
|
return r;
|
|
15054
15173
|
} : void 0
|
|
15055
15174
|
}
|
|
15056
|
-
) : pendingPlan ? /* @__PURE__ */
|
|
15175
|
+
) : pendingPlan ? /* @__PURE__ */ React62.createElement(
|
|
15057
15176
|
PlanConfirm,
|
|
15058
15177
|
{
|
|
15059
15178
|
plan: pendingPlan,
|
|
@@ -15062,7 +15181,7 @@ function AppInner({
|
|
|
15062
15181
|
onChoose: stableHandlePlanConfirm,
|
|
15063
15182
|
projectRoot: currentRootDir
|
|
15064
15183
|
}
|
|
15065
|
-
) : pendingReviseEditor ? /* @__PURE__ */
|
|
15184
|
+
) : pendingReviseEditor ? /* @__PURE__ */ React62.createElement(
|
|
15066
15185
|
PlanReviseEditor,
|
|
15067
15186
|
{
|
|
15068
15187
|
steps: planStepsRef.current ?? [],
|
|
@@ -15081,7 +15200,7 @@ function AppInner({
|
|
|
15081
15200
|
setPendingPlan(planText);
|
|
15082
15201
|
}
|
|
15083
15202
|
}
|
|
15084
|
-
) : pendingShell ? /* @__PURE__ */
|
|
15203
|
+
) : pendingShell ? /* @__PURE__ */ React62.createElement(
|
|
15085
15204
|
ShellConfirm,
|
|
15086
15205
|
{
|
|
15087
15206
|
command: pendingShell.command,
|
|
@@ -15089,7 +15208,7 @@ function AppInner({
|
|
|
15089
15208
|
kind: pendingShell.kind,
|
|
15090
15209
|
onChoose: handleShellConfirm
|
|
15091
15210
|
}
|
|
15092
|
-
) : pendingEditReview ? /* @__PURE__ */
|
|
15211
|
+
) : pendingEditReview ? /* @__PURE__ */ React62.createElement(
|
|
15093
15212
|
EditConfirm,
|
|
15094
15213
|
{
|
|
15095
15214
|
block: pendingEditReview,
|
|
@@ -15101,14 +15220,14 @@ function AppInner({
|
|
|
15101
15220
|
}
|
|
15102
15221
|
}
|
|
15103
15222
|
}
|
|
15104
|
-
) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */
|
|
15223
|
+
) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React62.createElement(
|
|
15105
15224
|
EditConfirm,
|
|
15106
15225
|
{
|
|
15107
15226
|
key: `walk-${pendingTick}`,
|
|
15108
15227
|
block: pendingEdits.current[0],
|
|
15109
15228
|
onChoose: handleWalkChoice
|
|
15110
15229
|
}
|
|
15111
|
-
) : !chatScroll.pinned ? /* @__PURE__ */
|
|
15230
|
+
) : !chatScroll.pinned ? /* @__PURE__ */ React62.createElement(Text53, { color: FG.faint }, " \u{1F4D6} reading history \u2014 End / PgDn to return \xB7 \u2193 to advance one line") : /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, codeMode ? /* @__PURE__ */ React62.createElement(
|
|
15112
15231
|
ModeStatusBar,
|
|
15113
15232
|
{
|
|
15114
15233
|
editMode,
|
|
@@ -15118,7 +15237,7 @@ function AppInner({
|
|
|
15118
15237
|
undoArmed: !!undoBanner || hasUndoable(),
|
|
15119
15238
|
jobs: codeMode.jobs
|
|
15120
15239
|
}
|
|
15121
|
-
) : null, activeLoop ? /* @__PURE__ */
|
|
15240
|
+
) : null, activeLoop ? /* @__PURE__ */ React62.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React62.createElement(StatusRow, null), /* @__PURE__ */ React62.createElement(
|
|
15122
15241
|
PromptInput,
|
|
15123
15242
|
{
|
|
15124
15243
|
value: input,
|
|
@@ -15128,7 +15247,7 @@ function AppInner({
|
|
|
15128
15247
|
onHistoryPrev: recallPrev,
|
|
15129
15248
|
onHistoryNext: recallNext
|
|
15130
15249
|
}
|
|
15131
|
-
)), /* @__PURE__ */
|
|
15250
|
+
)), /* @__PURE__ */ React62.createElement(Box50, { flexDirection: "column", flexShrink: 0, flexWrap: "nowrap" }, slashMatches !== null ? /* @__PURE__ */ React62.createElement(
|
|
15132
15251
|
SlashSuggestions,
|
|
15133
15252
|
{
|
|
15134
15253
|
key: `slash-suggestions:${slashGroupMode ? "group" : "search"}`,
|
|
@@ -15137,7 +15256,7 @@ function AppInner({
|
|
|
15137
15256
|
groupMode: slashGroupMode,
|
|
15138
15257
|
advancedHidden: slashAdvancedHidden
|
|
15139
15258
|
}
|
|
15140
|
-
) : null, atState !== null ? /* @__PURE__ */
|
|
15259
|
+
) : null, atState !== null ? /* @__PURE__ */ React62.createElement(AtMentionSuggestions, { state: atState, selectedIndex: atSelected }) : null), slashArgContext ? /* @__PURE__ */ React62.createElement(
|
|
15141
15260
|
SlashArgPicker,
|
|
15142
15261
|
{
|
|
15143
15262
|
matches: slashArgMatches,
|
|
@@ -15146,16 +15265,16 @@ function AppInner({
|
|
|
15146
15265
|
kind: slashArgContext.kind,
|
|
15147
15266
|
partial: slashArgContext.partial
|
|
15148
15267
|
}
|
|
15149
|
-
) : null))))));
|
|
15268
|
+
) : null)))))));
|
|
15150
15269
|
}
|
|
15151
15270
|
|
|
15152
15271
|
// src/cli/ui/Setup.tsx
|
|
15153
|
-
import { Box as
|
|
15154
|
-
import
|
|
15272
|
+
import { Box as Box51, Text as Text55, useApp } from "ink";
|
|
15273
|
+
import React64, { useState as useState21 } from "react";
|
|
15155
15274
|
|
|
15156
15275
|
// src/cli/ui/MaskedInput.tsx
|
|
15157
|
-
import { Text as
|
|
15158
|
-
import
|
|
15276
|
+
import { Text as Text54, useInput } from "ink";
|
|
15277
|
+
import React63, { useRef as useRef10 } from "react";
|
|
15159
15278
|
function stripPasteMarkers(s) {
|
|
15160
15279
|
return s.replace(/\u001b?\[20[01]~/g, "").replace(/\u001b/g, "");
|
|
15161
15280
|
}
|
|
@@ -15190,11 +15309,11 @@ function MaskedInput({
|
|
|
15190
15309
|
});
|
|
15191
15310
|
if (value.length === 0) {
|
|
15192
15311
|
if (placeholder.length === 0) {
|
|
15193
|
-
return /* @__PURE__ */
|
|
15312
|
+
return /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, " ");
|
|
15194
15313
|
}
|
|
15195
|
-
return /* @__PURE__ */
|
|
15314
|
+
return /* @__PURE__ */ React63.createElement(React63.Fragment, null, /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, placeholder[0]), /* @__PURE__ */ React63.createElement(Text54, { color: FG.faint }, placeholder.slice(1)));
|
|
15196
15315
|
}
|
|
15197
|
-
return /* @__PURE__ */
|
|
15316
|
+
return /* @__PURE__ */ React63.createElement(React63.Fragment, null, /* @__PURE__ */ React63.createElement(Text54, null, mask.repeat(value.length)), /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, " "));
|
|
15198
15317
|
}
|
|
15199
15318
|
|
|
15200
15319
|
// src/cli/ui/Setup.tsx
|
|
@@ -15221,7 +15340,7 @@ function Setup({ onReady }) {
|
|
|
15221
15340
|
}
|
|
15222
15341
|
onReady(trimmed);
|
|
15223
15342
|
};
|
|
15224
|
-
return /* @__PURE__ */
|
|
15343
|
+
return /* @__PURE__ */ React64.createElement(Box51, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React64.createElement(Box51, null, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React64.createElement(Text55, null, " "), /* @__PURE__ */ React64.createElement(Text55, { bold: true }, "Welcome to "), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React64.createElement(Box51, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " sign up at \xB7 "), /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React64.createElement(Box51, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " saved to "), /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React64.createElement(
|
|
15225
15344
|
MaskedInput,
|
|
15226
15345
|
{
|
|
15227
15346
|
value,
|
|
@@ -15230,7 +15349,7 @@ function Setup({ onReady }) {
|
|
|
15230
15349
|
mask: "\u2022",
|
|
15231
15350
|
placeholder: "sk-..."
|
|
15232
15351
|
}
|
|
15233
|
-
)), error ? /* @__PURE__ */
|
|
15352
|
+
)), error ? /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React64.createElement(Box51, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " /exit to abort")));
|
|
15234
15353
|
}
|
|
15235
15354
|
|
|
15236
15355
|
// src/cli/ui/drain-tty.ts
|
|
@@ -15441,7 +15560,7 @@ function Root({
|
|
|
15441
15560
|
const workspaceRoot = appProps.codeMode?.rootDir ?? process.cwd();
|
|
15442
15561
|
const [sessions2, setSessions] = useState22(() => listSessionsForWorkspace(workspaceRoot));
|
|
15443
15562
|
if (!key) {
|
|
15444
|
-
return /* @__PURE__ */
|
|
15563
|
+
return /* @__PURE__ */ React65.createElement(
|
|
15445
15564
|
Setup,
|
|
15446
15565
|
{
|
|
15447
15566
|
onReady: (k) => {
|
|
@@ -15453,7 +15572,7 @@ function Root({
|
|
|
15453
15572
|
}
|
|
15454
15573
|
process.env.DEEPSEEK_API_KEY = key;
|
|
15455
15574
|
if (pickerOpen) {
|
|
15456
|
-
return /* @__PURE__ */
|
|
15575
|
+
return /* @__PURE__ */ React65.createElement(KeystrokeProvider, null, /* @__PURE__ */ React65.createElement(
|
|
15457
15576
|
SessionPicker,
|
|
15458
15577
|
{
|
|
15459
15578
|
sessions: sessions2,
|
|
@@ -15486,7 +15605,7 @@ function Root({
|
|
|
15486
15605
|
}
|
|
15487
15606
|
));
|
|
15488
15607
|
}
|
|
15489
|
-
return /* @__PURE__ */
|
|
15608
|
+
return /* @__PURE__ */ React65.createElement(KeystrokeProvider, null, /* @__PURE__ */ React65.createElement(
|
|
15490
15609
|
App,
|
|
15491
15610
|
{
|
|
15492
15611
|
key: activeSession ?? "__new__",
|
|
@@ -15559,7 +15678,7 @@ async function chatCommand(opts) {
|
|
|
15559
15678
|
const showPicker = !opts.session && !opts.forceResume && listSessionsForWorkspace(launchWorkspace).length > 0;
|
|
15560
15679
|
markPhase("ink_render_call");
|
|
15561
15680
|
const { waitUntilExit } = render(
|
|
15562
|
-
/* @__PURE__ */
|
|
15681
|
+
/* @__PURE__ */ React65.createElement(
|
|
15563
15682
|
Root,
|
|
15564
15683
|
{
|
|
15565
15684
|
initialKey,
|
|
@@ -15600,4 +15719,4 @@ async function chatCommand(opts) {
|
|
|
15600
15719
|
export {
|
|
15601
15720
|
chatCommand
|
|
15602
15721
|
};
|
|
15603
|
-
//# sourceMappingURL=chunk-
|
|
15722
|
+
//# sourceMappingURL=chunk-NHV5YGTB.js.map
|