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