@ai-setting/roy-agent-cli 1.6.15 → 1.6.16
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/bin/roy-agent.js +546 -100
- package/dist/index.js +546 -100
- package/dist/roy-agent-linux-x64/bin/roy-agent +0 -0
- package/package.json +1 -1
package/dist/bin/roy-agent.js
CHANGED
|
@@ -904,7 +904,7 @@ var init_status_bar = __esm(() => {
|
|
|
904
904
|
var require_package = __commonJS((exports, module) => {
|
|
905
905
|
module.exports = {
|
|
906
906
|
name: "@ai-setting/roy-agent-cli",
|
|
907
|
-
version: "1.6.
|
|
907
|
+
version: "1.6.16",
|
|
908
908
|
type: "module",
|
|
909
909
|
description: "CLI for roy-agent - Non-interactive command execution",
|
|
910
910
|
main: "./dist/index.js",
|
|
@@ -1066,10 +1066,187 @@ function execAsync(cmd, args) {
|
|
|
1066
1066
|
}
|
|
1067
1067
|
var init_clipboard_helper = () => {};
|
|
1068
1068
|
|
|
1069
|
-
// src/commands/
|
|
1069
|
+
// src/commands/ui/commands-registry.ts
|
|
1070
|
+
function filterCommands(query) {
|
|
1071
|
+
const q = query.trim().replace(/^\/+/, "").toLowerCase();
|
|
1072
|
+
if (q === "") {
|
|
1073
|
+
return [...COMMANDS];
|
|
1074
|
+
}
|
|
1075
|
+
return COMMANDS.filter((c) => {
|
|
1076
|
+
const cmdName = c.cmd.replace(/^\/+/, "").toLowerCase();
|
|
1077
|
+
if (cmdName.startsWith(q))
|
|
1078
|
+
return true;
|
|
1079
|
+
if (cmdName.includes(q))
|
|
1080
|
+
return true;
|
|
1081
|
+
if (c.aliases) {
|
|
1082
|
+
for (const a of c.aliases) {
|
|
1083
|
+
if (a.toLowerCase().startsWith(q))
|
|
1084
|
+
return true;
|
|
1085
|
+
if (a.toLowerCase().includes(q))
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
return false;
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
var COMMANDS, MAX_POPUP_ITEMS = 8;
|
|
1093
|
+
var init_commands_registry = __esm(() => {
|
|
1094
|
+
COMMANDS = [
|
|
1095
|
+
{ cmd: "/help", desc: "Show all commands", category: "general", aliases: ["h"] },
|
|
1096
|
+
{ cmd: "/quit", desc: "Exit interactive mode", category: "general", aliases: ["q", "exit"] },
|
|
1097
|
+
{ cmd: "/init", desc: "Create memory file", category: "memory" },
|
|
1098
|
+
{ cmd: "/memory", desc: "Show memory", category: "memory" },
|
|
1099
|
+
{ cmd: "/model", desc: "Switch model", category: "model" },
|
|
1100
|
+
{ cmd: "/compact", desc: "Compress context", category: "session", aliases: ["c"] },
|
|
1101
|
+
{ cmd: "/sessions", desc: "List sessions", category: "session", aliases: ["s"] },
|
|
1102
|
+
{ cmd: "/attach", desc: "Add file/URL to attach", category: "attachment" },
|
|
1103
|
+
{ cmd: "/list", desc: "List attachments", category: "attachment" },
|
|
1104
|
+
{ cmd: "/paste", desc: "Paste from clipboard", category: "attachment" },
|
|
1105
|
+
{ cmd: "/clear", desc: "Clear attach list", category: "attachment", aliases: ["cls"] },
|
|
1106
|
+
{ cmd: "/status", desc: "Show session status", category: "system", aliases: ["st"] },
|
|
1107
|
+
{ cmd: "/abort", desc: "Abort in-flight request", category: "system" }
|
|
1108
|
+
];
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
// src/commands/ui/slash-command-popup.tsx
|
|
1070
1112
|
import * as React from "react";
|
|
1071
|
-
import { Box, Text } from "ink";
|
|
1113
|
+
import { Box, Text, useInput } from "ink";
|
|
1114
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
1115
|
+
function clampSelectedIndex(index, filteredLength) {
|
|
1116
|
+
if (filteredLength === 0)
|
|
1117
|
+
return 0;
|
|
1118
|
+
return Math.max(0, Math.min(filteredLength - 1, index));
|
|
1119
|
+
}
|
|
1120
|
+
var CommandRow, SlashCommandPopup;
|
|
1121
|
+
var init_slash_command_popup = __esm(() => {
|
|
1122
|
+
init_commands_registry();
|
|
1123
|
+
CommandRow = React.memo(function CommandRow2({
|
|
1124
|
+
cmd,
|
|
1125
|
+
isSelected
|
|
1126
|
+
}) {
|
|
1127
|
+
const cmdPadded = cmd.cmd.padEnd(12, " ");
|
|
1128
|
+
if (isSelected) {
|
|
1129
|
+
return /* @__PURE__ */ jsxDEV(Text, {
|
|
1130
|
+
inverse: true,
|
|
1131
|
+
children: [
|
|
1132
|
+
"▶ ",
|
|
1133
|
+
cmdPadded,
|
|
1134
|
+
cmd.desc
|
|
1135
|
+
]
|
|
1136
|
+
}, cmd.cmd, true, undefined, this);
|
|
1137
|
+
}
|
|
1138
|
+
return /* @__PURE__ */ jsxDEV(Text, {
|
|
1139
|
+
children: [
|
|
1140
|
+
" ",
|
|
1141
|
+
cmdPadded,
|
|
1142
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
1143
|
+
color: "gray",
|
|
1144
|
+
children: cmd.desc
|
|
1145
|
+
}, undefined, false, undefined, this)
|
|
1146
|
+
]
|
|
1147
|
+
}, cmd.cmd, true, undefined, this);
|
|
1148
|
+
});
|
|
1149
|
+
SlashCommandPopup = React.memo(function SlashCommandPopup2({
|
|
1150
|
+
query,
|
|
1151
|
+
selectedIndex: externalSelectedIndex,
|
|
1152
|
+
onIndexChange,
|
|
1153
|
+
onSelect,
|
|
1154
|
+
onClose
|
|
1155
|
+
}) {
|
|
1156
|
+
const filtered = React.useMemo(() => filterCommands(query), [query]);
|
|
1157
|
+
const [internalSelectedIndex, setInternalSelectedIndex] = React.useState(() => externalSelectedIndex ?? 0);
|
|
1158
|
+
React.useEffect(() => {
|
|
1159
|
+
if (externalSelectedIndex !== undefined && externalSelectedIndex !== internalSelectedIndex) {
|
|
1160
|
+
setInternalSelectedIndex(externalSelectedIndex);
|
|
1161
|
+
}
|
|
1162
|
+
}, [externalSelectedIndex, internalSelectedIndex]);
|
|
1163
|
+
const updateIndex = React.useCallback((next) => {
|
|
1164
|
+
setInternalSelectedIndex(next);
|
|
1165
|
+
onIndexChange?.(next);
|
|
1166
|
+
}, [onIndexChange]);
|
|
1167
|
+
React.useEffect(() => {
|
|
1168
|
+
if (filtered.length === 0)
|
|
1169
|
+
return;
|
|
1170
|
+
if (internalSelectedIndex >= filtered.length) {
|
|
1171
|
+
updateIndex(0);
|
|
1172
|
+
}
|
|
1173
|
+
}, [filtered, internalSelectedIndex, updateIndex]);
|
|
1174
|
+
useInput((input, key) => {
|
|
1175
|
+
if (key.upArrow) {
|
|
1176
|
+
if (filtered.length === 0)
|
|
1177
|
+
return;
|
|
1178
|
+
updateIndex((internalSelectedIndex - 1 + filtered.length) % filtered.length);
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
if (key.downArrow) {
|
|
1182
|
+
if (filtered.length === 0)
|
|
1183
|
+
return;
|
|
1184
|
+
updateIndex((internalSelectedIndex + 1) % filtered.length);
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
if (key.return && !key.meta && !key.shift && !key.ctrl) {
|
|
1188
|
+
const cmd = filtered[internalSelectedIndex];
|
|
1189
|
+
if (cmd && onSelect) {
|
|
1190
|
+
onSelect(cmd);
|
|
1191
|
+
}
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
if (key.tab) {
|
|
1195
|
+
const cmd = filtered[internalSelectedIndex];
|
|
1196
|
+
if (cmd && onSelect) {
|
|
1197
|
+
onSelect(cmd);
|
|
1198
|
+
}
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
if (key.escape) {
|
|
1202
|
+
if (onClose) {
|
|
1203
|
+
onClose();
|
|
1204
|
+
}
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
}, { isActive: filtered.length > 0 });
|
|
1208
|
+
if (filtered.length === 0) {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
const selectedIndex = Math.max(0, Math.min(filtered.length - 1, internalSelectedIndex));
|
|
1212
|
+
const filteredLength = filtered.length;
|
|
1213
|
+
const scrollOffset = filteredLength <= MAX_POPUP_ITEMS ? 0 : Math.max(0, Math.min(filteredLength - MAX_POPUP_ITEMS, selectedIndex - 3));
|
|
1214
|
+
const visible = filtered.slice(scrollOffset, scrollOffset + MAX_POPUP_ITEMS);
|
|
1215
|
+
const hiddenBefore = scrollOffset;
|
|
1216
|
+
const hiddenAfter = filteredLength - (scrollOffset + visible.length);
|
|
1217
|
+
const windowedIndex = selectedIndex - scrollOffset;
|
|
1218
|
+
return /* @__PURE__ */ jsxDEV(Box, {
|
|
1219
|
+
flexDirection: "column",
|
|
1220
|
+
borderStyle: "single",
|
|
1221
|
+
borderColor: "cyan",
|
|
1222
|
+
paddingX: 1,
|
|
1223
|
+
marginBottom: 0,
|
|
1224
|
+
children: [
|
|
1225
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
1226
|
+
color: "gray",
|
|
1227
|
+
dimColor: true,
|
|
1228
|
+
children: [
|
|
1229
|
+
"Commands (",
|
|
1230
|
+
filteredLength,
|
|
1231
|
+
")",
|
|
1232
|
+
hiddenBefore > 0 ? ` · ${hiddenBefore} more ↑` : "",
|
|
1233
|
+
hiddenAfter > 0 ? ` · ${hiddenAfter} more ↓` : ""
|
|
1234
|
+
]
|
|
1235
|
+
}, undefined, true, undefined, this),
|
|
1236
|
+
visible.map((cmd, i) => /* @__PURE__ */ jsxDEV(CommandRow, {
|
|
1237
|
+
cmd,
|
|
1238
|
+
isSelected: i === windowedIndex
|
|
1239
|
+
}, cmd.cmd, false, undefined, this))
|
|
1240
|
+
]
|
|
1241
|
+
}, undefined, true, undefined, this);
|
|
1242
|
+
});
|
|
1243
|
+
});
|
|
1244
|
+
|
|
1245
|
+
// src/commands/markdown-renderer.tsx
|
|
1246
|
+
import * as React2 from "react";
|
|
1247
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
1072
1248
|
import chalk6 from "chalk";
|
|
1249
|
+
import { wrapFunction } from "@ai-setting/roy-agent-core";
|
|
1073
1250
|
function parseInline(text, keyPrefix) {
|
|
1074
1251
|
const nodes = [];
|
|
1075
1252
|
const pattern = /(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)|(~~([^~]+)~~)|(\[([^\]]+)\]\(([^)]+)\))/g;
|
|
@@ -1078,30 +1255,144 @@ function parseInline(text, keyPrefix) {
|
|
|
1078
1255
|
let counter = 0;
|
|
1079
1256
|
while ((match = pattern.exec(text)) !== null) {
|
|
1080
1257
|
if (match.index > lastIndex) {
|
|
1081
|
-
nodes.push(
|
|
1258
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-t-${counter++}` }, text.slice(lastIndex, match.index)));
|
|
1082
1259
|
}
|
|
1083
1260
|
if (match[1] !== undefined) {
|
|
1084
|
-
nodes.push(
|
|
1261
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-c-${counter++}`, color: "white", backgroundColor: "gray" }, ` ${match[2]} `));
|
|
1085
1262
|
} else if (match[3] !== undefined) {
|
|
1086
|
-
nodes.push(
|
|
1263
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-b-${counter++}`, color: "yellow", bold: true }, match[4]));
|
|
1087
1264
|
} else if (match[5] !== undefined) {
|
|
1088
|
-
nodes.push(
|
|
1265
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-i-${counter++}`, color: "yellow" }, match[6]));
|
|
1089
1266
|
} else if (match[7] !== undefined) {
|
|
1090
|
-
nodes.push(
|
|
1267
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-s-${counter++}`, dimColor: true }, match[8]));
|
|
1091
1268
|
} else if (match[9] !== undefined) {
|
|
1092
|
-
nodes.push(
|
|
1269
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-l-${counter++}`, color: "cyan", underline: true }, match[10]), React2.createElement(Text2, { key: `${keyPrefix}-u-${counter++}`, color: "blue", dimColor: true }, ` (${match[11]})`));
|
|
1093
1270
|
}
|
|
1094
1271
|
lastIndex = pattern.lastIndex;
|
|
1095
1272
|
}
|
|
1096
1273
|
if (lastIndex < text.length) {
|
|
1097
|
-
nodes.push(
|
|
1274
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-e-${counter++}` }, text.slice(lastIndex)));
|
|
1098
1275
|
}
|
|
1099
1276
|
if (nodes.length === 0) {
|
|
1100
|
-
nodes.push(
|
|
1277
|
+
nodes.push(React2.createElement(Text2, { key: `${keyPrefix}-all` }, text));
|
|
1101
1278
|
}
|
|
1102
1279
|
return nodes;
|
|
1103
1280
|
}
|
|
1104
|
-
function
|
|
1281
|
+
function splitTableRow(rawLine) {
|
|
1282
|
+
let s = rawLine.trim();
|
|
1283
|
+
if (s.startsWith("|"))
|
|
1284
|
+
s = s.slice(1);
|
|
1285
|
+
if (s.endsWith("|") && !s.endsWith("\\|"))
|
|
1286
|
+
s = s.slice(0, -1);
|
|
1287
|
+
return s.split("|").map((c) => c.trim());
|
|
1288
|
+
}
|
|
1289
|
+
function isTableSeparator(line) {
|
|
1290
|
+
const trimmed = line.trim();
|
|
1291
|
+
if (!trimmed.includes("|"))
|
|
1292
|
+
return false;
|
|
1293
|
+
const cells = splitTableRow(trimmed);
|
|
1294
|
+
if (cells.length === 0)
|
|
1295
|
+
return false;
|
|
1296
|
+
return cells.every((c) => /^:?\s*-{1,}\s*:?$/.test(c));
|
|
1297
|
+
}
|
|
1298
|
+
function parseAlignments(sepCells) {
|
|
1299
|
+
return sepCells.map((c) => {
|
|
1300
|
+
const t = c.trim();
|
|
1301
|
+
const startsColon = t.startsWith(":");
|
|
1302
|
+
const endsColon = t.endsWith(":");
|
|
1303
|
+
if (startsColon && endsColon)
|
|
1304
|
+
return "center";
|
|
1305
|
+
if (endsColon)
|
|
1306
|
+
return "right";
|
|
1307
|
+
if (startsColon)
|
|
1308
|
+
return "left";
|
|
1309
|
+
return "left";
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
function padCell(content, width, align) {
|
|
1313
|
+
const len = content.length;
|
|
1314
|
+
if (len >= width)
|
|
1315
|
+
return content;
|
|
1316
|
+
const totalPad = width - len;
|
|
1317
|
+
if (align === "right")
|
|
1318
|
+
return " ".repeat(totalPad) + content;
|
|
1319
|
+
if (align === "center") {
|
|
1320
|
+
const left = Math.floor(totalPad / 2);
|
|
1321
|
+
const right = totalPad - left;
|
|
1322
|
+
return " ".repeat(left) + content + " ".repeat(right);
|
|
1323
|
+
}
|
|
1324
|
+
return content + " ".repeat(totalPad);
|
|
1325
|
+
}
|
|
1326
|
+
function parseTableStart(lines, i) {
|
|
1327
|
+
const header = lines[i] ?? "";
|
|
1328
|
+
const sep = lines[i + 1] ?? "";
|
|
1329
|
+
if (!header.trim().startsWith("|"))
|
|
1330
|
+
return false;
|
|
1331
|
+
if (!header.trim().includes("|"))
|
|
1332
|
+
return false;
|
|
1333
|
+
if (!isTableSeparator(sep))
|
|
1334
|
+
return false;
|
|
1335
|
+
return true;
|
|
1336
|
+
}
|
|
1337
|
+
function parseTableBlock(lines, startIndex) {
|
|
1338
|
+
if (!parseTableStart(lines, startIndex))
|
|
1339
|
+
return null;
|
|
1340
|
+
const header = splitTableRow(lines[startIndex] ?? "");
|
|
1341
|
+
const alignments = parseAlignments(splitTableRow(lines[startIndex + 1] ?? ""));
|
|
1342
|
+
const rows = [];
|
|
1343
|
+
let i = startIndex + 2;
|
|
1344
|
+
while (i < lines.length) {
|
|
1345
|
+
const ln = lines[i] ?? "";
|
|
1346
|
+
if (ln.trim() === "")
|
|
1347
|
+
break;
|
|
1348
|
+
if (!ln.trim().startsWith("|"))
|
|
1349
|
+
break;
|
|
1350
|
+
rows.push(splitTableRow(ln));
|
|
1351
|
+
i++;
|
|
1352
|
+
}
|
|
1353
|
+
return { header, rows, alignments, endIndex: i };
|
|
1354
|
+
}
|
|
1355
|
+
function renderTableBlock(tbl, key) {
|
|
1356
|
+
const colCount = Math.max(tbl.header.length, ...tbl.rows.map((r) => r.length));
|
|
1357
|
+
const widths = [];
|
|
1358
|
+
for (let c = 0;c < colCount; c++) {
|
|
1359
|
+
const headerW = (tbl.header[c] ?? "").length;
|
|
1360
|
+
let dataW = 0;
|
|
1361
|
+
for (const r of tbl.rows) {
|
|
1362
|
+
const cell = r[c] ?? "";
|
|
1363
|
+
if (cell.length > dataW)
|
|
1364
|
+
dataW = cell.length;
|
|
1365
|
+
}
|
|
1366
|
+
widths.push(Math.max(headerW, dataW));
|
|
1367
|
+
}
|
|
1368
|
+
const alignments = [];
|
|
1369
|
+
for (let c = 0;c < colCount; c++) {
|
|
1370
|
+
alignments.push(tbl.alignments[c] ?? "left");
|
|
1371
|
+
}
|
|
1372
|
+
const renderRow = (cells, rowIdx) => {
|
|
1373
|
+
const cellNodes = [];
|
|
1374
|
+
for (let c = 0;c < colCount; c++) {
|
|
1375
|
+
const raw = cells[c] ?? "";
|
|
1376
|
+
const w = widths[c] ?? raw.length;
|
|
1377
|
+
const align = alignments[c] ?? "left";
|
|
1378
|
+
const padded = padCell(raw, w, align);
|
|
1379
|
+
cellNodes.push(React2.createElement(Box2, { key: `tbl-${rowIdx}-c${c}`, flexDirection: "row" }, ...parseInline(padded, `tbl-${rowIdx}-c${c}`)));
|
|
1380
|
+
if (c < colCount - 1) {
|
|
1381
|
+
cellNodes.push(React2.createElement(Text2, { key: `tbl-${rowIdx}-sep${c}`, color: "gray" }, " │ "));
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
return React2.createElement(Box2, { key: `tbl-${rowIdx}`, flexDirection: "row" }, React2.createElement(Text2, { color: "gray" }, "│ "), ...cellNodes, React2.createElement(Text2, { color: "gray" }, " │"));
|
|
1385
|
+
};
|
|
1386
|
+
const children = [];
|
|
1387
|
+
children.push(renderRow(tbl.header, 0));
|
|
1388
|
+
const sepLine = "├" + widths.map((w) => "─".repeat(w + 2)).join("┼") + "┤";
|
|
1389
|
+
children.push(React2.createElement(Text2, { key: "tbl-sep", color: "gray" }, sepLine));
|
|
1390
|
+
tbl.rows.forEach((r, ri) => {
|
|
1391
|
+
children.push(renderRow(r, ri + 1));
|
|
1392
|
+
});
|
|
1393
|
+
return React2.createElement(Box2, { key, flexDirection: "column", marginY: 1 }, ...children);
|
|
1394
|
+
}
|
|
1395
|
+
function renderMarkdownLegacyImpl(content) {
|
|
1105
1396
|
const lines = content.split(`
|
|
1106
1397
|
`);
|
|
1107
1398
|
const blocks = [];
|
|
@@ -1117,19 +1408,19 @@ function renderMarkdown(content) {
|
|
|
1117
1408
|
i++;
|
|
1118
1409
|
}
|
|
1119
1410
|
i++;
|
|
1120
|
-
blocks.push(
|
|
1411
|
+
blocks.push(React2.createElement(Box2, {
|
|
1121
1412
|
key: `blk-code-${blockKey++}`,
|
|
1122
1413
|
flexDirection: "column",
|
|
1123
1414
|
borderStyle: "single",
|
|
1124
1415
|
borderColor: "gray",
|
|
1125
1416
|
paddingX: 1,
|
|
1126
1417
|
marginY: 1
|
|
1127
|
-
},
|
|
1418
|
+
}, React2.createElement(Text2, { color: "white" }, codeLines.length === 0 ? " " : codeLines.join(`
|
|
1128
1419
|
`))));
|
|
1129
1420
|
continue;
|
|
1130
1421
|
}
|
|
1131
1422
|
if (/^(-{3,}|\*{3,})$/.test(line.trim())) {
|
|
1132
|
-
blocks.push(
|
|
1423
|
+
blocks.push(React2.createElement(Box2, { key: `blk-hr-${blockKey++}`, marginY: 1 }, React2.createElement(Text2, { color: "gray" }, "─".repeat(50))));
|
|
1133
1424
|
i++;
|
|
1134
1425
|
continue;
|
|
1135
1426
|
}
|
|
@@ -1139,10 +1430,10 @@ function renderMarkdown(content) {
|
|
|
1139
1430
|
const text = headingMatch[2];
|
|
1140
1431
|
if (level === 1) {
|
|
1141
1432
|
const styled = chalk6.cyan.bold.underline(`▌ ${text}`);
|
|
1142
|
-
blocks.push(
|
|
1433
|
+
blocks.push(React2.createElement(Box2, { key: `blk-h1-${blockKey++}`, marginY: 1 }, React2.createElement(Text2, {}, styled)));
|
|
1143
1434
|
} else if (level === 2) {
|
|
1144
1435
|
const styled = chalk6.green.bold(`▶ ${text}`);
|
|
1145
|
-
blocks.push(
|
|
1436
|
+
blocks.push(React2.createElement(Box2, { key: `blk-h2-${blockKey++}`, marginY: 1 }, React2.createElement(Text2, {}, styled)));
|
|
1146
1437
|
} else {
|
|
1147
1438
|
const colors = {
|
|
1148
1439
|
3: "yellow",
|
|
@@ -1152,7 +1443,7 @@ function renderMarkdown(content) {
|
|
|
1152
1443
|
};
|
|
1153
1444
|
const color = colors[level] ?? "white";
|
|
1154
1445
|
const prefix = "▶".repeat(level - 1) + " ";
|
|
1155
|
-
blocks.push(
|
|
1446
|
+
blocks.push(React2.createElement(Box2, { key: `blk-h-${blockKey++}`, marginY: 1 }, React2.createElement(Text2, { color, bold: true }, `${prefix}${text}`)));
|
|
1156
1447
|
}
|
|
1157
1448
|
i++;
|
|
1158
1449
|
continue;
|
|
@@ -1163,7 +1454,7 @@ function renderMarkdown(content) {
|
|
|
1163
1454
|
quoteLines.push((lines[i] ?? "").replace(/^>\s?/, ""));
|
|
1164
1455
|
i++;
|
|
1165
1456
|
}
|
|
1166
|
-
blocks.push(
|
|
1457
|
+
blocks.push(React2.createElement(Box2, {
|
|
1167
1458
|
key: `blk-q-${blockKey++}`,
|
|
1168
1459
|
flexDirection: "column",
|
|
1169
1460
|
marginLeft: 2,
|
|
@@ -1174,7 +1465,7 @@ function renderMarkdown(content) {
|
|
|
1174
1465
|
borderRight: false,
|
|
1175
1466
|
borderBottom: false,
|
|
1176
1467
|
paddingLeft: 1
|
|
1177
|
-
}, ...quoteLines.map((ql, qi) =>
|
|
1468
|
+
}, ...quoteLines.map((ql, qi) => React2.createElement(Box2, { key: `q-${qi}` }, React2.createElement(Text2, { color: "gray", dimColor: true }, ql)))));
|
|
1178
1469
|
continue;
|
|
1179
1470
|
}
|
|
1180
1471
|
if (/^[-*]\s+/.test(line)) {
|
|
@@ -1183,7 +1474,7 @@ function renderMarkdown(content) {
|
|
|
1183
1474
|
items.push((lines[i] ?? "").replace(/^[-*]\s+/, ""));
|
|
1184
1475
|
i++;
|
|
1185
1476
|
}
|
|
1186
|
-
blocks.push(
|
|
1477
|
+
blocks.push(React2.createElement(Box2, { key: `blk-ul-${blockKey++}`, flexDirection: "column", marginLeft: 2 }, ...items.map((it, ii) => React2.createElement(Box2, { key: `ul-${ii}` }, React2.createElement(Text2, { color: "yellow", bold: true }, "▸ "), ...parseInline(it, `ul-${ii}`)))));
|
|
1187
1478
|
continue;
|
|
1188
1479
|
}
|
|
1189
1480
|
if (/^\d+\.\s+/.test(line)) {
|
|
@@ -1192,9 +1483,17 @@ function renderMarkdown(content) {
|
|
|
1192
1483
|
items.push((lines[i] ?? "").replace(/^\d+\.\s+/, ""));
|
|
1193
1484
|
i++;
|
|
1194
1485
|
}
|
|
1195
|
-
blocks.push(
|
|
1486
|
+
blocks.push(React2.createElement(Box2, { key: `blk-ol-${blockKey++}`, flexDirection: "column", marginLeft: 2 }, ...items.map((it, ii) => React2.createElement(Box2, { key: `ol-${ii}` }, React2.createElement(Text2, { color: "cyan", bold: true }, `${(ii + 1).toString().padStart(2, " ")}. `), ...parseInline(it, `ol-${ii}`)))));
|
|
1196
1487
|
continue;
|
|
1197
1488
|
}
|
|
1489
|
+
if (parseTableStart(lines, i)) {
|
|
1490
|
+
const tbl = parseTableBlock(lines, i);
|
|
1491
|
+
if (tbl) {
|
|
1492
|
+
i = tbl.endIndex;
|
|
1493
|
+
blocks.push(renderTableBlock(tbl, `blk-table-${blockKey++}`));
|
|
1494
|
+
continue;
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1198
1497
|
if (line.trim() === "") {
|
|
1199
1498
|
i++;
|
|
1200
1499
|
continue;
|
|
@@ -1205,11 +1504,22 @@ function renderMarkdown(content) {
|
|
|
1205
1504
|
i++;
|
|
1206
1505
|
}
|
|
1207
1506
|
const paraText = paraLines.join(" ");
|
|
1208
|
-
blocks.push(
|
|
1507
|
+
blocks.push(React2.createElement(Box2, { key: `blk-p-${blockKey++}`, marginY: 0 }, ...parseInline(paraText, `p-${blockKey}`)));
|
|
1209
1508
|
}
|
|
1210
1509
|
return blocks;
|
|
1211
1510
|
}
|
|
1212
|
-
var
|
|
1511
|
+
var renderMarkdown;
|
|
1512
|
+
var init_markdown_renderer2 = __esm(() => {
|
|
1513
|
+
renderMarkdown = wrapFunction(renderMarkdownLegacyImpl, "markdown.render", {
|
|
1514
|
+
recordParams: true,
|
|
1515
|
+
recordResult: false,
|
|
1516
|
+
paramFilter: (args) => ({
|
|
1517
|
+
"content.length": (args?.[0] && typeof args[0] === "string" ? args[0].length : 0) ?? 0,
|
|
1518
|
+
"content.first-line": (args?.[0] && typeof args[0] === "string" ? args[0].split(`
|
|
1519
|
+
`)[0]?.slice(0, 60) : "") ?? ""
|
|
1520
|
+
})
|
|
1521
|
+
});
|
|
1522
|
+
});
|
|
1213
1523
|
|
|
1214
1524
|
// src/commands/repl-ink.tsx
|
|
1215
1525
|
var exports_repl_ink = {};
|
|
@@ -1218,10 +1528,10 @@ __export(exports_repl_ink, {
|
|
|
1218
1528
|
REPLInk: () => REPLInk,
|
|
1219
1529
|
MultilineInput: () => MultilineInput
|
|
1220
1530
|
});
|
|
1221
|
-
import * as
|
|
1222
|
-
import { Box as
|
|
1531
|
+
import * as React3 from "react";
|
|
1532
|
+
import { Box as Box3, Text as Text3, Static, useApp, useInput as useInput2 } from "ink";
|
|
1223
1533
|
import { createLogger as createLogger4 } from "@ai-setting/roy-agent-core";
|
|
1224
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
1534
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
1225
1535
|
function REPLInk(props) {
|
|
1226
1536
|
const {
|
|
1227
1537
|
initialContext,
|
|
@@ -1234,19 +1544,55 @@ function REPLInk(props) {
|
|
|
1234
1544
|
onEscape
|
|
1235
1545
|
} = props;
|
|
1236
1546
|
const { exit: appExit } = useApp();
|
|
1237
|
-
const [messages, setMessages] =
|
|
1238
|
-
|
|
1239
|
-
|
|
1547
|
+
const [messages, setMessages] = React3.useState(() => [
|
|
1548
|
+
{
|
|
1549
|
+
role: "system",
|
|
1550
|
+
kind: "welcome",
|
|
1551
|
+
content: buildWelcomeCardText(initialContext)
|
|
1552
|
+
},
|
|
1553
|
+
...initialMessages
|
|
1554
|
+
]);
|
|
1555
|
+
const [mode, setMode] = React3.useState(initialMode);
|
|
1556
|
+
const [statusBarCtx, setStatusBarCtxState] = React3.useState({
|
|
1240
1557
|
mode: initialMode,
|
|
1241
1558
|
cwd: initialStatusBarCtx.cwd ?? initialContext.cwd,
|
|
1242
1559
|
gitBranch: initialStatusBarCtx.gitBranch,
|
|
1243
1560
|
model: initialStatusBarCtx.model ?? initialContext.model
|
|
1244
1561
|
});
|
|
1245
|
-
const
|
|
1246
|
-
const
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1562
|
+
const [inputValue, setInputValue] = React3.useState("");
|
|
1563
|
+
const [popupIndex, setPopupIndex] = React3.useState(0);
|
|
1564
|
+
const filteredCmds = React3.useMemo(() => {
|
|
1565
|
+
if (!/^\/\S*$/.test(inputValue))
|
|
1566
|
+
return [];
|
|
1567
|
+
return filterCommands(inputValue);
|
|
1568
|
+
}, [inputValue]);
|
|
1569
|
+
const showPopup = filteredCmds.length > 0;
|
|
1570
|
+
React3.useEffect(() => {
|
|
1571
|
+
setPopupIndex(0);
|
|
1572
|
+
}, [filteredCmds]);
|
|
1573
|
+
const safePopupIndex = clampSelectedIndex(popupIndex, filteredCmds.length);
|
|
1574
|
+
const handlePopupSelect = React3.useCallback((cmd) => {
|
|
1575
|
+
multilineInputRef.current?.setBuffer(cmd.cmd + " ");
|
|
1576
|
+
setInputValue(cmd.cmd + " ");
|
|
1577
|
+
}, []);
|
|
1578
|
+
const handlePopupClose = React3.useCallback(() => {
|
|
1579
|
+
const current = multilineInputRef.current?.getBuffer() ?? "";
|
|
1580
|
+
const stripped = current.replace(/^\/+/, "");
|
|
1581
|
+
multilineInputRef.current?.setBuffer(stripped);
|
|
1582
|
+
setInputValue(stripped);
|
|
1583
|
+
}, []);
|
|
1584
|
+
const handlePopupIndexChange = React3.useCallback((idx) => {
|
|
1585
|
+
setPopupIndex(idx);
|
|
1586
|
+
}, []);
|
|
1587
|
+
const streamingIndexRef = React3.useRef(-1);
|
|
1588
|
+
const lastFlushTsRef = React3.useRef(0);
|
|
1589
|
+
const STALE_STREAM_THRESHOLD_MS = 1000;
|
|
1590
|
+
const multilineInputRef = React3.useRef(null);
|
|
1591
|
+
const lastEscapeTsRef = React3.useRef(0);
|
|
1592
|
+
const pendingDeltaRef = React3.useRef("");
|
|
1593
|
+
const throttleTimerRef = React3.useRef(null);
|
|
1594
|
+
const isFirstDeltaInStreamRef = React3.useRef(true);
|
|
1595
|
+
const flushStreamingDelta = React3.useCallback(() => {
|
|
1250
1596
|
const delta = pendingDeltaRef.current;
|
|
1251
1597
|
pendingDeltaRef.current = "";
|
|
1252
1598
|
throttleTimerRef.current = null;
|
|
@@ -1260,6 +1606,11 @@ function REPLInk(props) {
|
|
|
1260
1606
|
break;
|
|
1261
1607
|
}
|
|
1262
1608
|
}
|
|
1609
|
+
if (idx !== -1 && Date.now() - lastFlushTsRef.current > STALE_STREAM_THRESHOLD_MS) {
|
|
1610
|
+
const updated2 = [...msgs];
|
|
1611
|
+
updated2[idx] = { ...updated2[idx], streaming: false };
|
|
1612
|
+
idx = -1;
|
|
1613
|
+
}
|
|
1263
1614
|
if (idx === -1) {
|
|
1264
1615
|
streamingIndexRef.current = msgs.length;
|
|
1265
1616
|
return [...msgs, { role: "assistant", content: delta, streaming: true }];
|
|
@@ -1268,8 +1619,9 @@ function REPLInk(props) {
|
|
|
1268
1619
|
updated[idx] = { ...updated[idx], content: updated[idx].content + delta };
|
|
1269
1620
|
return updated;
|
|
1270
1621
|
});
|
|
1622
|
+
lastFlushTsRef.current = Date.now();
|
|
1271
1623
|
}, []);
|
|
1272
|
-
|
|
1624
|
+
React3.useEffect(() => {
|
|
1273
1625
|
return () => {
|
|
1274
1626
|
if (throttleTimerRef.current !== null) {
|
|
1275
1627
|
clearTimeout(throttleTimerRef.current);
|
|
@@ -1277,8 +1629,8 @@ function REPLInk(props) {
|
|
|
1277
1629
|
}
|
|
1278
1630
|
};
|
|
1279
1631
|
}, []);
|
|
1280
|
-
const apiRef =
|
|
1281
|
-
|
|
1632
|
+
const apiRef = React3.useRef(null);
|
|
1633
|
+
React3.useEffect(() => {
|
|
1282
1634
|
const api = {
|
|
1283
1635
|
appendMessage: (msg) => {
|
|
1284
1636
|
setMessages((msgs) => [...msgs, msg]);
|
|
@@ -1288,7 +1640,12 @@ function REPLInk(props) {
|
|
|
1288
1640
|
return;
|
|
1289
1641
|
pendingDeltaRef.current += delta;
|
|
1290
1642
|
if (throttleTimerRef.current === null) {
|
|
1291
|
-
|
|
1643
|
+
if (isFirstDeltaInStreamRef.current) {
|
|
1644
|
+
isFirstDeltaInStreamRef.current = false;
|
|
1645
|
+
flushStreamingDelta();
|
|
1646
|
+
} else {
|
|
1647
|
+
throttleTimerRef.current = setTimeout(flushStreamingDelta, 50);
|
|
1648
|
+
}
|
|
1292
1649
|
}
|
|
1293
1650
|
},
|
|
1294
1651
|
finishAssistantStream: () => {
|
|
@@ -1312,6 +1669,7 @@ function REPLInk(props) {
|
|
|
1312
1669
|
return updated;
|
|
1313
1670
|
});
|
|
1314
1671
|
streamingIndexRef.current = -1;
|
|
1672
|
+
isFirstDeltaInStreamRef.current = true;
|
|
1315
1673
|
},
|
|
1316
1674
|
setMode: (newMode) => {
|
|
1317
1675
|
setMode(newMode);
|
|
@@ -1321,7 +1679,13 @@ function REPLInk(props) {
|
|
|
1321
1679
|
setStatusBarCtxState((s) => ({ ...s, ...ctx }));
|
|
1322
1680
|
},
|
|
1323
1681
|
clearMessages: () => {
|
|
1324
|
-
setMessages([
|
|
1682
|
+
setMessages([
|
|
1683
|
+
{
|
|
1684
|
+
role: "system",
|
|
1685
|
+
kind: "welcome",
|
|
1686
|
+
content: buildWelcomeCardText(initialContext)
|
|
1687
|
+
}
|
|
1688
|
+
]);
|
|
1325
1689
|
},
|
|
1326
1690
|
exit: () => {
|
|
1327
1691
|
appExit();
|
|
@@ -1330,19 +1694,42 @@ function REPLInk(props) {
|
|
|
1330
1694
|
if (onCommand) {
|
|
1331
1695
|
Promise.resolve(onCommand("compact")).catch(() => {});
|
|
1332
1696
|
}
|
|
1697
|
+
},
|
|
1698
|
+
setInputBuffer: (value) => {
|
|
1699
|
+
multilineInputRef.current?.setBuffer(value);
|
|
1700
|
+
setInputValue(value);
|
|
1701
|
+
},
|
|
1702
|
+
getInputBuffer: () => {
|
|
1703
|
+
return multilineInputRef.current?.getBuffer() ?? "";
|
|
1333
1704
|
}
|
|
1334
1705
|
};
|
|
1335
1706
|
apiRef.current = api;
|
|
1336
1707
|
onReady?.(api);
|
|
1337
1708
|
}, [appExit, onCommand, onReady]);
|
|
1338
|
-
|
|
1709
|
+
const handleEscapeCascade = React3.useCallback(() => {
|
|
1710
|
+
const now = Date.now();
|
|
1711
|
+
if (now - lastEscapeTsRef.current < 100) {
|
|
1712
|
+
return;
|
|
1713
|
+
}
|
|
1714
|
+
lastEscapeTsRef.current = now;
|
|
1715
|
+
if (onEscape) {
|
|
1716
|
+
Promise.resolve().then(() => onEscape()).catch((err) => {
|
|
1717
|
+
inkLogger.warn(`[REPLInk] onEscape failed: ${err}`);
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
}, [onEscape]);
|
|
1721
|
+
useInput2((_input, key) => {
|
|
1722
|
+
if (showPopup) {
|
|
1723
|
+
if (key.escape || key.upArrow || key.downArrow || key.tab) {
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
if (key.return && !key.meta && !key.shift && !key.ctrl) {
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1339
1730
|
if (key.escape) {
|
|
1340
1731
|
multilineInputRef.current?.clearBuffer();
|
|
1341
|
-
|
|
1342
|
-
Promise.resolve().then(() => onEscape()).catch((err) => {
|
|
1343
|
-
inkLogger.warn(`[REPLInk] onEscape failed: ${err}`);
|
|
1344
|
-
});
|
|
1345
|
-
}
|
|
1732
|
+
handleEscapeCascade();
|
|
1346
1733
|
}
|
|
1347
1734
|
if (key.ctrl && key.c === true) {
|
|
1348
1735
|
if (onCommand) {
|
|
@@ -1363,7 +1750,7 @@ function REPLInk(props) {
|
|
|
1363
1750
|
}
|
|
1364
1751
|
}
|
|
1365
1752
|
});
|
|
1366
|
-
const handleSubmit =
|
|
1753
|
+
const handleSubmit = React3.useCallback(async (value) => {
|
|
1367
1754
|
if (!value || value.trim() === "") {
|
|
1368
1755
|
return;
|
|
1369
1756
|
}
|
|
@@ -1389,43 +1776,60 @@ function REPLInk(props) {
|
|
|
1389
1776
|
setMessages((msgs) => [...msgs, { role: "system", content: `[Error] ${msg}` }]);
|
|
1390
1777
|
}
|
|
1391
1778
|
}, [onCommand, onSubmit]);
|
|
1779
|
+
const staticItems = React3.useMemo(() => {
|
|
1780
|
+
if (messages.length <= 1)
|
|
1781
|
+
return [];
|
|
1782
|
+
return messages.slice(0, -1);
|
|
1783
|
+
}, [messages.length <= 1 ? 0 : messages.length - 1]);
|
|
1392
1784
|
const statusBarText = buildStatusBar({
|
|
1393
1785
|
mode,
|
|
1394
1786
|
cwd: statusBarCtx.cwd,
|
|
1395
1787
|
gitBranch: statusBarCtx.gitBranch,
|
|
1396
1788
|
model: shortModel(statusBarCtx.model)
|
|
1397
1789
|
});
|
|
1398
|
-
return /* @__PURE__ */
|
|
1790
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1399
1791
|
flexDirection: "column",
|
|
1400
1792
|
children: [
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
/* @__PURE__ */ jsxDEV(Box2, {
|
|
1793
|
+
staticItems.length > 0 ? /* @__PURE__ */ jsxDEV2(Static, {
|
|
1794
|
+
items: staticItems,
|
|
1795
|
+
children: (msg, i) => /* @__PURE__ */ jsxDEV2(MessageView, {
|
|
1796
|
+
msg
|
|
1797
|
+
}, `h-${i}`, false, undefined, this)
|
|
1798
|
+
}, undefined, false, undefined, this) : null,
|
|
1799
|
+
messages.length > 0 ? /* @__PURE__ */ jsxDEV2(MessageView, {
|
|
1800
|
+
msg: messages[messages.length - 1]
|
|
1801
|
+
}, undefined, false, undefined, this) : null,
|
|
1802
|
+
/* @__PURE__ */ jsxDEV2(Box3, {
|
|
1412
1803
|
flexDirection: "column",
|
|
1413
1804
|
marginTop: 1,
|
|
1414
|
-
children: /* @__PURE__ */
|
|
1805
|
+
children: /* @__PURE__ */ jsxDEV2(Text3, {
|
|
1415
1806
|
children: statusBarText
|
|
1416
1807
|
}, undefined, false, undefined, this)
|
|
1417
1808
|
}, undefined, false, undefined, this),
|
|
1418
|
-
/* @__PURE__ */
|
|
1809
|
+
showPopup ? /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1810
|
+
marginBottom: 0,
|
|
1811
|
+
children: /* @__PURE__ */ jsxDEV2(SlashCommandPopup, {
|
|
1812
|
+
query: inputValue,
|
|
1813
|
+
selectedIndex: safePopupIndex,
|
|
1814
|
+
onIndexChange: handlePopupIndexChange,
|
|
1815
|
+
onSelect: handlePopupSelect,
|
|
1816
|
+
onClose: handlePopupClose
|
|
1817
|
+
}, undefined, false, undefined, this)
|
|
1818
|
+
}, undefined, false, undefined, this) : null,
|
|
1819
|
+
/* @__PURE__ */ jsxDEV2(Box3, {
|
|
1419
1820
|
flexDirection: "column",
|
|
1420
1821
|
children: [
|
|
1421
|
-
/* @__PURE__ */
|
|
1822
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1422
1823
|
children: COLORS.muted("─".repeat(40))
|
|
1423
1824
|
}, undefined, false, undefined, this),
|
|
1424
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsxDEV2(MultilineInput, {
|
|
1425
1826
|
ref: multilineInputRef,
|
|
1426
|
-
onSubmit: handleSubmit
|
|
1827
|
+
onSubmit: handleSubmit,
|
|
1828
|
+
onEscape: handleEscapeCascade,
|
|
1829
|
+
popupActive: showPopup,
|
|
1830
|
+
onChange: setInputValue
|
|
1427
1831
|
}, undefined, false, undefined, this),
|
|
1428
|
-
/* @__PURE__ */
|
|
1832
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1429
1833
|
children: COLORS.muted("─".repeat(40))
|
|
1430
1834
|
}, undefined, false, undefined, this)
|
|
1431
1835
|
]
|
|
@@ -1444,7 +1848,7 @@ function shortModel(model) {
|
|
|
1444
1848
|
}
|
|
1445
1849
|
async function renderInkREPL(props) {
|
|
1446
1850
|
const ink = await import("ink");
|
|
1447
|
-
const { waitUntilExit } = ink.render(
|
|
1851
|
+
const { waitUntilExit } = ink.render(React3.createElement(REPLInk, props));
|
|
1448
1852
|
await waitUntilExit();
|
|
1449
1853
|
}
|
|
1450
1854
|
var inkLogger, MultilineInput, MessageView;
|
|
@@ -1452,19 +1856,43 @@ var init_repl_ink = __esm(() => {
|
|
|
1452
1856
|
init_stream_output_service();
|
|
1453
1857
|
init_status_bar();
|
|
1454
1858
|
init_welcome_card();
|
|
1859
|
+
init_commands_registry();
|
|
1860
|
+
init_slash_command_popup();
|
|
1455
1861
|
init_markdown_renderer2();
|
|
1456
1862
|
inkLogger = createLogger4("repl-ink");
|
|
1457
|
-
MultilineInput =
|
|
1458
|
-
const { onSubmit, placeholder } = props;
|
|
1459
|
-
const [buffer, setBuffer] =
|
|
1460
|
-
const [cursor, setCursor] =
|
|
1461
|
-
|
|
1863
|
+
MultilineInput = React3.memo(React3.forwardRef(function MultilineInput2(props, ref) {
|
|
1864
|
+
const { onSubmit, placeholder, popupActive, onChange, onEscape } = props;
|
|
1865
|
+
const [buffer, setBuffer] = React3.useState("");
|
|
1866
|
+
const [cursor, setCursor] = React3.useState(0);
|
|
1867
|
+
React3.useEffect(() => {
|
|
1868
|
+
onChange?.(buffer);
|
|
1869
|
+
}, [buffer, onChange]);
|
|
1870
|
+
React3.useImperativeHandle(ref, () => ({
|
|
1462
1871
|
clearBuffer: () => {
|
|
1463
1872
|
setBuffer("");
|
|
1464
1873
|
setCursor(0);
|
|
1874
|
+
},
|
|
1875
|
+
getBuffer: () => {
|
|
1876
|
+
return buffer;
|
|
1877
|
+
},
|
|
1878
|
+
setBuffer: (value) => {
|
|
1879
|
+
setBuffer(value);
|
|
1880
|
+
setCursor(value.length);
|
|
1881
|
+
}
|
|
1882
|
+
}), [buffer]);
|
|
1883
|
+
useInput2((input, key) => {
|
|
1884
|
+
if (key.escape) {
|
|
1885
|
+
setBuffer("");
|
|
1886
|
+
setCursor(0);
|
|
1887
|
+
if (onEscape) {
|
|
1888
|
+
try {
|
|
1889
|
+
onEscape();
|
|
1890
|
+
} catch (err) {
|
|
1891
|
+
inkLogger.warn(`[MultilineInput] onEscape failed: ${err}`);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
return;
|
|
1465
1895
|
}
|
|
1466
|
-
}), []);
|
|
1467
|
-
useInput((input, key) => {
|
|
1468
1896
|
if (key.return && (key.meta || key.shift || key.ctrl)) {
|
|
1469
1897
|
setBuffer((b) => {
|
|
1470
1898
|
const newBuf = b.slice(0, cursor) + `
|
|
@@ -1475,6 +1903,9 @@ var init_repl_ink = __esm(() => {
|
|
|
1475
1903
|
return;
|
|
1476
1904
|
}
|
|
1477
1905
|
if (key.return) {
|
|
1906
|
+
if (popupActive) {
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1478
1909
|
if (buffer.trim() === "") {
|
|
1479
1910
|
return;
|
|
1480
1911
|
}
|
|
@@ -1624,12 +2055,12 @@ var init_repl_ink = __esm(() => {
|
|
|
1624
2055
|
}
|
|
1625
2056
|
}
|
|
1626
2057
|
const showPlaceholder = buffer.length === 0 && placeholder;
|
|
1627
|
-
return /* @__PURE__ */
|
|
2058
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1628
2059
|
flexDirection: "column",
|
|
1629
2060
|
children: lines.map((line, i) => {
|
|
1630
2061
|
const isFirst = i === 0;
|
|
1631
2062
|
const isCursorRow = i === cursorRow;
|
|
1632
|
-
const prefixEl = /* @__PURE__ */
|
|
2063
|
+
const prefixEl = /* @__PURE__ */ jsxDEV2(Text3, {
|
|
1633
2064
|
color: isFirst ? "red" : "gray",
|
|
1634
2065
|
children: isFirst ? "❯ " : "... "
|
|
1635
2066
|
}, undefined, false, undefined, this);
|
|
@@ -1644,29 +2075,29 @@ var init_repl_ink = __esm(() => {
|
|
|
1644
2075
|
atCursor = line[cursorCol] ?? " ";
|
|
1645
2076
|
afterCursor = line.slice(cursorCol + 1);
|
|
1646
2077
|
}
|
|
1647
|
-
return /* @__PURE__ */
|
|
2078
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1648
2079
|
children: [
|
|
1649
2080
|
prefixEl,
|
|
1650
|
-
/* @__PURE__ */
|
|
2081
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1651
2082
|
children: beforeCursor
|
|
1652
2083
|
}, undefined, false, undefined, this),
|
|
1653
|
-
/* @__PURE__ */
|
|
2084
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1654
2085
|
inverse: !showPlaceholder,
|
|
1655
2086
|
children: atCursor
|
|
1656
2087
|
}, undefined, false, undefined, this),
|
|
1657
|
-
showPlaceholder ? /* @__PURE__ */
|
|
2088
|
+
showPlaceholder ? /* @__PURE__ */ jsxDEV2(Text3, {
|
|
1658
2089
|
color: "gray",
|
|
1659
2090
|
children: placeholder?.slice(1) ?? ""
|
|
1660
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2091
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV2(Text3, {
|
|
1661
2092
|
children: afterCursor
|
|
1662
2093
|
}, undefined, false, undefined, this)
|
|
1663
2094
|
]
|
|
1664
2095
|
}, i, true, undefined, this);
|
|
1665
2096
|
}
|
|
1666
|
-
return /* @__PURE__ */
|
|
2097
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1667
2098
|
children: [
|
|
1668
2099
|
prefixEl,
|
|
1669
|
-
/* @__PURE__ */
|
|
2100
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1670
2101
|
children: line
|
|
1671
2102
|
}, undefined, false, undefined, this)
|
|
1672
2103
|
]
|
|
@@ -1674,7 +2105,15 @@ var init_repl_ink = __esm(() => {
|
|
|
1674
2105
|
})
|
|
1675
2106
|
}, undefined, false, undefined, this);
|
|
1676
2107
|
}));
|
|
1677
|
-
MessageView =
|
|
2108
|
+
MessageView = React3.memo(function MessageView2({ msg }) {
|
|
2109
|
+
if (msg.kind === "welcome") {
|
|
2110
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
2111
|
+
flexDirection: "column",
|
|
2112
|
+
children: /* @__PURE__ */ jsxDEV2(Text3, {
|
|
2113
|
+
children: msg.content
|
|
2114
|
+
}, undefined, false, undefined, this)
|
|
2115
|
+
}, undefined, false, undefined, this);
|
|
2116
|
+
}
|
|
1678
2117
|
let prefix;
|
|
1679
2118
|
let color;
|
|
1680
2119
|
let contentColor;
|
|
@@ -1713,11 +2152,11 @@ var init_repl_ink = __esm(() => {
|
|
|
1713
2152
|
}
|
|
1714
2153
|
const displayContent = msg.role === "tool" || msg.role === "tool_result" ? `${msg.toolName ?? "tool"}: ${msg.content}` : msg.content;
|
|
1715
2154
|
if (msg.role === "assistant") {
|
|
1716
|
-
return /* @__PURE__ */
|
|
2155
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1717
2156
|
flexDirection: "column",
|
|
1718
2157
|
children: [
|
|
1719
|
-
/* @__PURE__ */
|
|
1720
|
-
children: /* @__PURE__ */
|
|
2158
|
+
/* @__PURE__ */ jsxDEV2(Box3, {
|
|
2159
|
+
children: /* @__PURE__ */ jsxDEV2(Text3, {
|
|
1721
2160
|
color: "green",
|
|
1722
2161
|
bold: true,
|
|
1723
2162
|
children: [
|
|
@@ -1726,12 +2165,12 @@ var init_repl_ink = __esm(() => {
|
|
|
1726
2165
|
]
|
|
1727
2166
|
}, undefined, true, undefined, this)
|
|
1728
2167
|
}, undefined, false, undefined, this),
|
|
1729
|
-
/* @__PURE__ */
|
|
2168
|
+
/* @__PURE__ */ jsxDEV2(Box3, {
|
|
1730
2169
|
flexDirection: "column",
|
|
1731
2170
|
marginLeft: 2,
|
|
1732
2171
|
children: [
|
|
1733
2172
|
renderMarkdown(displayContent),
|
|
1734
|
-
msg.streaming ? /* @__PURE__ */
|
|
2173
|
+
msg.streaming ? /* @__PURE__ */ jsxDEV2(Text3, {
|
|
1735
2174
|
color: "gray",
|
|
1736
2175
|
children: "▌"
|
|
1737
2176
|
}, undefined, false, undefined, this) : null
|
|
@@ -1740,9 +2179,9 @@ var init_repl_ink = __esm(() => {
|
|
|
1740
2179
|
]
|
|
1741
2180
|
}, undefined, true, undefined, this);
|
|
1742
2181
|
}
|
|
1743
|
-
return /* @__PURE__ */
|
|
2182
|
+
return /* @__PURE__ */ jsxDEV2(Box3, {
|
|
1744
2183
|
children: [
|
|
1745
|
-
/* @__PURE__ */
|
|
2184
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1746
2185
|
color,
|
|
1747
2186
|
bold: true,
|
|
1748
2187
|
children: [
|
|
@@ -1750,7 +2189,7 @@ var init_repl_ink = __esm(() => {
|
|
|
1750
2189
|
" "
|
|
1751
2190
|
]
|
|
1752
2191
|
}, undefined, true, undefined, this),
|
|
1753
|
-
/* @__PURE__ */
|
|
2192
|
+
/* @__PURE__ */ jsxDEV2(Text3, {
|
|
1754
2193
|
color: contentColor,
|
|
1755
2194
|
children: [
|
|
1756
2195
|
displayContent,
|
|
@@ -12160,6 +12599,13 @@ ${COLORS.error("❌ 执行失败: " + error)}
|
|
|
12160
12599
|
}
|
|
12161
12600
|
}
|
|
12162
12601
|
abortStream();
|
|
12602
|
+
if (this.inkApi && typeof this.inkApi.finishAssistantStream === "function") {
|
|
12603
|
+
try {
|
|
12604
|
+
this.inkApi.finishAssistantStream();
|
|
12605
|
+
} catch (err) {
|
|
12606
|
+
logger4.warn("[Esc] finishAssistantStream failed", { error: String(err) });
|
|
12607
|
+
}
|
|
12608
|
+
}
|
|
12163
12609
|
const mainSessionId = this.options.sessionId;
|
|
12164
12610
|
if (this.env && mainSessionId) {
|
|
12165
12611
|
let timer;
|
|
@@ -21973,9 +22419,9 @@ import chalk73 from "chalk";
|
|
|
21973
22419
|
import fs5 from "fs";
|
|
21974
22420
|
import path8 from "path";
|
|
21975
22421
|
import { createRunWorkflowTool } from "@ai-setting/roy-agent-core/env/workflow/tools";
|
|
21976
|
-
import { getTracerProvider as getTracerProvider4, propagation, wrapFunction } from "@ai-setting/roy-agent-core";
|
|
22422
|
+
import { getTracerProvider as getTracerProvider4, propagation, wrapFunction as wrapFunction2 } from "@ai-setting/roy-agent-core";
|
|
21977
22423
|
import { isValidSessionId } from "@ai-setting/roy-agent-core/env/session";
|
|
21978
|
-
var runWorkflow =
|
|
22424
|
+
var runWorkflow = wrapFunction2(async function runWorkflowImpl(args) {
|
|
21979
22425
|
const output = new OutputService2;
|
|
21980
22426
|
const envService = new EnvironmentService(output);
|
|
21981
22427
|
const traceparent = process.env.TRACEPARENT;
|
|
@@ -22252,8 +22698,8 @@ var WorkflowRunCommand = {
|
|
|
22252
22698
|
// src/commands/workflow/commands/stop.ts
|
|
22253
22699
|
import chalk74 from "chalk";
|
|
22254
22700
|
import { createWorkflowRunStopTool } from "@ai-setting/roy-agent-core/env/workflow/tools";
|
|
22255
|
-
import { wrapFunction as
|
|
22256
|
-
var stopWorkflow =
|
|
22701
|
+
import { wrapFunction as wrapFunction3 } from "@ai-setting/roy-agent-core";
|
|
22702
|
+
var stopWorkflow = wrapFunction3(async function stopWorkflowImpl(args) {
|
|
22257
22703
|
const output = new OutputService2;
|
|
22258
22704
|
const envService = new EnvironmentService(output);
|
|
22259
22705
|
try {
|
|
@@ -22908,7 +23354,7 @@ Error: ${error.message}`));
|
|
|
22908
23354
|
|
|
22909
23355
|
// src/commands/workflow/commands/search.ts
|
|
22910
23356
|
import chalk78 from "chalk";
|
|
22911
|
-
import { wrapFunction as
|
|
23357
|
+
import { wrapFunction as wrapFunction4 } from "@ai-setting/roy-agent-core";
|
|
22912
23358
|
var WorkflowSearchCommand = {
|
|
22913
23359
|
command: "search",
|
|
22914
23360
|
describe: "Search workflows by keyword and/or tags (multiple tags use AND filter). v2: returns available_tags.",
|
|
@@ -23083,14 +23529,14 @@ var _runWorkflowSearchImpl = async function(opts) {
|
|
|
23083
23529
|
}
|
|
23084
23530
|
}
|
|
23085
23531
|
};
|
|
23086
|
-
var runWorkflowSearch =
|
|
23532
|
+
var runWorkflowSearch = wrapFunction4(_runWorkflowSearchImpl, "workflow.cli.search", {
|
|
23087
23533
|
recordParams: true,
|
|
23088
23534
|
recordResult: false,
|
|
23089
23535
|
log: false
|
|
23090
23536
|
});
|
|
23091
23537
|
|
|
23092
23538
|
// src/commands/workflow/commands/tag.ts
|
|
23093
|
-
import { wrapFunction as
|
|
23539
|
+
import { wrapFunction as wrapFunction5 } from "@ai-setting/roy-agent-core";
|
|
23094
23540
|
import chalk79 from "chalk";
|
|
23095
23541
|
var WorkflowTagListCommand = {
|
|
23096
23542
|
command: "list",
|
|
@@ -23290,12 +23736,12 @@ function formatDate2(iso) {
|
|
|
23290
23736
|
return iso;
|
|
23291
23737
|
}
|
|
23292
23738
|
}
|
|
23293
|
-
var runWorkflowTagList =
|
|
23739
|
+
var runWorkflowTagList = wrapFunction5(_runWorkflowTagListImpl, "workflow.cli.tag.list", {
|
|
23294
23740
|
recordParams: true,
|
|
23295
23741
|
recordResult: false,
|
|
23296
23742
|
log: false
|
|
23297
23743
|
});
|
|
23298
|
-
var runWorkflowTagGet =
|
|
23744
|
+
var runWorkflowTagGet = wrapFunction5(_runWorkflowTagGetImpl, "workflow.cli.tag.get", {
|
|
23299
23745
|
recordParams: true,
|
|
23300
23746
|
recordResult: false,
|
|
23301
23747
|
log: false
|