@ai-setting/roy-agent-cli 1.7.17 → 1.7.18
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 +223 -24
- package/dist/index.js +223 -24
- package/dist/roy-agent-linux-x64/bin/roy-agent +0 -0
- package/package.json +1 -1
package/dist/bin/roy-agent.js
CHANGED
|
@@ -9461,7 +9461,7 @@ class CliQuietModeService {
|
|
|
9461
9461
|
// package.json
|
|
9462
9462
|
var package_default = {
|
|
9463
9463
|
name: "@ai-setting/roy-agent-cli",
|
|
9464
|
-
version: "1.7.
|
|
9464
|
+
version: "1.7.18",
|
|
9465
9465
|
type: "module",
|
|
9466
9466
|
description: "CLI for roy-agent - Non-interactive command execution",
|
|
9467
9467
|
main: "./dist/index.js",
|
|
@@ -12108,6 +12108,52 @@ async function shutdownInteractiveSteps(deps) {
|
|
|
12108
12108
|
}
|
|
12109
12109
|
}
|
|
12110
12110
|
|
|
12111
|
+
// src/commands/lifecycle.ts
|
|
12112
|
+
var DEFAULT_LOGGER = {
|
|
12113
|
+
warn: (msg) => console.error(`[shutdown] ${msg}`)
|
|
12114
|
+
};
|
|
12115
|
+
function registerShutdownHandlers(cleanup, options = {}) {
|
|
12116
|
+
const logger5 = options.logger ?? DEFAULT_LOGGER;
|
|
12117
|
+
const exitCode = options.exitCode ?? 0;
|
|
12118
|
+
const shutdownMessage = options.shutdownMessage ?? "Cleaning up...";
|
|
12119
|
+
let shuttingDown = false;
|
|
12120
|
+
const shutdown = async (signal) => {
|
|
12121
|
+
if (shuttingDown) {
|
|
12122
|
+
return;
|
|
12123
|
+
}
|
|
12124
|
+
shuttingDown = true;
|
|
12125
|
+
try {
|
|
12126
|
+
logger5.debug?.(`[${signal}] ${shutdownMessage}`);
|
|
12127
|
+
} catch {}
|
|
12128
|
+
if (cleanup) {
|
|
12129
|
+
try {
|
|
12130
|
+
await cleanup();
|
|
12131
|
+
} catch (err) {
|
|
12132
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12133
|
+
try {
|
|
12134
|
+
logger5.warn(`Cleanup failed: ${message}`);
|
|
12135
|
+
} catch {
|
|
12136
|
+
try {
|
|
12137
|
+
process.stderr.write(`[shutdown] Cleanup failed: ${message}
|
|
12138
|
+
`);
|
|
12139
|
+
} catch {}
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
}
|
|
12143
|
+
try {
|
|
12144
|
+
process.exit(exitCode);
|
|
12145
|
+
} catch {}
|
|
12146
|
+
};
|
|
12147
|
+
process.on("SIGINT", shutdown);
|
|
12148
|
+
process.on("SIGTERM", shutdown);
|
|
12149
|
+
return {
|
|
12150
|
+
dispose: () => {
|
|
12151
|
+
process.removeListener("SIGINT", shutdown);
|
|
12152
|
+
process.removeListener("SIGTERM", shutdown);
|
|
12153
|
+
}
|
|
12154
|
+
};
|
|
12155
|
+
}
|
|
12156
|
+
|
|
12111
12157
|
// src/commands/interactive.ts
|
|
12112
12158
|
import { AskUserError, cascadeStopSessionTree } from "@ai-setting/roy-agent-core";
|
|
12113
12159
|
|
|
@@ -13453,6 +13499,22 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13453
13499
|
});
|
|
13454
13500
|
}
|
|
13455
13501
|
}, env);
|
|
13502
|
+
registerShutdownHandlers(async () => {
|
|
13503
|
+
await shutdownInteractiveSteps({
|
|
13504
|
+
memoryPluginDispose,
|
|
13505
|
+
memoryPluginInstance,
|
|
13506
|
+
lspManagerDispose,
|
|
13507
|
+
pluginAdapterDispose,
|
|
13508
|
+
eventHandler,
|
|
13509
|
+
queryExecutor,
|
|
13510
|
+
env,
|
|
13511
|
+
envService,
|
|
13512
|
+
shouldDisposeEnvService,
|
|
13513
|
+
output,
|
|
13514
|
+
logger: logger5,
|
|
13515
|
+
console
|
|
13516
|
+
});
|
|
13517
|
+
});
|
|
13456
13518
|
const eventHandler = new EventHandler({
|
|
13457
13519
|
env,
|
|
13458
13520
|
eventTypes: ["task.background.*", "event-source.event.*"],
|
|
@@ -13682,9 +13744,9 @@ var App = ({
|
|
|
13682
13744
|
}, undefined, true, undefined, this),
|
|
13683
13745
|
/* @__PURE__ */ jsxDEV6(Static2, {
|
|
13684
13746
|
items: history,
|
|
13685
|
-
children: (item) => /* @__PURE__ */ jsxDEV6(HistoryEntry, {
|
|
13747
|
+
children: (item, index) => /* @__PURE__ */ jsxDEV6(HistoryEntry, {
|
|
13686
13748
|
item
|
|
13687
|
-
}, `${item.role}:${
|
|
13749
|
+
}, item.id ?? `${item.role}:${index}`, false, undefined, this)
|
|
13688
13750
|
}, undefined, false, undefined, this),
|
|
13689
13751
|
status === "thinking" ? /* @__PURE__ */ jsxDEV6(Box4, {
|
|
13690
13752
|
marginBottom: 1,
|
|
@@ -13965,6 +14027,7 @@ var RunScreen = ({
|
|
|
13965
14027
|
const assistantTurnCountRef = useRef2(0);
|
|
13966
14028
|
const isProcessingRef = useRef2(0);
|
|
13967
14029
|
const executeQueryRef = useRef2(null);
|
|
14030
|
+
const historyIdRef = useRef2(0);
|
|
13968
14031
|
const width = process.stdout.columns ?? 80;
|
|
13969
14032
|
const doExit = useCallback4(() => {
|
|
13970
14033
|
onExit?.();
|
|
@@ -13983,15 +14046,20 @@ var RunScreen = ({
|
|
|
13983
14046
|
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
13984
14047
|
const finalText = truncateForTerminal(rendered, maxLines);
|
|
13985
14048
|
stream.finish();
|
|
13986
|
-
|
|
14049
|
+
const assistantId = `h${++historyIdRef.current}`;
|
|
14050
|
+
setHistory((h) => [
|
|
14051
|
+
...h,
|
|
14052
|
+
{ role: "assistant", content: finalText, id: assistantId }
|
|
14053
|
+
]);
|
|
13987
14054
|
assistantTurnCountRef.current += 1;
|
|
13988
14055
|
} catch (err) {
|
|
13989
14056
|
const msg = err instanceof Error ? err.message : String(err);
|
|
13990
14057
|
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
13991
14058
|
setErrorMessage(msg);
|
|
14059
|
+
const errorId = `h${++historyIdRef.current}`;
|
|
13992
14060
|
setHistory((h) => [
|
|
13993
14061
|
...h,
|
|
13994
|
-
{ role: "tool", content: `❌ Error: ${msg}
|
|
14062
|
+
{ role: "tool", content: `❌ Error: ${msg}`, id: errorId }
|
|
13995
14063
|
]);
|
|
13996
14064
|
} finally {
|
|
13997
14065
|
isProcessingRef.current -= 1;
|
|
@@ -14004,9 +14072,10 @@ var RunScreen = ({
|
|
|
14004
14072
|
if (!onRegisterHandlers)
|
|
14005
14073
|
return;
|
|
14006
14074
|
const handleNotification = async (message, _envEvent) => {
|
|
14075
|
+
const notifId = `h${++historyIdRef.current}`;
|
|
14007
14076
|
setHistory((h) => [
|
|
14008
14077
|
...h,
|
|
14009
|
-
{ role: "tool", content: `\uD83D\uDCE2 ${message}
|
|
14078
|
+
{ role: "tool", content: `\uD83D\uDCE2 ${message}`, id: notifId }
|
|
14010
14079
|
]);
|
|
14011
14080
|
if (executeQueryRef.current) {
|
|
14012
14081
|
await executeQueryRef.current(message);
|
|
@@ -14030,10 +14099,12 @@ var RunScreen = ({
|
|
|
14030
14099
|
};
|
|
14031
14100
|
const result = dispatchSlashCommand(trimmed, slashCtx);
|
|
14032
14101
|
if (result.kind === "exit") {
|
|
14102
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14103
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14033
14104
|
setHistory((h) => [
|
|
14034
14105
|
...h,
|
|
14035
|
-
{ role: "user", content: trimmed },
|
|
14036
|
-
{ role: "tool", content: "\uD83D\uDC4B Goodbye!" }
|
|
14106
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14107
|
+
{ role: "tool", content: "\uD83D\uDC4B Goodbye!", id: toolId }
|
|
14037
14108
|
]);
|
|
14038
14109
|
doExit();
|
|
14039
14110
|
return;
|
|
@@ -14047,35 +14118,46 @@ var RunScreen = ({
|
|
|
14047
14118
|
setErrorMessage(null);
|
|
14048
14119
|
return;
|
|
14049
14120
|
}
|
|
14121
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14122
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14050
14123
|
setHistory((h) => [
|
|
14051
14124
|
...h,
|
|
14052
|
-
{ role: "user", content: trimmed },
|
|
14053
|
-
{ role: "tool", content: result.message }
|
|
14125
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14126
|
+
{ role: "tool", content: result.message, id: toolId }
|
|
14054
14127
|
]);
|
|
14055
14128
|
return;
|
|
14056
14129
|
}
|
|
14057
14130
|
if (result.kind === "unknown") {
|
|
14131
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14132
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14058
14133
|
setHistory((h) => [
|
|
14059
14134
|
...h,
|
|
14060
|
-
{ role: "user", content: trimmed },
|
|
14061
|
-
{ role: "tool", content: `⚠ ${result.message}
|
|
14135
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14136
|
+
{ role: "tool", content: `⚠ ${result.message}`, id: toolId }
|
|
14062
14137
|
]);
|
|
14063
14138
|
return;
|
|
14064
14139
|
}
|
|
14065
14140
|
if (result.kind === "set-max-lines") {
|
|
14066
14141
|
setMaxLines(result.value);
|
|
14142
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14143
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14067
14144
|
setHistory((h) => [
|
|
14068
14145
|
...h,
|
|
14069
|
-
{ role: "user", content: trimmed },
|
|
14146
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14070
14147
|
{
|
|
14071
14148
|
role: "tool",
|
|
14072
|
-
content: `max-lines set to ${result.value}
|
|
14149
|
+
content: `max-lines set to ${result.value}`,
|
|
14150
|
+
id: toolId
|
|
14073
14151
|
}
|
|
14074
14152
|
]);
|
|
14075
14153
|
return;
|
|
14076
14154
|
}
|
|
14077
14155
|
setErrorMessage(null);
|
|
14078
|
-
|
|
14156
|
+
const userId = `h${++historyIdRef.current}`;
|
|
14157
|
+
setHistory((h) => [
|
|
14158
|
+
...h,
|
|
14159
|
+
{ role: "user", content: trimmed, id: userId }
|
|
14160
|
+
]);
|
|
14079
14161
|
setUserHistory((uh) => [trimmed, ...uh]);
|
|
14080
14162
|
userTurnCountRef.current += 1;
|
|
14081
14163
|
await executeQuery(trimmed);
|
|
@@ -14128,6 +14210,89 @@ var RunTui_default = RunScreen;
|
|
|
14128
14210
|
|
|
14129
14211
|
// src/commands/run.ts
|
|
14130
14212
|
init_markdown();
|
|
14213
|
+
|
|
14214
|
+
// src/commands/run-shutdown.ts
|
|
14215
|
+
import { TempFileManager as TempFileManager3 } from "@ai-setting/roy-agent-core/utils/temp-file-manager";
|
|
14216
|
+
async function shutdownRunSteps(deps) {
|
|
14217
|
+
const {
|
|
14218
|
+
lspManagerDispose,
|
|
14219
|
+
pluginAdapterDispose,
|
|
14220
|
+
stopEventHandler,
|
|
14221
|
+
stopTaskEventHandler,
|
|
14222
|
+
queryExecutor,
|
|
14223
|
+
env,
|
|
14224
|
+
envService,
|
|
14225
|
+
shouldDisposeEnvService,
|
|
14226
|
+
output,
|
|
14227
|
+
logger: logger6
|
|
14228
|
+
} = deps;
|
|
14229
|
+
try {
|
|
14230
|
+
stopEventHandler();
|
|
14231
|
+
} catch (err) {
|
|
14232
|
+
logger6?.warn?.(`[Shutdown] EventHandler.stop failed: ${err}`);
|
|
14233
|
+
}
|
|
14234
|
+
try {
|
|
14235
|
+
stopTaskEventHandler();
|
|
14236
|
+
} catch (err) {
|
|
14237
|
+
logger6?.warn?.(`[Shutdown] TaskEventHandler.stop failed: ${err}`);
|
|
14238
|
+
}
|
|
14239
|
+
if (lspManagerDispose) {
|
|
14240
|
+
try {
|
|
14241
|
+
await lspManagerDispose();
|
|
14242
|
+
} catch (err) {
|
|
14243
|
+
logger6?.warn?.(`[Shutdown] LSP Manager dispose failed: ${err}`);
|
|
14244
|
+
}
|
|
14245
|
+
}
|
|
14246
|
+
if (pluginAdapterDispose) {
|
|
14247
|
+
try {
|
|
14248
|
+
await pluginAdapterDispose();
|
|
14249
|
+
} catch (err) {
|
|
14250
|
+
logger6?.warn?.(`[Shutdown] PluginAdapter dispose failed: ${err}`);
|
|
14251
|
+
}
|
|
14252
|
+
}
|
|
14253
|
+
try {
|
|
14254
|
+
queryExecutor.dispose();
|
|
14255
|
+
} catch (err) {
|
|
14256
|
+
logger6?.warn?.(`[Shutdown] QueryExecutor.dispose failed: ${err}`);
|
|
14257
|
+
}
|
|
14258
|
+
try {
|
|
14259
|
+
const eventSourceComponent = env.getComponent("event-source");
|
|
14260
|
+
if (eventSourceComponent) {
|
|
14261
|
+
const sources = eventSourceComponent.list?.();
|
|
14262
|
+
if (sources && sources.length > 0) {
|
|
14263
|
+
for (const source of sources) {
|
|
14264
|
+
const status = eventSourceComponent.getStatus?.(source.id);
|
|
14265
|
+
logger6?.debug?.(`[Shutdown] 检查事件源: ${source.id}, 状态: ${status}`);
|
|
14266
|
+
if (status !== "stopped" && status !== "created") {
|
|
14267
|
+
try {
|
|
14268
|
+
await eventSourceComponent.stopSource(source.id);
|
|
14269
|
+
output?.info?.(`✓ 已停止事件源: ${source.name} (${status})`);
|
|
14270
|
+
} catch (error) {
|
|
14271
|
+
output?.warn?.(`⚠️ 停止事件源 ${source.name} 失败: ${error}`);
|
|
14272
|
+
}
|
|
14273
|
+
}
|
|
14274
|
+
}
|
|
14275
|
+
}
|
|
14276
|
+
}
|
|
14277
|
+
} catch (err) {
|
|
14278
|
+
logger6?.warn?.(`[Shutdown] EventSource cleanup failed: ${err}`);
|
|
14279
|
+
}
|
|
14280
|
+
if (shouldDisposeEnvService) {
|
|
14281
|
+
try {
|
|
14282
|
+
await envService.dispose();
|
|
14283
|
+
} catch (err) {
|
|
14284
|
+
logger6?.warn?.(`[Shutdown] envService.dispose failed: ${err}`);
|
|
14285
|
+
}
|
|
14286
|
+
}
|
|
14287
|
+
try {
|
|
14288
|
+
await TempFileManager3.getInstance().cleanupAll();
|
|
14289
|
+
logger6?.debug?.("[Shutdown] TempFileManager cleaned up");
|
|
14290
|
+
} catch (err) {
|
|
14291
|
+
logger6?.warn?.(`[Shutdown] TempFileManager cleanup failed: ${err}`);
|
|
14292
|
+
}
|
|
14293
|
+
}
|
|
14294
|
+
|
|
14295
|
+
// src/commands/run.ts
|
|
14131
14296
|
async function loadHandleQuery(options, hooks) {
|
|
14132
14297
|
const quiet = CliQuietModeService.getInstance().isQuiet();
|
|
14133
14298
|
const output = new OutputService2;
|
|
@@ -14237,7 +14402,8 @@ async function loadHandleQuery(options, hooks) {
|
|
|
14237
14402
|
eventSourceSystemPrompt,
|
|
14238
14403
|
sessionComponent,
|
|
14239
14404
|
eventHandler,
|
|
14240
|
-
taskEventHandler
|
|
14405
|
+
taskEventHandler,
|
|
14406
|
+
sessionManager
|
|
14241
14407
|
};
|
|
14242
14408
|
}
|
|
14243
14409
|
function createStreamHandleQuery(queryExecutor, sessionId, options, agentContext, eventSourceSystemPrompt) {
|
|
@@ -14353,16 +14519,33 @@ function createRunCommand() {
|
|
|
14353
14519
|
};
|
|
14354
14520
|
const {
|
|
14355
14521
|
handleQuery,
|
|
14522
|
+
envService,
|
|
14523
|
+
env,
|
|
14356
14524
|
queryExecutor,
|
|
14357
14525
|
sessionId,
|
|
14358
14526
|
agentContext,
|
|
14359
14527
|
eventSourceSystemPrompt,
|
|
14360
14528
|
eventHandler,
|
|
14361
|
-
taskEventHandler
|
|
14529
|
+
taskEventHandler,
|
|
14530
|
+
sessionManager: _sessionManager
|
|
14362
14531
|
} = await loadHandleQuery(argv, {
|
|
14363
14532
|
isIdle: () => runState.isIdle(),
|
|
14364
14533
|
onNotification: (msg, envEvent) => runState.onNotification(msg, envEvent)
|
|
14365
14534
|
});
|
|
14535
|
+
const shutdownHandle = registerShutdownHandlers(async () => {
|
|
14536
|
+
await shutdownRunSteps({
|
|
14537
|
+
lspManagerDispose: null,
|
|
14538
|
+
pluginAdapterDispose: null,
|
|
14539
|
+
stopEventHandler,
|
|
14540
|
+
stopTaskEventHandler,
|
|
14541
|
+
queryExecutor,
|
|
14542
|
+
env,
|
|
14543
|
+
envService,
|
|
14544
|
+
shouldDisposeEnvService: true,
|
|
14545
|
+
output: undefined,
|
|
14546
|
+
logger: undefined
|
|
14547
|
+
});
|
|
14548
|
+
});
|
|
14366
14549
|
const streamHandleQuery = createStreamHandleQuery(queryExecutor, sessionId, argv, agentContext, eventSourceSystemPrompt);
|
|
14367
14550
|
const stopEventHandler = eventHandler.start();
|
|
14368
14551
|
const stopTaskEventHandler = taskEventHandler.start();
|
|
@@ -14382,9 +14565,19 @@ function createRunCommand() {
|
|
|
14382
14565
|
try {
|
|
14383
14566
|
await waitUntilExit();
|
|
14384
14567
|
} finally {
|
|
14385
|
-
|
|
14386
|
-
|
|
14387
|
-
|
|
14568
|
+
shutdownHandle.dispose();
|
|
14569
|
+
await shutdownRunSteps({
|
|
14570
|
+
lspManagerDispose: null,
|
|
14571
|
+
pluginAdapterDispose: null,
|
|
14572
|
+
stopEventHandler,
|
|
14573
|
+
stopTaskEventHandler,
|
|
14574
|
+
queryExecutor,
|
|
14575
|
+
env,
|
|
14576
|
+
envService,
|
|
14577
|
+
shouldDisposeEnvService: true,
|
|
14578
|
+
output: undefined,
|
|
14579
|
+
logger: undefined
|
|
14580
|
+
});
|
|
14388
14581
|
process.exit(0);
|
|
14389
14582
|
}
|
|
14390
14583
|
}
|
|
@@ -14397,7 +14590,7 @@ import React8 from "react";
|
|
|
14397
14590
|
import { render as render2 } from "ink";
|
|
14398
14591
|
|
|
14399
14592
|
// src/ChatTui.tsx
|
|
14400
|
-
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
14593
|
+
import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
|
|
14401
14594
|
import { Box as Box7, useApp as useApp3 } from "ink";
|
|
14402
14595
|
init_markdown();
|
|
14403
14596
|
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
@@ -14411,8 +14604,9 @@ var ChatScreen = ({
|
|
|
14411
14604
|
markdownEnabled: markdownEnabled2
|
|
14412
14605
|
}) => {
|
|
14413
14606
|
const [history, setHistory] = useState7([
|
|
14414
|
-
{ role: "user", content: message }
|
|
14607
|
+
{ role: "user", content: message, id: "h-init-1" }
|
|
14415
14608
|
]);
|
|
14609
|
+
const historyIdRef = useRef3(1);
|
|
14416
14610
|
const stream = useStreamingAccumulator();
|
|
14417
14611
|
const { exit } = useApp3();
|
|
14418
14612
|
const width = process.stdout.columns ?? 80;
|
|
@@ -14432,16 +14626,21 @@ var ChatScreen = ({
|
|
|
14432
14626
|
stream.finish();
|
|
14433
14627
|
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
14434
14628
|
const finalText = truncateForTerminal(rendered, maxLines);
|
|
14435
|
-
|
|
14629
|
+
const assistantId = `h${++historyIdRef.current}`;
|
|
14630
|
+
setHistory((h) => [
|
|
14631
|
+
...h,
|
|
14632
|
+
{ role: "assistant", content: finalText, id: assistantId }
|
|
14633
|
+
]);
|
|
14436
14634
|
setTimeout(() => exit(), 100);
|
|
14437
14635
|
} catch (err) {
|
|
14438
14636
|
if (cancelled)
|
|
14439
14637
|
return;
|
|
14440
14638
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14441
14639
|
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
14640
|
+
const errorId = `h${++historyIdRef.current}`;
|
|
14442
14641
|
setHistory((h) => [
|
|
14443
14642
|
...h,
|
|
14444
|
-
{ role: "tool", content: `❌ Error: ${msg}
|
|
14643
|
+
{ role: "tool", content: `❌ Error: ${msg}`, id: errorId }
|
|
14445
14644
|
]);
|
|
14446
14645
|
setTimeout(() => exit(), 100);
|
|
14447
14646
|
}
|
package/dist/index.js
CHANGED
|
@@ -9460,7 +9460,7 @@ class CliQuietModeService {
|
|
|
9460
9460
|
// package.json
|
|
9461
9461
|
var package_default = {
|
|
9462
9462
|
name: "@ai-setting/roy-agent-cli",
|
|
9463
|
-
version: "1.7.
|
|
9463
|
+
version: "1.7.18",
|
|
9464
9464
|
type: "module",
|
|
9465
9465
|
description: "CLI for roy-agent - Non-interactive command execution",
|
|
9466
9466
|
main: "./dist/index.js",
|
|
@@ -12107,6 +12107,52 @@ async function shutdownInteractiveSteps(deps) {
|
|
|
12107
12107
|
}
|
|
12108
12108
|
}
|
|
12109
12109
|
|
|
12110
|
+
// src/commands/lifecycle.ts
|
|
12111
|
+
var DEFAULT_LOGGER = {
|
|
12112
|
+
warn: (msg) => console.error(`[shutdown] ${msg}`)
|
|
12113
|
+
};
|
|
12114
|
+
function registerShutdownHandlers(cleanup, options = {}) {
|
|
12115
|
+
const logger5 = options.logger ?? DEFAULT_LOGGER;
|
|
12116
|
+
const exitCode = options.exitCode ?? 0;
|
|
12117
|
+
const shutdownMessage = options.shutdownMessage ?? "Cleaning up...";
|
|
12118
|
+
let shuttingDown = false;
|
|
12119
|
+
const shutdown = async (signal) => {
|
|
12120
|
+
if (shuttingDown) {
|
|
12121
|
+
return;
|
|
12122
|
+
}
|
|
12123
|
+
shuttingDown = true;
|
|
12124
|
+
try {
|
|
12125
|
+
logger5.debug?.(`[${signal}] ${shutdownMessage}`);
|
|
12126
|
+
} catch {}
|
|
12127
|
+
if (cleanup) {
|
|
12128
|
+
try {
|
|
12129
|
+
await cleanup();
|
|
12130
|
+
} catch (err) {
|
|
12131
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12132
|
+
try {
|
|
12133
|
+
logger5.warn(`Cleanup failed: ${message}`);
|
|
12134
|
+
} catch {
|
|
12135
|
+
try {
|
|
12136
|
+
process.stderr.write(`[shutdown] Cleanup failed: ${message}
|
|
12137
|
+
`);
|
|
12138
|
+
} catch {}
|
|
12139
|
+
}
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
try {
|
|
12143
|
+
process.exit(exitCode);
|
|
12144
|
+
} catch {}
|
|
12145
|
+
};
|
|
12146
|
+
process.on("SIGINT", shutdown);
|
|
12147
|
+
process.on("SIGTERM", shutdown);
|
|
12148
|
+
return {
|
|
12149
|
+
dispose: () => {
|
|
12150
|
+
process.removeListener("SIGINT", shutdown);
|
|
12151
|
+
process.removeListener("SIGTERM", shutdown);
|
|
12152
|
+
}
|
|
12153
|
+
};
|
|
12154
|
+
}
|
|
12155
|
+
|
|
12110
12156
|
// src/commands/interactive.ts
|
|
12111
12157
|
import { AskUserError, cascadeStopSessionTree } from "@ai-setting/roy-agent-core";
|
|
12112
12158
|
|
|
@@ -13452,6 +13498,22 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13452
13498
|
});
|
|
13453
13499
|
}
|
|
13454
13500
|
}, env);
|
|
13501
|
+
registerShutdownHandlers(async () => {
|
|
13502
|
+
await shutdownInteractiveSteps({
|
|
13503
|
+
memoryPluginDispose,
|
|
13504
|
+
memoryPluginInstance,
|
|
13505
|
+
lspManagerDispose,
|
|
13506
|
+
pluginAdapterDispose,
|
|
13507
|
+
eventHandler,
|
|
13508
|
+
queryExecutor,
|
|
13509
|
+
env,
|
|
13510
|
+
envService,
|
|
13511
|
+
shouldDisposeEnvService,
|
|
13512
|
+
output,
|
|
13513
|
+
logger: logger5,
|
|
13514
|
+
console
|
|
13515
|
+
});
|
|
13516
|
+
});
|
|
13455
13517
|
const eventHandler = new EventHandler({
|
|
13456
13518
|
env,
|
|
13457
13519
|
eventTypes: ["task.background.*", "event-source.event.*"],
|
|
@@ -13681,9 +13743,9 @@ var App = ({
|
|
|
13681
13743
|
}, undefined, true, undefined, this),
|
|
13682
13744
|
/* @__PURE__ */ jsxDEV6(Static2, {
|
|
13683
13745
|
items: history,
|
|
13684
|
-
children: (item) => /* @__PURE__ */ jsxDEV6(HistoryEntry, {
|
|
13746
|
+
children: (item, index) => /* @__PURE__ */ jsxDEV6(HistoryEntry, {
|
|
13685
13747
|
item
|
|
13686
|
-
}, `${item.role}:${
|
|
13748
|
+
}, item.id ?? `${item.role}:${index}`, false, undefined, this)
|
|
13687
13749
|
}, undefined, false, undefined, this),
|
|
13688
13750
|
status === "thinking" ? /* @__PURE__ */ jsxDEV6(Box4, {
|
|
13689
13751
|
marginBottom: 1,
|
|
@@ -13964,6 +14026,7 @@ var RunScreen = ({
|
|
|
13964
14026
|
const assistantTurnCountRef = useRef2(0);
|
|
13965
14027
|
const isProcessingRef = useRef2(0);
|
|
13966
14028
|
const executeQueryRef = useRef2(null);
|
|
14029
|
+
const historyIdRef = useRef2(0);
|
|
13967
14030
|
const width = process.stdout.columns ?? 80;
|
|
13968
14031
|
const doExit = useCallback4(() => {
|
|
13969
14032
|
onExit?.();
|
|
@@ -13982,15 +14045,20 @@ var RunScreen = ({
|
|
|
13982
14045
|
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
13983
14046
|
const finalText = truncateForTerminal(rendered, maxLines);
|
|
13984
14047
|
stream.finish();
|
|
13985
|
-
|
|
14048
|
+
const assistantId = `h${++historyIdRef.current}`;
|
|
14049
|
+
setHistory((h) => [
|
|
14050
|
+
...h,
|
|
14051
|
+
{ role: "assistant", content: finalText, id: assistantId }
|
|
14052
|
+
]);
|
|
13986
14053
|
assistantTurnCountRef.current += 1;
|
|
13987
14054
|
} catch (err) {
|
|
13988
14055
|
const msg = err instanceof Error ? err.message : String(err);
|
|
13989
14056
|
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
13990
14057
|
setErrorMessage(msg);
|
|
14058
|
+
const errorId = `h${++historyIdRef.current}`;
|
|
13991
14059
|
setHistory((h) => [
|
|
13992
14060
|
...h,
|
|
13993
|
-
{ role: "tool", content: `❌ Error: ${msg}
|
|
14061
|
+
{ role: "tool", content: `❌ Error: ${msg}`, id: errorId }
|
|
13994
14062
|
]);
|
|
13995
14063
|
} finally {
|
|
13996
14064
|
isProcessingRef.current -= 1;
|
|
@@ -14003,9 +14071,10 @@ var RunScreen = ({
|
|
|
14003
14071
|
if (!onRegisterHandlers)
|
|
14004
14072
|
return;
|
|
14005
14073
|
const handleNotification = async (message, _envEvent) => {
|
|
14074
|
+
const notifId = `h${++historyIdRef.current}`;
|
|
14006
14075
|
setHistory((h) => [
|
|
14007
14076
|
...h,
|
|
14008
|
-
{ role: "tool", content: `\uD83D\uDCE2 ${message}
|
|
14077
|
+
{ role: "tool", content: `\uD83D\uDCE2 ${message}`, id: notifId }
|
|
14009
14078
|
]);
|
|
14010
14079
|
if (executeQueryRef.current) {
|
|
14011
14080
|
await executeQueryRef.current(message);
|
|
@@ -14029,10 +14098,12 @@ var RunScreen = ({
|
|
|
14029
14098
|
};
|
|
14030
14099
|
const result = dispatchSlashCommand(trimmed, slashCtx);
|
|
14031
14100
|
if (result.kind === "exit") {
|
|
14101
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14102
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14032
14103
|
setHistory((h) => [
|
|
14033
14104
|
...h,
|
|
14034
|
-
{ role: "user", content: trimmed },
|
|
14035
|
-
{ role: "tool", content: "\uD83D\uDC4B Goodbye!" }
|
|
14105
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14106
|
+
{ role: "tool", content: "\uD83D\uDC4B Goodbye!", id: toolId }
|
|
14036
14107
|
]);
|
|
14037
14108
|
doExit();
|
|
14038
14109
|
return;
|
|
@@ -14046,35 +14117,46 @@ var RunScreen = ({
|
|
|
14046
14117
|
setErrorMessage(null);
|
|
14047
14118
|
return;
|
|
14048
14119
|
}
|
|
14120
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14121
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14049
14122
|
setHistory((h) => [
|
|
14050
14123
|
...h,
|
|
14051
|
-
{ role: "user", content: trimmed },
|
|
14052
|
-
{ role: "tool", content: result.message }
|
|
14124
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14125
|
+
{ role: "tool", content: result.message, id: toolId }
|
|
14053
14126
|
]);
|
|
14054
14127
|
return;
|
|
14055
14128
|
}
|
|
14056
14129
|
if (result.kind === "unknown") {
|
|
14130
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14131
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14057
14132
|
setHistory((h) => [
|
|
14058
14133
|
...h,
|
|
14059
|
-
{ role: "user", content: trimmed },
|
|
14060
|
-
{ role: "tool", content: `⚠ ${result.message}
|
|
14134
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14135
|
+
{ role: "tool", content: `⚠ ${result.message}`, id: toolId }
|
|
14061
14136
|
]);
|
|
14062
14137
|
return;
|
|
14063
14138
|
}
|
|
14064
14139
|
if (result.kind === "set-max-lines") {
|
|
14065
14140
|
setMaxLines(result.value);
|
|
14141
|
+
const userId2 = `h${++historyIdRef.current}`;
|
|
14142
|
+
const toolId = `h${++historyIdRef.current}`;
|
|
14066
14143
|
setHistory((h) => [
|
|
14067
14144
|
...h,
|
|
14068
|
-
{ role: "user", content: trimmed },
|
|
14145
|
+
{ role: "user", content: trimmed, id: userId2 },
|
|
14069
14146
|
{
|
|
14070
14147
|
role: "tool",
|
|
14071
|
-
content: `max-lines set to ${result.value}
|
|
14148
|
+
content: `max-lines set to ${result.value}`,
|
|
14149
|
+
id: toolId
|
|
14072
14150
|
}
|
|
14073
14151
|
]);
|
|
14074
14152
|
return;
|
|
14075
14153
|
}
|
|
14076
14154
|
setErrorMessage(null);
|
|
14077
|
-
|
|
14155
|
+
const userId = `h${++historyIdRef.current}`;
|
|
14156
|
+
setHistory((h) => [
|
|
14157
|
+
...h,
|
|
14158
|
+
{ role: "user", content: trimmed, id: userId }
|
|
14159
|
+
]);
|
|
14078
14160
|
setUserHistory((uh) => [trimmed, ...uh]);
|
|
14079
14161
|
userTurnCountRef.current += 1;
|
|
14080
14162
|
await executeQuery(trimmed);
|
|
@@ -14127,6 +14209,89 @@ var RunTui_default = RunScreen;
|
|
|
14127
14209
|
|
|
14128
14210
|
// src/commands/run.ts
|
|
14129
14211
|
init_markdown();
|
|
14212
|
+
|
|
14213
|
+
// src/commands/run-shutdown.ts
|
|
14214
|
+
import { TempFileManager as TempFileManager3 } from "@ai-setting/roy-agent-core/utils/temp-file-manager";
|
|
14215
|
+
async function shutdownRunSteps(deps) {
|
|
14216
|
+
const {
|
|
14217
|
+
lspManagerDispose,
|
|
14218
|
+
pluginAdapterDispose,
|
|
14219
|
+
stopEventHandler,
|
|
14220
|
+
stopTaskEventHandler,
|
|
14221
|
+
queryExecutor,
|
|
14222
|
+
env,
|
|
14223
|
+
envService,
|
|
14224
|
+
shouldDisposeEnvService,
|
|
14225
|
+
output,
|
|
14226
|
+
logger: logger6
|
|
14227
|
+
} = deps;
|
|
14228
|
+
try {
|
|
14229
|
+
stopEventHandler();
|
|
14230
|
+
} catch (err) {
|
|
14231
|
+
logger6?.warn?.(`[Shutdown] EventHandler.stop failed: ${err}`);
|
|
14232
|
+
}
|
|
14233
|
+
try {
|
|
14234
|
+
stopTaskEventHandler();
|
|
14235
|
+
} catch (err) {
|
|
14236
|
+
logger6?.warn?.(`[Shutdown] TaskEventHandler.stop failed: ${err}`);
|
|
14237
|
+
}
|
|
14238
|
+
if (lspManagerDispose) {
|
|
14239
|
+
try {
|
|
14240
|
+
await lspManagerDispose();
|
|
14241
|
+
} catch (err) {
|
|
14242
|
+
logger6?.warn?.(`[Shutdown] LSP Manager dispose failed: ${err}`);
|
|
14243
|
+
}
|
|
14244
|
+
}
|
|
14245
|
+
if (pluginAdapterDispose) {
|
|
14246
|
+
try {
|
|
14247
|
+
await pluginAdapterDispose();
|
|
14248
|
+
} catch (err) {
|
|
14249
|
+
logger6?.warn?.(`[Shutdown] PluginAdapter dispose failed: ${err}`);
|
|
14250
|
+
}
|
|
14251
|
+
}
|
|
14252
|
+
try {
|
|
14253
|
+
queryExecutor.dispose();
|
|
14254
|
+
} catch (err) {
|
|
14255
|
+
logger6?.warn?.(`[Shutdown] QueryExecutor.dispose failed: ${err}`);
|
|
14256
|
+
}
|
|
14257
|
+
try {
|
|
14258
|
+
const eventSourceComponent = env.getComponent("event-source");
|
|
14259
|
+
if (eventSourceComponent) {
|
|
14260
|
+
const sources = eventSourceComponent.list?.();
|
|
14261
|
+
if (sources && sources.length > 0) {
|
|
14262
|
+
for (const source of sources) {
|
|
14263
|
+
const status = eventSourceComponent.getStatus?.(source.id);
|
|
14264
|
+
logger6?.debug?.(`[Shutdown] 检查事件源: ${source.id}, 状态: ${status}`);
|
|
14265
|
+
if (status !== "stopped" && status !== "created") {
|
|
14266
|
+
try {
|
|
14267
|
+
await eventSourceComponent.stopSource(source.id);
|
|
14268
|
+
output?.info?.(`✓ 已停止事件源: ${source.name} (${status})`);
|
|
14269
|
+
} catch (error) {
|
|
14270
|
+
output?.warn?.(`⚠️ 停止事件源 ${source.name} 失败: ${error}`);
|
|
14271
|
+
}
|
|
14272
|
+
}
|
|
14273
|
+
}
|
|
14274
|
+
}
|
|
14275
|
+
}
|
|
14276
|
+
} catch (err) {
|
|
14277
|
+
logger6?.warn?.(`[Shutdown] EventSource cleanup failed: ${err}`);
|
|
14278
|
+
}
|
|
14279
|
+
if (shouldDisposeEnvService) {
|
|
14280
|
+
try {
|
|
14281
|
+
await envService.dispose();
|
|
14282
|
+
} catch (err) {
|
|
14283
|
+
logger6?.warn?.(`[Shutdown] envService.dispose failed: ${err}`);
|
|
14284
|
+
}
|
|
14285
|
+
}
|
|
14286
|
+
try {
|
|
14287
|
+
await TempFileManager3.getInstance().cleanupAll();
|
|
14288
|
+
logger6?.debug?.("[Shutdown] TempFileManager cleaned up");
|
|
14289
|
+
} catch (err) {
|
|
14290
|
+
logger6?.warn?.(`[Shutdown] TempFileManager cleanup failed: ${err}`);
|
|
14291
|
+
}
|
|
14292
|
+
}
|
|
14293
|
+
|
|
14294
|
+
// src/commands/run.ts
|
|
14130
14295
|
async function loadHandleQuery(options, hooks) {
|
|
14131
14296
|
const quiet = CliQuietModeService.getInstance().isQuiet();
|
|
14132
14297
|
const output = new OutputService2;
|
|
@@ -14236,7 +14401,8 @@ async function loadHandleQuery(options, hooks) {
|
|
|
14236
14401
|
eventSourceSystemPrompt,
|
|
14237
14402
|
sessionComponent,
|
|
14238
14403
|
eventHandler,
|
|
14239
|
-
taskEventHandler
|
|
14404
|
+
taskEventHandler,
|
|
14405
|
+
sessionManager
|
|
14240
14406
|
};
|
|
14241
14407
|
}
|
|
14242
14408
|
function createStreamHandleQuery(queryExecutor, sessionId, options, agentContext, eventSourceSystemPrompt) {
|
|
@@ -14352,16 +14518,33 @@ function createRunCommand() {
|
|
|
14352
14518
|
};
|
|
14353
14519
|
const {
|
|
14354
14520
|
handleQuery,
|
|
14521
|
+
envService,
|
|
14522
|
+
env,
|
|
14355
14523
|
queryExecutor,
|
|
14356
14524
|
sessionId,
|
|
14357
14525
|
agentContext,
|
|
14358
14526
|
eventSourceSystemPrompt,
|
|
14359
14527
|
eventHandler,
|
|
14360
|
-
taskEventHandler
|
|
14528
|
+
taskEventHandler,
|
|
14529
|
+
sessionManager: _sessionManager
|
|
14361
14530
|
} = await loadHandleQuery(argv, {
|
|
14362
14531
|
isIdle: () => runState.isIdle(),
|
|
14363
14532
|
onNotification: (msg, envEvent) => runState.onNotification(msg, envEvent)
|
|
14364
14533
|
});
|
|
14534
|
+
const shutdownHandle = registerShutdownHandlers(async () => {
|
|
14535
|
+
await shutdownRunSteps({
|
|
14536
|
+
lspManagerDispose: null,
|
|
14537
|
+
pluginAdapterDispose: null,
|
|
14538
|
+
stopEventHandler,
|
|
14539
|
+
stopTaskEventHandler,
|
|
14540
|
+
queryExecutor,
|
|
14541
|
+
env,
|
|
14542
|
+
envService,
|
|
14543
|
+
shouldDisposeEnvService: true,
|
|
14544
|
+
output: undefined,
|
|
14545
|
+
logger: undefined
|
|
14546
|
+
});
|
|
14547
|
+
});
|
|
14365
14548
|
const streamHandleQuery = createStreamHandleQuery(queryExecutor, sessionId, argv, agentContext, eventSourceSystemPrompt);
|
|
14366
14549
|
const stopEventHandler = eventHandler.start();
|
|
14367
14550
|
const stopTaskEventHandler = taskEventHandler.start();
|
|
@@ -14381,9 +14564,19 @@ function createRunCommand() {
|
|
|
14381
14564
|
try {
|
|
14382
14565
|
await waitUntilExit();
|
|
14383
14566
|
} finally {
|
|
14384
|
-
|
|
14385
|
-
|
|
14386
|
-
|
|
14567
|
+
shutdownHandle.dispose();
|
|
14568
|
+
await shutdownRunSteps({
|
|
14569
|
+
lspManagerDispose: null,
|
|
14570
|
+
pluginAdapterDispose: null,
|
|
14571
|
+
stopEventHandler,
|
|
14572
|
+
stopTaskEventHandler,
|
|
14573
|
+
queryExecutor,
|
|
14574
|
+
env,
|
|
14575
|
+
envService,
|
|
14576
|
+
shouldDisposeEnvService: true,
|
|
14577
|
+
output: undefined,
|
|
14578
|
+
logger: undefined
|
|
14579
|
+
});
|
|
14387
14580
|
process.exit(0);
|
|
14388
14581
|
}
|
|
14389
14582
|
}
|
|
@@ -14396,7 +14589,7 @@ import React8 from "react";
|
|
|
14396
14589
|
import { render as render2 } from "ink";
|
|
14397
14590
|
|
|
14398
14591
|
// src/ChatTui.tsx
|
|
14399
|
-
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
14592
|
+
import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
|
|
14400
14593
|
import { Box as Box7, useApp as useApp3 } from "ink";
|
|
14401
14594
|
init_markdown();
|
|
14402
14595
|
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
@@ -14410,8 +14603,9 @@ var ChatScreen = ({
|
|
|
14410
14603
|
markdownEnabled: markdownEnabled2
|
|
14411
14604
|
}) => {
|
|
14412
14605
|
const [history, setHistory] = useState7([
|
|
14413
|
-
{ role: "user", content: message }
|
|
14606
|
+
{ role: "user", content: message, id: "h-init-1" }
|
|
14414
14607
|
]);
|
|
14608
|
+
const historyIdRef = useRef3(1);
|
|
14415
14609
|
const stream = useStreamingAccumulator();
|
|
14416
14610
|
const { exit } = useApp3();
|
|
14417
14611
|
const width = process.stdout.columns ?? 80;
|
|
@@ -14431,16 +14625,21 @@ var ChatScreen = ({
|
|
|
14431
14625
|
stream.finish();
|
|
14432
14626
|
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
14433
14627
|
const finalText = truncateForTerminal(rendered, maxLines);
|
|
14434
|
-
|
|
14628
|
+
const assistantId = `h${++historyIdRef.current}`;
|
|
14629
|
+
setHistory((h) => [
|
|
14630
|
+
...h,
|
|
14631
|
+
{ role: "assistant", content: finalText, id: assistantId }
|
|
14632
|
+
]);
|
|
14435
14633
|
setTimeout(() => exit(), 100);
|
|
14436
14634
|
} catch (err) {
|
|
14437
14635
|
if (cancelled)
|
|
14438
14636
|
return;
|
|
14439
14637
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14440
14638
|
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
14639
|
+
const errorId = `h${++historyIdRef.current}`;
|
|
14441
14640
|
setHistory((h) => [
|
|
14442
14641
|
...h,
|
|
14443
|
-
{ role: "tool", content: `❌ Error: ${msg}
|
|
14642
|
+
{ role: "tool", content: `❌ Error: ${msg}`, id: errorId }
|
|
14444
14643
|
]);
|
|
14445
14644
|
setTimeout(() => exit(), 100);
|
|
14446
14645
|
}
|
|
Binary file
|