@ai-setting/roy-agent-cli 1.7.36 → 1.7.38

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.
@@ -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.36",
9464
+ version: "1.7.38",
9465
9465
  type: "module",
9466
9466
  description: "CLI for roy-agent - Non-interactive command execution",
9467
9467
  main: "./dist/index.js",
@@ -11527,6 +11527,12 @@ function extractChatId(event) {
11527
11527
  return;
11528
11528
  }
11529
11529
 
11530
+ // src/commands/shared/event-handler-wiring.ts
11531
+ import { existsSync, mkdirSync } from "node:fs";
11532
+ import { join } from "node:path";
11533
+ import { homedir } from "node:os";
11534
+ import { EventStoreImpl, setSharedEventStore } from "@ai-setting/roy-agent-core/env/event-source/event-store";
11535
+
11530
11536
  // src/commands/shared/event-handler.ts
11531
11537
  import { TracedAs as TracedAs5 } from "@ai-setting/roy-agent-core";
11532
11538
  class EventHandler {
@@ -11543,6 +11549,8 @@ class EventHandler {
11543
11549
  unsubscribe = null;
11544
11550
  sessionComponent = null;
11545
11551
  activeEventSessionId = null;
11552
+ eventStore = null;
11553
+ getHandlerForEsType = null;
11546
11554
  constructor(options) {
11547
11555
  this.env = options.env;
11548
11556
  this.eventTypes = options.eventTypes;
@@ -11552,6 +11560,8 @@ class EventHandler {
11552
11560
  this.isIdle = options.isIdle ?? (() => true);
11553
11561
  this.idleCheckInterval = options.idleCheckInterval ?? 100;
11554
11562
  this.sessionComponent = options.sessionComponent ?? null;
11563
+ this.eventStore = options.eventStore ?? null;
11564
+ this.getHandlerForEsType = options.getHandlerForEsType ?? null;
11555
11565
  }
11556
11566
  start() {
11557
11567
  this.isStopped = false;
@@ -11589,13 +11599,94 @@ class EventHandler {
11589
11599
  this.isProcessing = false;
11590
11600
  this.clearActiveSession();
11591
11601
  }
11592
- handleEvent(event) {
11602
+ async handleEvent(event) {
11593
11603
  if (this.isStopped) {
11594
11604
  return;
11595
11605
  }
11596
- const formatted = this.formatter.formatWithEvent(event);
11606
+ const formatted = await this.formatEvent(event);
11597
11607
  this.enqueue(formatted);
11598
11608
  }
11609
+ async formatEvent(event) {
11610
+ if (event.type.startsWith("task.background.") && event.metadata?.triggerEventId && this.eventStore && this.getHandlerForEsType) {
11611
+ try {
11612
+ const v2Formatted = await this.formatEventViaESPluginV2(event);
11613
+ if (v2Formatted) {
11614
+ return v2Formatted;
11615
+ }
11616
+ } catch (err) {
11617
+ console.error(`[EventHandler] ESPlugin v2 path failed, falling back to formatter`, err);
11618
+ }
11619
+ }
11620
+ return this.formatter.formatWithEvent(event);
11621
+ }
11622
+ async formatEventViaESPluginV2(event) {
11623
+ const triggerEventId = event.metadata.triggerEventId;
11624
+ const triggerEvent = await this.eventStore.getEventById(triggerEventId);
11625
+ if (!triggerEvent) {
11626
+ return null;
11627
+ }
11628
+ const handler = this.getHandlerForEsType(triggerEvent.esType);
11629
+ if (!handler || !handler.buildNotifyHandlePrompt) {
11630
+ return null;
11631
+ }
11632
+ const payload = event.payload;
11633
+ const subAgentResult = {
11634
+ summary: typeof payload?.result === "string" ? payload.result : typeof payload?.error === "string" ? payload.error : "(无结果)"
11635
+ };
11636
+ const profile = triggerEvent.metadata?.profile ?? undefined;
11637
+ const prompt = handler.buildNotifyHandlePrompt({
11638
+ notifyEvent: {
11639
+ type: event.type,
11640
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11641
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11642
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11643
+ error: typeof payload?.error === "string" ? payload.error : undefined
11644
+ },
11645
+ triggerEvent,
11646
+ subAgentResult,
11647
+ profile
11648
+ });
11649
+ if (handler.postProcessNotifyEvent) {
11650
+ const notifyEventForHook = {
11651
+ type: event.type,
11652
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11653
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11654
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11655
+ error: typeof payload?.error === "string" ? payload.error : undefined
11656
+ };
11657
+ setTimeout(() => {
11658
+ Promise.resolve(handler.postProcessNotifyEvent({
11659
+ notifyEvent: notifyEventForHook,
11660
+ triggerEvent,
11661
+ subAgentResult,
11662
+ formattedPrompt: prompt.promptText,
11663
+ profile
11664
+ })).catch((err) => {
11665
+ console.error(`[EventHandler] postProcessNotifyEvent hook failed (swallowed)`, err);
11666
+ });
11667
+ }, 0);
11668
+ }
11669
+ const triggerChatId = triggerEvent.metadata?.chatId ?? undefined;
11670
+ const triggerMessageId = triggerEvent.metadata?.messageId ?? undefined;
11671
+ const triggerSessionId = event?.metadata?.trigger_session_id;
11672
+ return {
11673
+ message: prompt.promptText,
11674
+ envEvent: event,
11675
+ triggerSessionId,
11676
+ chatId: triggerChatId,
11677
+ ...triggerMessageId ? { triggerMessageId } : {}
11678
+ };
11679
+ }
11680
+ async handleNotifyEventForTest(event) {
11681
+ if (this.isStopped)
11682
+ return;
11683
+ const formatted = await this.formatEvent(event);
11684
+ if (this.onEventWithEnv) {
11685
+ await this.onEventWithEnv(formatted);
11686
+ } else {
11687
+ await this.onEvent(formatted.message);
11688
+ }
11689
+ }
11599
11690
  enqueue(formattedEvent) {
11600
11691
  if (this.isStopped) {
11601
11692
  return;
@@ -11613,12 +11704,7 @@ class EventHandler {
11613
11704
  }
11614
11705
  async processQueue() {
11615
11706
  this.isProcessing = true;
11616
- const sessionId = await this.ensureActiveSession();
11617
- if (this.isStopped) {
11618
- this.clearActiveSession();
11619
- this.isProcessing = false;
11620
- return;
11621
- }
11707
+ const chatSessionCache = new Map;
11622
11708
  while (!this.isStopped && this.queue.length > 0) {
11623
11709
  await this.waitForIdle();
11624
11710
  if (this.isStopped) {
@@ -11628,6 +11714,27 @@ class EventHandler {
11628
11714
  if (!item) {
11629
11715
  break;
11630
11716
  }
11717
+ let sessionId = null;
11718
+ if (item.chatId && this.sessionComponent) {
11719
+ const cached = chatSessionCache.get(item.chatId);
11720
+ if (cached) {
11721
+ sessionId = cached;
11722
+ } else {
11723
+ sessionId = await this.ensureChatSession(item.chatId);
11724
+ if (sessionId) {
11725
+ chatSessionCache.set(item.chatId, sessionId);
11726
+ }
11727
+ }
11728
+ if (!sessionId) {
11729
+ console.warn(`[EventHandler] Failed to ensure chat-keyed session (chatId=${item.chatId}), ` + `falling back to trigger_session_id path`);
11730
+ sessionId = await this.ensureActiveSession(item.triggerSessionId);
11731
+ }
11732
+ } else {
11733
+ sessionId = await this.ensureActiveSession(item.triggerSessionId);
11734
+ }
11735
+ if (this.isStopped) {
11736
+ break;
11737
+ }
11631
11738
  if (sessionId) {
11632
11739
  item.eventSessionId = sessionId;
11633
11740
  }
@@ -11643,24 +11750,13 @@ class EventHandler {
11643
11750
  }
11644
11751
  this.isProcessing = false;
11645
11752
  }
11646
- async ensureActiveSession() {
11753
+ async ensureActiveSession(triggerSessionIdOverride) {
11647
11754
  if (!this.sessionComponent)
11648
11755
  return null;
11649
- const queueChatId = this.queue.map((item) => item.chatId).find((id) => !!id);
11650
- if (queueChatId) {
11651
- const chatSessionId = await this.ensureChatSession(queueChatId);
11652
- if (chatSessionId) {
11653
- if (this.isStopped) {
11654
- return null;
11655
- }
11656
- return chatSessionId;
11657
- }
11658
- console.warn(`[EventHandler] Failed to ensure chat-keyed session (chatId=${queueChatId}), ` + `falling back to trigger_session_id path`);
11659
- }
11660
11756
  if (this.activeEventSessionId) {
11661
11757
  return this.activeEventSessionId;
11662
11758
  }
11663
- const triggerSessionId = this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
11759
+ const triggerSessionId = triggerSessionIdOverride ?? this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
11664
11760
  if (triggerSessionId) {
11665
11761
  try {
11666
11762
  const existing = await this.sessionComponent.get(triggerSessionId);
@@ -11766,17 +11862,35 @@ class EventHandler {
11766
11862
  }
11767
11863
  }
11768
11864
  __legacyDecorateClassTS([
11769
- TracedAs5("cli.event-handler.handleEvent", { recordParams: true }),
11865
+ TracedAs5("event_handler.handle_event", { recordParams: true }),
11770
11866
  __legacyMetadataTS("design:type", Function),
11771
11867
  __legacyMetadataTS("design:paramtypes", [
11772
11868
  typeof EnvEvent === "undefined" ? Object : EnvEvent
11773
11869
  ]),
11774
- __legacyMetadataTS("design:returntype", undefined)
11870
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11775
11871
  ], EventHandler.prototype, "handleEvent", null);
11872
+ __legacyDecorateClassTS([
11873
+ TracedAs5("cli.event-handler.formatEvent", { recordParams: true, recordResult: false }),
11874
+ __legacyMetadataTS("design:type", Function),
11875
+ __legacyMetadataTS("design:paramtypes", [
11876
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11877
+ ]),
11878
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11879
+ ], EventHandler.prototype, "formatEvent", null);
11880
+ __legacyDecorateClassTS([
11881
+ TracedAs5("event_handler.process_notify", { recordParams: true, recordResult: false }),
11882
+ __legacyMetadataTS("design:type", Function),
11883
+ __legacyMetadataTS("design:paramtypes", [
11884
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11885
+ ]),
11886
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11887
+ ], EventHandler.prototype, "formatEventViaESPluginV2", null);
11776
11888
  __legacyDecorateClassTS([
11777
11889
  TracedAs5("cli.event-handler.ensureActiveSession", { recordParams: true }),
11778
11890
  __legacyMetadataTS("design:type", Function),
11779
- __legacyMetadataTS("design:paramtypes", []),
11891
+ __legacyMetadataTS("design:paramtypes", [
11892
+ String
11893
+ ]),
11780
11894
  __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11781
11895
  ], EventHandler.prototype, "ensureActiveSession", null);
11782
11896
  __legacyDecorateClassTS([
@@ -11788,6 +11902,62 @@ __legacyDecorateClassTS([
11788
11902
  __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11789
11903
  ], EventHandler.prototype, "ensureChatSession", null);
11790
11904
 
11905
+ // src/commands/shared/event-handler-wiring.ts
11906
+ var storeCache = new Map;
11907
+ function getOrCreateEventStore(dbPath) {
11908
+ const normalized = normalizeDbPath(dbPath);
11909
+ let store = storeCache.get(normalized);
11910
+ if (store)
11911
+ return store;
11912
+ ensureParentDir(normalized);
11913
+ store = new EventStoreImpl({ dbPath: normalized });
11914
+ storeCache.set(normalized, store);
11915
+ setSharedEventStore(store);
11916
+ return store;
11917
+ }
11918
+ function normalizeDbPath(dbPath) {
11919
+ const expanded = dbPath.startsWith("~") ? join(homedir(), dbPath.slice(1).replace(/^\//, "")) : dbPath;
11920
+ return expanded;
11921
+ }
11922
+ function ensureParentDir(dbPath) {
11923
+ const parent = join(dbPath, "..");
11924
+ if (!existsSync(parent)) {
11925
+ mkdirSync(parent, { recursive: true });
11926
+ }
11927
+ }
11928
+ function getHandlerForEsTypeForEnv(env) {
11929
+ let component = null;
11930
+ try {
11931
+ component = env.getComponent?.("event-source") ?? null;
11932
+ } catch {
11933
+ component = null;
11934
+ }
11935
+ const hasGetHandler = component !== null && component !== undefined && typeof component.getHandler === "function";
11936
+ return (esType) => {
11937
+ if (!hasGetHandler)
11938
+ return;
11939
+ try {
11940
+ const h = component.getHandler(esType);
11941
+ return h ?? undefined;
11942
+ } catch {
11943
+ return;
11944
+ }
11945
+ };
11946
+ }
11947
+ function createDefaultEventStoreDbPath() {
11948
+ return join(homedir(), ".roy-agent", "event-store.db");
11949
+ }
11950
+ function createEventHandlerForInteractive(options) {
11951
+ const dbPath = options.dbPath ?? createDefaultEventStoreDbPath();
11952
+ const eventStore = getOrCreateEventStore(dbPath);
11953
+ const getHandlerForEsType = getHandlerForEsTypeForEnv(options.env);
11954
+ return new EventHandler({
11955
+ ...options,
11956
+ eventStore,
11957
+ getHandlerForEsType
11958
+ });
11959
+ }
11960
+
11791
11961
  // src/commands/shared/esc-active-descendant.ts
11792
11962
  function hasActiveDescendants(env, parentSessionId) {
11793
11963
  if (!env || !parentSessionId)
@@ -13639,12 +13809,13 @@ function createInteractiveCommand(externalEnvService) {
13639
13809
  console
13640
13810
  });
13641
13811
  });
13642
- const eventHandler = new EventHandler({
13812
+ const eventHandler = createEventHandlerForInteractive({
13643
13813
  env,
13644
13814
  eventTypes: ["task.background.*", "event-source.event.*"],
13645
13815
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
13646
13816
  isIdle: () => repl.isIdle(),
13647
13817
  sessionComponent,
13818
+ onEvent: async (_message) => {},
13648
13819
  onEventWithEnv: async (formattedEvent) => {
13649
13820
  await repl.handleEventMessageWithEnv(formattedEvent);
13650
13821
  }
@@ -14503,7 +14674,7 @@ async function loadHandleQuery(options, hooks) {
14503
14674
  env,
14504
14675
  enabled: true
14505
14676
  });
14506
- const eventHandler = new EventHandler({
14677
+ const eventHandler = createEventHandlerForInteractive({
14507
14678
  env,
14508
14679
  eventTypes: ["task.background.*", "event-source.event.*"],
14509
14680
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
@@ -14639,7 +14810,7 @@ function createRunCommand() {
14639
14810
  const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
14640
14811
  const runState = {
14641
14812
  isIdle: () => true,
14642
- onNotification: () => {}
14813
+ onNotification: async () => {}
14643
14814
  };
14644
14815
  const {
14645
14816
  handleQuery,
@@ -21443,15 +21614,15 @@ function resolveServerUrl(serverUrl, fallback) {
21443
21614
  }
21444
21615
 
21445
21616
  // src/lib/bounty-profile-reader.ts
21446
- import { existsSync as existsSync2, readFileSync } from "node:fs";
21447
- import { homedir } from "node:os";
21448
- import { join } from "node:path";
21617
+ import { existsSync as existsSync3, readFileSync } from "node:fs";
21618
+ import { homedir as homedir2 } from "node:os";
21619
+ import { join as join2 } from "node:path";
21449
21620
  function readBountyProfile(name, profilesDir) {
21450
21621
  if (!name)
21451
21622
  return null;
21452
- const dir = profilesDir ?? join(homedir(), ".config", "bounty", "profiles");
21453
- const profilePath = join(dir, `${name}.json`);
21454
- if (!existsSync2(profilePath))
21623
+ const dir = profilesDir ?? join2(homedir2(), ".config", "bounty", "profiles");
21624
+ const profilePath = join2(dir, `${name}.json`);
21625
+ if (!existsSync3(profilePath))
21455
21626
  return null;
21456
21627
  try {
21457
21628
  const raw = readFileSync(profilePath, "utf-8");
@@ -25868,19 +26039,19 @@ var LspCommand = {
25868
26039
 
25869
26040
  // src/commands/install/index.ts
25870
26041
  import { spawnSync } from "node:child_process";
25871
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync, mkdirSync, rmSync as rmSync2 } from "node:fs";
25872
- import { join as join6, resolve } from "node:path";
25873
- import { homedir as homedir4 } from "node:os";
26042
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync, mkdirSync as mkdirSync2, rmSync as rmSync2 } from "node:fs";
26043
+ import { join as join7, resolve } from "node:path";
26044
+ import { homedir as homedir5 } from "node:os";
25874
26045
 
25875
26046
  // src/commands/install/cleanup-stale-plugin-copies.ts
25876
- import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
25877
- import { join as join5 } from "node:path";
26047
+ import { existsSync as existsSync5, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
26048
+ import { join as join6 } from "node:path";
25878
26049
  import { homedir as nodeHomedir, tmpdir as nodeTmpdir } from "node:os";
25879
26050
  function cleanupStalePluginCopies(packageName, options) {
25880
26051
  const HOME = options.homedir ?? nodeHomedir();
25881
26052
  const paths = options.localNodeModulesPaths ?? [
25882
- join5(HOME, "node_modules"),
25883
- join5(HOME, ".roy-agent", "node_modules")
26053
+ join6(HOME, "node_modules"),
26054
+ join6(HOME, ".roy-agent", "node_modules")
25884
26055
  ];
25885
26056
  const backupRoot = options.backupDir ?? nodeTmpdir();
25886
26057
  const result = {
@@ -25890,15 +26061,15 @@ function cleanupStalePluginCopies(packageName, options) {
25890
26061
  };
25891
26062
  if (!options.globalVersion) {
25892
26063
  for (const p of paths) {
25893
- const candidate = join5(p, packageName);
26064
+ const candidate = join6(p, packageName);
25894
26065
  result.skipped.push({ path: candidate, reason: "no-global-version" });
25895
26066
  }
25896
26067
  return result;
25897
26068
  }
25898
26069
  for (const nmPath of paths) {
25899
- const localPkgDir = join5(nmPath, packageName);
25900
- const localPkgJson = join5(localPkgDir, "package.json");
25901
- if (!existsSync4(localPkgJson)) {
26070
+ const localPkgDir = join6(nmPath, packageName);
26071
+ const localPkgJson = join6(localPkgDir, "package.json");
26072
+ if (!existsSync5(localPkgJson)) {
25902
26073
  result.skipped.push({ path: localPkgDir, reason: "no-local-copy" });
25903
26074
  continue;
25904
26075
  }
@@ -25919,7 +26090,7 @@ function cleanupStalePluginCopies(packageName, options) {
25919
26090
  const safeName = packageName.replace(/@/g, "").replace(/[^a-zA-Z0-9._/-]/g, "-");
25920
26091
  const safeLocalVersion = (localVersion ?? "unknown").replace(/[^a-zA-Z0-9._-]/g, "-");
25921
26092
  const timestamp = Date.now();
25922
- backupPath = join5(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
26093
+ backupPath = join6(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
25923
26094
  cpSync(localPkgDir, backupPath, { recursive: true });
25924
26095
  result.backups.push({ originalPath: localPkgDir, backupPath });
25925
26096
  } catch (err) {
@@ -25954,19 +26125,19 @@ function compareVersions(a, b) {
25954
26125
 
25955
26126
  // src/commands/install/index.ts
25956
26127
  function getConfigDir(scope) {
25957
- return scope === "global" ? join6(homedir4(), ".roy-agent") : join6(process.cwd(), ".roy");
26128
+ return scope === "global" ? join7(homedir5(), ".roy-agent") : join7(process.cwd(), ".roy");
25958
26129
  }
25959
26130
  function detectDefaultScope() {
25960
- const projectDir = join6(process.cwd(), ".roy");
25961
- return existsSync5(projectDir) ? "project" : "global";
26131
+ const projectDir = join7(process.cwd(), ".roy");
26132
+ return existsSync6(projectDir) ? "project" : "global";
25962
26133
  }
25963
26134
  function getConfigPath(scope) {
25964
- return join6(getConfigDir(scope), "plugins.json");
26135
+ return join7(getConfigDir(scope), "plugins.json");
25965
26136
  }
25966
26137
  function loadPlugins(scope) {
25967
26138
  const configPath = getConfigPath(scope);
25968
26139
  try {
25969
- if (existsSync5(configPath)) {
26140
+ if (existsSync6(configPath)) {
25970
26141
  const raw = readFileSync4(configPath, "utf-8");
25971
26142
  const config = JSON.parse(raw);
25972
26143
  return config.plugins ?? [];
@@ -25977,8 +26148,8 @@ function loadPlugins(scope) {
25977
26148
  function savePlugins(plugins, scope) {
25978
26149
  const configDir = getConfigDir(scope);
25979
26150
  const configPath = getConfigPath(scope);
25980
- if (!existsSync5(configDir)) {
25981
- mkdirSync(configDir, { recursive: true });
26151
+ if (!existsSync6(configDir)) {
26152
+ mkdirSync2(configDir, { recursive: true });
25982
26153
  }
25983
26154
  const config = { plugins };
25984
26155
  writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
@@ -25993,8 +26164,8 @@ function stripVersionSpec(packageName) {
25993
26164
  function readPackageInfo(packageName) {
25994
26165
  const bareName = packageName.startsWith("/") || packageName.startsWith(".") ? packageName : stripVersionSpec(packageName);
25995
26166
  if (packageName.startsWith("/") || packageName.startsWith(".")) {
25996
- const localPkgPath = join6(packageName, "package.json");
25997
- if (existsSync5(localPkgPath)) {
26167
+ const localPkgPath = join7(packageName, "package.json");
26168
+ if (existsSync6(localPkgPath)) {
25998
26169
  try {
25999
26170
  const pkg = JSON.parse(readFileSync4(localPkgPath, "utf-8"));
26000
26171
  return {
@@ -26008,18 +26179,18 @@ function readPackageInfo(packageName) {
26008
26179
  }
26009
26180
  }
26010
26181
  const searchPaths = [
26011
- join6(process.cwd(), "node_modules", bareName, "package.json"),
26182
+ join7(process.cwd(), "node_modules", bareName, "package.json"),
26012
26183
  resolve(process.cwd(), "..", "node_modules", bareName, "package.json"),
26013
- join6(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26184
+ join7(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26014
26185
  ...(() => {
26015
26186
  const globalRoot = getNpmGlobalRoot();
26016
- return globalRoot ? [join6(globalRoot, bareName, "package.json")] : [];
26187
+ return globalRoot ? [join7(globalRoot, bareName, "package.json")] : [];
26017
26188
  })(),
26018
- join6(homedir4(), ".roy-agent", "node_modules", bareName, "package.json")
26189
+ join7(homedir5(), ".roy-agent", "node_modules", bareName, "package.json")
26019
26190
  ];
26020
26191
  for (const pkgPath of searchPaths) {
26021
26192
  try {
26022
- if (existsSync5(pkgPath)) {
26193
+ if (existsSync6(pkgPath)) {
26023
26194
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
26024
26195
  return {
26025
26196
  version: pkg.version ?? "0.0.0",
@@ -26053,15 +26224,15 @@ async function verifyInstalledVersion(packageName, declaredVersion) {
26053
26224
  return { ok: true, actualVersion: actual.version };
26054
26225
  }
26055
26226
  function getPackageManagerCommand() {
26056
- if (existsSync5(join6(process.cwd(), "pnpm-lock.yaml"))) {
26057
- if (existsSync5(join6(process.cwd(), "pnpm-workspace.yaml"))) {
26227
+ if (existsSync6(join7(process.cwd(), "pnpm-lock.yaml"))) {
26228
+ if (existsSync6(join7(process.cwd(), "pnpm-workspace.yaml"))) {
26058
26229
  return "pnpm -w";
26059
26230
  }
26060
26231
  return "pnpm";
26061
26232
  }
26062
- if (existsSync5(join6(process.cwd(), "yarn.lock")))
26233
+ if (existsSync6(join7(process.cwd(), "yarn.lock")))
26063
26234
  return "yarn";
26064
- if (existsSync5(join6(process.cwd(), "bun.lock")) || existsSync5(join6(process.cwd(), "bun.lockb")))
26235
+ if (existsSync6(join7(process.cwd(), "bun.lock")) || existsSync6(join7(process.cwd(), "bun.lockb")))
26065
26236
  return "bun";
26066
26237
  return "npm";
26067
26238
  }
@@ -26100,15 +26271,15 @@ var InstallPackageCommand = {
26100
26271
  }
26101
26272
  resolvedName = info2.name;
26102
26273
  const srcDir = resolve(packageName);
26103
- if (!existsSync5(srcDir)) {
26274
+ if (!existsSync6(srcDir)) {
26104
26275
  console.error(`
26105
26276
  ❌ Local path '${srcDir}' does not exist.
26106
26277
  `);
26107
26278
  process.exit(1);
26108
26279
  }
26109
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26110
- if (!existsSync5(pluginDir)) {
26111
- mkdirSync(pluginDir, { recursive: true });
26280
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26281
+ if (!existsSync6(pluginDir)) {
26282
+ mkdirSync2(pluginDir, { recursive: true });
26112
26283
  }
26113
26284
  const result = spawnSync("cp", ["-r", `${srcDir}/.`, pluginDir], {
26114
26285
  stdio: "inherit",
@@ -26142,12 +26313,12 @@ var InstallPackageCommand = {
26142
26313
  process.exit(1);
26143
26314
  }
26144
26315
  resolvedName = info2.name;
26145
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26146
- if (!existsSync5(pluginDir)) {
26147
- mkdirSync(pluginDir, { recursive: true });
26316
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26317
+ if (!existsSync6(pluginDir)) {
26318
+ mkdirSync2(pluginDir, { recursive: true });
26148
26319
  }
26149
- const nmPath = join6(process.cwd(), "node_modules", packageName);
26150
- if (existsSync5(nmPath)) {
26320
+ const nmPath = join7(process.cwd(), "node_modules", packageName);
26321
+ if (existsSync6(nmPath)) {
26151
26322
  spawnSync("cp", ["-r", `${nmPath}/.`, pluginDir], { stdio: "inherit", shell: false });
26152
26323
  }
26153
26324
  }
@@ -26169,7 +26340,7 @@ var InstallPackageCommand = {
26169
26340
  if (tmpInfo) {
26170
26341
  const cleanupResult = cleanupStalePluginCopies(tmpInfo.name, {
26171
26342
  globalVersion: tmpInfo.version,
26172
- homedir: homedir4()
26343
+ homedir: homedir5()
26173
26344
  });
26174
26345
  if (cleanupResult.cleaned.length > 0) {
26175
26346
  console.log(`
@@ -26309,8 +26480,8 @@ var InstallRemoveCommand = {
26309
26480
  \uD83D\uDDD1️ Removing plugin: ${plugin.packageName}@${plugin.version} (${scope})
26310
26481
  `);
26311
26482
  if (scope === "project") {
26312
- const pluginDir = join6(process.cwd(), ".roy", "plugins", plugin.packageName);
26313
- if (existsSync5(pluginDir)) {
26483
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", plugin.packageName);
26484
+ if (existsSync6(pluginDir)) {
26314
26485
  spawnSync("rm", ["-rf", pluginDir], { stdio: "inherit", shell: false });
26315
26486
  console.log(` Removed plugin directory: ${pluginDir}`);
26316
26487
  }
@@ -26325,8 +26496,8 @@ var InstallRemoveCommand = {
26325
26496
  `);
26326
26497
  process.exit(result.status ?? 1);
26327
26498
  }
26328
- const globalNm = join6(homedir4(), ".roy-agent", "node_modules", plugin.packageName);
26329
- if (existsSync5(globalNm)) {
26499
+ const globalNm = join7(homedir5(), ".roy-agent", "node_modules", plugin.packageName);
26500
+ if (existsSync6(globalNm)) {
26330
26501
  spawnSync("rm", ["-rf", globalNm], { stdio: "inherit", shell: false });
26331
26502
  }
26332
26503
  }
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.36",
9463
+ version: "1.7.38",
9464
9464
  type: "module",
9465
9465
  description: "CLI for roy-agent - Non-interactive command execution",
9466
9466
  main: "./dist/index.js",
@@ -11526,6 +11526,12 @@ function extractChatId(event) {
11526
11526
  return;
11527
11527
  }
11528
11528
 
11529
+ // src/commands/shared/event-handler-wiring.ts
11530
+ import { existsSync, mkdirSync } from "node:fs";
11531
+ import { join } from "node:path";
11532
+ import { homedir } from "node:os";
11533
+ import { EventStoreImpl, setSharedEventStore } from "@ai-setting/roy-agent-core/env/event-source/event-store";
11534
+
11529
11535
  // src/commands/shared/event-handler.ts
11530
11536
  import { TracedAs as TracedAs5 } from "@ai-setting/roy-agent-core";
11531
11537
  class EventHandler {
@@ -11542,6 +11548,8 @@ class EventHandler {
11542
11548
  unsubscribe = null;
11543
11549
  sessionComponent = null;
11544
11550
  activeEventSessionId = null;
11551
+ eventStore = null;
11552
+ getHandlerForEsType = null;
11545
11553
  constructor(options) {
11546
11554
  this.env = options.env;
11547
11555
  this.eventTypes = options.eventTypes;
@@ -11551,6 +11559,8 @@ class EventHandler {
11551
11559
  this.isIdle = options.isIdle ?? (() => true);
11552
11560
  this.idleCheckInterval = options.idleCheckInterval ?? 100;
11553
11561
  this.sessionComponent = options.sessionComponent ?? null;
11562
+ this.eventStore = options.eventStore ?? null;
11563
+ this.getHandlerForEsType = options.getHandlerForEsType ?? null;
11554
11564
  }
11555
11565
  start() {
11556
11566
  this.isStopped = false;
@@ -11588,13 +11598,94 @@ class EventHandler {
11588
11598
  this.isProcessing = false;
11589
11599
  this.clearActiveSession();
11590
11600
  }
11591
- handleEvent(event) {
11601
+ async handleEvent(event) {
11592
11602
  if (this.isStopped) {
11593
11603
  return;
11594
11604
  }
11595
- const formatted = this.formatter.formatWithEvent(event);
11605
+ const formatted = await this.formatEvent(event);
11596
11606
  this.enqueue(formatted);
11597
11607
  }
11608
+ async formatEvent(event) {
11609
+ if (event.type.startsWith("task.background.") && event.metadata?.triggerEventId && this.eventStore && this.getHandlerForEsType) {
11610
+ try {
11611
+ const v2Formatted = await this.formatEventViaESPluginV2(event);
11612
+ if (v2Formatted) {
11613
+ return v2Formatted;
11614
+ }
11615
+ } catch (err) {
11616
+ console.error(`[EventHandler] ESPlugin v2 path failed, falling back to formatter`, err);
11617
+ }
11618
+ }
11619
+ return this.formatter.formatWithEvent(event);
11620
+ }
11621
+ async formatEventViaESPluginV2(event) {
11622
+ const triggerEventId = event.metadata.triggerEventId;
11623
+ const triggerEvent = await this.eventStore.getEventById(triggerEventId);
11624
+ if (!triggerEvent) {
11625
+ return null;
11626
+ }
11627
+ const handler = this.getHandlerForEsType(triggerEvent.esType);
11628
+ if (!handler || !handler.buildNotifyHandlePrompt) {
11629
+ return null;
11630
+ }
11631
+ const payload = event.payload;
11632
+ const subAgentResult = {
11633
+ summary: typeof payload?.result === "string" ? payload.result : typeof payload?.error === "string" ? payload.error : "(无结果)"
11634
+ };
11635
+ const profile = triggerEvent.metadata?.profile ?? undefined;
11636
+ const prompt = handler.buildNotifyHandlePrompt({
11637
+ notifyEvent: {
11638
+ type: event.type,
11639
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11640
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11641
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11642
+ error: typeof payload?.error === "string" ? payload.error : undefined
11643
+ },
11644
+ triggerEvent,
11645
+ subAgentResult,
11646
+ profile
11647
+ });
11648
+ if (handler.postProcessNotifyEvent) {
11649
+ const notifyEventForHook = {
11650
+ type: event.type,
11651
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11652
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11653
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11654
+ error: typeof payload?.error === "string" ? payload.error : undefined
11655
+ };
11656
+ setTimeout(() => {
11657
+ Promise.resolve(handler.postProcessNotifyEvent({
11658
+ notifyEvent: notifyEventForHook,
11659
+ triggerEvent,
11660
+ subAgentResult,
11661
+ formattedPrompt: prompt.promptText,
11662
+ profile
11663
+ })).catch((err) => {
11664
+ console.error(`[EventHandler] postProcessNotifyEvent hook failed (swallowed)`, err);
11665
+ });
11666
+ }, 0);
11667
+ }
11668
+ const triggerChatId = triggerEvent.metadata?.chatId ?? undefined;
11669
+ const triggerMessageId = triggerEvent.metadata?.messageId ?? undefined;
11670
+ const triggerSessionId = event?.metadata?.trigger_session_id;
11671
+ return {
11672
+ message: prompt.promptText,
11673
+ envEvent: event,
11674
+ triggerSessionId,
11675
+ chatId: triggerChatId,
11676
+ ...triggerMessageId ? { triggerMessageId } : {}
11677
+ };
11678
+ }
11679
+ async handleNotifyEventForTest(event) {
11680
+ if (this.isStopped)
11681
+ return;
11682
+ const formatted = await this.formatEvent(event);
11683
+ if (this.onEventWithEnv) {
11684
+ await this.onEventWithEnv(formatted);
11685
+ } else {
11686
+ await this.onEvent(formatted.message);
11687
+ }
11688
+ }
11598
11689
  enqueue(formattedEvent) {
11599
11690
  if (this.isStopped) {
11600
11691
  return;
@@ -11612,12 +11703,7 @@ class EventHandler {
11612
11703
  }
11613
11704
  async processQueue() {
11614
11705
  this.isProcessing = true;
11615
- const sessionId = await this.ensureActiveSession();
11616
- if (this.isStopped) {
11617
- this.clearActiveSession();
11618
- this.isProcessing = false;
11619
- return;
11620
- }
11706
+ const chatSessionCache = new Map;
11621
11707
  while (!this.isStopped && this.queue.length > 0) {
11622
11708
  await this.waitForIdle();
11623
11709
  if (this.isStopped) {
@@ -11627,6 +11713,27 @@ class EventHandler {
11627
11713
  if (!item) {
11628
11714
  break;
11629
11715
  }
11716
+ let sessionId = null;
11717
+ if (item.chatId && this.sessionComponent) {
11718
+ const cached = chatSessionCache.get(item.chatId);
11719
+ if (cached) {
11720
+ sessionId = cached;
11721
+ } else {
11722
+ sessionId = await this.ensureChatSession(item.chatId);
11723
+ if (sessionId) {
11724
+ chatSessionCache.set(item.chatId, sessionId);
11725
+ }
11726
+ }
11727
+ if (!sessionId) {
11728
+ console.warn(`[EventHandler] Failed to ensure chat-keyed session (chatId=${item.chatId}), ` + `falling back to trigger_session_id path`);
11729
+ sessionId = await this.ensureActiveSession(item.triggerSessionId);
11730
+ }
11731
+ } else {
11732
+ sessionId = await this.ensureActiveSession(item.triggerSessionId);
11733
+ }
11734
+ if (this.isStopped) {
11735
+ break;
11736
+ }
11630
11737
  if (sessionId) {
11631
11738
  item.eventSessionId = sessionId;
11632
11739
  }
@@ -11642,24 +11749,13 @@ class EventHandler {
11642
11749
  }
11643
11750
  this.isProcessing = false;
11644
11751
  }
11645
- async ensureActiveSession() {
11752
+ async ensureActiveSession(triggerSessionIdOverride) {
11646
11753
  if (!this.sessionComponent)
11647
11754
  return null;
11648
- const queueChatId = this.queue.map((item) => item.chatId).find((id) => !!id);
11649
- if (queueChatId) {
11650
- const chatSessionId = await this.ensureChatSession(queueChatId);
11651
- if (chatSessionId) {
11652
- if (this.isStopped) {
11653
- return null;
11654
- }
11655
- return chatSessionId;
11656
- }
11657
- console.warn(`[EventHandler] Failed to ensure chat-keyed session (chatId=${queueChatId}), ` + `falling back to trigger_session_id path`);
11658
- }
11659
11755
  if (this.activeEventSessionId) {
11660
11756
  return this.activeEventSessionId;
11661
11757
  }
11662
- const triggerSessionId = this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
11758
+ const triggerSessionId = triggerSessionIdOverride ?? this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
11663
11759
  if (triggerSessionId) {
11664
11760
  try {
11665
11761
  const existing = await this.sessionComponent.get(triggerSessionId);
@@ -11765,17 +11861,35 @@ class EventHandler {
11765
11861
  }
11766
11862
  }
11767
11863
  __legacyDecorateClassTS([
11768
- TracedAs5("cli.event-handler.handleEvent", { recordParams: true }),
11864
+ TracedAs5("event_handler.handle_event", { recordParams: true }),
11769
11865
  __legacyMetadataTS("design:type", Function),
11770
11866
  __legacyMetadataTS("design:paramtypes", [
11771
11867
  typeof EnvEvent === "undefined" ? Object : EnvEvent
11772
11868
  ]),
11773
- __legacyMetadataTS("design:returntype", undefined)
11869
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11774
11870
  ], EventHandler.prototype, "handleEvent", null);
11871
+ __legacyDecorateClassTS([
11872
+ TracedAs5("cli.event-handler.formatEvent", { recordParams: true, recordResult: false }),
11873
+ __legacyMetadataTS("design:type", Function),
11874
+ __legacyMetadataTS("design:paramtypes", [
11875
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11876
+ ]),
11877
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11878
+ ], EventHandler.prototype, "formatEvent", null);
11879
+ __legacyDecorateClassTS([
11880
+ TracedAs5("event_handler.process_notify", { recordParams: true, recordResult: false }),
11881
+ __legacyMetadataTS("design:type", Function),
11882
+ __legacyMetadataTS("design:paramtypes", [
11883
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11884
+ ]),
11885
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11886
+ ], EventHandler.prototype, "formatEventViaESPluginV2", null);
11775
11887
  __legacyDecorateClassTS([
11776
11888
  TracedAs5("cli.event-handler.ensureActiveSession", { recordParams: true }),
11777
11889
  __legacyMetadataTS("design:type", Function),
11778
- __legacyMetadataTS("design:paramtypes", []),
11890
+ __legacyMetadataTS("design:paramtypes", [
11891
+ String
11892
+ ]),
11779
11893
  __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11780
11894
  ], EventHandler.prototype, "ensureActiveSession", null);
11781
11895
  __legacyDecorateClassTS([
@@ -11787,6 +11901,62 @@ __legacyDecorateClassTS([
11787
11901
  __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11788
11902
  ], EventHandler.prototype, "ensureChatSession", null);
11789
11903
 
11904
+ // src/commands/shared/event-handler-wiring.ts
11905
+ var storeCache = new Map;
11906
+ function getOrCreateEventStore(dbPath) {
11907
+ const normalized = normalizeDbPath(dbPath);
11908
+ let store = storeCache.get(normalized);
11909
+ if (store)
11910
+ return store;
11911
+ ensureParentDir(normalized);
11912
+ store = new EventStoreImpl({ dbPath: normalized });
11913
+ storeCache.set(normalized, store);
11914
+ setSharedEventStore(store);
11915
+ return store;
11916
+ }
11917
+ function normalizeDbPath(dbPath) {
11918
+ const expanded = dbPath.startsWith("~") ? join(homedir(), dbPath.slice(1).replace(/^\//, "")) : dbPath;
11919
+ return expanded;
11920
+ }
11921
+ function ensureParentDir(dbPath) {
11922
+ const parent = join(dbPath, "..");
11923
+ if (!existsSync(parent)) {
11924
+ mkdirSync(parent, { recursive: true });
11925
+ }
11926
+ }
11927
+ function getHandlerForEsTypeForEnv(env) {
11928
+ let component = null;
11929
+ try {
11930
+ component = env.getComponent?.("event-source") ?? null;
11931
+ } catch {
11932
+ component = null;
11933
+ }
11934
+ const hasGetHandler = component !== null && component !== undefined && typeof component.getHandler === "function";
11935
+ return (esType) => {
11936
+ if (!hasGetHandler)
11937
+ return;
11938
+ try {
11939
+ const h = component.getHandler(esType);
11940
+ return h ?? undefined;
11941
+ } catch {
11942
+ return;
11943
+ }
11944
+ };
11945
+ }
11946
+ function createDefaultEventStoreDbPath() {
11947
+ return join(homedir(), ".roy-agent", "event-store.db");
11948
+ }
11949
+ function createEventHandlerForInteractive(options) {
11950
+ const dbPath = options.dbPath ?? createDefaultEventStoreDbPath();
11951
+ const eventStore = getOrCreateEventStore(dbPath);
11952
+ const getHandlerForEsType = getHandlerForEsTypeForEnv(options.env);
11953
+ return new EventHandler({
11954
+ ...options,
11955
+ eventStore,
11956
+ getHandlerForEsType
11957
+ });
11958
+ }
11959
+
11790
11960
  // src/commands/shared/esc-active-descendant.ts
11791
11961
  function hasActiveDescendants(env, parentSessionId) {
11792
11962
  if (!env || !parentSessionId)
@@ -13638,12 +13808,13 @@ function createInteractiveCommand(externalEnvService) {
13638
13808
  console
13639
13809
  });
13640
13810
  });
13641
- const eventHandler = new EventHandler({
13811
+ const eventHandler = createEventHandlerForInteractive({
13642
13812
  env,
13643
13813
  eventTypes: ["task.background.*", "event-source.event.*"],
13644
13814
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
13645
13815
  isIdle: () => repl.isIdle(),
13646
13816
  sessionComponent,
13817
+ onEvent: async (_message) => {},
13647
13818
  onEventWithEnv: async (formattedEvent) => {
13648
13819
  await repl.handleEventMessageWithEnv(formattedEvent);
13649
13820
  }
@@ -14502,7 +14673,7 @@ async function loadHandleQuery(options, hooks) {
14502
14673
  env,
14503
14674
  enabled: true
14504
14675
  });
14505
- const eventHandler = new EventHandler({
14676
+ const eventHandler = createEventHandlerForInteractive({
14506
14677
  env,
14507
14678
  eventTypes: ["task.background.*", "event-source.event.*"],
14508
14679
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
@@ -14638,7 +14809,7 @@ function createRunCommand() {
14638
14809
  const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
14639
14810
  const runState = {
14640
14811
  isIdle: () => true,
14641
- onNotification: () => {}
14812
+ onNotification: async () => {}
14642
14813
  };
14643
14814
  const {
14644
14815
  handleQuery,
@@ -21442,15 +21613,15 @@ function resolveServerUrl(serverUrl, fallback) {
21442
21613
  }
21443
21614
 
21444
21615
  // src/lib/bounty-profile-reader.ts
21445
- import { existsSync as existsSync2, readFileSync } from "node:fs";
21446
- import { homedir } from "node:os";
21447
- import { join } from "node:path";
21616
+ import { existsSync as existsSync3, readFileSync } from "node:fs";
21617
+ import { homedir as homedir2 } from "node:os";
21618
+ import { join as join2 } from "node:path";
21448
21619
  function readBountyProfile(name, profilesDir) {
21449
21620
  if (!name)
21450
21621
  return null;
21451
- const dir = profilesDir ?? join(homedir(), ".config", "bounty", "profiles");
21452
- const profilePath = join(dir, `${name}.json`);
21453
- if (!existsSync2(profilePath))
21622
+ const dir = profilesDir ?? join2(homedir2(), ".config", "bounty", "profiles");
21623
+ const profilePath = join2(dir, `${name}.json`);
21624
+ if (!existsSync3(profilePath))
21454
21625
  return null;
21455
21626
  try {
21456
21627
  const raw = readFileSync(profilePath, "utf-8");
@@ -25867,19 +26038,19 @@ var LspCommand = {
25867
26038
 
25868
26039
  // src/commands/install/index.ts
25869
26040
  import { spawnSync } from "node:child_process";
25870
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync, mkdirSync, rmSync as rmSync2 } from "node:fs";
25871
- import { join as join6, resolve } from "node:path";
25872
- import { homedir as homedir4 } from "node:os";
26041
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync, mkdirSync as mkdirSync2, rmSync as rmSync2 } from "node:fs";
26042
+ import { join as join7, resolve } from "node:path";
26043
+ import { homedir as homedir5 } from "node:os";
25873
26044
 
25874
26045
  // src/commands/install/cleanup-stale-plugin-copies.ts
25875
- import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
25876
- import { join as join5 } from "node:path";
26046
+ import { existsSync as existsSync5, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
26047
+ import { join as join6 } from "node:path";
25877
26048
  import { homedir as nodeHomedir, tmpdir as nodeTmpdir } from "node:os";
25878
26049
  function cleanupStalePluginCopies(packageName, options) {
25879
26050
  const HOME = options.homedir ?? nodeHomedir();
25880
26051
  const paths = options.localNodeModulesPaths ?? [
25881
- join5(HOME, "node_modules"),
25882
- join5(HOME, ".roy-agent", "node_modules")
26052
+ join6(HOME, "node_modules"),
26053
+ join6(HOME, ".roy-agent", "node_modules")
25883
26054
  ];
25884
26055
  const backupRoot = options.backupDir ?? nodeTmpdir();
25885
26056
  const result = {
@@ -25889,15 +26060,15 @@ function cleanupStalePluginCopies(packageName, options) {
25889
26060
  };
25890
26061
  if (!options.globalVersion) {
25891
26062
  for (const p of paths) {
25892
- const candidate = join5(p, packageName);
26063
+ const candidate = join6(p, packageName);
25893
26064
  result.skipped.push({ path: candidate, reason: "no-global-version" });
25894
26065
  }
25895
26066
  return result;
25896
26067
  }
25897
26068
  for (const nmPath of paths) {
25898
- const localPkgDir = join5(nmPath, packageName);
25899
- const localPkgJson = join5(localPkgDir, "package.json");
25900
- if (!existsSync4(localPkgJson)) {
26069
+ const localPkgDir = join6(nmPath, packageName);
26070
+ const localPkgJson = join6(localPkgDir, "package.json");
26071
+ if (!existsSync5(localPkgJson)) {
25901
26072
  result.skipped.push({ path: localPkgDir, reason: "no-local-copy" });
25902
26073
  continue;
25903
26074
  }
@@ -25918,7 +26089,7 @@ function cleanupStalePluginCopies(packageName, options) {
25918
26089
  const safeName = packageName.replace(/@/g, "").replace(/[^a-zA-Z0-9._/-]/g, "-");
25919
26090
  const safeLocalVersion = (localVersion ?? "unknown").replace(/[^a-zA-Z0-9._-]/g, "-");
25920
26091
  const timestamp = Date.now();
25921
- backupPath = join5(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
26092
+ backupPath = join6(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
25922
26093
  cpSync(localPkgDir, backupPath, { recursive: true });
25923
26094
  result.backups.push({ originalPath: localPkgDir, backupPath });
25924
26095
  } catch (err) {
@@ -25953,19 +26124,19 @@ function compareVersions(a, b) {
25953
26124
 
25954
26125
  // src/commands/install/index.ts
25955
26126
  function getConfigDir(scope) {
25956
- return scope === "global" ? join6(homedir4(), ".roy-agent") : join6(process.cwd(), ".roy");
26127
+ return scope === "global" ? join7(homedir5(), ".roy-agent") : join7(process.cwd(), ".roy");
25957
26128
  }
25958
26129
  function detectDefaultScope() {
25959
- const projectDir = join6(process.cwd(), ".roy");
25960
- return existsSync5(projectDir) ? "project" : "global";
26130
+ const projectDir = join7(process.cwd(), ".roy");
26131
+ return existsSync6(projectDir) ? "project" : "global";
25961
26132
  }
25962
26133
  function getConfigPath(scope) {
25963
- return join6(getConfigDir(scope), "plugins.json");
26134
+ return join7(getConfigDir(scope), "plugins.json");
25964
26135
  }
25965
26136
  function loadPlugins(scope) {
25966
26137
  const configPath = getConfigPath(scope);
25967
26138
  try {
25968
- if (existsSync5(configPath)) {
26139
+ if (existsSync6(configPath)) {
25969
26140
  const raw = readFileSync4(configPath, "utf-8");
25970
26141
  const config = JSON.parse(raw);
25971
26142
  return config.plugins ?? [];
@@ -25976,8 +26147,8 @@ function loadPlugins(scope) {
25976
26147
  function savePlugins(plugins, scope) {
25977
26148
  const configDir = getConfigDir(scope);
25978
26149
  const configPath = getConfigPath(scope);
25979
- if (!existsSync5(configDir)) {
25980
- mkdirSync(configDir, { recursive: true });
26150
+ if (!existsSync6(configDir)) {
26151
+ mkdirSync2(configDir, { recursive: true });
25981
26152
  }
25982
26153
  const config = { plugins };
25983
26154
  writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
@@ -25992,8 +26163,8 @@ function stripVersionSpec(packageName) {
25992
26163
  function readPackageInfo(packageName) {
25993
26164
  const bareName = packageName.startsWith("/") || packageName.startsWith(".") ? packageName : stripVersionSpec(packageName);
25994
26165
  if (packageName.startsWith("/") || packageName.startsWith(".")) {
25995
- const localPkgPath = join6(packageName, "package.json");
25996
- if (existsSync5(localPkgPath)) {
26166
+ const localPkgPath = join7(packageName, "package.json");
26167
+ if (existsSync6(localPkgPath)) {
25997
26168
  try {
25998
26169
  const pkg = JSON.parse(readFileSync4(localPkgPath, "utf-8"));
25999
26170
  return {
@@ -26007,18 +26178,18 @@ function readPackageInfo(packageName) {
26007
26178
  }
26008
26179
  }
26009
26180
  const searchPaths = [
26010
- join6(process.cwd(), "node_modules", bareName, "package.json"),
26181
+ join7(process.cwd(), "node_modules", bareName, "package.json"),
26011
26182
  resolve(process.cwd(), "..", "node_modules", bareName, "package.json"),
26012
- join6(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26183
+ join7(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26013
26184
  ...(() => {
26014
26185
  const globalRoot = getNpmGlobalRoot();
26015
- return globalRoot ? [join6(globalRoot, bareName, "package.json")] : [];
26186
+ return globalRoot ? [join7(globalRoot, bareName, "package.json")] : [];
26016
26187
  })(),
26017
- join6(homedir4(), ".roy-agent", "node_modules", bareName, "package.json")
26188
+ join7(homedir5(), ".roy-agent", "node_modules", bareName, "package.json")
26018
26189
  ];
26019
26190
  for (const pkgPath of searchPaths) {
26020
26191
  try {
26021
- if (existsSync5(pkgPath)) {
26192
+ if (existsSync6(pkgPath)) {
26022
26193
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
26023
26194
  return {
26024
26195
  version: pkg.version ?? "0.0.0",
@@ -26052,15 +26223,15 @@ async function verifyInstalledVersion(packageName, declaredVersion) {
26052
26223
  return { ok: true, actualVersion: actual.version };
26053
26224
  }
26054
26225
  function getPackageManagerCommand() {
26055
- if (existsSync5(join6(process.cwd(), "pnpm-lock.yaml"))) {
26056
- if (existsSync5(join6(process.cwd(), "pnpm-workspace.yaml"))) {
26226
+ if (existsSync6(join7(process.cwd(), "pnpm-lock.yaml"))) {
26227
+ if (existsSync6(join7(process.cwd(), "pnpm-workspace.yaml"))) {
26057
26228
  return "pnpm -w";
26058
26229
  }
26059
26230
  return "pnpm";
26060
26231
  }
26061
- if (existsSync5(join6(process.cwd(), "yarn.lock")))
26232
+ if (existsSync6(join7(process.cwd(), "yarn.lock")))
26062
26233
  return "yarn";
26063
- if (existsSync5(join6(process.cwd(), "bun.lock")) || existsSync5(join6(process.cwd(), "bun.lockb")))
26234
+ if (existsSync6(join7(process.cwd(), "bun.lock")) || existsSync6(join7(process.cwd(), "bun.lockb")))
26064
26235
  return "bun";
26065
26236
  return "npm";
26066
26237
  }
@@ -26099,15 +26270,15 @@ var InstallPackageCommand = {
26099
26270
  }
26100
26271
  resolvedName = info2.name;
26101
26272
  const srcDir = resolve(packageName);
26102
- if (!existsSync5(srcDir)) {
26273
+ if (!existsSync6(srcDir)) {
26103
26274
  console.error(`
26104
26275
  ❌ Local path '${srcDir}' does not exist.
26105
26276
  `);
26106
26277
  process.exit(1);
26107
26278
  }
26108
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26109
- if (!existsSync5(pluginDir)) {
26110
- mkdirSync(pluginDir, { recursive: true });
26279
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26280
+ if (!existsSync6(pluginDir)) {
26281
+ mkdirSync2(pluginDir, { recursive: true });
26111
26282
  }
26112
26283
  const result = spawnSync("cp", ["-r", `${srcDir}/.`, pluginDir], {
26113
26284
  stdio: "inherit",
@@ -26141,12 +26312,12 @@ var InstallPackageCommand = {
26141
26312
  process.exit(1);
26142
26313
  }
26143
26314
  resolvedName = info2.name;
26144
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26145
- if (!existsSync5(pluginDir)) {
26146
- mkdirSync(pluginDir, { recursive: true });
26315
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26316
+ if (!existsSync6(pluginDir)) {
26317
+ mkdirSync2(pluginDir, { recursive: true });
26147
26318
  }
26148
- const nmPath = join6(process.cwd(), "node_modules", packageName);
26149
- if (existsSync5(nmPath)) {
26319
+ const nmPath = join7(process.cwd(), "node_modules", packageName);
26320
+ if (existsSync6(nmPath)) {
26150
26321
  spawnSync("cp", ["-r", `${nmPath}/.`, pluginDir], { stdio: "inherit", shell: false });
26151
26322
  }
26152
26323
  }
@@ -26168,7 +26339,7 @@ var InstallPackageCommand = {
26168
26339
  if (tmpInfo) {
26169
26340
  const cleanupResult = cleanupStalePluginCopies(tmpInfo.name, {
26170
26341
  globalVersion: tmpInfo.version,
26171
- homedir: homedir4()
26342
+ homedir: homedir5()
26172
26343
  });
26173
26344
  if (cleanupResult.cleaned.length > 0) {
26174
26345
  console.log(`
@@ -26308,8 +26479,8 @@ var InstallRemoveCommand = {
26308
26479
  \uD83D\uDDD1️ Removing plugin: ${plugin.packageName}@${plugin.version} (${scope})
26309
26480
  `);
26310
26481
  if (scope === "project") {
26311
- const pluginDir = join6(process.cwd(), ".roy", "plugins", plugin.packageName);
26312
- if (existsSync5(pluginDir)) {
26482
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", plugin.packageName);
26483
+ if (existsSync6(pluginDir)) {
26313
26484
  spawnSync("rm", ["-rf", pluginDir], { stdio: "inherit", shell: false });
26314
26485
  console.log(` Removed plugin directory: ${pluginDir}`);
26315
26486
  }
@@ -26324,8 +26495,8 @@ var InstallRemoveCommand = {
26324
26495
  `);
26325
26496
  process.exit(result.status ?? 1);
26326
26497
  }
26327
- const globalNm = join6(homedir4(), ".roy-agent", "node_modules", plugin.packageName);
26328
- if (existsSync5(globalNm)) {
26498
+ const globalNm = join7(homedir5(), ".roy-agent", "node_modules", plugin.packageName);
26499
+ if (existsSync6(globalNm)) {
26329
26500
  spawnSync("rm", ["-rf", globalNm], { stdio: "inherit", shell: false });
26330
26501
  }
26331
26502
  }
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/roy-agent-linux-x64/bin/roy-agent
3
- size: 109570176 bytes
4
- sha256: c9411373bf0add3a633ba527bbe1f3608b6260c1861b53e4f0eae11012164de5
3
+ size: 109602944 bytes
4
+ sha256: 4bff7951c55594175f880f2caca477359a3c55c89b5b973d9ba7cf8e721d8928
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-cli",
3
- "version": "1.7.36",
3
+ "version": "1.7.38",
4
4
  "type": "module",
5
5
  "description": "CLI for roy-agent - Non-interactive command execution",
6
6
  "main": "./dist/index.js",