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