@ai-setting/roy-agent-cli 1.6.41 → 1.7.0
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 +379 -173
- package/dist/index.js +379 -173
- package/dist/roy-agent-linux-x64/bin/roy-agent +0 -0
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -796,99 +796,6 @@ var init_welcome_card = __esm(() => {
|
|
|
796
796
|
];
|
|
797
797
|
});
|
|
798
798
|
|
|
799
|
-
// package.json
|
|
800
|
-
var require_package = __commonJS((exports, module) => {
|
|
801
|
-
module.exports = {
|
|
802
|
-
name: "@ai-setting/roy-agent-cli",
|
|
803
|
-
version: "1.6.41",
|
|
804
|
-
type: "module",
|
|
805
|
-
description: "CLI for roy-agent - Non-interactive command execution",
|
|
806
|
-
main: "./dist/index.js",
|
|
807
|
-
module: "./dist/index.js",
|
|
808
|
-
types: "./dist/index.d.ts",
|
|
809
|
-
bin: {
|
|
810
|
-
"roy-agent": "./dist/bin/roy-agent.js"
|
|
811
|
-
},
|
|
812
|
-
exports: {
|
|
813
|
-
".": {
|
|
814
|
-
import: "./dist/index.js",
|
|
815
|
-
types: "./dist/index.d.ts"
|
|
816
|
-
},
|
|
817
|
-
"./package.json": "./package.json"
|
|
818
|
-
},
|
|
819
|
-
files: [
|
|
820
|
-
"dist/**/*",
|
|
821
|
-
"README.md"
|
|
822
|
-
],
|
|
823
|
-
scripts: {
|
|
824
|
-
build: "bunup && bun run postbuild",
|
|
825
|
-
postbuild: "bun run scripts/postbuild.ts",
|
|
826
|
-
clean: "rm -rf dist",
|
|
827
|
-
lint: "eslint --max-warnings 0 src/",
|
|
828
|
-
"lint:fix": "eslint --fix src/",
|
|
829
|
-
typecheck: "npx tsc --noEmit --skipLibCheck"
|
|
830
|
-
},
|
|
831
|
-
dependencies: {
|
|
832
|
-
"@ai-setting/roy-agent-coder-harness": "^1.5.50",
|
|
833
|
-
"@ai-setting/roy-agent-core": "^1.5.83",
|
|
834
|
-
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
835
|
-
"@clack/prompts": "^1.7.0",
|
|
836
|
-
chalk: "^5.6.2",
|
|
837
|
-
"cli-highlight": "^2.1.11",
|
|
838
|
-
commander: "^14.0.3",
|
|
839
|
-
effect: "^3.21.2",
|
|
840
|
-
ink: "^5.2.1",
|
|
841
|
-
"ink-text-input": "^6.0.0",
|
|
842
|
-
marked: "^18.0.7",
|
|
843
|
-
pyright: "^1.1.409",
|
|
844
|
-
react: "^18",
|
|
845
|
-
"react-devtools-core": "^7.0.1",
|
|
846
|
-
"react-dom": "^18",
|
|
847
|
-
"typescript-language-server": "^5.1.3",
|
|
848
|
-
"vscode-css-languageserver-bin": "^1.4.0",
|
|
849
|
-
"vscode-html-languageserver-bin": "^1.4.0",
|
|
850
|
-
"vscode-json-languageserver": "^1.3.4",
|
|
851
|
-
yargs: "^17.7.2",
|
|
852
|
-
"zod-to-json-schema": "^3.25.2"
|
|
853
|
-
},
|
|
854
|
-
devDependencies: {
|
|
855
|
-
"@types/node": "^20.10.0",
|
|
856
|
-
"@types/react": "^18",
|
|
857
|
-
"@types/react-dom": "^18",
|
|
858
|
-
"@types/yargs": "^17.0.32",
|
|
859
|
-
"@typescript-eslint/parser": "^8.62.1",
|
|
860
|
-
bunup: "^0.16.0",
|
|
861
|
-
eslint: "^10.6.0",
|
|
862
|
-
"ink-testing-library": "^4.0.0",
|
|
863
|
-
typescript: "^5.3.0"
|
|
864
|
-
},
|
|
865
|
-
engines: {
|
|
866
|
-
node: ">=18.0.0"
|
|
867
|
-
},
|
|
868
|
-
repository: {
|
|
869
|
-
type: "git",
|
|
870
|
-
url: "https://github.com/ai-setting/roy-agent.git",
|
|
871
|
-
directory: "packages/cli"
|
|
872
|
-
},
|
|
873
|
-
publishConfig: {
|
|
874
|
-
registry: "https://registry.npmjs.org",
|
|
875
|
-
access: "public"
|
|
876
|
-
},
|
|
877
|
-
keywords: [
|
|
878
|
-
"roy-agent",
|
|
879
|
-
"agent",
|
|
880
|
-
"ai",
|
|
881
|
-
"cli",
|
|
882
|
-
"command-line"
|
|
883
|
-
],
|
|
884
|
-
author: "ai-setting",
|
|
885
|
-
license: "MIT",
|
|
886
|
-
bugs: {
|
|
887
|
-
url: "https://github.com/ai-setting/roy-agent/issues"
|
|
888
|
-
}
|
|
889
|
-
};
|
|
890
|
-
});
|
|
891
|
-
|
|
892
799
|
// src/commands/shared/clipboard-helper.ts
|
|
893
800
|
var exports_clipboard_helper = {};
|
|
894
801
|
__export(exports_clipboard_helper, {
|
|
@@ -9550,6 +9457,105 @@ class CliQuietModeService {
|
|
|
9550
9457
|
setCoreQuietMode(false);
|
|
9551
9458
|
}
|
|
9552
9459
|
}
|
|
9460
|
+
// package.json
|
|
9461
|
+
var package_default = {
|
|
9462
|
+
name: "@ai-setting/roy-agent-cli",
|
|
9463
|
+
version: "1.7.0",
|
|
9464
|
+
type: "module",
|
|
9465
|
+
description: "CLI for roy-agent - Non-interactive command execution",
|
|
9466
|
+
main: "./dist/index.js",
|
|
9467
|
+
module: "./dist/index.js",
|
|
9468
|
+
types: "./dist/index.d.ts",
|
|
9469
|
+
bin: {
|
|
9470
|
+
"roy-agent": "./dist/bin/roy-agent.js"
|
|
9471
|
+
},
|
|
9472
|
+
exports: {
|
|
9473
|
+
".": {
|
|
9474
|
+
import: "./dist/index.js",
|
|
9475
|
+
types: "./dist/index.d.ts"
|
|
9476
|
+
},
|
|
9477
|
+
"./package.json": "./package.json"
|
|
9478
|
+
},
|
|
9479
|
+
files: [
|
|
9480
|
+
"dist/**/*",
|
|
9481
|
+
"README.md"
|
|
9482
|
+
],
|
|
9483
|
+
scripts: {
|
|
9484
|
+
build: "bunup && bun run postbuild",
|
|
9485
|
+
postbuild: "bun run scripts/postbuild.ts",
|
|
9486
|
+
clean: "rm -rf dist",
|
|
9487
|
+
lint: "eslint --max-warnings 0 src/",
|
|
9488
|
+
"lint:fix": "eslint --fix src/",
|
|
9489
|
+
typecheck: "npx tsc --noEmit --skipLibCheck"
|
|
9490
|
+
},
|
|
9491
|
+
dependencies: {
|
|
9492
|
+
"@ai-setting/roy-agent-coder-harness": "^1.5.50",
|
|
9493
|
+
"@ai-setting/roy-agent-core": "^1.5.83",
|
|
9494
|
+
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
9495
|
+
"@clack/prompts": "^1.7.0",
|
|
9496
|
+
chalk: "^5.6.2",
|
|
9497
|
+
"cli-highlight": "^2.1.11",
|
|
9498
|
+
commander: "^14.0.3",
|
|
9499
|
+
effect: "^3.21.2",
|
|
9500
|
+
ink: "^5.2.1",
|
|
9501
|
+
"ink-text-input": "^6.0.0",
|
|
9502
|
+
marked: "^18.0.7",
|
|
9503
|
+
pyright: "^1.1.409",
|
|
9504
|
+
react: "^18",
|
|
9505
|
+
"react-devtools-core": "^7.0.1",
|
|
9506
|
+
"react-dom": "^18",
|
|
9507
|
+
"typescript-language-server": "^5.1.3",
|
|
9508
|
+
"vscode-css-languageserver-bin": "^1.4.0",
|
|
9509
|
+
"vscode-html-languageserver-bin": "^1.4.0",
|
|
9510
|
+
"vscode-json-languageserver": "^1.3.4",
|
|
9511
|
+
yargs: "^17.7.2",
|
|
9512
|
+
"zod-to-json-schema": "^3.25.2",
|
|
9513
|
+
"@earendil-works/pi-ai": "^0.74.2"
|
|
9514
|
+
},
|
|
9515
|
+
devDependencies: {
|
|
9516
|
+
"@types/node": "^20.10.0",
|
|
9517
|
+
"@types/react": "^18",
|
|
9518
|
+
"@types/react-dom": "^18",
|
|
9519
|
+
"@types/yargs": "^17.0.32",
|
|
9520
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
9521
|
+
bunup: "^0.16.0",
|
|
9522
|
+
eslint: "^10.6.0",
|
|
9523
|
+
"ink-testing-library": "^4.0.0",
|
|
9524
|
+
typescript: "^5.3.0"
|
|
9525
|
+
},
|
|
9526
|
+
engines: {
|
|
9527
|
+
node: ">=18.0.0"
|
|
9528
|
+
},
|
|
9529
|
+
repository: {
|
|
9530
|
+
type: "git",
|
|
9531
|
+
url: "https://github.com/ai-setting/roy-agent.git",
|
|
9532
|
+
directory: "packages/cli"
|
|
9533
|
+
},
|
|
9534
|
+
publishConfig: {
|
|
9535
|
+
registry: "https://registry.npmjs.org",
|
|
9536
|
+
access: "public"
|
|
9537
|
+
},
|
|
9538
|
+
keywords: [
|
|
9539
|
+
"roy-agent",
|
|
9540
|
+
"agent",
|
|
9541
|
+
"ai",
|
|
9542
|
+
"cli",
|
|
9543
|
+
"command-line"
|
|
9544
|
+
],
|
|
9545
|
+
author: "ai-setting",
|
|
9546
|
+
license: "MIT",
|
|
9547
|
+
bugs: {
|
|
9548
|
+
url: "https://github.com/ai-setting/roy-agent/issues"
|
|
9549
|
+
}
|
|
9550
|
+
};
|
|
9551
|
+
|
|
9552
|
+
// src/lib/version.ts
|
|
9553
|
+
function getPackageVersion() {
|
|
9554
|
+
if (typeof ROY_AGENT_VERSION !== "undefined") {
|
|
9555
|
+
return ROY_AGENT_VERSION;
|
|
9556
|
+
}
|
|
9557
|
+
return package_default.version;
|
|
9558
|
+
}
|
|
9553
9559
|
|
|
9554
9560
|
// src/commands/act.ts
|
|
9555
9561
|
import { execFile, execFileSync } from "node:child_process";
|
|
@@ -12269,12 +12275,6 @@ var COLOR_BY_STATUS = {
|
|
|
12269
12275
|
running: COLORS.accent,
|
|
12270
12276
|
busy: COLORS.accent
|
|
12271
12277
|
};
|
|
12272
|
-
// src/lib/version.ts
|
|
12273
|
-
var import__package = __toESM(require_package(), 1);
|
|
12274
|
-
function getPackageVersion() {
|
|
12275
|
-
return import__package.default.version;
|
|
12276
|
-
}
|
|
12277
|
-
|
|
12278
12278
|
// src/commands/interactive.ts
|
|
12279
12279
|
var logger4 = createLogger5("cli:interactive");
|
|
12280
12280
|
var USER_PROMPT = COLORS.accent("❯ ");
|
|
@@ -13380,6 +13380,9 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13380
13380
|
showToolCalls: args.toolCalls,
|
|
13381
13381
|
showToolResults: args.toolResults
|
|
13382
13382
|
}, traceId, mergedContext);
|
|
13383
|
+
if (result && !queryExecutor.getFullText()) {
|
|
13384
|
+
console.log(result);
|
|
13385
|
+
}
|
|
13383
13386
|
repl.setLastUsage(queryExecutor.getLastUsage());
|
|
13384
13387
|
return result;
|
|
13385
13388
|
},
|
|
@@ -13518,7 +13521,7 @@ import React6 from "react";
|
|
|
13518
13521
|
import { render } from "ink";
|
|
13519
13522
|
|
|
13520
13523
|
// src/RunTui.tsx
|
|
13521
|
-
import { useState as useState6, useCallback as useCallback4, useRef as useRef2 } from "react";
|
|
13524
|
+
import { useState as useState6, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect5 } from "react";
|
|
13522
13525
|
import { Box as Box6, Text as Text8, useApp as useApp2 } from "ink";
|
|
13523
13526
|
|
|
13524
13527
|
// src/tui/App.tsx
|
|
@@ -13830,7 +13833,7 @@ function useStreamingAccumulator() {
|
|
|
13830
13833
|
let snapshot = "";
|
|
13831
13834
|
setStreamingText((prev) => {
|
|
13832
13835
|
snapshot = prev;
|
|
13833
|
-
return
|
|
13836
|
+
return "";
|
|
13834
13837
|
});
|
|
13835
13838
|
return snapshot;
|
|
13836
13839
|
}, []);
|
|
@@ -13839,7 +13842,7 @@ function useStreamingAccumulator() {
|
|
|
13839
13842
|
let snapshot = "";
|
|
13840
13843
|
setStreamingText((prev) => {
|
|
13841
13844
|
snapshot = prev;
|
|
13842
|
-
return
|
|
13845
|
+
return "";
|
|
13843
13846
|
});
|
|
13844
13847
|
return snapshot;
|
|
13845
13848
|
}, []);
|
|
@@ -13930,7 +13933,8 @@ var RunScreen = ({
|
|
|
13930
13933
|
workdir,
|
|
13931
13934
|
maxLines: initialMaxLines,
|
|
13932
13935
|
markdownEnabled: markdownEnabled2,
|
|
13933
|
-
onExit
|
|
13936
|
+
onExit,
|
|
13937
|
+
onRegisterHandlers
|
|
13934
13938
|
}) => {
|
|
13935
13939
|
const [history, setHistory] = useState6([]);
|
|
13936
13940
|
const [errorMessage, setErrorMessage] = useState6(null);
|
|
@@ -13941,11 +13945,60 @@ var RunScreen = ({
|
|
|
13941
13945
|
const { exit } = useApp2();
|
|
13942
13946
|
const userTurnCountRef = useRef2(0);
|
|
13943
13947
|
const assistantTurnCountRef = useRef2(0);
|
|
13948
|
+
const isProcessingRef = useRef2(0);
|
|
13949
|
+
const executeQueryRef = useRef2(null);
|
|
13944
13950
|
const width = process.stdout.columns ?? 80;
|
|
13945
13951
|
const doExit = useCallback4(() => {
|
|
13946
13952
|
onExit?.();
|
|
13947
13953
|
exit();
|
|
13948
13954
|
}, [onExit, exit]);
|
|
13955
|
+
const executeQuery = useCallback4(async (message) => {
|
|
13956
|
+
isProcessingRef.current += 1;
|
|
13957
|
+
stream.start();
|
|
13958
|
+
try {
|
|
13959
|
+
let responseText;
|
|
13960
|
+
if (streamHandleQuery) {
|
|
13961
|
+
responseText = await streamHandleQuery(message, (chunk) => stream.append(chunk));
|
|
13962
|
+
} else {
|
|
13963
|
+
responseText = await handleQuery(message);
|
|
13964
|
+
}
|
|
13965
|
+
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
13966
|
+
const finalText = truncateForTerminal(rendered, maxLines);
|
|
13967
|
+
stream.finish();
|
|
13968
|
+
setHistory((h) => [...h, { role: "assistant", content: finalText }]);
|
|
13969
|
+
assistantTurnCountRef.current += 1;
|
|
13970
|
+
} catch (err) {
|
|
13971
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
13972
|
+
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
13973
|
+
setErrorMessage(msg);
|
|
13974
|
+
setHistory((h) => [
|
|
13975
|
+
...h,
|
|
13976
|
+
{ role: "tool", content: `❌ Error: ${msg}` }
|
|
13977
|
+
]);
|
|
13978
|
+
} finally {
|
|
13979
|
+
isProcessingRef.current -= 1;
|
|
13980
|
+
}
|
|
13981
|
+
}, [handleQuery, markdownEnabled2, maxLines, stream, streamHandleQuery, width]);
|
|
13982
|
+
useEffect5(() => {
|
|
13983
|
+
executeQueryRef.current = executeQuery;
|
|
13984
|
+
}, [executeQuery]);
|
|
13985
|
+
useEffect5(() => {
|
|
13986
|
+
if (!onRegisterHandlers)
|
|
13987
|
+
return;
|
|
13988
|
+
const handleNotification = async (message, _envEvent) => {
|
|
13989
|
+
setHistory((h) => [
|
|
13990
|
+
...h,
|
|
13991
|
+
{ role: "tool", content: `\uD83D\uDCE2 ${message}` }
|
|
13992
|
+
]);
|
|
13993
|
+
if (executeQueryRef.current) {
|
|
13994
|
+
await executeQueryRef.current(message);
|
|
13995
|
+
}
|
|
13996
|
+
};
|
|
13997
|
+
const isIdle = () => {
|
|
13998
|
+
return isProcessingRef.current === 0;
|
|
13999
|
+
};
|
|
14000
|
+
onRegisterHandlers({ onNotification: handleNotification, isIdle });
|
|
14001
|
+
}, [onRegisterHandlers]);
|
|
13949
14002
|
const handleSubmit = useCallback4(async (raw) => {
|
|
13950
14003
|
const trimmed = raw.trim();
|
|
13951
14004
|
if (!trimmed)
|
|
@@ -14007,38 +14060,14 @@ var RunScreen = ({
|
|
|
14007
14060
|
setHistory((h) => [...h, { role: "user", content: trimmed }]);
|
|
14008
14061
|
setUserHistory((uh) => [trimmed, ...uh]);
|
|
14009
14062
|
userTurnCountRef.current += 1;
|
|
14010
|
-
|
|
14011
|
-
try {
|
|
14012
|
-
let responseText;
|
|
14013
|
-
if (streamHandleQuery) {
|
|
14014
|
-
responseText = await streamHandleQuery(trimmed, (chunk) => stream.append(chunk));
|
|
14015
|
-
} else {
|
|
14016
|
-
responseText = await handleQuery(trimmed);
|
|
14017
|
-
}
|
|
14018
|
-
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
14019
|
-
const finalText = truncateForTerminal(rendered, maxLines);
|
|
14020
|
-
stream.finish();
|
|
14021
|
-
setHistory((h) => [...h, { role: "assistant", content: finalText }]);
|
|
14022
|
-
assistantTurnCountRef.current += 1;
|
|
14023
|
-
} catch (err) {
|
|
14024
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
14025
|
-
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
14026
|
-
setErrorMessage(msg);
|
|
14027
|
-
setHistory((h) => [
|
|
14028
|
-
...h,
|
|
14029
|
-
{ role: "tool", content: `❌ Error: ${msg}` }
|
|
14030
|
-
]);
|
|
14031
|
-
}
|
|
14063
|
+
await executeQuery(trimmed);
|
|
14032
14064
|
}, [
|
|
14033
14065
|
doExit,
|
|
14034
14066
|
exit,
|
|
14035
|
-
|
|
14036
|
-
markdownEnabled2,
|
|
14067
|
+
executeQuery,
|
|
14037
14068
|
maxLines,
|
|
14038
14069
|
model,
|
|
14039
|
-
|
|
14040
|
-
streamHandleQuery,
|
|
14041
|
-
width
|
|
14070
|
+
workdir
|
|
14042
14071
|
]);
|
|
14043
14072
|
const handleCancel = useCallback4(() => {
|
|
14044
14073
|
doExit();
|
|
@@ -14081,7 +14110,7 @@ var RunTui_default = RunScreen;
|
|
|
14081
14110
|
|
|
14082
14111
|
// src/commands/run.ts
|
|
14083
14112
|
init_markdown();
|
|
14084
|
-
async function loadHandleQuery(options) {
|
|
14113
|
+
async function loadHandleQuery(options, hooks) {
|
|
14085
14114
|
const quiet = CliQuietModeService.getInstance().isQuiet();
|
|
14086
14115
|
const output = new OutputService2;
|
|
14087
14116
|
output.configure({ quiet });
|
|
@@ -14098,10 +14127,126 @@ async function loadHandleQuery(options) {
|
|
|
14098
14127
|
if (!env) {
|
|
14099
14128
|
throw new Error("Failed to create environment");
|
|
14100
14129
|
}
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14130
|
+
const sessionComponent = envService.getSession();
|
|
14131
|
+
if (!sessionComponent) {
|
|
14132
|
+
throw new Error("Failed to create session component");
|
|
14133
|
+
}
|
|
14134
|
+
const sessionManager = new SessionManager({
|
|
14135
|
+
sessionComponent,
|
|
14136
|
+
output,
|
|
14137
|
+
quiet: true
|
|
14138
|
+
});
|
|
14139
|
+
const sessionResult = await sessionManager.init(options.session, options.continue);
|
|
14140
|
+
const sessionId = sessionResult.sessionId;
|
|
14141
|
+
const queryExecutor = new QueryExecutor({
|
|
14142
|
+
env,
|
|
14143
|
+
sessionComponent,
|
|
14144
|
+
output,
|
|
14145
|
+
quiet: true,
|
|
14146
|
+
silent: true
|
|
14147
|
+
});
|
|
14148
|
+
let agentContext = undefined;
|
|
14149
|
+
if (options.agent && options.agent !== "default") {
|
|
14150
|
+
const agentComponent = env.getComponent("agent");
|
|
14151
|
+
const validation = validateActAgent(agentComponent, options.agent);
|
|
14152
|
+
if (!validation.valid) {
|
|
14153
|
+
output.error(validation.message);
|
|
14154
|
+
output.info("提示: roy-agent agents list");
|
|
14155
|
+
process.exit(1);
|
|
14156
|
+
}
|
|
14157
|
+
agentContext = buildActAgentContext(options.agent);
|
|
14158
|
+
}
|
|
14159
|
+
let eventSourceSystemPrompt;
|
|
14160
|
+
const rawEventSourceIds = options.eventSource;
|
|
14161
|
+
const eventSourceIds = Array.isArray(rawEventSourceIds) ? rawEventSourceIds.filter((s) => !!s) : rawEventSourceIds ? [rawEventSourceIds] : [];
|
|
14162
|
+
if (eventSourceIds.length > 0) {
|
|
14163
|
+
const eventSourceComponent = env.getComponent("event-source");
|
|
14164
|
+
if (!eventSourceComponent || typeof eventSourceComponent.startSource !== "function") {
|
|
14165
|
+
output.error("❌ 未找到事件源组件或 startSource 方法");
|
|
14166
|
+
output.info("请确保 EventSourceComponent 已正确注册");
|
|
14167
|
+
process.exit(1);
|
|
14168
|
+
}
|
|
14169
|
+
const summary = await startEventSources(eventSourceIds, eventSourceComponent, output);
|
|
14170
|
+
const preloadedPrompts = collectEventSourceSystemPrompts(eventSourceIds, eventSourceComponent);
|
|
14171
|
+
eventSourceSystemPrompt = preloadedPrompts.length > 0 ? joinResolvedSystemPrompts(preloadedPrompts) : undefined;
|
|
14172
|
+
if (eventSourceIds.length === 1 && summary.failedCount > 0) {
|
|
14173
|
+
process.exit(1);
|
|
14174
|
+
}
|
|
14175
|
+
}
|
|
14176
|
+
const llmComponent = envService.getLLM();
|
|
14177
|
+
queryExecutor.initStreamOutput(llmComponent ?? null);
|
|
14178
|
+
const handleQuery = async (message) => {
|
|
14179
|
+
const mergedContext = {
|
|
14180
|
+
...agentContext,
|
|
14181
|
+
model: options.model,
|
|
14182
|
+
eventSourceSystemPrompt,
|
|
14183
|
+
metadata: {
|
|
14184
|
+
...agentContext?.metadata ?? {},
|
|
14185
|
+
defaultAgentName: options.defaultAgentName
|
|
14186
|
+
}
|
|
14187
|
+
};
|
|
14188
|
+
const result = await queryExecutor.execute(message, sessionId, {
|
|
14189
|
+
showReasoning: options.reasoning ?? true,
|
|
14190
|
+
showToolCalls: options.toolCalls ?? true,
|
|
14191
|
+
showToolResults: options.toolResults ?? false
|
|
14192
|
+
}, undefined, mergedContext);
|
|
14193
|
+
return String(result ?? "");
|
|
14194
|
+
};
|
|
14195
|
+
const taskEventHandler = new TaskEventHandler({
|
|
14196
|
+
env,
|
|
14197
|
+
enabled: true
|
|
14198
|
+
});
|
|
14199
|
+
const eventHandler = new EventHandler({
|
|
14200
|
+
env,
|
|
14201
|
+
eventTypes: ["task.background.*", "event-source.event.*"],
|
|
14202
|
+
formatter: new EventMessageFormatter({ prefix: "[通知]" }),
|
|
14203
|
+
isIdle: hooks?.isIdle ?? (() => true),
|
|
14204
|
+
sessionComponent,
|
|
14205
|
+
onEvent: async (_message) => {},
|
|
14206
|
+
onEventWithEnv: async (formattedEvent) => {
|
|
14207
|
+
if (hooks?.onNotification) {
|
|
14208
|
+
await hooks.onNotification(formattedEvent.message, formattedEvent.envEvent);
|
|
14209
|
+
}
|
|
14210
|
+
}
|
|
14211
|
+
});
|
|
14212
|
+
return {
|
|
14213
|
+
handleQuery,
|
|
14214
|
+
envService,
|
|
14215
|
+
env,
|
|
14216
|
+
sessionId,
|
|
14217
|
+
queryExecutor,
|
|
14218
|
+
agentContext,
|
|
14219
|
+
eventSourceSystemPrompt,
|
|
14220
|
+
sessionComponent,
|
|
14221
|
+
eventHandler,
|
|
14222
|
+
taskEventHandler
|
|
14223
|
+
};
|
|
14224
|
+
}
|
|
14225
|
+
function createStreamHandleQuery(queryExecutor, sessionId, options, agentContext, eventSourceSystemPrompt) {
|
|
14226
|
+
return async (message, onChunk) => {
|
|
14227
|
+
queryExecutor.setChunkCallback((event) => {
|
|
14228
|
+
if (event.type === "llm.text") {
|
|
14229
|
+
if (event.delta) {
|
|
14230
|
+
onChunk(event.delta);
|
|
14231
|
+
} else if (event.content) {
|
|
14232
|
+
onChunk(event.content);
|
|
14233
|
+
}
|
|
14234
|
+
}
|
|
14104
14235
|
});
|
|
14236
|
+
const mergedContext = {
|
|
14237
|
+
...agentContext,
|
|
14238
|
+
model: options.model,
|
|
14239
|
+
eventSourceSystemPrompt,
|
|
14240
|
+
metadata: {
|
|
14241
|
+
...agentContext?.metadata ?? {},
|
|
14242
|
+
defaultAgentName: options.defaultAgentName
|
|
14243
|
+
}
|
|
14244
|
+
};
|
|
14245
|
+
const result = await queryExecutor.execute(message, sessionId, {
|
|
14246
|
+
showReasoning: options.reasoning ?? true,
|
|
14247
|
+
showToolCalls: options.toolCalls ?? true,
|
|
14248
|
+
showToolResults: options.toolResults ?? false
|
|
14249
|
+
}, undefined, mergedContext);
|
|
14105
14250
|
return String(result ?? "");
|
|
14106
14251
|
};
|
|
14107
14252
|
}
|
|
@@ -14141,6 +14286,41 @@ function createRunCommand() {
|
|
|
14141
14286
|
}).option("env", {
|
|
14142
14287
|
type: "string",
|
|
14143
14288
|
describe: "Environment name"
|
|
14289
|
+
}).option("session", {
|
|
14290
|
+
type: "string",
|
|
14291
|
+
describe: "指定会话 ID(注: -s 已被 --system-prompt 占用)"
|
|
14292
|
+
}).option("continue", {
|
|
14293
|
+
alias: "c",
|
|
14294
|
+
type: "boolean",
|
|
14295
|
+
describe: "继续上次会话",
|
|
14296
|
+
default: false
|
|
14297
|
+
}).option("reasoning", {
|
|
14298
|
+
alias: "r",
|
|
14299
|
+
type: "boolean",
|
|
14300
|
+
describe: "显示 AI 思考过程",
|
|
14301
|
+
default: true
|
|
14302
|
+
}).option("tool-calls", {
|
|
14303
|
+
type: "boolean",
|
|
14304
|
+
describe: "显示工具调用",
|
|
14305
|
+
default: true
|
|
14306
|
+
}).option("tool-results", {
|
|
14307
|
+
type: "boolean",
|
|
14308
|
+
describe: "显示工具执行结果",
|
|
14309
|
+
default: false
|
|
14310
|
+
}).option("event-source", {
|
|
14311
|
+
alias: "es",
|
|
14312
|
+
type: "array",
|
|
14313
|
+
string: true,
|
|
14314
|
+
describe: "启动时一并启动的事件源 ID(可多次指定,支持 --es a --es b)"
|
|
14315
|
+
}).option("agent", {
|
|
14316
|
+
alias: "a",
|
|
14317
|
+
type: "string",
|
|
14318
|
+
describe: "指定使用的 agent (如 explore, general)"
|
|
14319
|
+
}).option("default-agent-name", {
|
|
14320
|
+
alias: "dan",
|
|
14321
|
+
type: "string",
|
|
14322
|
+
describe: "Default agent 名字(默认 Roy,可被覆盖)",
|
|
14323
|
+
default: "Roy"
|
|
14144
14324
|
}),
|
|
14145
14325
|
handler: async (argv) => {
|
|
14146
14326
|
if (argv.markdown === false) {
|
|
@@ -14149,18 +14329,44 @@ function createRunCommand() {
|
|
|
14149
14329
|
setMarkdownEnabled(true);
|
|
14150
14330
|
}
|
|
14151
14331
|
const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
|
|
14152
|
-
const
|
|
14332
|
+
const runState = {
|
|
14333
|
+
isIdle: () => true,
|
|
14334
|
+
onNotification: () => {}
|
|
14335
|
+
};
|
|
14336
|
+
const {
|
|
14337
|
+
handleQuery,
|
|
14338
|
+
queryExecutor,
|
|
14339
|
+
sessionId,
|
|
14340
|
+
agentContext,
|
|
14341
|
+
eventSourceSystemPrompt,
|
|
14342
|
+
eventHandler,
|
|
14343
|
+
taskEventHandler
|
|
14344
|
+
} = await loadHandleQuery(argv, {
|
|
14345
|
+
isIdle: () => runState.isIdle(),
|
|
14346
|
+
onNotification: (msg, envEvent) => runState.onNotification(msg, envEvent)
|
|
14347
|
+
});
|
|
14348
|
+
const streamHandleQuery = createStreamHandleQuery(queryExecutor, sessionId, argv, agentContext, eventSourceSystemPrompt);
|
|
14349
|
+
const stopEventHandler = eventHandler.start();
|
|
14350
|
+
const stopTaskEventHandler = taskEventHandler.start();
|
|
14153
14351
|
const { waitUntilExit } = render(React6.createElement(RunTui_default, {
|
|
14154
14352
|
handleQuery,
|
|
14353
|
+
streamHandleQuery,
|
|
14155
14354
|
model: argv.model,
|
|
14156
14355
|
workdir: argv.workdir,
|
|
14157
14356
|
maxLines,
|
|
14158
14357
|
markdownEnabled: argv.markdown !== false,
|
|
14358
|
+
onRegisterHandlers: (handlers) => {
|
|
14359
|
+
runState.onNotification = handlers.onNotification;
|
|
14360
|
+
runState.isIdle = handlers.isIdle;
|
|
14361
|
+
},
|
|
14159
14362
|
onExit: () => {}
|
|
14160
14363
|
}), { exitOnCtrlC: true });
|
|
14161
14364
|
try {
|
|
14162
14365
|
await waitUntilExit();
|
|
14163
14366
|
} finally {
|
|
14367
|
+
stopEventHandler();
|
|
14368
|
+
stopTaskEventHandler();
|
|
14369
|
+
queryExecutor.dispose();
|
|
14164
14370
|
process.exit(0);
|
|
14165
14371
|
}
|
|
14166
14372
|
}
|
|
@@ -14173,7 +14379,7 @@ import React8 from "react";
|
|
|
14173
14379
|
import { render as render2 } from "ink";
|
|
14174
14380
|
|
|
14175
14381
|
// src/ChatTui.tsx
|
|
14176
|
-
import { useEffect as
|
|
14382
|
+
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
14177
14383
|
import { Box as Box7, useApp as useApp3 } from "ink";
|
|
14178
14384
|
init_markdown();
|
|
14179
14385
|
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
@@ -14192,7 +14398,7 @@ var ChatScreen = ({
|
|
|
14192
14398
|
const stream = useStreamingAccumulator();
|
|
14193
14399
|
const { exit } = useApp3();
|
|
14194
14400
|
const width = process.stdout.columns ?? 80;
|
|
14195
|
-
|
|
14401
|
+
useEffect6(() => {
|
|
14196
14402
|
let cancelled = false;
|
|
14197
14403
|
stream.start();
|
|
14198
14404
|
(async () => {
|
|
@@ -25056,10 +25262,10 @@ var LspInstallCommand = {
|
|
|
25056
25262
|
console.log(`
|
|
25057
25263
|
\uD83D\uDCE6 LSP Server Status
|
|
25058
25264
|
`);
|
|
25059
|
-
for (const
|
|
25060
|
-
const isInstalled = installed.includes(
|
|
25265
|
+
for (const pkg of LSP_PACKAGES) {
|
|
25266
|
+
const isInstalled = installed.includes(pkg.serverId);
|
|
25061
25267
|
const status = isInstalled ? "✓ installed" : "✗ not installed";
|
|
25062
|
-
console.log(` ${status.padEnd(20)} ${
|
|
25268
|
+
console.log(` ${status.padEnd(20)} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25063
25269
|
}
|
|
25064
25270
|
console.log(`
|
|
25065
25271
|
${installed.length}/${LSP_PACKAGES.length} installed
|
|
@@ -25110,10 +25316,10 @@ ${installed.length}/${LSP_PACKAGES.length} installed
|
|
|
25110
25316
|
console.log(`
|
|
25111
25317
|
\uD83D\uDCE6 Available LSP Servers
|
|
25112
25318
|
`);
|
|
25113
|
-
for (const
|
|
25114
|
-
const isInstalled = installer.isInstalled(
|
|
25319
|
+
for (const pkg of LSP_PACKAGES) {
|
|
25320
|
+
const isInstalled = installer.isInstalled(pkg.npmPackage);
|
|
25115
25321
|
const status = isInstalled ? "✓" : "○";
|
|
25116
|
-
console.log(` ${status} ${
|
|
25322
|
+
console.log(` ${status} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25117
25323
|
}
|
|
25118
25324
|
console.log(`
|
|
25119
25325
|
Run 'roy-agent lsp install <language>' to install specific servers`);
|
|
@@ -25142,11 +25348,11 @@ var LspListCommand = {
|
|
|
25142
25348
|
const installer = createInstaller2();
|
|
25143
25349
|
const installed = installer.getInstalledPackages();
|
|
25144
25350
|
if (argv.json) {
|
|
25145
|
-
const result = LSP_PACKAGES2.map((
|
|
25146
|
-
serverId:
|
|
25147
|
-
npmPackage:
|
|
25148
|
-
description:
|
|
25149
|
-
installed: installed.includes(
|
|
25351
|
+
const result = LSP_PACKAGES2.map((pkg) => ({
|
|
25352
|
+
serverId: pkg.serverId,
|
|
25353
|
+
npmPackage: pkg.npmPackage,
|
|
25354
|
+
description: pkg.description,
|
|
25355
|
+
installed: installed.includes(pkg.serverId)
|
|
25150
25356
|
}));
|
|
25151
25357
|
console.log(JSON.stringify(result, null, 2));
|
|
25152
25358
|
return;
|
|
@@ -25154,14 +25360,14 @@ var LspListCommand = {
|
|
|
25154
25360
|
console.log(`
|
|
25155
25361
|
\uD83D\uDCE6 LSP Servers
|
|
25156
25362
|
`);
|
|
25157
|
-
for (const
|
|
25158
|
-
const isInstalled = installed.includes(
|
|
25363
|
+
for (const pkg of LSP_PACKAGES2) {
|
|
25364
|
+
const isInstalled = installed.includes(pkg.serverId);
|
|
25159
25365
|
const status = isInstalled ? "✓" : "○";
|
|
25160
25366
|
const installedText = isInstalled ? "installed" : "not installed";
|
|
25161
|
-
console.log(` ${status} ${
|
|
25162
|
-
console.log(` ${
|
|
25367
|
+
console.log(` ${status} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25368
|
+
console.log(` ${pkg.npmPackage} - ${installedText}`);
|
|
25163
25369
|
if (argv.verbose && isInstalled) {
|
|
25164
|
-
const verify = installer.verify(
|
|
25370
|
+
const verify = installer.verify(pkg.serverId);
|
|
25165
25371
|
if (verify.binary) {
|
|
25166
25372
|
console.log(` Binary: ${verify.binary}`);
|
|
25167
25373
|
}
|
|
@@ -25199,12 +25405,12 @@ var LspCheckCommand = {
|
|
|
25199
25405
|
const servers2 = argv.serverId ? LSP_PACKAGES3.filter((p) => p.serverId === argv.serverId) : LSP_PACKAGES3;
|
|
25200
25406
|
const result = {
|
|
25201
25407
|
config: config.toJSON(),
|
|
25202
|
-
servers: servers2.map((
|
|
25203
|
-
serverId:
|
|
25204
|
-
npmPackage:
|
|
25205
|
-
description:
|
|
25206
|
-
installed: installer.isInstalled(
|
|
25207
|
-
verify: installer.verify(
|
|
25408
|
+
servers: servers2.map((pkg) => ({
|
|
25409
|
+
serverId: pkg.serverId,
|
|
25410
|
+
npmPackage: pkg.npmPackage,
|
|
25411
|
+
description: pkg.description,
|
|
25412
|
+
installed: installer.isInstalled(pkg.npmPackage),
|
|
25413
|
+
verify: installer.verify(pkg.serverId)
|
|
25208
25414
|
}))
|
|
25209
25415
|
};
|
|
25210
25416
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -25222,12 +25428,12 @@ var LspCheckCommand = {
|
|
|
25222
25428
|
\uD83D\uDCE6 LSP Servers Status
|
|
25223
25429
|
`);
|
|
25224
25430
|
let hasIssues = false;
|
|
25225
|
-
for (const
|
|
25226
|
-
const verify = installer.verify(
|
|
25431
|
+
for (const pkg of servers) {
|
|
25432
|
+
const verify = installer.verify(pkg.serverId);
|
|
25227
25433
|
const installed = verify.installed ? "✓ Installed" : "✗ Not installed";
|
|
25228
|
-
console.log(` ${
|
|
25434
|
+
console.log(` ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25229
25435
|
console.log(` ${installed}`);
|
|
25230
|
-
console.log(` Package: ${
|
|
25436
|
+
console.log(` Package: ${pkg.npmPackage}`);
|
|
25231
25437
|
if (verify.binary) {
|
|
25232
25438
|
console.log(` Binary in PATH: ${verify.binary}`);
|
|
25233
25439
|
} else if (verify.installed) {
|
|
@@ -25302,11 +25508,11 @@ function readPackageInfo(packageName) {
|
|
|
25302
25508
|
const localPkgPath = join5(packageName, "package.json");
|
|
25303
25509
|
if (existsSync4(localPkgPath)) {
|
|
25304
25510
|
try {
|
|
25305
|
-
const
|
|
25511
|
+
const pkg = JSON.parse(readFileSync3(localPkgPath, "utf-8"));
|
|
25306
25512
|
return {
|
|
25307
|
-
version:
|
|
25308
|
-
name:
|
|
25309
|
-
description:
|
|
25513
|
+
version: pkg.version ?? "0.0.0",
|
|
25514
|
+
name: pkg.name ?? packageName,
|
|
25515
|
+
description: pkg.description
|
|
25310
25516
|
};
|
|
25311
25517
|
} catch (err) {
|
|
25312
25518
|
console.warn(`⚠️ Failed to parse local package.json at '${localPkgPath}': ${err}`);
|
|
@@ -25326,11 +25532,11 @@ function readPackageInfo(packageName) {
|
|
|
25326
25532
|
for (const pkgPath of searchPaths) {
|
|
25327
25533
|
try {
|
|
25328
25534
|
if (existsSync4(pkgPath)) {
|
|
25329
|
-
const
|
|
25535
|
+
const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
25330
25536
|
return {
|
|
25331
|
-
version:
|
|
25332
|
-
name:
|
|
25333
|
-
description:
|
|
25537
|
+
version: pkg.version ?? "0.0.0",
|
|
25538
|
+
name: pkg.name ?? bareName,
|
|
25539
|
+
description: pkg.description
|
|
25334
25540
|
};
|
|
25335
25541
|
}
|
|
25336
25542
|
} catch (err) {
|
|
@@ -25669,9 +25875,9 @@ Examples:
|
|
|
25669
25875
|
--plugin reminder Enable iteration reminder
|
|
25670
25876
|
--plugin tslsp code-check Enable multiple plugins`;
|
|
25671
25877
|
async function runCli() {
|
|
25672
|
-
const
|
|
25878
|
+
const version = getPackageVersion();
|
|
25673
25879
|
const yargs = yargsLib;
|
|
25674
|
-
await yargs(hideBin(process.argv)).scriptName("roy-agent").version(
|
|
25880
|
+
await yargs(hideBin(process.argv)).scriptName("roy-agent").version(version).option("quiet", {
|
|
25675
25881
|
describe: "Quiet mode (default: on, use --no-quiet to enable logging)",
|
|
25676
25882
|
type: "boolean",
|
|
25677
25883
|
default: true,
|