@robota-sdk/agent-cli 3.0.0-beta.29 → 3.0.0-beta.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/bin.cjs +232 -122
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-74GXDZY7.js → chunk-MCZP5QLE.js} +212 -102
- package/dist/node/index.cjs +232 -122
- package/dist/node/index.js +1 -1
- package/package.json +3 -3
package/dist/node/bin.js
CHANGED
|
@@ -150,12 +150,38 @@ import { render } from "ink";
|
|
|
150
150
|
|
|
151
151
|
// src/ui/App.tsx
|
|
152
152
|
import { useState as useState7, useRef as useRef5 } from "react";
|
|
153
|
-
import { Box as
|
|
153
|
+
import { Box as Box9, Text as Text11, useApp, useInput as useInput5 } from "ink";
|
|
154
154
|
import { getModelName } from "@robota-sdk/agent-core";
|
|
155
155
|
|
|
156
156
|
// src/ui/hooks/useSession.ts
|
|
157
157
|
import { useState, useCallback, useRef } from "react";
|
|
158
158
|
import { createSession, FileSessionLogger, projectPaths } from "@robota-sdk/agent-sdk";
|
|
159
|
+
|
|
160
|
+
// src/utils/edit-diff.ts
|
|
161
|
+
function generateDiffLines(oldStr, newStr) {
|
|
162
|
+
if (oldStr === newStr) return [];
|
|
163
|
+
const lines = [];
|
|
164
|
+
for (const line of oldStr.split("\n")) {
|
|
165
|
+
lines.push({ type: "remove", text: line });
|
|
166
|
+
}
|
|
167
|
+
for (const line of newStr.split("\n")) {
|
|
168
|
+
lines.push({ type: "add", text: line });
|
|
169
|
+
}
|
|
170
|
+
return lines;
|
|
171
|
+
}
|
|
172
|
+
function extractEditDiff(toolName, toolArgs) {
|
|
173
|
+
if (toolName !== "Edit" || !toolArgs) return null;
|
|
174
|
+
const filePath = toolArgs.file_path ?? toolArgs.filePath;
|
|
175
|
+
const oldStr = toolArgs.old_string ?? toolArgs.oldString;
|
|
176
|
+
const newStr = toolArgs.new_string ?? toolArgs.newString;
|
|
177
|
+
if (typeof filePath !== "string") return null;
|
|
178
|
+
if (typeof oldStr !== "string" || typeof newStr !== "string") return null;
|
|
179
|
+
const lines = generateDiffLines(oldStr, newStr);
|
|
180
|
+
if (lines.length === 0) return null;
|
|
181
|
+
return { file: filePath, lines };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/ui/hooks/useSession.ts
|
|
159
185
|
var TOOL_ARG_DISPLAY_MAX = 80;
|
|
160
186
|
var TAIL_KEEP = 30;
|
|
161
187
|
var MAX_COMPLETED_TOOLS = 50;
|
|
@@ -221,14 +247,26 @@ function useSession(props) {
|
|
|
221
247
|
}
|
|
222
248
|
setActiveTools((prev) => [
|
|
223
249
|
...prev,
|
|
224
|
-
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
250
|
+
{ toolName: event.toolName, firstArg, isRunning: true, _toolArgs: event.toolArgs }
|
|
225
251
|
]);
|
|
226
252
|
} else {
|
|
227
253
|
const toolResult = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
228
254
|
setActiveTools((prev) => {
|
|
229
|
-
const updated = prev.map(
|
|
230
|
-
(t
|
|
231
|
-
|
|
255
|
+
const updated = prev.map((t) => {
|
|
256
|
+
if (!(t.toolName === event.toolName && t.isRunning)) return t;
|
|
257
|
+
const editDiff = extractEditDiff(event.toolName, t._toolArgs);
|
|
258
|
+
const finished = {
|
|
259
|
+
...t,
|
|
260
|
+
isRunning: false,
|
|
261
|
+
result: toolResult
|
|
262
|
+
};
|
|
263
|
+
if (editDiff) {
|
|
264
|
+
finished.diffLines = editDiff.lines;
|
|
265
|
+
finished.diffFile = editDiff.file;
|
|
266
|
+
}
|
|
267
|
+
delete finished._toolArgs;
|
|
268
|
+
return finished;
|
|
269
|
+
});
|
|
232
270
|
const completed = updated.filter((t) => !t.isRunning);
|
|
233
271
|
if (completed.length > MAX_COMPLETED_TOOLS) {
|
|
234
272
|
const excess = completed.length - MAX_COMPLETED_TOOLS;
|
|
@@ -609,19 +647,33 @@ import { useCallback as useCallback4 } from "react";
|
|
|
609
647
|
// src/utils/tool-call-extractor.ts
|
|
610
648
|
var TOOL_ARG_MAX_LENGTH = 80;
|
|
611
649
|
var TAIL_KEEP2 = 30;
|
|
612
|
-
function
|
|
613
|
-
const
|
|
650
|
+
function extractToolCallsWithDiff(history, startIndex) {
|
|
651
|
+
const summaries = [];
|
|
614
652
|
for (let i = startIndex; i < history.length; i++) {
|
|
615
653
|
const msg = history[i];
|
|
616
654
|
if (msg.role === "assistant" && msg.toolCalls) {
|
|
617
655
|
for (const tc of msg.toolCalls) {
|
|
618
656
|
const value = parseFirstArgValue(tc.function.arguments);
|
|
619
657
|
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_MAX_LENGTH - TAIL_KEEP2 - 3) + "..." + value.slice(-TAIL_KEEP2) : value;
|
|
620
|
-
|
|
658
|
+
const summary = {
|
|
659
|
+
line: `${tc.function.name}(${truncated})`
|
|
660
|
+
};
|
|
661
|
+
if (tc.function.name === "Edit") {
|
|
662
|
+
try {
|
|
663
|
+
const args = JSON.parse(tc.function.arguments);
|
|
664
|
+
const diff = extractEditDiff("Edit", args);
|
|
665
|
+
if (diff) {
|
|
666
|
+
summary.diffLines = diff.lines;
|
|
667
|
+
summary.diffFile = diff.file;
|
|
668
|
+
}
|
|
669
|
+
} catch {
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
summaries.push(summary);
|
|
621
673
|
}
|
|
622
674
|
}
|
|
623
675
|
}
|
|
624
|
-
return
|
|
676
|
+
return summaries;
|
|
625
677
|
}
|
|
626
678
|
function parseFirstArgValue(argsJson) {
|
|
627
679
|
try {
|
|
@@ -708,15 +760,15 @@ async function runSessionPrompt(prompt, session, addMessage, clearStreamingText,
|
|
|
708
760
|
const response = await session.run(prompt, rawInput);
|
|
709
761
|
clearStreamingText();
|
|
710
762
|
const history = session.getHistory();
|
|
711
|
-
const
|
|
763
|
+
const toolSummaries = extractToolCallsWithDiff(
|
|
712
764
|
history,
|
|
713
765
|
historyBefore
|
|
714
766
|
);
|
|
715
|
-
if (
|
|
767
|
+
if (toolSummaries.length > 0) {
|
|
716
768
|
addMessage({
|
|
717
769
|
role: "tool",
|
|
718
|
-
content:
|
|
719
|
-
toolName: `${
|
|
770
|
+
content: JSON.stringify(toolSummaries),
|
|
771
|
+
toolName: `${toolSummaries.length} tools`
|
|
720
772
|
});
|
|
721
773
|
}
|
|
722
774
|
addMessage({ role: "assistant", content: response || "(empty response)" });
|
|
@@ -1215,7 +1267,7 @@ function usePluginCallbacks(cwd) {
|
|
|
1215
1267
|
|
|
1216
1268
|
// src/ui/MessageList.tsx
|
|
1217
1269
|
import React2 from "react";
|
|
1218
|
-
import { Box, Text } from "ink";
|
|
1270
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
1219
1271
|
|
|
1220
1272
|
// src/ui/render-markdown.ts
|
|
1221
1273
|
import { marked } from "marked";
|
|
@@ -1228,48 +1280,103 @@ function renderMarkdown(md) {
|
|
|
1228
1280
|
return typeof result === "string" ? result.trimEnd() : md;
|
|
1229
1281
|
}
|
|
1230
1282
|
|
|
1283
|
+
// src/ui/DiffBlock.tsx
|
|
1284
|
+
import { Box, Text } from "ink";
|
|
1285
|
+
import { jsxs } from "react/jsx-runtime";
|
|
1286
|
+
var MAX_DIFF_LINES = 10;
|
|
1287
|
+
var TRUNCATED_SHOW = 8;
|
|
1288
|
+
function DiffBlock({ file, lines }) {
|
|
1289
|
+
const truncated = lines.length > MAX_DIFF_LINES;
|
|
1290
|
+
const visible = truncated ? lines.slice(0, TRUNCATED_SHOW) : lines;
|
|
1291
|
+
const remaining = lines.length - TRUNCATED_SHOW;
|
|
1292
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 4, children: [
|
|
1293
|
+
file && /* @__PURE__ */ jsxs(Text, { color: "white", dimColor: true, children: [
|
|
1294
|
+
"\u2502 ",
|
|
1295
|
+
file
|
|
1296
|
+
] }),
|
|
1297
|
+
visible.map((line, i) => /* @__PURE__ */ jsxs(Text, { color: line.type === "remove" ? "red" : "greenBright", children: [
|
|
1298
|
+
"\u2502 ",
|
|
1299
|
+
line.type === "remove" ? "-" : "+",
|
|
1300
|
+
" ",
|
|
1301
|
+
line.text
|
|
1302
|
+
] }, i)),
|
|
1303
|
+
truncated && /* @__PURE__ */ jsxs(Text, { color: "white", dimColor: true, children: [
|
|
1304
|
+
"\u2502 ... and ",
|
|
1305
|
+
remaining,
|
|
1306
|
+
" more lines"
|
|
1307
|
+
] })
|
|
1308
|
+
] });
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1231
1311
|
// src/ui/MessageList.tsx
|
|
1232
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1312
|
+
import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1233
1313
|
function RoleLabel({ role }) {
|
|
1234
1314
|
switch (role) {
|
|
1235
1315
|
case "user":
|
|
1236
|
-
return /* @__PURE__ */
|
|
1316
|
+
return /* @__PURE__ */ jsxs2(Text2, { color: "green", bold: true, children: [
|
|
1237
1317
|
"You:",
|
|
1238
1318
|
" "
|
|
1239
1319
|
] });
|
|
1240
1320
|
case "assistant":
|
|
1241
|
-
return /* @__PURE__ */
|
|
1321
|
+
return /* @__PURE__ */ jsxs2(Text2, { color: "cyan", bold: true, children: [
|
|
1242
1322
|
"Robota:",
|
|
1243
1323
|
" "
|
|
1244
1324
|
] });
|
|
1245
1325
|
case "system":
|
|
1246
|
-
return /* @__PURE__ */
|
|
1326
|
+
return /* @__PURE__ */ jsxs2(Text2, { color: "yellow", bold: true, children: [
|
|
1247
1327
|
"System:",
|
|
1248
1328
|
" "
|
|
1249
1329
|
] });
|
|
1250
1330
|
case "tool":
|
|
1251
|
-
return /* @__PURE__ */
|
|
1331
|
+
return /* @__PURE__ */ jsxs2(Text2, { color: "white", bold: true, children: [
|
|
1252
1332
|
"Tool:",
|
|
1253
1333
|
" "
|
|
1254
1334
|
] });
|
|
1255
1335
|
}
|
|
1256
1336
|
}
|
|
1257
1337
|
function ToolMessage({ message }) {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1338
|
+
let summaries = null;
|
|
1339
|
+
try {
|
|
1340
|
+
const parsed = JSON.parse(message.content);
|
|
1341
|
+
if (Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0].line === "string") {
|
|
1342
|
+
summaries = parsed;
|
|
1343
|
+
}
|
|
1344
|
+
} catch {
|
|
1345
|
+
}
|
|
1346
|
+
if (summaries) {
|
|
1347
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
|
|
1348
|
+
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
1349
|
+
/* @__PURE__ */ jsx(Text2, { color: "white", bold: true, children: "Tool: " }),
|
|
1350
|
+
message.toolName && /* @__PURE__ */ jsxs2(Text2, { color: "white", dimColor: true, children: [
|
|
1351
|
+
"[",
|
|
1352
|
+
message.toolName,
|
|
1353
|
+
"]"
|
|
1354
|
+
] })
|
|
1264
1355
|
] }),
|
|
1265
|
-
|
|
1356
|
+
/* @__PURE__ */ jsx(Text2, { children: " " }),
|
|
1357
|
+
summaries.map((s, i) => /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
1358
|
+
/* @__PURE__ */ jsxs2(Text2, { color: "green", children: [
|
|
1359
|
+
" ",
|
|
1360
|
+
"\u2713",
|
|
1361
|
+
" ",
|
|
1362
|
+
s.line
|
|
1363
|
+
] }),
|
|
1364
|
+
s.diffLines && s.diffLines.length > 0 && /* @__PURE__ */ jsx(DiffBlock, { file: s.diffFile, lines: s.diffLines })
|
|
1365
|
+
] }, i))
|
|
1366
|
+
] });
|
|
1367
|
+
}
|
|
1368
|
+
const lines = message.content.split("\n").filter((l) => l.trim());
|
|
1369
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
|
|
1370
|
+
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
1371
|
+
/* @__PURE__ */ jsx(Text2, { color: "white", bold: true, children: "Tool: " }),
|
|
1372
|
+
message.toolName && /* @__PURE__ */ jsxs2(Text2, { color: "white", dimColor: true, children: [
|
|
1266
1373
|
"[",
|
|
1267
1374
|
message.toolName,
|
|
1268
1375
|
"]"
|
|
1269
1376
|
] })
|
|
1270
1377
|
] }),
|
|
1271
|
-
/* @__PURE__ */ jsx(
|
|
1272
|
-
lines.map((line, i) => /* @__PURE__ */
|
|
1378
|
+
/* @__PURE__ */ jsx(Text2, { children: " " }),
|
|
1379
|
+
lines.map((line, i) => /* @__PURE__ */ jsxs2(Text2, { color: "green", children: [
|
|
1273
1380
|
" ",
|
|
1274
1381
|
"\u2713",
|
|
1275
1382
|
" ",
|
|
@@ -1283,28 +1390,28 @@ var MessageItem = React2.memo(function MessageItem2({
|
|
|
1283
1390
|
if (message.role === "tool") {
|
|
1284
1391
|
return /* @__PURE__ */ jsx(ToolMessage, { message });
|
|
1285
1392
|
}
|
|
1286
|
-
return /* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1393
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
|
|
1394
|
+
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
1288
1395
|
/* @__PURE__ */ jsx(RoleLabel, { role: message.role }),
|
|
1289
|
-
message.toolName && /* @__PURE__ */
|
|
1396
|
+
message.toolName && /* @__PURE__ */ jsxs2(Text2, { color: "magenta", dimColor: true, children: [
|
|
1290
1397
|
"[",
|
|
1291
1398
|
message.toolName,
|
|
1292
1399
|
"]",
|
|
1293
1400
|
" "
|
|
1294
1401
|
] })
|
|
1295
1402
|
] }),
|
|
1296
|
-
/* @__PURE__ */ jsx(
|
|
1297
|
-
/* @__PURE__ */ jsx(
|
|
1403
|
+
/* @__PURE__ */ jsx(Text2, { children: " " }),
|
|
1404
|
+
/* @__PURE__ */ jsx(Box2, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text2, { wrap: "wrap", children: message.role === "assistant" ? renderMarkdown(message.content) : message.content }) })
|
|
1298
1405
|
] });
|
|
1299
1406
|
});
|
|
1300
1407
|
function MessageList({ messages }) {
|
|
1301
|
-
return /* @__PURE__ */ jsx(
|
|
1408
|
+
return /* @__PURE__ */ jsx(Box2, { flexDirection: "column", children: messages.map((msg) => /* @__PURE__ */ jsx(MessageItem, { message: msg }, msg.id)) });
|
|
1302
1409
|
}
|
|
1303
1410
|
|
|
1304
1411
|
// src/ui/StatusBar.tsx
|
|
1305
|
-
import { Box as
|
|
1412
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
1306
1413
|
import { formatTokenCount as formatTokenCount2 } from "@robota-sdk/agent-core";
|
|
1307
|
-
import { jsx as jsx2, jsxs as
|
|
1414
|
+
import { jsx as jsx2, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1308
1415
|
var CONTEXT_YELLOW_THRESHOLD = 70;
|
|
1309
1416
|
var CONTEXT_RED_THRESHOLD = 90;
|
|
1310
1417
|
function getContextColor(percentage) {
|
|
@@ -1323,8 +1430,8 @@ function StatusBar({
|
|
|
1323
1430
|
contextMaxTokens
|
|
1324
1431
|
}) {
|
|
1325
1432
|
const contextColor = getContextColor(contextPercentage);
|
|
1326
|
-
return /* @__PURE__ */
|
|
1327
|
-
|
|
1433
|
+
return /* @__PURE__ */ jsxs3(
|
|
1434
|
+
Box3,
|
|
1328
1435
|
{
|
|
1329
1436
|
borderStyle: "single",
|
|
1330
1437
|
borderColor: "gray",
|
|
@@ -1332,14 +1439,14 @@ function StatusBar({
|
|
|
1332
1439
|
paddingRight: 1,
|
|
1333
1440
|
justifyContent: "space-between",
|
|
1334
1441
|
children: [
|
|
1335
|
-
/* @__PURE__ */
|
|
1336
|
-
/* @__PURE__ */ jsx2(
|
|
1442
|
+
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
1443
|
+
/* @__PURE__ */ jsx2(Text3, { color: "cyan", bold: true, children: "Mode:" }),
|
|
1337
1444
|
" ",
|
|
1338
|
-
/* @__PURE__ */ jsx2(
|
|
1445
|
+
/* @__PURE__ */ jsx2(Text3, { children: permissionMode }),
|
|
1339
1446
|
" | ",
|
|
1340
|
-
/* @__PURE__ */ jsx2(
|
|
1447
|
+
/* @__PURE__ */ jsx2(Text3, { dimColor: true, children: modelName }),
|
|
1341
1448
|
" | ",
|
|
1342
|
-
/* @__PURE__ */
|
|
1449
|
+
/* @__PURE__ */ jsxs3(Text3, { color: contextColor, children: [
|
|
1343
1450
|
"Context: ",
|
|
1344
1451
|
Math.round(contextPercentage),
|
|
1345
1452
|
"% (",
|
|
@@ -1349,9 +1456,9 @@ function StatusBar({
|
|
|
1349
1456
|
")"
|
|
1350
1457
|
] })
|
|
1351
1458
|
] }),
|
|
1352
|
-
/* @__PURE__ */
|
|
1353
|
-
isThinking && /* @__PURE__ */ jsx2(
|
|
1354
|
-
/* @__PURE__ */
|
|
1459
|
+
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
1460
|
+
isThinking && /* @__PURE__ */ jsx2(Text3, { color: "yellow", children: "Thinking... " }),
|
|
1461
|
+
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
1355
1462
|
"msgs: ",
|
|
1356
1463
|
messageCount
|
|
1357
1464
|
] })
|
|
@@ -1363,11 +1470,11 @@ function StatusBar({
|
|
|
1363
1470
|
|
|
1364
1471
|
// src/ui/InputArea.tsx
|
|
1365
1472
|
import React5, { useState as useState5, useCallback as useCallback5, useMemo as useMemo2 } from "react";
|
|
1366
|
-
import { Box as
|
|
1473
|
+
import { Box as Box5, Text as Text7, useInput as useInput2 } from "ink";
|
|
1367
1474
|
|
|
1368
1475
|
// src/ui/CjkTextInput.tsx
|
|
1369
1476
|
import { useRef as useRef3, useState as useState3 } from "react";
|
|
1370
|
-
import { Text as
|
|
1477
|
+
import { Text as Text4, useInput } from "ink";
|
|
1371
1478
|
import chalk from "chalk";
|
|
1372
1479
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1373
1480
|
function filterPrintable(input) {
|
|
@@ -1440,7 +1547,7 @@ function CjkTextInput({
|
|
|
1440
1547
|
},
|
|
1441
1548
|
{ isActive: focus }
|
|
1442
1549
|
);
|
|
1443
|
-
return /* @__PURE__ */ jsx3(
|
|
1550
|
+
return /* @__PURE__ */ jsx3(Text4, { children: renderWithCursor(valueRef.current, cursorRef.current, placeholder, showCursor && focus) });
|
|
1444
1551
|
}
|
|
1445
1552
|
function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
1446
1553
|
if (!showCursor) {
|
|
@@ -1466,7 +1573,7 @@ function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
|
1466
1573
|
|
|
1467
1574
|
// src/ui/WaveText.tsx
|
|
1468
1575
|
import { useState as useState4, useEffect } from "react";
|
|
1469
|
-
import { Text as
|
|
1576
|
+
import { Text as Text5 } from "ink";
|
|
1470
1577
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1471
1578
|
var WAVE_COLORS = ["#666666", "#888888", "#aaaaaa", "#888888"];
|
|
1472
1579
|
var INTERVAL_MS = 400;
|
|
@@ -1480,23 +1587,23 @@ function WaveText({ text }) {
|
|
|
1480
1587
|
return () => clearInterval(timer);
|
|
1481
1588
|
}, []);
|
|
1482
1589
|
const chars = [...text];
|
|
1483
|
-
return /* @__PURE__ */ jsx4(
|
|
1590
|
+
return /* @__PURE__ */ jsx4(Text5, { children: chars.map((char, i) => {
|
|
1484
1591
|
const group = Math.floor(i / CHARS_PER_GROUP);
|
|
1485
1592
|
const colorIndex = (tick + group) % WAVE_COLORS.length;
|
|
1486
|
-
return /* @__PURE__ */ jsx4(
|
|
1593
|
+
return /* @__PURE__ */ jsx4(Text5, { color: WAVE_COLORS[colorIndex], children: char }, i);
|
|
1487
1594
|
}) });
|
|
1488
1595
|
}
|
|
1489
1596
|
|
|
1490
1597
|
// src/ui/SlashAutocomplete.tsx
|
|
1491
|
-
import { Box as
|
|
1492
|
-
import { jsx as jsx5, jsxs as
|
|
1598
|
+
import { Box as Box4, Text as Text6 } from "ink";
|
|
1599
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1493
1600
|
var MAX_VISIBLE = 8;
|
|
1494
1601
|
function CommandRow(props) {
|
|
1495
1602
|
const { cmd, isSelected, showSlash } = props;
|
|
1496
1603
|
const indicator = isSelected ? "\u25B8 " : " ";
|
|
1497
1604
|
const nameColor = isSelected ? "cyan" : void 0;
|
|
1498
1605
|
const dimmed = !isSelected;
|
|
1499
|
-
return /* @__PURE__ */ jsx5(
|
|
1606
|
+
return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsxs4(Text6, { color: nameColor, dimColor: dimmed, children: [
|
|
1500
1607
|
indicator,
|
|
1501
1608
|
showSlash ? `/${cmd.name} ${cmd.description}` : cmd.description
|
|
1502
1609
|
] }) });
|
|
@@ -1510,7 +1617,7 @@ function SlashAutocomplete({
|
|
|
1510
1617
|
if (!visible || commands.length === 0) return null;
|
|
1511
1618
|
const scrollOffset = computeScrollOffset(selectedIndex, commands.length);
|
|
1512
1619
|
const visibleCommands = commands.slice(scrollOffset, scrollOffset + MAX_VISIBLE);
|
|
1513
|
-
return /* @__PURE__ */ jsx5(
|
|
1620
|
+
return /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: visibleCommands.map((cmd, i) => /* @__PURE__ */ jsx5(
|
|
1514
1621
|
CommandRow,
|
|
1515
1622
|
{
|
|
1516
1623
|
cmd,
|
|
@@ -1528,7 +1635,7 @@ function computeScrollOffset(selectedIndex, total) {
|
|
|
1528
1635
|
}
|
|
1529
1636
|
|
|
1530
1637
|
// src/ui/InputArea.tsx
|
|
1531
|
-
import { jsx as jsx6, jsxs as
|
|
1638
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1532
1639
|
function parseSlashInput(value) {
|
|
1533
1640
|
if (!value.startsWith("/")) return { isSlash: false, parentCommand: "", filter: "" };
|
|
1534
1641
|
const afterSlash = value.slice(1);
|
|
@@ -1639,7 +1746,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1639
1746
|
},
|
|
1640
1747
|
{ isActive: showPopup && !isDisabled }
|
|
1641
1748
|
);
|
|
1642
|
-
return /* @__PURE__ */
|
|
1749
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
1643
1750
|
showPopup && /* @__PURE__ */ jsx6(
|
|
1644
1751
|
SlashAutocomplete,
|
|
1645
1752
|
{
|
|
@@ -1649,8 +1756,8 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1649
1756
|
isSubcommandMode
|
|
1650
1757
|
}
|
|
1651
1758
|
),
|
|
1652
|
-
/* @__PURE__ */ jsx6(
|
|
1653
|
-
/* @__PURE__ */ jsx6(
|
|
1759
|
+
/* @__PURE__ */ jsx6(Box5, { borderStyle: "single", borderColor: isDisabled ? "gray" : "green", paddingLeft: 1, children: isDisabled ? /* @__PURE__ */ jsx6(WaveText, { text: " Waiting for response..." }) : /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
1760
|
+
/* @__PURE__ */ jsx6(Text7, { color: "green", bold: true, children: "> " }),
|
|
1654
1761
|
/* @__PURE__ */ jsx6(
|
|
1655
1762
|
CjkTextInput,
|
|
1656
1763
|
{
|
|
@@ -1666,8 +1773,8 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1666
1773
|
|
|
1667
1774
|
// src/ui/ConfirmPrompt.tsx
|
|
1668
1775
|
import { useState as useState6, useCallback as useCallback6, useRef as useRef4 } from "react";
|
|
1669
|
-
import { Box as
|
|
1670
|
-
import { jsx as jsx7, jsxs as
|
|
1776
|
+
import { Box as Box6, Text as Text8, useInput as useInput3 } from "ink";
|
|
1777
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1671
1778
|
function ConfirmPrompt({
|
|
1672
1779
|
message,
|
|
1673
1780
|
options = ["Yes", "No"],
|
|
@@ -1697,20 +1804,20 @@ function ConfirmPrompt({
|
|
|
1697
1804
|
doSelect(1);
|
|
1698
1805
|
}
|
|
1699
1806
|
});
|
|
1700
|
-
return /* @__PURE__ */
|
|
1701
|
-
/* @__PURE__ */ jsx7(
|
|
1702
|
-
/* @__PURE__ */ jsx7(
|
|
1807
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
1808
|
+
/* @__PURE__ */ jsx7(Text8, { color: "yellow", children: message }),
|
|
1809
|
+
/* @__PURE__ */ jsx7(Box6, { marginTop: 1, children: options.map((opt, i) => /* @__PURE__ */ jsx7(Box6, { marginRight: 2, children: /* @__PURE__ */ jsxs6(Text8, { color: i === selected ? "cyan" : void 0, bold: i === selected, children: [
|
|
1703
1810
|
i === selected ? "> " : " ",
|
|
1704
1811
|
opt
|
|
1705
1812
|
] }) }, opt)) }),
|
|
1706
|
-
/* @__PURE__ */ jsx7(
|
|
1813
|
+
/* @__PURE__ */ jsx7(Text8, { dimColor: true, children: " arrow keys to select, Enter to confirm" })
|
|
1707
1814
|
] });
|
|
1708
1815
|
}
|
|
1709
1816
|
|
|
1710
1817
|
// src/ui/PermissionPrompt.tsx
|
|
1711
1818
|
import React7 from "react";
|
|
1712
|
-
import { Box as
|
|
1713
|
-
import { jsx as jsx8, jsxs as
|
|
1819
|
+
import { Box as Box7, Text as Text9, useInput as useInput4 } from "ink";
|
|
1820
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1714
1821
|
var OPTIONS = ["Allow", "Allow always (this session)", "Deny"];
|
|
1715
1822
|
function formatArgs(args) {
|
|
1716
1823
|
const entries = Object.entries(args);
|
|
@@ -1752,28 +1859,28 @@ function PermissionPrompt({ request }) {
|
|
|
1752
1859
|
doResolve(2);
|
|
1753
1860
|
}
|
|
1754
1861
|
});
|
|
1755
|
-
return /* @__PURE__ */
|
|
1756
|
-
/* @__PURE__ */ jsx8(
|
|
1757
|
-
/* @__PURE__ */
|
|
1862
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
1863
|
+
/* @__PURE__ */ jsx8(Text9, { color: "yellow", bold: true, children: "[Permission Required]" }),
|
|
1864
|
+
/* @__PURE__ */ jsxs7(Text9, { children: [
|
|
1758
1865
|
"Tool:",
|
|
1759
1866
|
" ",
|
|
1760
|
-
/* @__PURE__ */ jsx8(
|
|
1867
|
+
/* @__PURE__ */ jsx8(Text9, { color: "cyan", bold: true, children: request.toolName })
|
|
1761
1868
|
] }),
|
|
1762
|
-
/* @__PURE__ */
|
|
1869
|
+
/* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
|
|
1763
1870
|
" ",
|
|
1764
1871
|
formatArgs(request.toolArgs)
|
|
1765
1872
|
] }),
|
|
1766
|
-
/* @__PURE__ */ jsx8(
|
|
1873
|
+
/* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: OPTIONS.map((opt, i) => /* @__PURE__ */ jsx8(Box7, { marginRight: 2, children: /* @__PURE__ */ jsxs7(Text9, { color: i === selected ? "cyan" : void 0, bold: i === selected, children: [
|
|
1767
1874
|
i === selected ? "> " : " ",
|
|
1768
1875
|
opt
|
|
1769
1876
|
] }) }, opt)) }),
|
|
1770
|
-
/* @__PURE__ */ jsx8(
|
|
1877
|
+
/* @__PURE__ */ jsx8(Text9, { dimColor: true, children: " left/right to select, Enter to confirm" })
|
|
1771
1878
|
] });
|
|
1772
1879
|
}
|
|
1773
1880
|
|
|
1774
1881
|
// src/ui/StreamingIndicator.tsx
|
|
1775
|
-
import { Box as
|
|
1776
|
-
import { jsx as jsx9, jsxs as
|
|
1882
|
+
import { Box as Box8, Text as Text10 } from "ink";
|
|
1883
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1777
1884
|
function getToolStyle(t) {
|
|
1778
1885
|
if (t.isRunning) return { color: "yellow", icon: "\u27F3", strikethrough: false };
|
|
1779
1886
|
if (t.result === "error") return { color: "red", icon: "\u2717", strikethrough: true };
|
|
@@ -1784,35 +1891,38 @@ function StreamingIndicator({ text, activeTools }) {
|
|
|
1784
1891
|
const hasTools = activeTools.length > 0;
|
|
1785
1892
|
const hasText = text.length > 0;
|
|
1786
1893
|
if (!hasTools && !hasText) {
|
|
1787
|
-
return /* @__PURE__ */ jsx9(
|
|
1894
|
+
return /* @__PURE__ */ jsx9(Text10, { color: "yellow", children: "Thinking..." });
|
|
1788
1895
|
}
|
|
1789
|
-
return /* @__PURE__ */
|
|
1790
|
-
hasTools && /* @__PURE__ */
|
|
1791
|
-
/* @__PURE__ */ jsx9(
|
|
1792
|
-
/* @__PURE__ */ jsx9(
|
|
1896
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1897
|
+
hasTools && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginBottom: 1, children: [
|
|
1898
|
+
/* @__PURE__ */ jsx9(Text10, { color: "white", bold: true, children: "Tools:" }),
|
|
1899
|
+
/* @__PURE__ */ jsx9(Text10, { children: " " }),
|
|
1793
1900
|
activeTools.map((t, i) => {
|
|
1794
1901
|
const { color, icon, strikethrough } = getToolStyle(t);
|
|
1795
|
-
return /* @__PURE__ */
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1902
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1903
|
+
/* @__PURE__ */ jsxs8(Text10, { color, strikethrough, children: [
|
|
1904
|
+
" ",
|
|
1905
|
+
icon,
|
|
1906
|
+
" ",
|
|
1907
|
+
t.toolName,
|
|
1908
|
+
"(",
|
|
1909
|
+
t.firstArg,
|
|
1910
|
+
")"
|
|
1911
|
+
] }),
|
|
1912
|
+
t.diffLines && t.diffLines.length > 0 && /* @__PURE__ */ jsx9(DiffBlock, { file: t.diffFile, lines: t.diffLines })
|
|
1803
1913
|
] }, `${t.toolName}-${i}`);
|
|
1804
1914
|
})
|
|
1805
1915
|
] }),
|
|
1806
|
-
hasText && /* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */ jsx9(
|
|
1808
|
-
/* @__PURE__ */ jsx9(
|
|
1809
|
-
/* @__PURE__ */ jsx9(
|
|
1916
|
+
hasText && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginBottom: 1, children: [
|
|
1917
|
+
/* @__PURE__ */ jsx9(Text10, { color: "cyan", bold: true, children: "Robota:" }),
|
|
1918
|
+
/* @__PURE__ */ jsx9(Text10, { children: " " }),
|
|
1919
|
+
/* @__PURE__ */ jsx9(Box8, { marginLeft: 2, children: /* @__PURE__ */ jsx9(Text10, { wrap: "wrap", children: renderMarkdown(text) }) })
|
|
1810
1920
|
] })
|
|
1811
1921
|
] });
|
|
1812
1922
|
}
|
|
1813
1923
|
|
|
1814
1924
|
// src/ui/App.tsx
|
|
1815
|
-
import { jsx as jsx10, jsxs as
|
|
1925
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1816
1926
|
var EXIT_DELAY_MS2 = 500;
|
|
1817
1927
|
function mergeHooksIntoConfig(configHooks, pluginHooks) {
|
|
1818
1928
|
const pluginKeys = Object.keys(pluginHooks);
|
|
@@ -1880,23 +1990,23 @@ function App(props) {
|
|
|
1880
1990
|
},
|
|
1881
1991
|
{ isActive: !permissionRequest }
|
|
1882
1992
|
);
|
|
1883
|
-
return /* @__PURE__ */
|
|
1884
|
-
/* @__PURE__ */
|
|
1885
|
-
/* @__PURE__ */ jsx10(
|
|
1993
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
1994
|
+
/* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
1995
|
+
/* @__PURE__ */ jsx10(Text11, { color: "cyan", bold: true, children: `
|
|
1886
1996
|
____ ___ ____ ___ _____ _
|
|
1887
1997
|
| _ \\ / _ \\| __ ) / _ \\_ _|/ \\
|
|
1888
1998
|
| |_) | | | | _ \\| | | || | / _ \\
|
|
1889
1999
|
| _ <| |_| | |_) | |_| || |/ ___ \\
|
|
1890
2000
|
|_| \\_\\\\___/|____/ \\___/ |_/_/ \\_\\
|
|
1891
2001
|
` }),
|
|
1892
|
-
/* @__PURE__ */
|
|
2002
|
+
/* @__PURE__ */ jsxs9(Text11, { dimColor: true, children: [
|
|
1893
2003
|
" v",
|
|
1894
2004
|
props.version ?? "0.0.0"
|
|
1895
2005
|
] })
|
|
1896
2006
|
] }),
|
|
1897
|
-
/* @__PURE__ */
|
|
2007
|
+
/* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
1898
2008
|
/* @__PURE__ */ jsx10(MessageList, { messages }),
|
|
1899
|
-
isThinking && /* @__PURE__ */ jsx10(
|
|
2009
|
+
isThinking && /* @__PURE__ */ jsx10(Box9, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx10(StreamingIndicator, { text: streamingText, activeTools }) })
|
|
1900
2010
|
] }),
|
|
1901
2011
|
permissionRequest && /* @__PURE__ */ jsx10(PermissionPrompt, { request: permissionRequest }),
|
|
1902
2012
|
pendingModelId && /* @__PURE__ */ jsx10(
|
|
@@ -1948,7 +2058,7 @@ function App(props) {
|
|
|
1948
2058
|
registry
|
|
1949
2059
|
}
|
|
1950
2060
|
),
|
|
1951
|
-
/* @__PURE__ */ jsx10(
|
|
2061
|
+
/* @__PURE__ */ jsx10(Text11, { children: " " })
|
|
1952
2062
|
] });
|
|
1953
2063
|
}
|
|
1954
2064
|
|