@okxweb3/a2a-node 0.0.14 → 0.0.15-beta-1d2e01866f-260623014705

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.
Files changed (3) hide show
  1. package/dist/cli.js +3164 -3511
  2. package/dist/index.js +243 -613
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1589,7 +1589,7 @@ var require_misc = __commonJS({
1589
1589
  }
1590
1590
  }
1591
1591
  var SEMVER_REGEXP = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
1592
- function parseSemver3(input) {
1592
+ function parseSemver2(input) {
1593
1593
  const match = input.match(SEMVER_REGEXP) || [];
1594
1594
  const major = parseInt(match[1], 10);
1595
1595
  const minor = parseInt(match[2], 10);
@@ -1631,7 +1631,7 @@ var require_misc = __commonJS({
1631
1631
  exports2.arrayify = arrayify;
1632
1632
  exports2.checkOrSetAlreadyCaught = checkOrSetAlreadyCaught;
1633
1633
  exports2.getEventDescription = getEventDescription;
1634
- exports2.parseSemver = parseSemver3;
1634
+ exports2.parseSemver = parseSemver2;
1635
1635
  exports2.uuid4 = uuid4;
1636
1636
  }
1637
1637
  });
@@ -67969,7 +67969,6 @@ __export(index_exports, {
67969
67969
  detectCurrentAiProvider: () => detectCurrentAiProvider,
67970
67970
  detectGatewayInvocation: () => detectGatewayInvocation,
67971
67971
  detectRuntime: () => detectRuntime,
67972
- ensureCommunicationMinVersions: () => ensureCommunicationMinVersions,
67973
67972
  ensureDefaultAiProvider: () => ensureDefaultAiProvider,
67974
67973
  extractAiSessionId: () => extractAiSessionId,
67975
67974
  extractXmtpSentAtMs: () => extractXmtpSentAtMs2,
@@ -67977,7 +67976,6 @@ __export(index_exports, {
67977
67976
  handleXmtpSendCommand: () => handleXmtpSendCommand,
67978
67977
  hasAiRuntimeMarker: () => hasAiRuntimeMarker,
67979
67978
  heartbeatUserAttentionWatcher: () => heartbeatUserAttentionWatcher,
67980
- isBelowRequiredVersion: () => isBelowRequiredVersion,
67981
67979
  isOriginalParentProcessAlive: () => isOriginalParentProcessAlive,
67982
67980
  isPrereleaseVersion: () => isPrereleaseVersion,
67983
67981
  isRetryableOpenClawGatewayError: () => isRetryableOpenClawGatewayError,
@@ -70321,7 +70319,7 @@ function detectGatewayInvocation(env = process.env) {
70321
70319
  if (!isTruthyRuntimeMarker(env.OKX_A2A_IN_GATEWAY)) {
70322
70320
  return null;
70323
70321
  }
70324
- const provider = env.OKX_A2A_GATEWAY_PROVIDER;
70322
+ const provider = env.OKX_A2A_GATEWAY_PROVIDER ?? env.OKX_A2A_AI_PROVIDER ?? env.OKX_AGENT_TASK_AI_CLI;
70325
70323
  if (!provider) {
70326
70324
  return null;
70327
70325
  }
@@ -71012,8 +71010,6 @@ var LogEvent = {
71012
71010
  AGENTS_WAKEUP_NOTIFIED: "Agents wakeup notified",
71013
71011
  CONFIG_SENSITIVE_WORDS_REFRESHED: "Sensitive words config refreshed",
71014
71012
  CONFIG_SYSTEM_REFRESHED: "System config refreshed",
71015
- FORCED_UPDATE_STARTED: "Forced update started",
71016
- FORCED_UPDATE_SUCCEEDED: "Forced update succeeded",
71017
71013
  GATEWAY_DISCONNECTED: "Gateway disconnected",
71018
71014
  GATEWAY_REQUEST: "Gateway request",
71019
71015
  GATEWAY_DELIVERY_BUFFERED: "Gateway delivery buffered",
@@ -71076,7 +71072,6 @@ var LogEvent = {
71076
71072
  CACHE_LOAD_FAILED: "Cache load failed",
71077
71073
  CACHE_WRITE_FAILED: "Cache write failed",
71078
71074
  CONFIG_LOAD_FAILED: "Config load failed",
71079
- FORCED_UPDATE_FAILED: "Forced update failed",
71080
71075
  SENTRY_INIT_SKIPPED: "Sentry init skipped",
71081
71076
  AGENT_DB_DIR_CREATE_FAILED: "Agent DB dir create failed"
71082
71077
  };
@@ -71253,8 +71248,6 @@ var SENTRY_INFO_ALLOWLIST = /* @__PURE__ */ new Set([
71253
71248
  LogEvent.BOOTSTRAP_APPLIED,
71254
71249
  LogEvent.CONFIG_SENSITIVE_WORDS_REFRESHED,
71255
71250
  LogEvent.CONFIG_SYSTEM_REFRESHED,
71256
- LogEvent.FORCED_UPDATE_STARTED,
71257
- LogEvent.FORCED_UPDATE_SUCCEEDED,
71258
71251
  LogEvent.CONVERSATION_HISTORY_QUERIED,
71259
71252
  LogEvent.FILE_DOWNLOADED,
71260
71253
  LogEvent.FILE_UPLOADED,
@@ -83541,18 +83534,6 @@ function parseTips(raw) {
83541
83534
  function parseStringArray(raw) {
83542
83535
  return Array.isArray(raw) ? raw.filter((value) => typeof value === "string" && value.length > 0) : [];
83543
83536
  }
83544
- function readOptionalString(record, key) {
83545
- const value = record[key];
83546
- return typeof value === "string" ? value : "";
83547
- }
83548
- function readMinVersion(raw) {
83549
- const container = raw.minVersion && typeof raw.minVersion === "object" && !Array.isArray(raw.minVersion) ? raw.minVersion : raw.minVersions && typeof raw.minVersions === "object" && !Array.isArray(raw.minVersions) ? raw.minVersions : {};
83550
- return {
83551
- cli: readOptionalString(container, "cli") || readOptionalString(raw, "cliMinVersion"),
83552
- openclaw: readOptionalString(container, "openclaw") || readOptionalString(raw, "openclawMinVersion"),
83553
- hermes: readOptionalString(container, "hermes") || readOptionalString(raw, "hermesMinVersion")
83554
- };
83555
- }
83556
83537
  function parseExtConfig(raw) {
83557
83538
  const obj = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
83558
83539
  return {
@@ -83574,14 +83555,13 @@ function parseSystemConfig(raw) {
83574
83555
  acc.push({ address, inboxId, type });
83575
83556
  return acc;
83576
83557
  }, []) : [];
83577
- const minVersion = readMinVersion(raw);
83578
83558
  return {
83579
83559
  heartbeatInterval: typeof raw.heartbeatInterval === "number" ? raw.heartbeatInterval : SYSTEM_CONFIG_DEFAULTS.heartbeatInterval,
83580
83560
  maxFileSizeBytes: typeof raw.maxFileSizeBytes === "number" && Number.isFinite(raw.maxFileSizeBytes) && raw.maxFileSizeBytes > 0 ? raw.maxFileSizeBytes : SYSTEM_CONFIG_DEFAULTS.maxFileSizeBytes,
83581
83561
  sensitiveUploadReg: parseStringArray(raw.SENSITIVE_UPLOAD_REG),
83582
83562
  accounts,
83583
83563
  sentryDsn: typeof raw.sentryDsn === "string" ? raw.sentryDsn : "",
83584
- minVersion,
83564
+ minAvailablePluginVersion: typeof raw.minAvailablePluginVersion === "string" ? raw.minAvailablePluginVersion : "",
83585
83565
  extConfig: parseExtConfig(raw.extConfig)
83586
83566
  };
83587
83567
  }
@@ -83630,7 +83610,11 @@ var XmtpService = class _XmtpService {
83630
83610
  _initFailures = [];
83631
83611
  _backupReady = Promise.resolve();
83632
83612
  _onAfterInitError = null;
83633
- _cliVersion = "";
83613
+ _pluginVersion = "";
83614
+ _pluginVersionStatus = {
83615
+ unavailable: false,
83616
+ minVersion: ""
83617
+ };
83634
83618
  dataDir = DEFAULT_DATA_DIR;
83635
83619
  syncByAddress = /* @__PURE__ */ new Map();
83636
83620
  agentListFingerprint;
@@ -83678,11 +83662,11 @@ var XmtpService = class _XmtpService {
83678
83662
  ]);
83679
83663
  if (systemConfigResult.status === "fulfilled" && systemConfigResult.value) {
83680
83664
  this.systemConfig = parseSystemConfig(systemConfigResult.value);
83681
- const cliMinVersion = this.systemConfig.minVersion.cli;
83682
- if (this.isCliBelowMinVersion(cliMinVersion)) {
83665
+ this.evaluatePluginVersion();
83666
+ if (this._pluginVersionStatus.unavailable) {
83683
83667
  this._initialized = false;
83684
83668
  logWithTimestamp(
83685
- `[xmtp-sdk] init paused: cli v${this._cliVersion} is below the required minimum v${cliMinVersion}; daemon updater will attempt a forced update.`
83669
+ `[xmtp-sdk] init aborted: plugin v${this._pluginVersion} is below the required minimum v${this._pluginVersionStatus.minVersion}. Run \`openclaw plugins update okx-a2a\` to upgrade.`
83686
83670
  );
83687
83671
  return;
83688
83672
  }
@@ -83726,6 +83710,9 @@ var XmtpService = class _XmtpService {
83726
83710
  logWithTimestamp("[xmtp-sdk] init: initXmtpInstall failed:", err2.message);
83727
83711
  }
83728
83712
  this._initialized = this._initFailures.length === 0;
83713
+ if (this._initialized) {
83714
+ this.evaluatePluginVersion();
83715
+ }
83729
83716
  const clientCount = clientsResult.status === "fulfilled" ? clientsResult.value.size : 0;
83730
83717
  logWithTimestamp(
83731
83718
  `[xmtp-sdk] init done: initialized=${this._initialized}, clients=${clientCount}, failures=${this._initFailures.length}`
@@ -83767,6 +83754,7 @@ var XmtpService = class _XmtpService {
83767
83754
  this._initFailures = remaining;
83768
83755
  if (remaining.length === 0) {
83769
83756
  this._initialized = true;
83757
+ this.evaluatePluginVersion();
83770
83758
  }
83771
83759
  return { ok: remaining.length === 0, failures: remaining };
83772
83760
  }
@@ -84259,14 +84247,27 @@ var XmtpService = class _XmtpService {
84259
84247
  getSystemConfig() {
84260
84248
  return this.systemConfig;
84261
84249
  }
84262
- // The daemon reports its own build version before init(); startup can pause
84263
- // before XMTP clients are created while the node listener performs the actual
84264
- // forced update.
84265
- setCliVersion(version2) {
84266
- this._cliVersion = version2 ?? "";
84267
- }
84268
- isCliBelowMinVersion(minVersion) {
84269
- return Boolean(minVersion) && isValidSemver(minVersion) && isValidSemver(this._cliVersion) && semverLt(this._cliVersion, minVersion);
84250
+ // The plugin reports its own build version (injected via esbuild
84251
+ // define) before calling init(); we compare it once against
84252
+ // systemConfig.minAvailablePluginVersion when init completes, then
84253
+ // freeze the result. Tool guards read the cached status, so per-call
84254
+ // semver work is avoided entirely.
84255
+ setPluginVersion(version2) {
84256
+ this._pluginVersion = version2 ?? "";
84257
+ }
84258
+ get pluginVersionStatus() {
84259
+ return this._pluginVersionStatus;
84260
+ }
84261
+ evaluatePluginVersion() {
84262
+ const min = this.systemConfig.minAvailablePluginVersion;
84263
+ if (!min || !isValidSemver(min) || !isValidSemver(this._pluginVersion)) {
84264
+ this._pluginVersionStatus = { unavailable: false, minVersion: min ?? "" };
84265
+ return;
84266
+ }
84267
+ this._pluginVersionStatus = {
84268
+ unavailable: semverLt(this._pluginVersion, min),
84269
+ minVersion: min
84270
+ };
84270
84271
  }
84271
84272
  // Force-refresh systemConfig from onchainos API (falls back to disk
84272
84273
  // cache). Single in-flight promise is shared by concurrent callers so
@@ -84281,6 +84282,7 @@ var XmtpService = class _XmtpService {
84281
84282
  const raw = await loadSystemConfigWith(this.dataDir, this.tools.fetchSystemConfig);
84282
84283
  if (raw) {
84283
84284
  this.systemConfig = parseSystemConfig(raw);
84285
+ this.evaluatePluginVersion();
84284
84286
  }
84285
84287
  } finally {
84286
84288
  this.systemConfigRefreshInflight = null;
@@ -85719,12 +85721,6 @@ var sharedClient = null;
85719
85721
  function resolveOpenClawGatewayConfig(env = process.env) {
85720
85722
  const synced = readSyncedGatewayConfig(env);
85721
85723
  const explicitUrl = env.OKX_A2A_OPENCLAW_GATEWAY_URL?.trim() || void 0;
85722
- if (!explicitUrl && !synced && requiresSyncedOpenClawGatewayConfig(env)) {
85723
- const expectedPath = resolveOpenClawGatewayConfigPath(env.OKX_AGENT_TASK_HOME);
85724
- throw new Error(
85725
- `OpenClaw gateway URL was not synced. Expected ${expectedPath}. Restart the OpenClaw gateway so okx-a2a can read the gateway URL from openclaw-gateway.json.`
85726
- );
85727
- }
85728
85724
  const defaultUrl = `ws://127.0.0.1:${DEFAULT_GATEWAY_PORT}`;
85729
85725
  const url = explicitUrl ?? synced?.url ?? defaultUrl;
85730
85726
  const password = env.OKX_A2A_OPENCLAW_GATEWAY_PASSWORD?.trim() || synced?.password || void 0;
@@ -86090,9 +86086,6 @@ function readSyncedGatewayConfig(env) {
86090
86086
  return null;
86091
86087
  }
86092
86088
  }
86093
- function requiresSyncedOpenClawGatewayConfig(env) {
86094
- return env.OKX_A2A_GATEWAY_PROVIDER === "openclaw" || env.OKX_A2A_RUNTIME_CONTEXT === "openclaw-gateway" || env.OKX_A2A_IN_GATEWAY === "1";
86095
- }
86096
86089
  function buildConnectParams(config, instanceId, protocolVersion) {
86097
86090
  return {
86098
86091
  minProtocol: protocolVersion,
@@ -86100,7 +86093,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
86100
86093
  client: {
86101
86094
  id: "gateway-client",
86102
86095
  displayName: "okx-a2a-node",
86103
- version: "0.0.14",
86096
+ version: "0.0.15-beta-1d2e01866f-260623014705",
86104
86097
  platform: "node",
86105
86098
  mode: "backend",
86106
86099
  instanceId
@@ -86111,7 +86104,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
86111
86104
  commands: [],
86112
86105
  permissions: {},
86113
86106
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
86114
- userAgent: `okx-a2a-node/${"0.0.14"}`,
86107
+ userAgent: `okx-a2a-node/${"0.0.15-beta-1d2e01866f-260623014705"}`,
86115
86108
  auth: {
86116
86109
  ...config.token ? { token: config.token } : {},
86117
86110
  ...config.password ? { password: config.password } : {}
@@ -89657,545 +89650,10 @@ function userWatchEventDeliveredSentryExtra(event) {
89657
89650
  var environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
89658
89651
  var SENTRY_CONFIG = {
89659
89652
  projectName: "okx/openclaw-okx-a2a-extension",
89660
- release: "0.0.14",
89653
+ release: "0.0.15-beta-1d2e01866f-260623014705",
89661
89654
  environment
89662
89655
  };
89663
89656
 
89664
- // src/forced-update.ts
89665
- var import_node_child_process7 = require("node:child_process");
89666
-
89667
- // src/update-cli.ts
89668
- var import_node_child_process6 = require("node:child_process");
89669
- var import_promises6 = require("node:fs/promises");
89670
- var import_node_os5 = require("node:os");
89671
- var import_node_path17 = require("node:path");
89672
- var UPDATE_PACKAGES = {
89673
- node: "@okxweb3/a2a-node",
89674
- openclaw: "@okxweb3/a2a-openclaw",
89675
- hermes: "@okxweb3/a2a-hermes"
89676
- };
89677
- function isPrereleaseVersion(version2) {
89678
- return /\d+\.\d+\.\d+-[0-9A-Za-z.-]+/.test(version2);
89679
- }
89680
- async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
89681
- let content3;
89682
- try {
89683
- content3 = await (0, import_promises6.readFile)(configFile, "utf8");
89684
- } catch (error) {
89685
- if (isNodeError(error) && error.code === "ENOENT") {
89686
- return false;
89687
- }
89688
- throw error;
89689
- }
89690
- const normalized = normalizeHermesPluginConfigContent(content3);
89691
- if (!normalized.changed) {
89692
- return false;
89693
- }
89694
- await (0, import_promises6.writeFile)(configFile, normalized.content);
89695
- console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
89696
- return true;
89697
- }
89698
- function normalizeHermesPluginConfigContent(content3) {
89699
- const trailingNewline = content3.endsWith("\n");
89700
- const duplicateRepair = removeDuplicateInlineEnabledHeaders(content3.replace(/\n$/, "").split(/\n/));
89701
- const lines = duplicateRepair.lines;
89702
- let changed = duplicateRepair.changed;
89703
- let hasOkxA2a = false;
89704
- let inPlugins = false;
89705
- let pluginsIndent = -1;
89706
- let inEnabled = false;
89707
- let enabledIndent = -1;
89708
- let emittedOkxA2a = false;
89709
- const output = [];
89710
- for (const line of lines) {
89711
- const currentIndent = lineIndent(line);
89712
- const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
89713
- const parsedListValue = parseYamlListValue(line);
89714
- if (inEnabled && significant && (currentIndent < enabledIndent || currentIndent === enabledIndent && !parsedListValue)) {
89715
- inEnabled = false;
89716
- emittedOkxA2a = false;
89717
- }
89718
- if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
89719
- inPlugins = false;
89720
- inEnabled = false;
89721
- emittedOkxA2a = false;
89722
- }
89723
- if (isPluginsHeader(line)) {
89724
- inPlugins = true;
89725
- pluginsIndent = currentIndent;
89726
- output.push(line);
89727
- continue;
89728
- }
89729
- if (inPlugins && isEnabledHeader(line) && currentIndent > pluginsIndent) {
89730
- inEnabled = true;
89731
- enabledIndent = currentIndent;
89732
- emittedOkxA2a = false;
89733
- output.push(line);
89734
- continue;
89735
- }
89736
- const inlineEnabled = inPlugins ? parseInlineEnabledList(line) : null;
89737
- if (inlineEnabled && currentIndent > pluginsIndent) {
89738
- const normalized = normalizeInlineEnabledList(inlineEnabled);
89739
- output.push(...normalized.lines);
89740
- changed ||= normalized.changed;
89741
- hasOkxA2a ||= normalized.hasOkxA2a;
89742
- continue;
89743
- }
89744
- if (inEnabled) {
89745
- const parsed = parsedListValue;
89746
- if (parsed && (parsed.value === "okx-a2a" || parsed.value === "platforms/okx-a2a")) {
89747
- hasOkxA2a = true;
89748
- if (!emittedOkxA2a) {
89749
- const normalized = `${parsed.indent}- okx-a2a`;
89750
- output.push(normalized);
89751
- changed ||= normalized !== line;
89752
- emittedOkxA2a = true;
89753
- } else {
89754
- changed = true;
89755
- }
89756
- continue;
89757
- }
89758
- }
89759
- output.push(line);
89760
- }
89761
- return { content: `${output.join("\n")}${trailingNewline ? "\n" : ""}`, changed, hasOkxA2a };
89762
- }
89763
- function removeDuplicateInlineEnabledHeaders(lines) {
89764
- let changed = false;
89765
- let inPlugins = false;
89766
- let pluginsIndent = -1;
89767
- const output = [];
89768
- for (let i = 0; i < lines.length; i++) {
89769
- const line = lines[i];
89770
- const currentIndent = lineIndent(line);
89771
- const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
89772
- if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
89773
- inPlugins = false;
89774
- }
89775
- if (isPluginsHeader(line)) {
89776
- inPlugins = true;
89777
- pluginsIndent = currentIndent;
89778
- output.push(line);
89779
- continue;
89780
- }
89781
- if (inPlugins && isEmptyInlineEnabledList(line) && hasLaterEnabledHeaderInPlugins(lines, i + 1, pluginsIndent)) {
89782
- changed = true;
89783
- continue;
89784
- }
89785
- output.push(line);
89786
- }
89787
- return { lines: output, changed };
89788
- }
89789
- function hasLaterEnabledHeaderInPlugins(lines, startIndex, pluginsIndent) {
89790
- for (let i = startIndex; i < lines.length; i++) {
89791
- const line = lines[i];
89792
- const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
89793
- if (significant && lineIndent(line) <= pluginsIndent) {
89794
- return false;
89795
- }
89796
- if (isEnabledHeader(line) || parseInlineEnabledList(line)) {
89797
- return true;
89798
- }
89799
- }
89800
- return false;
89801
- }
89802
- function isEmptyInlineEnabledList(line) {
89803
- const inline = parseInlineEnabledList(line);
89804
- return !!inline && inline.values.length === 0;
89805
- }
89806
- function resolveHermesConfigPath() {
89807
- return (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "config.yaml");
89808
- }
89809
- function lineIndent(line) {
89810
- const match = line.match(/^\s*/);
89811
- return match?.[0].length ?? 0;
89812
- }
89813
- function isPluginsHeader(line) {
89814
- return /^[\s]*plugins:[\s]*(?:#.*)?$/.test(line);
89815
- }
89816
- function isEnabledHeader(line) {
89817
- return /^[\s]*enabled:[\s]*(?:#.*)?$/.test(line);
89818
- }
89819
- function parseInlineEnabledList(line) {
89820
- const match = line.match(/^(\s*)enabled:\s*\[(.*)\]\s*(?:#.*)?$/);
89821
- if (!match) {
89822
- return null;
89823
- }
89824
- const values = (match[2] ?? "").split(",").map((value) => value.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
89825
- return { indent: match[1] ?? "", values };
89826
- }
89827
- function normalizeInlineEnabledList(input) {
89828
- let hasOkxA2a = false;
89829
- const values = [];
89830
- for (const value of input.values) {
89831
- if (value === "okx-a2a" || value === "platforms/okx-a2a") {
89832
- hasOkxA2a = true;
89833
- if (!values.includes("okx-a2a")) {
89834
- values.push("okx-a2a");
89835
- }
89836
- continue;
89837
- }
89838
- values.push(value);
89839
- }
89840
- return {
89841
- lines: values.length > 0 ? [`${input.indent}enabled:`, ...values.map((value) => `${input.indent} - ${value}`)] : [`${input.indent}enabled: []`],
89842
- changed: hasOkxA2a,
89843
- hasOkxA2a
89844
- };
89845
- }
89846
- function parseYamlListValue(line) {
89847
- const match = line.match(/^(\s*)-\s*(?:"([^"]*)"|'([^']*)'|([^#\s]+))(?:\s*(?:#.*)?)?$/);
89848
- if (!match) {
89849
- return null;
89850
- }
89851
- return {
89852
- indent: match[1] ?? "",
89853
- value: match[2] ?? match[3] ?? match[4] ?? ""
89854
- };
89855
- }
89856
- function isNodeError(error) {
89857
- return error instanceof Error && "code" in error;
89858
- }
89859
- async function getInstalledGatewayPluginVersion(target) {
89860
- if (target === "hermes") {
89861
- return await getInstalledHermesPluginVersion() ?? await getGlobalNpmPackageVersion(UPDATE_PACKAGES.hermes);
89862
- }
89863
- return (await getInstalledOpenClawPluginInfo()).version;
89864
- }
89865
- async function getInstalledOpenClawPluginInfo() {
89866
- let result = await runCommandCaptureOptional("openclaw", ["plugins", "list", "--json"]);
89867
- if (!result.ok) {
89868
- result = await runCommandCaptureOptional("openclaw", ["plugins", "list"]);
89869
- }
89870
- if (!result.ok) {
89871
- return { installed: false, version: null };
89872
- }
89873
- return parseOpenClawPluginList(result.stdout);
89874
- }
89875
- function parseOpenClawPluginList(output) {
89876
- if (!output.trim()) {
89877
- return { installed: false, version: null };
89878
- }
89879
- try {
89880
- return findOpenClawPluginInJson(JSON.parse(output));
89881
- } catch {
89882
- return {
89883
- installed: output.includes(UPDATE_PACKAGES.openclaw) || /(^|[\s@/])okx-a2a($|[\s@])/.test(output),
89884
- version: parsePackageVersionFromText(output)
89885
- };
89886
- }
89887
- }
89888
- function findOpenClawPluginInJson(value) {
89889
- if (Array.isArray(value)) {
89890
- for (const item of value) {
89891
- const found = findOpenClawPluginInJson(item);
89892
- if (found.installed) {
89893
- return found;
89894
- }
89895
- }
89896
- return { installed: false, version: null };
89897
- }
89898
- if (!value || typeof value !== "object") {
89899
- return { installed: false, version: null };
89900
- }
89901
- const record = value;
89902
- if (isOpenClawPluginRecord(record)) {
89903
- return { installed: true, version: readVersionField(record) };
89904
- }
89905
- const dependencies = record.dependencies;
89906
- if (dependencies && typeof dependencies === "object") {
89907
- const dependency = dependencies[UPDATE_PACKAGES.openclaw] ?? dependencies["okx-a2a"];
89908
- if (dependency && typeof dependency === "object") {
89909
- return { installed: true, version: readVersionField(dependency) };
89910
- }
89911
- }
89912
- for (const key of ["plugins", "items", "data", "installed"]) {
89913
- const child = record[key];
89914
- if (child !== void 0) {
89915
- const found = findOpenClawPluginInJson(child);
89916
- if (found.installed) {
89917
- return found;
89918
- }
89919
- }
89920
- }
89921
- return { installed: false, version: null };
89922
- }
89923
- function isOpenClawPluginRecord(record) {
89924
- return Object.values(record).some((value) => {
89925
- if (typeof value !== "string") {
89926
- return false;
89927
- }
89928
- return value === "okx-a2a" || value === UPDATE_PACKAGES.openclaw || value.endsWith("/okx-a2a");
89929
- });
89930
- }
89931
- function readVersionField(record) {
89932
- for (const key of ["version", "installedVersion", "packageVersion"]) {
89933
- const value = record[key];
89934
- if (typeof value === "string" && value.trim()) {
89935
- return value.trim();
89936
- }
89937
- }
89938
- return null;
89939
- }
89940
- function parsePackageVersionFromText(output) {
89941
- return output.match(/@okxweb3\/a2a-openclaw@([0-9A-Za-z.+-]+)/)?.[1] ?? null;
89942
- }
89943
- async function getInstalledHermesPluginVersion() {
89944
- const pluginYaml = (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
89945
- try {
89946
- const content3 = await (0, import_promises6.readFile)(pluginYaml, "utf8");
89947
- return parsePluginYamlVersion(content3);
89948
- } catch (error) {
89949
- if (isNodeError(error) && error.code === "ENOENT") {
89950
- return null;
89951
- }
89952
- throw error;
89953
- }
89954
- }
89955
- function parsePluginYamlVersion(content3) {
89956
- for (const line of content3.split(/\r?\n/)) {
89957
- const match = line.match(/^\s*version:\s*(?:"([^"]+)"|'([^']+)'|([^#\s]+))/);
89958
- if (match) {
89959
- return match[1] ?? match[2] ?? match[3] ?? null;
89960
- }
89961
- }
89962
- return null;
89963
- }
89964
- async function getGlobalNpmPackageVersion(packageName) {
89965
- const result = await runCommandCaptureOptional("npm", ["list", "-g", packageName, "--depth=0", "--json"]);
89966
- if (!result.ok) {
89967
- return null;
89968
- }
89969
- try {
89970
- const parsed = JSON.parse(result.stdout);
89971
- return parsed.dependencies?.[packageName]?.version ?? null;
89972
- } catch {
89973
- return null;
89974
- }
89975
- }
89976
- async function runCommandCaptureOptional(command, args) {
89977
- return await new Promise((resolvePromise) => {
89978
- const child = (0, import_node_child_process6.spawn)(command, args, { stdio: ["ignore", "pipe", "ignore"] });
89979
- let stdout = "";
89980
- child.stdout.setEncoding("utf8");
89981
- child.stdout.on("data", (chunk) => {
89982
- stdout += chunk;
89983
- });
89984
- child.on("error", () => {
89985
- resolvePromise({ ok: false, stdout });
89986
- });
89987
- child.on("close", (code2) => {
89988
- resolvePromise({ ok: code2 === 0, stdout });
89989
- });
89990
- });
89991
- }
89992
-
89993
- // src/forced-update.ts
89994
- var SEMVER_RE2 = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
89995
- function normalizeSemverInput2(value) {
89996
- return value.trim().replace(/^v/, "");
89997
- }
89998
- function parseSemver2(value) {
89999
- const match = SEMVER_RE2.exec(normalizeSemverInput2(value));
90000
- if (!match) {
90001
- return null;
90002
- }
90003
- return {
90004
- major: Number(match[1]),
90005
- minor: Number(match[2]),
90006
- patch: Number(match[3]),
90007
- prerelease: match[4] ? match[4].split(".") : []
90008
- };
90009
- }
90010
- function comparePrereleaseId2(a, b) {
90011
- const aIsNumber = /^\d+$/.test(a);
90012
- const bIsNumber = /^\d+$/.test(b);
90013
- if (aIsNumber && bIsNumber) {
90014
- const an = Number(a);
90015
- const bn = Number(b);
90016
- return an < bn ? -1 : an > bn ? 1 : 0;
90017
- }
90018
- if (aIsNumber) {
90019
- return -1;
90020
- }
90021
- if (bIsNumber) {
90022
- return 1;
90023
- }
90024
- return a < b ? -1 : a > b ? 1 : 0;
90025
- }
90026
- function compareSemver2(a, b) {
90027
- if (a.major !== b.major) {
90028
- return a.major < b.major ? -1 : 1;
90029
- }
90030
- if (a.minor !== b.minor) {
90031
- return a.minor < b.minor ? -1 : 1;
90032
- }
90033
- if (a.patch !== b.patch) {
90034
- return a.patch < b.patch ? -1 : 1;
90035
- }
90036
- if (a.prerelease.length === 0 && b.prerelease.length === 0) {
90037
- return 0;
90038
- }
90039
- if (a.prerelease.length === 0) {
90040
- return 1;
90041
- }
90042
- if (b.prerelease.length === 0) {
90043
- return -1;
90044
- }
90045
- const len = Math.min(a.prerelease.length, b.prerelease.length);
90046
- for (let i = 0; i < len; i++) {
90047
- const diff = comparePrereleaseId2(a.prerelease[i], b.prerelease[i]);
90048
- if (diff !== 0) {
90049
- return diff;
90050
- }
90051
- }
90052
- if (a.prerelease.length !== b.prerelease.length) {
90053
- return a.prerelease.length < b.prerelease.length ? -1 : 1;
90054
- }
90055
- return 0;
90056
- }
90057
- function isBelowRequiredVersion(currentVersion, minVersion) {
90058
- const min = minVersion?.trim();
90059
- if (!min) {
90060
- return false;
90061
- }
90062
- const parsedMin = parseSemver2(min);
90063
- if (!parsedMin) {
90064
- logWithTimestamp(`[okx-agent-task] ignoring invalid forced minVersion=${min}`);
90065
- return false;
90066
- }
90067
- const current = currentVersion?.trim();
90068
- if (!current) {
90069
- return true;
90070
- }
90071
- const parsedCurrent = parseSemver2(current);
90072
- if (!parsedCurrent) {
90073
- logWithTimestamp(`[okx-agent-task] current version is invalid, forcing update current=${current} min=${min}`);
90074
- return true;
90075
- }
90076
- return compareSemver2(parsedCurrent, parsedMin) < 0;
90077
- }
90078
- async function ensureCommunicationMinVersions(input) {
90079
- const runUpdate = input.runUpdate ?? runOkxA2aForcedUpdate;
90080
- const cliMinVersion = input.systemConfig.minVersion.cli;
90081
- const currentCliVersion = input.currentCliVersion ?? "0.0.14";
90082
- if (isBelowRequiredVersion(currentCliVersion, cliMinVersion)) {
90083
- await forceUpdate({
90084
- target: "cli",
90085
- currentVersion: currentCliVersion,
90086
- minVersion: cliMinVersion,
90087
- stage: input.stage,
90088
- runUpdate
90089
- });
90090
- return { updated: true, target: "cli", currentVersion: currentCliVersion, minVersion: cliMinVersion };
90091
- }
90092
- const provider = resolveConfiguredAiProvider({ store: input.sessionStore, env: input.env });
90093
- const gatewayTarget = providerToGatewayTarget(provider);
90094
- if (!gatewayTarget) {
90095
- logWithTimestamp(`[okx-agent-task] forced minVersion gateway check skipped provider=${provider ?? "(not set)"}`);
90096
- return { updated: false };
90097
- }
90098
- const minVersion = input.systemConfig.minVersion[gatewayTarget];
90099
- if (!minVersion) {
90100
- return { updated: false, target: gatewayTarget };
90101
- }
90102
- const getGatewayVersion = input.getGatewayVersion ?? getInstalledGatewayPluginVersion;
90103
- const currentVersion = await getGatewayVersion(gatewayTarget);
90104
- if (!isBelowRequiredVersion(currentVersion, minVersion)) {
90105
- return { updated: false, target: gatewayTarget, currentVersion, minVersion };
90106
- }
90107
- await forceUpdate({
90108
- target: gatewayTarget,
90109
- currentVersion,
90110
- minVersion,
90111
- stage: input.stage,
90112
- runUpdate
90113
- });
90114
- return { updated: true, target: gatewayTarget, currentVersion, minVersion };
90115
- }
90116
- function providerToGatewayTarget(provider) {
90117
- return provider === "openclaw" || provider === "hermes" ? provider : null;
90118
- }
90119
- async function forceUpdate(input) {
90120
- const startedAt = Date.now();
90121
- logWithTimestamp(
90122
- `[okx-agent-task] forced update required target=${input.target} current=${input.currentVersion ?? "(unknown)"} min=${input.minVersion} stage=${input.stage}`
90123
- );
90124
- logger.info(LogEvent.FORCED_UPDATE_STARTED, forcedUpdateSentryExtra(input, startedAt, {
90125
- status: "started",
90126
- reason: "forced_update_required"
90127
- }));
90128
- try {
90129
- await input.runUpdate(input.target);
90130
- logger.info(LogEvent.FORCED_UPDATE_SUCCEEDED, forcedUpdateSentryExtra(input, startedAt, {
90131
- status: "succeeded",
90132
- reason: "update_completed"
90133
- }));
90134
- } catch (err2) {
90135
- const error = err2 instanceof Error ? err2 : new Error(String(err2));
90136
- logger.error(LogEvent.FORCED_UPDATE_FAILED, error, forcedUpdateSentryExtra(input, startedAt, {
90137
- status: "failed",
90138
- reason: "update_failed",
90139
- errorName: error.name,
90140
- errorMessage: error.message,
90141
- errorStack: error.stack ?? "",
90142
- ...forcedUpdateErrorDetails(err2)
90143
- }));
90144
- throw err2;
90145
- }
90146
- }
90147
- function forcedUpdateSentryExtra(input, startedAt, extra) {
90148
- return {
90149
- component: "node_listener",
90150
- stage: input.stage,
90151
- updateTarget: input.target,
90152
- currentVersion: input.currentVersion ?? "",
90153
- minVersion: input.minVersion,
90154
- durationMs: String(Date.now() - startedAt),
90155
- ...extra
90156
- };
90157
- }
90158
- function forcedUpdateErrorDetails(err2) {
90159
- if (!err2 || typeof err2 !== "object") {
90160
- return {};
90161
- }
90162
- const record = err2;
90163
- return {
90164
- exitCode: record.exitCode ?? record.code ?? "",
90165
- signal: record.signal ?? ""
90166
- };
90167
- }
90168
- function runOkxA2aForcedUpdate(target) {
90169
- const args = [
90170
- "update",
90171
- ...target === "cli" ? [] : [target],
90172
- "--release",
90173
- "latest",
90174
- "--restart",
90175
- "--yes"
90176
- ];
90177
- return new Promise((resolvePromise, reject) => {
90178
- const child = (0, import_node_child_process7.spawn)("okx-a2a", args, {
90179
- stdio: "inherit",
90180
- env: {
90181
- ...process.env,
90182
- OKX_A2A_FORCED_UPDATE_TARGET: target
90183
- }
90184
- });
90185
- child.on("error", reject);
90186
- child.on("close", (code2, signal) => {
90187
- if (code2 === 0) {
90188
- resolvePromise();
90189
- return;
90190
- }
90191
- reject(Object.assign(
90192
- new Error(`okx-a2a ${args.join(" ")} failed with ${signal ? `signal=${signal}` : `code=${code2}`}`),
90193
- { exitCode: code2, signal }
90194
- ));
90195
- });
90196
- });
90197
- }
90198
-
90199
89657
  // src/listener.ts
90200
89658
  var OFFLINE_REPLAY_SYNC_INTERVAL = 5;
90201
89659
  function shouldRunOfflineReplay(syncCount, interval = OFFLINE_REPLAY_SYNC_INTERVAL) {
@@ -90313,23 +89771,13 @@ async function runListenerWithLock(options, paths) {
90313
89771
  }));
90314
89772
  }
90315
89773
  });
90316
- service.setCliVersion("0.0.14");
89774
+ service.setPluginVersion("0.0.15-beta-1d2e01866f-260623014705");
90317
89775
  await service.init();
90318
- const startupVersionCheck = await ensureCommunicationMinVersions({
90319
- systemConfig: service.getSystemConfig(),
90320
- sessionStore,
90321
- stage: "startup"
90322
- });
90323
- if (startupVersionCheck.updated) {
90324
- logWithTimestamp(
90325
- `[okx-agent-task] forced update executed during startup target=${startupVersionCheck.target}; exiting current listener so restarted daemon can take over`
89776
+ const pluginVersionStatus = service.pluginVersionStatus;
89777
+ if (pluginVersionStatus.unavailable) {
89778
+ throw new Error(
89779
+ `@okxweb3/a2a-node v${"0.0.15-beta-1d2e01866f-260623014705"} is below the required minimum v${pluginVersionStatus.minVersion}`
90326
89780
  );
90327
- await watcherCoordinator.stop();
90328
- await userAttentionEvents?.close();
90329
- stopClients(service);
90330
- sessionStore.close();
90331
- commands.close();
90332
- return;
90333
89781
  }
90334
89782
  const systemConfig = service.getSystemConfig();
90335
89783
  if (systemConfig.sentryDsn) {
@@ -90346,7 +89794,7 @@ async function runListenerWithLock(options, paths) {
90346
89794
  onchainosAgentId: "*",
90347
89795
  reason: "system-config missing sentryDsn",
90348
89796
  pluginId: "@okxweb3/a2a-node",
90349
- pluginVersion: "0.0.14"
89797
+ pluginVersion: "0.0.15-beta-1d2e01866f-260623014705"
90350
89798
  });
90351
89799
  }
90352
89800
  logWithTimestamp(
@@ -90438,18 +89886,6 @@ async function runListenerWithLock(options, paths) {
90438
89886
  if (stopping) {
90439
89887
  return;
90440
89888
  }
90441
- const versionCheck = await ensureCommunicationMinVersions({
90442
- systemConfig: service.getSystemConfig(),
90443
- sessionStore,
90444
- stage: "system_config_refresh"
90445
- });
90446
- if (versionCheck.updated) {
90447
- logWithTimestamp(
90448
- `[okx-agent-task] forced update executed after system-config refresh target=${versionCheck.target}; stopping current listener`
90449
- );
90450
- process.kill(process.pid, "SIGTERM");
90451
- return;
90452
- }
90453
89889
  const nextIntervalSec = Math.max(10, service.getSystemConfig().heartbeatInterval);
90454
89890
  if (nextIntervalSec !== previousIntervalSec) {
90455
89891
  logWithTimestamp(
@@ -90524,6 +89960,202 @@ async function timeSettled(fn) {
90524
89960
  return { durationMs: Date.now() - startedAt, error };
90525
89961
  }
90526
89962
  }
89963
+
89964
+ // src/update-cli.ts
89965
+ var import_promises6 = require("node:fs/promises");
89966
+ var import_node_os5 = require("node:os");
89967
+ var import_node_path17 = require("node:path");
89968
+ function isPrereleaseVersion(version2) {
89969
+ return /\d+\.\d+\.\d+-[0-9A-Za-z.-]+/.test(version2);
89970
+ }
89971
+ async function normalizeHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPath()) {
89972
+ let content3;
89973
+ try {
89974
+ content3 = await (0, import_promises6.readFile)(configFile, "utf8");
89975
+ } catch (error) {
89976
+ if (isNodeError(error) && error.code === "ENOENT") {
89977
+ return false;
89978
+ }
89979
+ throw error;
89980
+ }
89981
+ const normalized = normalizeHermesPluginConfigContent(content3);
89982
+ if (!normalized.changed) {
89983
+ return false;
89984
+ }
89985
+ await (0, import_promises6.writeFile)(configFile, normalized.content);
89986
+ console.log(`[update] normalized Hermes plugins.enabled okx-a2a entry in ${configFile}`);
89987
+ return true;
89988
+ }
89989
+ function normalizeHermesPluginConfigContent(content3) {
89990
+ const trailingNewline = content3.endsWith("\n");
89991
+ const duplicateRepair = removeDuplicateInlineEnabledHeaders(content3.replace(/\n$/, "").split(/\n/));
89992
+ const lines = duplicateRepair.lines;
89993
+ let changed = duplicateRepair.changed;
89994
+ let hasOkxA2a = false;
89995
+ let inPlugins = false;
89996
+ let pluginsIndent = -1;
89997
+ let inEnabled = false;
89998
+ let enabledIndent = -1;
89999
+ let emittedOkxA2a = false;
90000
+ const output = [];
90001
+ for (const line of lines) {
90002
+ const currentIndent = lineIndent(line);
90003
+ const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
90004
+ const parsedListValue = parseYamlListValue(line);
90005
+ if (inEnabled && significant && (currentIndent < enabledIndent || currentIndent === enabledIndent && !parsedListValue)) {
90006
+ inEnabled = false;
90007
+ emittedOkxA2a = false;
90008
+ }
90009
+ if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
90010
+ inPlugins = false;
90011
+ inEnabled = false;
90012
+ emittedOkxA2a = false;
90013
+ }
90014
+ if (isPluginsHeader(line)) {
90015
+ inPlugins = true;
90016
+ pluginsIndent = currentIndent;
90017
+ output.push(line);
90018
+ continue;
90019
+ }
90020
+ if (inPlugins && isEnabledHeader(line) && currentIndent > pluginsIndent) {
90021
+ inEnabled = true;
90022
+ enabledIndent = currentIndent;
90023
+ emittedOkxA2a = false;
90024
+ output.push(line);
90025
+ continue;
90026
+ }
90027
+ const inlineEnabled = inPlugins ? parseInlineEnabledList(line) : null;
90028
+ if (inlineEnabled && currentIndent > pluginsIndent) {
90029
+ const normalized = normalizeInlineEnabledList(inlineEnabled);
90030
+ output.push(...normalized.lines);
90031
+ changed ||= normalized.changed;
90032
+ hasOkxA2a ||= normalized.hasOkxA2a;
90033
+ continue;
90034
+ }
90035
+ if (inEnabled) {
90036
+ const parsed = parsedListValue;
90037
+ if (parsed && (parsed.value === "okx-a2a" || parsed.value === "platforms/okx-a2a")) {
90038
+ hasOkxA2a = true;
90039
+ if (!emittedOkxA2a) {
90040
+ const normalized = `${parsed.indent}- okx-a2a`;
90041
+ output.push(normalized);
90042
+ changed ||= normalized !== line;
90043
+ emittedOkxA2a = true;
90044
+ } else {
90045
+ changed = true;
90046
+ }
90047
+ continue;
90048
+ }
90049
+ }
90050
+ output.push(line);
90051
+ }
90052
+ return { content: `${output.join("\n")}${trailingNewline ? "\n" : ""}`, changed, hasOkxA2a };
90053
+ }
90054
+ function removeDuplicateInlineEnabledHeaders(lines) {
90055
+ let changed = false;
90056
+ let inPlugins = false;
90057
+ let pluginsIndent = -1;
90058
+ const output = [];
90059
+ for (let i = 0; i < lines.length; i++) {
90060
+ const line = lines[i];
90061
+ const currentIndent = lineIndent(line);
90062
+ const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
90063
+ if (inPlugins && significant && currentIndent <= pluginsIndent && !isPluginsHeader(line)) {
90064
+ inPlugins = false;
90065
+ }
90066
+ if (isPluginsHeader(line)) {
90067
+ inPlugins = true;
90068
+ pluginsIndent = currentIndent;
90069
+ output.push(line);
90070
+ continue;
90071
+ }
90072
+ if (inPlugins && isEmptyInlineEnabledList(line) && hasLaterEnabledHeaderInPlugins(lines, i + 1, pluginsIndent)) {
90073
+ changed = true;
90074
+ continue;
90075
+ }
90076
+ output.push(line);
90077
+ }
90078
+ return { lines: output, changed };
90079
+ }
90080
+ function hasLaterEnabledHeaderInPlugins(lines, startIndex, pluginsIndent) {
90081
+ for (let i = startIndex; i < lines.length; i++) {
90082
+ const line = lines[i];
90083
+ const significant = line.trim() !== "" && !line.trimStart().startsWith("#");
90084
+ if (significant && lineIndent(line) <= pluginsIndent) {
90085
+ return false;
90086
+ }
90087
+ if (isEnabledHeader(line) || parseInlineEnabledList(line)) {
90088
+ return true;
90089
+ }
90090
+ }
90091
+ return false;
90092
+ }
90093
+ function isEmptyInlineEnabledList(line) {
90094
+ const inline = parseInlineEnabledList(line);
90095
+ return !!inline && inline.values.length === 0;
90096
+ }
90097
+ function resolveHermesConfigPath() {
90098
+ return (0, import_node_path17.join)(process.env.HERMES_HOME ?? (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".hermes"), "config.yaml");
90099
+ }
90100
+ function lineIndent(line) {
90101
+ const match = line.match(/^\s*/);
90102
+ return match?.[0].length ?? 0;
90103
+ }
90104
+ function isPluginsHeader(line) {
90105
+ return /^[\s]*plugins:[\s]*(?:#.*)?$/.test(line);
90106
+ }
90107
+ function isEnabledHeader(line) {
90108
+ return /^[\s]*enabled:[\s]*(?:#.*)?$/.test(line);
90109
+ }
90110
+ function parseInlineEnabledList(line) {
90111
+ const match = line.match(/^(\s*)enabled:\s*\[(.*)\]\s*(?:#.*)?$/);
90112
+ if (!match) {
90113
+ return null;
90114
+ }
90115
+ const values = (match[2] ?? "").split(",").map((value) => value.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
90116
+ return { indent: match[1] ?? "", values };
90117
+ }
90118
+ function normalizeInlineEnabledList(input) {
90119
+ let hasOkxA2a = false;
90120
+ const values = [];
90121
+ for (const value of input.values) {
90122
+ if (value === "okx-a2a" || value === "platforms/okx-a2a") {
90123
+ hasOkxA2a = true;
90124
+ if (!values.includes("okx-a2a")) {
90125
+ values.push("okx-a2a");
90126
+ }
90127
+ continue;
90128
+ }
90129
+ values.push(value);
90130
+ }
90131
+ return {
90132
+ lines: values.length > 0 ? [`${input.indent}enabled:`, ...values.map((value) => `${input.indent} - ${value}`)] : [`${input.indent}enabled: []`],
90133
+ changed: hasOkxA2a,
90134
+ hasOkxA2a
90135
+ };
90136
+ }
90137
+ function parseYamlListValue(line) {
90138
+ const match = line.match(/^(\s*)-\s*(?:"([^"]*)"|'([^']*)'|([^#\s]+))(?:\s*(?:#.*)?)?$/);
90139
+ if (!match) {
90140
+ return null;
90141
+ }
90142
+ return {
90143
+ indent: match[1] ?? "",
90144
+ value: match[2] ?? match[3] ?? match[4] ?? ""
90145
+ };
90146
+ }
90147
+ function isNodeError(error) {
90148
+ return error instanceof Error && "code" in error;
90149
+ }
90150
+ function parsePluginYamlVersion(content3) {
90151
+ for (const line of content3.split(/\r?\n/)) {
90152
+ const match = line.match(/^\s*version:\s*(?:"([^"]+)"|'([^']+)'|([^#\s]+))/);
90153
+ if (match) {
90154
+ return match[1] ?? match[2] ?? match[3] ?? null;
90155
+ }
90156
+ }
90157
+ return null;
90158
+ }
90527
90159
  // Annotate the CommonJS export names for ESM import in node:
90528
90160
  0 && (module.exports = {
90529
90161
  AI_PROVIDERS,
@@ -90572,7 +90204,6 @@ async function timeSettled(fn) {
90572
90204
  detectCurrentAiProvider,
90573
90205
  detectGatewayInvocation,
90574
90206
  detectRuntime,
90575
- ensureCommunicationMinVersions,
90576
90207
  ensureDefaultAiProvider,
90577
90208
  extractAiSessionId,
90578
90209
  extractXmtpSentAtMs,
@@ -90580,7 +90211,6 @@ async function timeSettled(fn) {
90580
90211
  handleXmtpSendCommand,
90581
90212
  hasAiRuntimeMarker,
90582
90213
  heartbeatUserAttentionWatcher,
90583
- isBelowRequiredVersion,
90584
90214
  isOriginalParentProcessAlive,
90585
90215
  isPrereleaseVersion,
90586
90216
  isRetryableOpenClawGatewayError,