@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/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 prev;
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 prev;
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
- stream.start();
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
- handleQuery,
14036
- markdownEnabled2,
14067
+ executeQuery,
14037
14068
  maxLines,
14038
14069
  model,
14039
- stream,
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
- return async (message) => {
14102
- const result = await env.handle_query(message, {
14103
- sessionId: "cli-run"
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 handleQuery = await loadHandleQuery(argv);
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 useEffect5, useState as useState7 } from "react";
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
- useEffect5(() => {
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 pkg2 of LSP_PACKAGES) {
25060
- const isInstalled = installed.includes(pkg2.serverId);
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)} ${pkg2.serverId.padEnd(12)} ${pkg2.description}`);
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 pkg2 of LSP_PACKAGES) {
25114
- const isInstalled = installer.isInstalled(pkg2.npmPackage);
25319
+ for (const pkg of LSP_PACKAGES) {
25320
+ const isInstalled = installer.isInstalled(pkg.npmPackage);
25115
25321
  const status = isInstalled ? "✓" : "○";
25116
- console.log(` ${status} ${pkg2.serverId.padEnd(12)} ${pkg2.description}`);
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((pkg2) => ({
25146
- serverId: pkg2.serverId,
25147
- npmPackage: pkg2.npmPackage,
25148
- description: pkg2.description,
25149
- installed: installed.includes(pkg2.serverId)
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 pkg2 of LSP_PACKAGES2) {
25158
- const isInstalled = installed.includes(pkg2.serverId);
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} ${pkg2.serverId.padEnd(12)} ${pkg2.description}`);
25162
- console.log(` ${pkg2.npmPackage} - ${installedText}`);
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(pkg2.serverId);
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((pkg2) => ({
25203
- serverId: pkg2.serverId,
25204
- npmPackage: pkg2.npmPackage,
25205
- description: pkg2.description,
25206
- installed: installer.isInstalled(pkg2.npmPackage),
25207
- verify: installer.verify(pkg2.serverId)
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 pkg2 of servers) {
25226
- const verify = installer.verify(pkg2.serverId);
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(` ${pkg2.serverId.padEnd(12)} ${pkg2.description}`);
25434
+ console.log(` ${pkg.serverId.padEnd(12)} ${pkg.description}`);
25229
25435
  console.log(` ${installed}`);
25230
- console.log(` Package: ${pkg2.npmPackage}`);
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 pkg2 = JSON.parse(readFileSync3(localPkgPath, "utf-8"));
25511
+ const pkg = JSON.parse(readFileSync3(localPkgPath, "utf-8"));
25306
25512
  return {
25307
- version: pkg2.version ?? "0.0.0",
25308
- name: pkg2.name ?? packageName,
25309
- description: pkg2.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 pkg2 = JSON.parse(readFileSync3(pkgPath, "utf-8"));
25535
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
25330
25536
  return {
25331
- version: pkg2.version ?? "0.0.0",
25332
- name: pkg2.name ?? bareName,
25333
- description: pkg2.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 pkg2 = await Promise.resolve().then(() => __toESM(require_package(), 1));
25878
+ const version = getPackageVersion();
25673
25879
  const yargs = yargsLib;
25674
- await yargs(hideBin(process.argv)).scriptName("roy-agent").version(pkg2.default.version).option("quiet", {
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,