@ai-setting/roy-agent-cli 1.7.37 → 1.7.39

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.37",
9464
+ version: "1.7.39",
9465
9465
  type: "module",
9466
9466
  description: "CLI for roy-agent - Non-interactive command execution",
9467
9467
  main: "./dist/index.js",
@@ -11527,8 +11527,26 @@ 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";
11538
+ function parseLarkPerTaskChatId(contextJson) {
11539
+ if (!contextJson)
11540
+ return;
11541
+ try {
11542
+ const obj = JSON.parse(contextJson);
11543
+ const id = obj?.larkPerTaskChatId;
11544
+ return typeof id === "string" && id.length > 0 ? id : undefined;
11545
+ } catch {
11546
+ return;
11547
+ }
11548
+ }
11549
+
11532
11550
  class EventHandler {
11533
11551
  env;
11534
11552
  eventTypes;
@@ -11543,6 +11561,9 @@ class EventHandler {
11543
11561
  unsubscribe = null;
11544
11562
  sessionComponent = null;
11545
11563
  activeEventSessionId = null;
11564
+ resolvedSessionByTrigger = new Map;
11565
+ eventStore = null;
11566
+ getHandlerForEsType = null;
11546
11567
  constructor(options) {
11547
11568
  this.env = options.env;
11548
11569
  this.eventTypes = options.eventTypes;
@@ -11552,6 +11573,8 @@ class EventHandler {
11552
11573
  this.isIdle = options.isIdle ?? (() => true);
11553
11574
  this.idleCheckInterval = options.idleCheckInterval ?? 100;
11554
11575
  this.sessionComponent = options.sessionComponent ?? null;
11576
+ this.eventStore = options.eventStore ?? null;
11577
+ this.getHandlerForEsType = options.getHandlerForEsType ?? null;
11555
11578
  }
11556
11579
  start() {
11557
11580
  this.isStopped = false;
@@ -11589,13 +11612,125 @@ class EventHandler {
11589
11612
  this.isProcessing = false;
11590
11613
  this.clearActiveSession();
11591
11614
  }
11592
- handleEvent(event) {
11615
+ async handleEvent(event) {
11593
11616
  if (this.isStopped) {
11594
11617
  return;
11595
11618
  }
11596
- const formatted = this.formatter.formatWithEvent(event);
11619
+ const formatted = await this.formatEvent(event);
11597
11620
  this.enqueue(formatted);
11598
11621
  }
11622
+ async formatEvent(event) {
11623
+ if (event.type.startsWith("task.background.") && event.metadata?.triggerEventId && this.eventStore && this.getHandlerForEsType) {
11624
+ try {
11625
+ const v2Formatted = await this.formatEventViaESPluginV2(event);
11626
+ if (v2Formatted) {
11627
+ return v2Formatted;
11628
+ }
11629
+ } catch (err) {
11630
+ console.error(`[EventHandler] ESPlugin v2 path failed, falling back to formatter`, err);
11631
+ }
11632
+ }
11633
+ return this.formatter.formatWithEvent(event);
11634
+ }
11635
+ async formatEventViaESPluginV2(event) {
11636
+ const triggerEventId = event.metadata.triggerEventId;
11637
+ const triggerEvent = await this.eventStore.getEventById(triggerEventId);
11638
+ if (!triggerEvent) {
11639
+ return null;
11640
+ }
11641
+ const handler = this.getHandlerForEsType(triggerEvent.esType);
11642
+ if (!handler || !handler.buildNotifyHandlePrompt) {
11643
+ return null;
11644
+ }
11645
+ const payload = event.payload;
11646
+ const subAgentResult = {
11647
+ summary: typeof payload?.result === "string" ? payload.result : typeof payload?.error === "string" ? payload.error : "(无结果)"
11648
+ };
11649
+ const profile = triggerEvent.metadata?.profile ?? undefined;
11650
+ const prompt = handler.buildNotifyHandlePrompt({
11651
+ notifyEvent: {
11652
+ type: event.type,
11653
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11654
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11655
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11656
+ error: typeof payload?.error === "string" ? payload.error : undefined
11657
+ },
11658
+ triggerEvent,
11659
+ subAgentResult,
11660
+ profile
11661
+ });
11662
+ if (handler.postProcessNotifyEvent) {
11663
+ const notifyEventForHook = {
11664
+ type: event.type,
11665
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11666
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11667
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11668
+ error: typeof payload?.error === "string" ? payload.error : undefined
11669
+ };
11670
+ setTimeout(() => {
11671
+ (async () => {
11672
+ const resolvedChatIds = await this.resolveNotifyChatIds(notifyEventForHook.taskId);
11673
+ await handler.postProcessNotifyEvent({
11674
+ notifyEvent: notifyEventForHook,
11675
+ triggerEvent,
11676
+ subAgentResult,
11677
+ formattedPrompt: prompt.promptText,
11678
+ profile,
11679
+ resolvedChatIds
11680
+ });
11681
+ })().catch((err) => {
11682
+ console.error(`[EventHandler] postProcessNotifyEvent hook failed (swallowed)`, err);
11683
+ });
11684
+ }, 0);
11685
+ }
11686
+ const triggerChatId = triggerEvent.metadata?.chatId ?? undefined;
11687
+ const triggerMessageId = triggerEvent.metadata?.messageId ?? undefined;
11688
+ const triggerSessionId = event?.metadata?.trigger_session_id;
11689
+ return {
11690
+ message: prompt.promptText,
11691
+ envEvent: event,
11692
+ triggerSessionId,
11693
+ chatId: triggerChatId,
11694
+ ...triggerMessageId ? { triggerMessageId } : {}
11695
+ };
11696
+ }
11697
+ async resolveNotifyChatIds(taskId) {
11698
+ if (!taskId)
11699
+ return [];
11700
+ const taskComp = this.env.getComponent("task");
11701
+ if (!taskComp?.getTask)
11702
+ return [];
11703
+ const seen = new Set;
11704
+ let id = taskId;
11705
+ while (id !== undefined && id !== null && !seen.has(id) && seen.size < 8) {
11706
+ seen.add(id);
11707
+ let task;
11708
+ try {
11709
+ task = await taskComp.getTask(id);
11710
+ } catch (err) {
11711
+ console.error(`[EventHandler] resolveNotifyChatIds: getTask(${id}) failed`, err);
11712
+ return [];
11713
+ }
11714
+ if (!task)
11715
+ return [];
11716
+ const chatId = parseLarkPerTaskChatId(task.context);
11717
+ if (chatId)
11718
+ return [chatId];
11719
+ const parent = task.parent_task_id;
11720
+ id = typeof parent === "number" && parent > 0 ? parent : undefined;
11721
+ }
11722
+ return [];
11723
+ }
11724
+ async handleNotifyEventForTest(event) {
11725
+ if (this.isStopped)
11726
+ return;
11727
+ const formatted = await this.formatEvent(event);
11728
+ if (this.onEventWithEnv) {
11729
+ await this.onEventWithEnv(formatted);
11730
+ } else {
11731
+ await this.onEvent(formatted.message);
11732
+ }
11733
+ }
11599
11734
  enqueue(formattedEvent) {
11600
11735
  if (this.isStopped) {
11601
11736
  return;
@@ -11662,7 +11797,12 @@ class EventHandler {
11662
11797
  async ensureActiveSession(triggerSessionIdOverride) {
11663
11798
  if (!this.sessionComponent)
11664
11799
  return null;
11665
- if (this.activeEventSessionId) {
11800
+ if (triggerSessionIdOverride) {
11801
+ const cached = this.resolvedSessionByTrigger.get(triggerSessionIdOverride);
11802
+ if (cached) {
11803
+ return cached;
11804
+ }
11805
+ } else if (this.activeEventSessionId) {
11666
11806
  return this.activeEventSessionId;
11667
11807
  }
11668
11808
  const triggerSessionId = triggerSessionIdOverride ?? this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
@@ -11674,6 +11814,7 @@ class EventHandler {
11674
11814
  return null;
11675
11815
  }
11676
11816
  this.activeEventSessionId = existing.id;
11817
+ this.cacheResolvedSession(triggerSessionIdOverride, existing.id);
11677
11818
  await this.sessionComponent.setActiveSession(existing.id);
11678
11819
  return existing.id;
11679
11820
  }
@@ -11691,13 +11832,16 @@ class EventHandler {
11691
11832
  return null;
11692
11833
  }
11693
11834
  this.activeEventSessionId = existing.id;
11835
+ this.cacheResolvedSession(triggerSessionIdOverride, existing.id);
11694
11836
  return existing.id;
11695
11837
  }
11696
11838
  }
11697
11839
  } catch (error) {
11698
11840
  console.error(`[EventHandler] Failed to lookup global active session:`, error);
11699
11841
  }
11700
- return this.createNewEventSession();
11842
+ const created = await this.createNewEventSession();
11843
+ this.cacheResolvedSession(triggerSessionIdOverride, created);
11844
+ return created;
11701
11845
  }
11702
11846
  async ensureChatSession(chatId) {
11703
11847
  if (!this.sessionComponent)
@@ -11757,6 +11901,12 @@ class EventHandler {
11757
11901
  }
11758
11902
  clearActiveSession() {
11759
11903
  this.activeEventSessionId = null;
11904
+ this.resolvedSessionByTrigger.clear();
11905
+ }
11906
+ cacheResolvedSession(triggerSessionIdOverride, sessionId) {
11907
+ if (triggerSessionIdOverride && sessionId) {
11908
+ this.resolvedSessionByTrigger.set(triggerSessionIdOverride, sessionId);
11909
+ }
11760
11910
  }
11761
11911
  getActiveEventSessionId() {
11762
11912
  return this.activeEventSessionId;
@@ -11771,15 +11921,31 @@ class EventHandler {
11771
11921
  }
11772
11922
  }
11773
11923
  __legacyDecorateClassTS([
11774
- TracedAs5("cli.event-handler.handleEvent", { recordParams: true }),
11924
+ TracedAs5("event_handler.handle_event", { recordParams: true }),
11775
11925
  __legacyMetadataTS("design:type", Function),
11776
11926
  __legacyMetadataTS("design:paramtypes", [
11777
11927
  typeof EnvEvent === "undefined" ? Object : EnvEvent
11778
11928
  ]),
11779
- __legacyMetadataTS("design:returntype", undefined)
11929
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11780
11930
  ], EventHandler.prototype, "handleEvent", null);
11781
11931
  __legacyDecorateClassTS([
11782
- TracedAs5("cli.event-handler.ensureActiveSession", { recordParams: true }),
11932
+ TracedAs5("cli.event-handler.formatEvent", { recordParams: true, recordResult: false }),
11933
+ __legacyMetadataTS("design:type", Function),
11934
+ __legacyMetadataTS("design:paramtypes", [
11935
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11936
+ ]),
11937
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11938
+ ], EventHandler.prototype, "formatEvent", null);
11939
+ __legacyDecorateClassTS([
11940
+ TracedAs5("event_handler.process_notify", { recordParams: true, recordResult: false }),
11941
+ __legacyMetadataTS("design:type", Function),
11942
+ __legacyMetadataTS("design:paramtypes", [
11943
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11944
+ ]),
11945
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11946
+ ], EventHandler.prototype, "formatEventViaESPluginV2", null);
11947
+ __legacyDecorateClassTS([
11948
+ TracedAs5("cli.event-handler.ensureActiveSession", { recordParams: true, recordResult: true }),
11783
11949
  __legacyMetadataTS("design:type", Function),
11784
11950
  __legacyMetadataTS("design:paramtypes", [
11785
11951
  String
@@ -11795,6 +11961,62 @@ __legacyDecorateClassTS([
11795
11961
  __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11796
11962
  ], EventHandler.prototype, "ensureChatSession", null);
11797
11963
 
11964
+ // src/commands/shared/event-handler-wiring.ts
11965
+ var storeCache = new Map;
11966
+ function getOrCreateEventStore(dbPath) {
11967
+ const normalized = normalizeDbPath(dbPath);
11968
+ let store = storeCache.get(normalized);
11969
+ if (store)
11970
+ return store;
11971
+ ensureParentDir(normalized);
11972
+ store = new EventStoreImpl({ dbPath: normalized });
11973
+ storeCache.set(normalized, store);
11974
+ setSharedEventStore(store);
11975
+ return store;
11976
+ }
11977
+ function normalizeDbPath(dbPath) {
11978
+ const expanded = dbPath.startsWith("~") ? join(homedir(), dbPath.slice(1).replace(/^\//, "")) : dbPath;
11979
+ return expanded;
11980
+ }
11981
+ function ensureParentDir(dbPath) {
11982
+ const parent = join(dbPath, "..");
11983
+ if (!existsSync(parent)) {
11984
+ mkdirSync(parent, { recursive: true });
11985
+ }
11986
+ }
11987
+ function getHandlerForEsTypeForEnv(env) {
11988
+ let component = null;
11989
+ try {
11990
+ component = env.getComponent?.("event-source") ?? null;
11991
+ } catch {
11992
+ component = null;
11993
+ }
11994
+ const hasGetHandler = component !== null && component !== undefined && typeof component.getHandler === "function";
11995
+ return (esType) => {
11996
+ if (!hasGetHandler)
11997
+ return;
11998
+ try {
11999
+ const h = component.getHandler(esType);
12000
+ return h ?? undefined;
12001
+ } catch {
12002
+ return;
12003
+ }
12004
+ };
12005
+ }
12006
+ function createDefaultEventStoreDbPath() {
12007
+ return join(homedir(), ".roy-agent", "event-store.db");
12008
+ }
12009
+ function createEventHandlerForInteractive(options) {
12010
+ const dbPath = options.dbPath ?? createDefaultEventStoreDbPath();
12011
+ const eventStore = getOrCreateEventStore(dbPath);
12012
+ const getHandlerForEsType = getHandlerForEsTypeForEnv(options.env);
12013
+ return new EventHandler({
12014
+ ...options,
12015
+ eventStore,
12016
+ getHandlerForEsType
12017
+ });
12018
+ }
12019
+
11798
12020
  // src/commands/shared/esc-active-descendant.ts
11799
12021
  function hasActiveDescendants(env, parentSessionId) {
11800
12022
  if (!env || !parentSessionId)
@@ -13646,12 +13868,13 @@ function createInteractiveCommand(externalEnvService) {
13646
13868
  console
13647
13869
  });
13648
13870
  });
13649
- const eventHandler = new EventHandler({
13871
+ const eventHandler = createEventHandlerForInteractive({
13650
13872
  env,
13651
13873
  eventTypes: ["task.background.*", "event-source.event.*"],
13652
13874
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
13653
13875
  isIdle: () => repl.isIdle(),
13654
13876
  sessionComponent,
13877
+ onEvent: async (_message) => {},
13655
13878
  onEventWithEnv: async (formattedEvent) => {
13656
13879
  await repl.handleEventMessageWithEnv(formattedEvent);
13657
13880
  }
@@ -14510,7 +14733,7 @@ async function loadHandleQuery(options, hooks) {
14510
14733
  env,
14511
14734
  enabled: true
14512
14735
  });
14513
- const eventHandler = new EventHandler({
14736
+ const eventHandler = createEventHandlerForInteractive({
14514
14737
  env,
14515
14738
  eventTypes: ["task.background.*", "event-source.event.*"],
14516
14739
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
@@ -14646,7 +14869,7 @@ function createRunCommand() {
14646
14869
  const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
14647
14870
  const runState = {
14648
14871
  isIdle: () => true,
14649
- onNotification: () => {}
14872
+ onNotification: async () => {}
14650
14873
  };
14651
14874
  const {
14652
14875
  handleQuery,
@@ -21450,15 +21673,15 @@ function resolveServerUrl(serverUrl, fallback) {
21450
21673
  }
21451
21674
 
21452
21675
  // src/lib/bounty-profile-reader.ts
21453
- import { existsSync as existsSync2, readFileSync } from "node:fs";
21454
- import { homedir } from "node:os";
21455
- import { join } from "node:path";
21676
+ import { existsSync as existsSync3, readFileSync } from "node:fs";
21677
+ import { homedir as homedir2 } from "node:os";
21678
+ import { join as join2 } from "node:path";
21456
21679
  function readBountyProfile(name, profilesDir) {
21457
21680
  if (!name)
21458
21681
  return null;
21459
- const dir = profilesDir ?? join(homedir(), ".config", "bounty", "profiles");
21460
- const profilePath = join(dir, `${name}.json`);
21461
- if (!existsSync2(profilePath))
21682
+ const dir = profilesDir ?? join2(homedir2(), ".config", "bounty", "profiles");
21683
+ const profilePath = join2(dir, `${name}.json`);
21684
+ if (!existsSync3(profilePath))
21462
21685
  return null;
21463
21686
  try {
21464
21687
  const raw = readFileSync(profilePath, "utf-8");
@@ -25875,19 +26098,19 @@ var LspCommand = {
25875
26098
 
25876
26099
  // src/commands/install/index.ts
25877
26100
  import { spawnSync } from "node:child_process";
25878
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync, mkdirSync, rmSync as rmSync2 } from "node:fs";
25879
- import { join as join6, resolve } from "node:path";
25880
- import { homedir as homedir4 } from "node:os";
26101
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync, mkdirSync as mkdirSync2, rmSync as rmSync2 } from "node:fs";
26102
+ import { join as join7, resolve } from "node:path";
26103
+ import { homedir as homedir5 } from "node:os";
25881
26104
 
25882
26105
  // src/commands/install/cleanup-stale-plugin-copies.ts
25883
- import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
25884
- import { join as join5 } from "node:path";
26106
+ import { existsSync as existsSync5, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
26107
+ import { join as join6 } from "node:path";
25885
26108
  import { homedir as nodeHomedir, tmpdir as nodeTmpdir } from "node:os";
25886
26109
  function cleanupStalePluginCopies(packageName, options) {
25887
26110
  const HOME = options.homedir ?? nodeHomedir();
25888
26111
  const paths = options.localNodeModulesPaths ?? [
25889
- join5(HOME, "node_modules"),
25890
- join5(HOME, ".roy-agent", "node_modules")
26112
+ join6(HOME, "node_modules"),
26113
+ join6(HOME, ".roy-agent", "node_modules")
25891
26114
  ];
25892
26115
  const backupRoot = options.backupDir ?? nodeTmpdir();
25893
26116
  const result = {
@@ -25897,15 +26120,15 @@ function cleanupStalePluginCopies(packageName, options) {
25897
26120
  };
25898
26121
  if (!options.globalVersion) {
25899
26122
  for (const p of paths) {
25900
- const candidate = join5(p, packageName);
26123
+ const candidate = join6(p, packageName);
25901
26124
  result.skipped.push({ path: candidate, reason: "no-global-version" });
25902
26125
  }
25903
26126
  return result;
25904
26127
  }
25905
26128
  for (const nmPath of paths) {
25906
- const localPkgDir = join5(nmPath, packageName);
25907
- const localPkgJson = join5(localPkgDir, "package.json");
25908
- if (!existsSync4(localPkgJson)) {
26129
+ const localPkgDir = join6(nmPath, packageName);
26130
+ const localPkgJson = join6(localPkgDir, "package.json");
26131
+ if (!existsSync5(localPkgJson)) {
25909
26132
  result.skipped.push({ path: localPkgDir, reason: "no-local-copy" });
25910
26133
  continue;
25911
26134
  }
@@ -25926,7 +26149,7 @@ function cleanupStalePluginCopies(packageName, options) {
25926
26149
  const safeName = packageName.replace(/@/g, "").replace(/[^a-zA-Z0-9._/-]/g, "-");
25927
26150
  const safeLocalVersion = (localVersion ?? "unknown").replace(/[^a-zA-Z0-9._-]/g, "-");
25928
26151
  const timestamp = Date.now();
25929
- backupPath = join5(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
26152
+ backupPath = join6(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
25930
26153
  cpSync(localPkgDir, backupPath, { recursive: true });
25931
26154
  result.backups.push({ originalPath: localPkgDir, backupPath });
25932
26155
  } catch (err) {
@@ -25961,19 +26184,19 @@ function compareVersions(a, b) {
25961
26184
 
25962
26185
  // src/commands/install/index.ts
25963
26186
  function getConfigDir(scope) {
25964
- return scope === "global" ? join6(homedir4(), ".roy-agent") : join6(process.cwd(), ".roy");
26187
+ return scope === "global" ? join7(homedir5(), ".roy-agent") : join7(process.cwd(), ".roy");
25965
26188
  }
25966
26189
  function detectDefaultScope() {
25967
- const projectDir = join6(process.cwd(), ".roy");
25968
- return existsSync5(projectDir) ? "project" : "global";
26190
+ const projectDir = join7(process.cwd(), ".roy");
26191
+ return existsSync6(projectDir) ? "project" : "global";
25969
26192
  }
25970
26193
  function getConfigPath(scope) {
25971
- return join6(getConfigDir(scope), "plugins.json");
26194
+ return join7(getConfigDir(scope), "plugins.json");
25972
26195
  }
25973
26196
  function loadPlugins(scope) {
25974
26197
  const configPath = getConfigPath(scope);
25975
26198
  try {
25976
- if (existsSync5(configPath)) {
26199
+ if (existsSync6(configPath)) {
25977
26200
  const raw = readFileSync4(configPath, "utf-8");
25978
26201
  const config = JSON.parse(raw);
25979
26202
  return config.plugins ?? [];
@@ -25984,8 +26207,8 @@ function loadPlugins(scope) {
25984
26207
  function savePlugins(plugins, scope) {
25985
26208
  const configDir = getConfigDir(scope);
25986
26209
  const configPath = getConfigPath(scope);
25987
- if (!existsSync5(configDir)) {
25988
- mkdirSync(configDir, { recursive: true });
26210
+ if (!existsSync6(configDir)) {
26211
+ mkdirSync2(configDir, { recursive: true });
25989
26212
  }
25990
26213
  const config = { plugins };
25991
26214
  writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
@@ -26000,8 +26223,8 @@ function stripVersionSpec(packageName) {
26000
26223
  function readPackageInfo(packageName) {
26001
26224
  const bareName = packageName.startsWith("/") || packageName.startsWith(".") ? packageName : stripVersionSpec(packageName);
26002
26225
  if (packageName.startsWith("/") || packageName.startsWith(".")) {
26003
- const localPkgPath = join6(packageName, "package.json");
26004
- if (existsSync5(localPkgPath)) {
26226
+ const localPkgPath = join7(packageName, "package.json");
26227
+ if (existsSync6(localPkgPath)) {
26005
26228
  try {
26006
26229
  const pkg = JSON.parse(readFileSync4(localPkgPath, "utf-8"));
26007
26230
  return {
@@ -26015,18 +26238,18 @@ function readPackageInfo(packageName) {
26015
26238
  }
26016
26239
  }
26017
26240
  const searchPaths = [
26018
- join6(process.cwd(), "node_modules", bareName, "package.json"),
26241
+ join7(process.cwd(), "node_modules", bareName, "package.json"),
26019
26242
  resolve(process.cwd(), "..", "node_modules", bareName, "package.json"),
26020
- join6(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26243
+ join7(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26021
26244
  ...(() => {
26022
26245
  const globalRoot = getNpmGlobalRoot();
26023
- return globalRoot ? [join6(globalRoot, bareName, "package.json")] : [];
26246
+ return globalRoot ? [join7(globalRoot, bareName, "package.json")] : [];
26024
26247
  })(),
26025
- join6(homedir4(), ".roy-agent", "node_modules", bareName, "package.json")
26248
+ join7(homedir5(), ".roy-agent", "node_modules", bareName, "package.json")
26026
26249
  ];
26027
26250
  for (const pkgPath of searchPaths) {
26028
26251
  try {
26029
- if (existsSync5(pkgPath)) {
26252
+ if (existsSync6(pkgPath)) {
26030
26253
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
26031
26254
  return {
26032
26255
  version: pkg.version ?? "0.0.0",
@@ -26060,15 +26283,15 @@ async function verifyInstalledVersion(packageName, declaredVersion) {
26060
26283
  return { ok: true, actualVersion: actual.version };
26061
26284
  }
26062
26285
  function getPackageManagerCommand() {
26063
- if (existsSync5(join6(process.cwd(), "pnpm-lock.yaml"))) {
26064
- if (existsSync5(join6(process.cwd(), "pnpm-workspace.yaml"))) {
26286
+ if (existsSync6(join7(process.cwd(), "pnpm-lock.yaml"))) {
26287
+ if (existsSync6(join7(process.cwd(), "pnpm-workspace.yaml"))) {
26065
26288
  return "pnpm -w";
26066
26289
  }
26067
26290
  return "pnpm";
26068
26291
  }
26069
- if (existsSync5(join6(process.cwd(), "yarn.lock")))
26292
+ if (existsSync6(join7(process.cwd(), "yarn.lock")))
26070
26293
  return "yarn";
26071
- if (existsSync5(join6(process.cwd(), "bun.lock")) || existsSync5(join6(process.cwd(), "bun.lockb")))
26294
+ if (existsSync6(join7(process.cwd(), "bun.lock")) || existsSync6(join7(process.cwd(), "bun.lockb")))
26072
26295
  return "bun";
26073
26296
  return "npm";
26074
26297
  }
@@ -26107,15 +26330,15 @@ var InstallPackageCommand = {
26107
26330
  }
26108
26331
  resolvedName = info2.name;
26109
26332
  const srcDir = resolve(packageName);
26110
- if (!existsSync5(srcDir)) {
26333
+ if (!existsSync6(srcDir)) {
26111
26334
  console.error(`
26112
26335
  ❌ Local path '${srcDir}' does not exist.
26113
26336
  `);
26114
26337
  process.exit(1);
26115
26338
  }
26116
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26117
- if (!existsSync5(pluginDir)) {
26118
- mkdirSync(pluginDir, { recursive: true });
26339
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26340
+ if (!existsSync6(pluginDir)) {
26341
+ mkdirSync2(pluginDir, { recursive: true });
26119
26342
  }
26120
26343
  const result = spawnSync("cp", ["-r", `${srcDir}/.`, pluginDir], {
26121
26344
  stdio: "inherit",
@@ -26149,12 +26372,12 @@ var InstallPackageCommand = {
26149
26372
  process.exit(1);
26150
26373
  }
26151
26374
  resolvedName = info2.name;
26152
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26153
- if (!existsSync5(pluginDir)) {
26154
- mkdirSync(pluginDir, { recursive: true });
26375
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26376
+ if (!existsSync6(pluginDir)) {
26377
+ mkdirSync2(pluginDir, { recursive: true });
26155
26378
  }
26156
- const nmPath = join6(process.cwd(), "node_modules", packageName);
26157
- if (existsSync5(nmPath)) {
26379
+ const nmPath = join7(process.cwd(), "node_modules", packageName);
26380
+ if (existsSync6(nmPath)) {
26158
26381
  spawnSync("cp", ["-r", `${nmPath}/.`, pluginDir], { stdio: "inherit", shell: false });
26159
26382
  }
26160
26383
  }
@@ -26176,7 +26399,7 @@ var InstallPackageCommand = {
26176
26399
  if (tmpInfo) {
26177
26400
  const cleanupResult = cleanupStalePluginCopies(tmpInfo.name, {
26178
26401
  globalVersion: tmpInfo.version,
26179
- homedir: homedir4()
26402
+ homedir: homedir5()
26180
26403
  });
26181
26404
  if (cleanupResult.cleaned.length > 0) {
26182
26405
  console.log(`
@@ -26316,8 +26539,8 @@ var InstallRemoveCommand = {
26316
26539
  \uD83D\uDDD1️ Removing plugin: ${plugin.packageName}@${plugin.version} (${scope})
26317
26540
  `);
26318
26541
  if (scope === "project") {
26319
- const pluginDir = join6(process.cwd(), ".roy", "plugins", plugin.packageName);
26320
- if (existsSync5(pluginDir)) {
26542
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", plugin.packageName);
26543
+ if (existsSync6(pluginDir)) {
26321
26544
  spawnSync("rm", ["-rf", pluginDir], { stdio: "inherit", shell: false });
26322
26545
  console.log(` Removed plugin directory: ${pluginDir}`);
26323
26546
  }
@@ -26332,8 +26555,8 @@ var InstallRemoveCommand = {
26332
26555
  `);
26333
26556
  process.exit(result.status ?? 1);
26334
26557
  }
26335
- const globalNm = join6(homedir4(), ".roy-agent", "node_modules", plugin.packageName);
26336
- if (existsSync5(globalNm)) {
26558
+ const globalNm = join7(homedir5(), ".roy-agent", "node_modules", plugin.packageName);
26559
+ if (existsSync6(globalNm)) {
26337
26560
  spawnSync("rm", ["-rf", globalNm], { stdio: "inherit", shell: false });
26338
26561
  }
26339
26562
  }
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.37",
9463
+ version: "1.7.39",
9464
9464
  type: "module",
9465
9465
  description: "CLI for roy-agent - Non-interactive command execution",
9466
9466
  main: "./dist/index.js",
@@ -11526,8 +11526,26 @@ 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";
11537
+ function parseLarkPerTaskChatId(contextJson) {
11538
+ if (!contextJson)
11539
+ return;
11540
+ try {
11541
+ const obj = JSON.parse(contextJson);
11542
+ const id = obj?.larkPerTaskChatId;
11543
+ return typeof id === "string" && id.length > 0 ? id : undefined;
11544
+ } catch {
11545
+ return;
11546
+ }
11547
+ }
11548
+
11531
11549
  class EventHandler {
11532
11550
  env;
11533
11551
  eventTypes;
@@ -11542,6 +11560,9 @@ class EventHandler {
11542
11560
  unsubscribe = null;
11543
11561
  sessionComponent = null;
11544
11562
  activeEventSessionId = null;
11563
+ resolvedSessionByTrigger = new Map;
11564
+ eventStore = null;
11565
+ getHandlerForEsType = null;
11545
11566
  constructor(options) {
11546
11567
  this.env = options.env;
11547
11568
  this.eventTypes = options.eventTypes;
@@ -11551,6 +11572,8 @@ class EventHandler {
11551
11572
  this.isIdle = options.isIdle ?? (() => true);
11552
11573
  this.idleCheckInterval = options.idleCheckInterval ?? 100;
11553
11574
  this.sessionComponent = options.sessionComponent ?? null;
11575
+ this.eventStore = options.eventStore ?? null;
11576
+ this.getHandlerForEsType = options.getHandlerForEsType ?? null;
11554
11577
  }
11555
11578
  start() {
11556
11579
  this.isStopped = false;
@@ -11588,13 +11611,125 @@ class EventHandler {
11588
11611
  this.isProcessing = false;
11589
11612
  this.clearActiveSession();
11590
11613
  }
11591
- handleEvent(event) {
11614
+ async handleEvent(event) {
11592
11615
  if (this.isStopped) {
11593
11616
  return;
11594
11617
  }
11595
- const formatted = this.formatter.formatWithEvent(event);
11618
+ const formatted = await this.formatEvent(event);
11596
11619
  this.enqueue(formatted);
11597
11620
  }
11621
+ async formatEvent(event) {
11622
+ if (event.type.startsWith("task.background.") && event.metadata?.triggerEventId && this.eventStore && this.getHandlerForEsType) {
11623
+ try {
11624
+ const v2Formatted = await this.formatEventViaESPluginV2(event);
11625
+ if (v2Formatted) {
11626
+ return v2Formatted;
11627
+ }
11628
+ } catch (err) {
11629
+ console.error(`[EventHandler] ESPlugin v2 path failed, falling back to formatter`, err);
11630
+ }
11631
+ }
11632
+ return this.formatter.formatWithEvent(event);
11633
+ }
11634
+ async formatEventViaESPluginV2(event) {
11635
+ const triggerEventId = event.metadata.triggerEventId;
11636
+ const triggerEvent = await this.eventStore.getEventById(triggerEventId);
11637
+ if (!triggerEvent) {
11638
+ return null;
11639
+ }
11640
+ const handler = this.getHandlerForEsType(triggerEvent.esType);
11641
+ if (!handler || !handler.buildNotifyHandlePrompt) {
11642
+ return null;
11643
+ }
11644
+ const payload = event.payload;
11645
+ const subAgentResult = {
11646
+ summary: typeof payload?.result === "string" ? payload.result : typeof payload?.error === "string" ? payload.error : "(无结果)"
11647
+ };
11648
+ const profile = triggerEvent.metadata?.profile ?? undefined;
11649
+ const prompt = handler.buildNotifyHandlePrompt({
11650
+ notifyEvent: {
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
+ triggerEvent,
11658
+ subAgentResult,
11659
+ profile
11660
+ });
11661
+ if (handler.postProcessNotifyEvent) {
11662
+ const notifyEventForHook = {
11663
+ type: event.type,
11664
+ taskId: typeof payload?.associatedTaskId === "number" ? payload.associatedTaskId : undefined,
11665
+ description: typeof payload?.description === "string" ? payload.description : undefined,
11666
+ result: typeof payload?.result === "string" ? payload.result : undefined,
11667
+ error: typeof payload?.error === "string" ? payload.error : undefined
11668
+ };
11669
+ setTimeout(() => {
11670
+ (async () => {
11671
+ const resolvedChatIds = await this.resolveNotifyChatIds(notifyEventForHook.taskId);
11672
+ await handler.postProcessNotifyEvent({
11673
+ notifyEvent: notifyEventForHook,
11674
+ triggerEvent,
11675
+ subAgentResult,
11676
+ formattedPrompt: prompt.promptText,
11677
+ profile,
11678
+ resolvedChatIds
11679
+ });
11680
+ })().catch((err) => {
11681
+ console.error(`[EventHandler] postProcessNotifyEvent hook failed (swallowed)`, err);
11682
+ });
11683
+ }, 0);
11684
+ }
11685
+ const triggerChatId = triggerEvent.metadata?.chatId ?? undefined;
11686
+ const triggerMessageId = triggerEvent.metadata?.messageId ?? undefined;
11687
+ const triggerSessionId = event?.metadata?.trigger_session_id;
11688
+ return {
11689
+ message: prompt.promptText,
11690
+ envEvent: event,
11691
+ triggerSessionId,
11692
+ chatId: triggerChatId,
11693
+ ...triggerMessageId ? { triggerMessageId } : {}
11694
+ };
11695
+ }
11696
+ async resolveNotifyChatIds(taskId) {
11697
+ if (!taskId)
11698
+ return [];
11699
+ const taskComp = this.env.getComponent("task");
11700
+ if (!taskComp?.getTask)
11701
+ return [];
11702
+ const seen = new Set;
11703
+ let id = taskId;
11704
+ while (id !== undefined && id !== null && !seen.has(id) && seen.size < 8) {
11705
+ seen.add(id);
11706
+ let task;
11707
+ try {
11708
+ task = await taskComp.getTask(id);
11709
+ } catch (err) {
11710
+ console.error(`[EventHandler] resolveNotifyChatIds: getTask(${id}) failed`, err);
11711
+ return [];
11712
+ }
11713
+ if (!task)
11714
+ return [];
11715
+ const chatId = parseLarkPerTaskChatId(task.context);
11716
+ if (chatId)
11717
+ return [chatId];
11718
+ const parent = task.parent_task_id;
11719
+ id = typeof parent === "number" && parent > 0 ? parent : undefined;
11720
+ }
11721
+ return [];
11722
+ }
11723
+ async handleNotifyEventForTest(event) {
11724
+ if (this.isStopped)
11725
+ return;
11726
+ const formatted = await this.formatEvent(event);
11727
+ if (this.onEventWithEnv) {
11728
+ await this.onEventWithEnv(formatted);
11729
+ } else {
11730
+ await this.onEvent(formatted.message);
11731
+ }
11732
+ }
11598
11733
  enqueue(formattedEvent) {
11599
11734
  if (this.isStopped) {
11600
11735
  return;
@@ -11661,7 +11796,12 @@ class EventHandler {
11661
11796
  async ensureActiveSession(triggerSessionIdOverride) {
11662
11797
  if (!this.sessionComponent)
11663
11798
  return null;
11664
- if (this.activeEventSessionId) {
11799
+ if (triggerSessionIdOverride) {
11800
+ const cached = this.resolvedSessionByTrigger.get(triggerSessionIdOverride);
11801
+ if (cached) {
11802
+ return cached;
11803
+ }
11804
+ } else if (this.activeEventSessionId) {
11665
11805
  return this.activeEventSessionId;
11666
11806
  }
11667
11807
  const triggerSessionId = triggerSessionIdOverride ?? this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
@@ -11673,6 +11813,7 @@ class EventHandler {
11673
11813
  return null;
11674
11814
  }
11675
11815
  this.activeEventSessionId = existing.id;
11816
+ this.cacheResolvedSession(triggerSessionIdOverride, existing.id);
11676
11817
  await this.sessionComponent.setActiveSession(existing.id);
11677
11818
  return existing.id;
11678
11819
  }
@@ -11690,13 +11831,16 @@ class EventHandler {
11690
11831
  return null;
11691
11832
  }
11692
11833
  this.activeEventSessionId = existing.id;
11834
+ this.cacheResolvedSession(triggerSessionIdOverride, existing.id);
11693
11835
  return existing.id;
11694
11836
  }
11695
11837
  }
11696
11838
  } catch (error) {
11697
11839
  console.error(`[EventHandler] Failed to lookup global active session:`, error);
11698
11840
  }
11699
- return this.createNewEventSession();
11841
+ const created = await this.createNewEventSession();
11842
+ this.cacheResolvedSession(triggerSessionIdOverride, created);
11843
+ return created;
11700
11844
  }
11701
11845
  async ensureChatSession(chatId) {
11702
11846
  if (!this.sessionComponent)
@@ -11756,6 +11900,12 @@ class EventHandler {
11756
11900
  }
11757
11901
  clearActiveSession() {
11758
11902
  this.activeEventSessionId = null;
11903
+ this.resolvedSessionByTrigger.clear();
11904
+ }
11905
+ cacheResolvedSession(triggerSessionIdOverride, sessionId) {
11906
+ if (triggerSessionIdOverride && sessionId) {
11907
+ this.resolvedSessionByTrigger.set(triggerSessionIdOverride, sessionId);
11908
+ }
11759
11909
  }
11760
11910
  getActiveEventSessionId() {
11761
11911
  return this.activeEventSessionId;
@@ -11770,15 +11920,31 @@ class EventHandler {
11770
11920
  }
11771
11921
  }
11772
11922
  __legacyDecorateClassTS([
11773
- TracedAs5("cli.event-handler.handleEvent", { recordParams: true }),
11923
+ TracedAs5("event_handler.handle_event", { recordParams: true }),
11774
11924
  __legacyMetadataTS("design:type", Function),
11775
11925
  __legacyMetadataTS("design:paramtypes", [
11776
11926
  typeof EnvEvent === "undefined" ? Object : EnvEvent
11777
11927
  ]),
11778
- __legacyMetadataTS("design:returntype", undefined)
11928
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11779
11929
  ], EventHandler.prototype, "handleEvent", null);
11780
11930
  __legacyDecorateClassTS([
11781
- TracedAs5("cli.event-handler.ensureActiveSession", { recordParams: true }),
11931
+ TracedAs5("cli.event-handler.formatEvent", { recordParams: true, recordResult: false }),
11932
+ __legacyMetadataTS("design:type", Function),
11933
+ __legacyMetadataTS("design:paramtypes", [
11934
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11935
+ ]),
11936
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11937
+ ], EventHandler.prototype, "formatEvent", null);
11938
+ __legacyDecorateClassTS([
11939
+ TracedAs5("event_handler.process_notify", { recordParams: true, recordResult: false }),
11940
+ __legacyMetadataTS("design:type", Function),
11941
+ __legacyMetadataTS("design:paramtypes", [
11942
+ typeof EnvEvent === "undefined" ? Object : EnvEvent
11943
+ ]),
11944
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11945
+ ], EventHandler.prototype, "formatEventViaESPluginV2", null);
11946
+ __legacyDecorateClassTS([
11947
+ TracedAs5("cli.event-handler.ensureActiveSession", { recordParams: true, recordResult: true }),
11782
11948
  __legacyMetadataTS("design:type", Function),
11783
11949
  __legacyMetadataTS("design:paramtypes", [
11784
11950
  String
@@ -11794,6 +11960,62 @@ __legacyDecorateClassTS([
11794
11960
  __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
11795
11961
  ], EventHandler.prototype, "ensureChatSession", null);
11796
11962
 
11963
+ // src/commands/shared/event-handler-wiring.ts
11964
+ var storeCache = new Map;
11965
+ function getOrCreateEventStore(dbPath) {
11966
+ const normalized = normalizeDbPath(dbPath);
11967
+ let store = storeCache.get(normalized);
11968
+ if (store)
11969
+ return store;
11970
+ ensureParentDir(normalized);
11971
+ store = new EventStoreImpl({ dbPath: normalized });
11972
+ storeCache.set(normalized, store);
11973
+ setSharedEventStore(store);
11974
+ return store;
11975
+ }
11976
+ function normalizeDbPath(dbPath) {
11977
+ const expanded = dbPath.startsWith("~") ? join(homedir(), dbPath.slice(1).replace(/^\//, "")) : dbPath;
11978
+ return expanded;
11979
+ }
11980
+ function ensureParentDir(dbPath) {
11981
+ const parent = join(dbPath, "..");
11982
+ if (!existsSync(parent)) {
11983
+ mkdirSync(parent, { recursive: true });
11984
+ }
11985
+ }
11986
+ function getHandlerForEsTypeForEnv(env) {
11987
+ let component = null;
11988
+ try {
11989
+ component = env.getComponent?.("event-source") ?? null;
11990
+ } catch {
11991
+ component = null;
11992
+ }
11993
+ const hasGetHandler = component !== null && component !== undefined && typeof component.getHandler === "function";
11994
+ return (esType) => {
11995
+ if (!hasGetHandler)
11996
+ return;
11997
+ try {
11998
+ const h = component.getHandler(esType);
11999
+ return h ?? undefined;
12000
+ } catch {
12001
+ return;
12002
+ }
12003
+ };
12004
+ }
12005
+ function createDefaultEventStoreDbPath() {
12006
+ return join(homedir(), ".roy-agent", "event-store.db");
12007
+ }
12008
+ function createEventHandlerForInteractive(options) {
12009
+ const dbPath = options.dbPath ?? createDefaultEventStoreDbPath();
12010
+ const eventStore = getOrCreateEventStore(dbPath);
12011
+ const getHandlerForEsType = getHandlerForEsTypeForEnv(options.env);
12012
+ return new EventHandler({
12013
+ ...options,
12014
+ eventStore,
12015
+ getHandlerForEsType
12016
+ });
12017
+ }
12018
+
11797
12019
  // src/commands/shared/esc-active-descendant.ts
11798
12020
  function hasActiveDescendants(env, parentSessionId) {
11799
12021
  if (!env || !parentSessionId)
@@ -13645,12 +13867,13 @@ function createInteractiveCommand(externalEnvService) {
13645
13867
  console
13646
13868
  });
13647
13869
  });
13648
- const eventHandler = new EventHandler({
13870
+ const eventHandler = createEventHandlerForInteractive({
13649
13871
  env,
13650
13872
  eventTypes: ["task.background.*", "event-source.event.*"],
13651
13873
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
13652
13874
  isIdle: () => repl.isIdle(),
13653
13875
  sessionComponent,
13876
+ onEvent: async (_message) => {},
13654
13877
  onEventWithEnv: async (formattedEvent) => {
13655
13878
  await repl.handleEventMessageWithEnv(formattedEvent);
13656
13879
  }
@@ -14509,7 +14732,7 @@ async function loadHandleQuery(options, hooks) {
14509
14732
  env,
14510
14733
  enabled: true
14511
14734
  });
14512
- const eventHandler = new EventHandler({
14735
+ const eventHandler = createEventHandlerForInteractive({
14513
14736
  env,
14514
14737
  eventTypes: ["task.background.*", "event-source.event.*"],
14515
14738
  formatter: new EventMessageFormatter({ prefix: "[通知]" }),
@@ -14645,7 +14868,7 @@ function createRunCommand() {
14645
14868
  const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
14646
14869
  const runState = {
14647
14870
  isIdle: () => true,
14648
- onNotification: () => {}
14871
+ onNotification: async () => {}
14649
14872
  };
14650
14873
  const {
14651
14874
  handleQuery,
@@ -21449,15 +21672,15 @@ function resolveServerUrl(serverUrl, fallback) {
21449
21672
  }
21450
21673
 
21451
21674
  // src/lib/bounty-profile-reader.ts
21452
- import { existsSync as existsSync2, readFileSync } from "node:fs";
21453
- import { homedir } from "node:os";
21454
- import { join } from "node:path";
21675
+ import { existsSync as existsSync3, readFileSync } from "node:fs";
21676
+ import { homedir as homedir2 } from "node:os";
21677
+ import { join as join2 } from "node:path";
21455
21678
  function readBountyProfile(name, profilesDir) {
21456
21679
  if (!name)
21457
21680
  return null;
21458
- const dir = profilesDir ?? join(homedir(), ".config", "bounty", "profiles");
21459
- const profilePath = join(dir, `${name}.json`);
21460
- if (!existsSync2(profilePath))
21681
+ const dir = profilesDir ?? join2(homedir2(), ".config", "bounty", "profiles");
21682
+ const profilePath = join2(dir, `${name}.json`);
21683
+ if (!existsSync3(profilePath))
21461
21684
  return null;
21462
21685
  try {
21463
21686
  const raw = readFileSync(profilePath, "utf-8");
@@ -25874,19 +26097,19 @@ var LspCommand = {
25874
26097
 
25875
26098
  // src/commands/install/index.ts
25876
26099
  import { spawnSync } from "node:child_process";
25877
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync, mkdirSync, rmSync as rmSync2 } from "node:fs";
25878
- import { join as join6, resolve } from "node:path";
25879
- import { homedir as homedir4 } from "node:os";
26100
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync, mkdirSync as mkdirSync2, rmSync as rmSync2 } from "node:fs";
26101
+ import { join as join7, resolve } from "node:path";
26102
+ import { homedir as homedir5 } from "node:os";
25880
26103
 
25881
26104
  // src/commands/install/cleanup-stale-plugin-copies.ts
25882
- import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
25883
- import { join as join5 } from "node:path";
26105
+ import { existsSync as existsSync5, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
26106
+ import { join as join6 } from "node:path";
25884
26107
  import { homedir as nodeHomedir, tmpdir as nodeTmpdir } from "node:os";
25885
26108
  function cleanupStalePluginCopies(packageName, options) {
25886
26109
  const HOME = options.homedir ?? nodeHomedir();
25887
26110
  const paths = options.localNodeModulesPaths ?? [
25888
- join5(HOME, "node_modules"),
25889
- join5(HOME, ".roy-agent", "node_modules")
26111
+ join6(HOME, "node_modules"),
26112
+ join6(HOME, ".roy-agent", "node_modules")
25890
26113
  ];
25891
26114
  const backupRoot = options.backupDir ?? nodeTmpdir();
25892
26115
  const result = {
@@ -25896,15 +26119,15 @@ function cleanupStalePluginCopies(packageName, options) {
25896
26119
  };
25897
26120
  if (!options.globalVersion) {
25898
26121
  for (const p of paths) {
25899
- const candidate = join5(p, packageName);
26122
+ const candidate = join6(p, packageName);
25900
26123
  result.skipped.push({ path: candidate, reason: "no-global-version" });
25901
26124
  }
25902
26125
  return result;
25903
26126
  }
25904
26127
  for (const nmPath of paths) {
25905
- const localPkgDir = join5(nmPath, packageName);
25906
- const localPkgJson = join5(localPkgDir, "package.json");
25907
- if (!existsSync4(localPkgJson)) {
26128
+ const localPkgDir = join6(nmPath, packageName);
26129
+ const localPkgJson = join6(localPkgDir, "package.json");
26130
+ if (!existsSync5(localPkgJson)) {
25908
26131
  result.skipped.push({ path: localPkgDir, reason: "no-local-copy" });
25909
26132
  continue;
25910
26133
  }
@@ -25925,7 +26148,7 @@ function cleanupStalePluginCopies(packageName, options) {
25925
26148
  const safeName = packageName.replace(/@/g, "").replace(/[^a-zA-Z0-9._/-]/g, "-");
25926
26149
  const safeLocalVersion = (localVersion ?? "unknown").replace(/[^a-zA-Z0-9._-]/g, "-");
25927
26150
  const timestamp = Date.now();
25928
- backupPath = join5(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
26151
+ backupPath = join6(backupRoot, `${safeName}-${safeLocalVersion}-backup-${timestamp}`);
25929
26152
  cpSync(localPkgDir, backupPath, { recursive: true });
25930
26153
  result.backups.push({ originalPath: localPkgDir, backupPath });
25931
26154
  } catch (err) {
@@ -25960,19 +26183,19 @@ function compareVersions(a, b) {
25960
26183
 
25961
26184
  // src/commands/install/index.ts
25962
26185
  function getConfigDir(scope) {
25963
- return scope === "global" ? join6(homedir4(), ".roy-agent") : join6(process.cwd(), ".roy");
26186
+ return scope === "global" ? join7(homedir5(), ".roy-agent") : join7(process.cwd(), ".roy");
25964
26187
  }
25965
26188
  function detectDefaultScope() {
25966
- const projectDir = join6(process.cwd(), ".roy");
25967
- return existsSync5(projectDir) ? "project" : "global";
26189
+ const projectDir = join7(process.cwd(), ".roy");
26190
+ return existsSync6(projectDir) ? "project" : "global";
25968
26191
  }
25969
26192
  function getConfigPath(scope) {
25970
- return join6(getConfigDir(scope), "plugins.json");
26193
+ return join7(getConfigDir(scope), "plugins.json");
25971
26194
  }
25972
26195
  function loadPlugins(scope) {
25973
26196
  const configPath = getConfigPath(scope);
25974
26197
  try {
25975
- if (existsSync5(configPath)) {
26198
+ if (existsSync6(configPath)) {
25976
26199
  const raw = readFileSync4(configPath, "utf-8");
25977
26200
  const config = JSON.parse(raw);
25978
26201
  return config.plugins ?? [];
@@ -25983,8 +26206,8 @@ function loadPlugins(scope) {
25983
26206
  function savePlugins(plugins, scope) {
25984
26207
  const configDir = getConfigDir(scope);
25985
26208
  const configPath = getConfigPath(scope);
25986
- if (!existsSync5(configDir)) {
25987
- mkdirSync(configDir, { recursive: true });
26209
+ if (!existsSync6(configDir)) {
26210
+ mkdirSync2(configDir, { recursive: true });
25988
26211
  }
25989
26212
  const config = { plugins };
25990
26213
  writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
@@ -25999,8 +26222,8 @@ function stripVersionSpec(packageName) {
25999
26222
  function readPackageInfo(packageName) {
26000
26223
  const bareName = packageName.startsWith("/") || packageName.startsWith(".") ? packageName : stripVersionSpec(packageName);
26001
26224
  if (packageName.startsWith("/") || packageName.startsWith(".")) {
26002
- const localPkgPath = join6(packageName, "package.json");
26003
- if (existsSync5(localPkgPath)) {
26225
+ const localPkgPath = join7(packageName, "package.json");
26226
+ if (existsSync6(localPkgPath)) {
26004
26227
  try {
26005
26228
  const pkg = JSON.parse(readFileSync4(localPkgPath, "utf-8"));
26006
26229
  return {
@@ -26014,18 +26237,18 @@ function readPackageInfo(packageName) {
26014
26237
  }
26015
26238
  }
26016
26239
  const searchPaths = [
26017
- join6(process.cwd(), "node_modules", bareName, "package.json"),
26240
+ join7(process.cwd(), "node_modules", bareName, "package.json"),
26018
26241
  resolve(process.cwd(), "..", "node_modules", bareName, "package.json"),
26019
- join6(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26242
+ join7(process.cwd(), ".roy", "plugins", bareName, "package.json"),
26020
26243
  ...(() => {
26021
26244
  const globalRoot = getNpmGlobalRoot();
26022
- return globalRoot ? [join6(globalRoot, bareName, "package.json")] : [];
26245
+ return globalRoot ? [join7(globalRoot, bareName, "package.json")] : [];
26023
26246
  })(),
26024
- join6(homedir4(), ".roy-agent", "node_modules", bareName, "package.json")
26247
+ join7(homedir5(), ".roy-agent", "node_modules", bareName, "package.json")
26025
26248
  ];
26026
26249
  for (const pkgPath of searchPaths) {
26027
26250
  try {
26028
- if (existsSync5(pkgPath)) {
26251
+ if (existsSync6(pkgPath)) {
26029
26252
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
26030
26253
  return {
26031
26254
  version: pkg.version ?? "0.0.0",
@@ -26059,15 +26282,15 @@ async function verifyInstalledVersion(packageName, declaredVersion) {
26059
26282
  return { ok: true, actualVersion: actual.version };
26060
26283
  }
26061
26284
  function getPackageManagerCommand() {
26062
- if (existsSync5(join6(process.cwd(), "pnpm-lock.yaml"))) {
26063
- if (existsSync5(join6(process.cwd(), "pnpm-workspace.yaml"))) {
26285
+ if (existsSync6(join7(process.cwd(), "pnpm-lock.yaml"))) {
26286
+ if (existsSync6(join7(process.cwd(), "pnpm-workspace.yaml"))) {
26064
26287
  return "pnpm -w";
26065
26288
  }
26066
26289
  return "pnpm";
26067
26290
  }
26068
- if (existsSync5(join6(process.cwd(), "yarn.lock")))
26291
+ if (existsSync6(join7(process.cwd(), "yarn.lock")))
26069
26292
  return "yarn";
26070
- if (existsSync5(join6(process.cwd(), "bun.lock")) || existsSync5(join6(process.cwd(), "bun.lockb")))
26293
+ if (existsSync6(join7(process.cwd(), "bun.lock")) || existsSync6(join7(process.cwd(), "bun.lockb")))
26071
26294
  return "bun";
26072
26295
  return "npm";
26073
26296
  }
@@ -26106,15 +26329,15 @@ var InstallPackageCommand = {
26106
26329
  }
26107
26330
  resolvedName = info2.name;
26108
26331
  const srcDir = resolve(packageName);
26109
- if (!existsSync5(srcDir)) {
26332
+ if (!existsSync6(srcDir)) {
26110
26333
  console.error(`
26111
26334
  ❌ Local path '${srcDir}' does not exist.
26112
26335
  `);
26113
26336
  process.exit(1);
26114
26337
  }
26115
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26116
- if (!existsSync5(pluginDir)) {
26117
- mkdirSync(pluginDir, { recursive: true });
26338
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26339
+ if (!existsSync6(pluginDir)) {
26340
+ mkdirSync2(pluginDir, { recursive: true });
26118
26341
  }
26119
26342
  const result = spawnSync("cp", ["-r", `${srcDir}/.`, pluginDir], {
26120
26343
  stdio: "inherit",
@@ -26148,12 +26371,12 @@ var InstallPackageCommand = {
26148
26371
  process.exit(1);
26149
26372
  }
26150
26373
  resolvedName = info2.name;
26151
- const pluginDir = join6(process.cwd(), ".roy", "plugins", resolvedName);
26152
- if (!existsSync5(pluginDir)) {
26153
- mkdirSync(pluginDir, { recursive: true });
26374
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", resolvedName);
26375
+ if (!existsSync6(pluginDir)) {
26376
+ mkdirSync2(pluginDir, { recursive: true });
26154
26377
  }
26155
- const nmPath = join6(process.cwd(), "node_modules", packageName);
26156
- if (existsSync5(nmPath)) {
26378
+ const nmPath = join7(process.cwd(), "node_modules", packageName);
26379
+ if (existsSync6(nmPath)) {
26157
26380
  spawnSync("cp", ["-r", `${nmPath}/.`, pluginDir], { stdio: "inherit", shell: false });
26158
26381
  }
26159
26382
  }
@@ -26175,7 +26398,7 @@ var InstallPackageCommand = {
26175
26398
  if (tmpInfo) {
26176
26399
  const cleanupResult = cleanupStalePluginCopies(tmpInfo.name, {
26177
26400
  globalVersion: tmpInfo.version,
26178
- homedir: homedir4()
26401
+ homedir: homedir5()
26179
26402
  });
26180
26403
  if (cleanupResult.cleaned.length > 0) {
26181
26404
  console.log(`
@@ -26315,8 +26538,8 @@ var InstallRemoveCommand = {
26315
26538
  \uD83D\uDDD1️ Removing plugin: ${plugin.packageName}@${plugin.version} (${scope})
26316
26539
  `);
26317
26540
  if (scope === "project") {
26318
- const pluginDir = join6(process.cwd(), ".roy", "plugins", plugin.packageName);
26319
- if (existsSync5(pluginDir)) {
26541
+ const pluginDir = join7(process.cwd(), ".roy", "plugins", plugin.packageName);
26542
+ if (existsSync6(pluginDir)) {
26320
26543
  spawnSync("rm", ["-rf", pluginDir], { stdio: "inherit", shell: false });
26321
26544
  console.log(` Removed plugin directory: ${pluginDir}`);
26322
26545
  }
@@ -26331,8 +26554,8 @@ var InstallRemoveCommand = {
26331
26554
  `);
26332
26555
  process.exit(result.status ?? 1);
26333
26556
  }
26334
- const globalNm = join6(homedir4(), ".roy-agent", "node_modules", plugin.packageName);
26335
- if (existsSync5(globalNm)) {
26557
+ const globalNm = join7(homedir5(), ".roy-agent", "node_modules", plugin.packageName);
26558
+ if (existsSync6(globalNm)) {
26336
26559
  spawnSync("rm", ["-rf", globalNm], { stdio: "inherit", shell: false });
26337
26560
  }
26338
26561
  }
@@ -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: 109578368 bytes
4
- sha256: ad7560c97b5e09248411d66d1355e7f4c0e9d6bfbbfdf7674bf6ca63635c4fe0
3
+ size: 109615232 bytes
4
+ sha256: bc11a701a8e4abd25b0b9ba8acc34523b56c936f17885321dd6ad9f4b331cf85
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-cli",
3
- "version": "1.7.37",
3
+ "version": "1.7.39",
4
4
  "type": "module",
5
5
  "description": "CLI for roy-agent - Non-interactive command execution",
6
6
  "main": "./dist/index.js",