@okxweb3/a2a-node 0.2.9 → 0.2.10-beta-98689bff7a-260826143751

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 (4) hide show
  1. package/README.md +26 -0
  2. package/dist/cli.js +1246 -262
  3. package/dist/index.js +1042 -211
  4. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3772,6 +3772,10 @@ function isDaemonCommand(value) {
3772
3772
  if (parsed.type === "xmtp-send") {
3773
3773
  return typeof parsed.jobId === "string" && typeof parsed.message === "string";
3774
3774
  }
3775
+ if (parsed.type === "signal-publish") {
3776
+ const command = parsed;
3777
+ return typeof command.serviceId === "string" && !!command.signal && typeof command.signal === "object";
3778
+ }
3775
3779
  if (parsed.type === "xmtp-get-pending-list") {
3776
3780
  return true;
3777
3781
  }
@@ -3881,6 +3885,15 @@ var init_command_store = __esm({
3881
3885
  createdAt: Date.now()
3882
3886
  };
3883
3887
  }
3888
+ createSignalPublishCommand(params) {
3889
+ return {
3890
+ id: (0, import_node_crypto2.randomUUID)(),
3891
+ type: "signal-publish",
3892
+ serviceId: params.serviceId,
3893
+ signal: params.signal,
3894
+ createdAt: Date.now()
3895
+ };
3896
+ }
3884
3897
  createXmtpGetConversationHistoryCommand(params) {
3885
3898
  return {
3886
3899
  id: (0, import_node_crypto2.randomUUID)(),
@@ -4677,7 +4690,7 @@ var require_is = __commonJS({
4677
4690
  function isPrimitive(wat) {
4678
4691
  return wat === null || typeof wat !== "object" && typeof wat !== "function";
4679
4692
  }
4680
- function isPlainObject4(wat) {
4693
+ function isPlainObject6(wat) {
4681
4694
  return isBuiltin(wat, "Object");
4682
4695
  }
4683
4696
  function isEvent(wat) {
@@ -4693,7 +4706,7 @@ var require_is = __commonJS({
4693
4706
  return Boolean(wat && wat.then && typeof wat.then === "function");
4694
4707
  }
4695
4708
  function isSyntheticEvent(wat) {
4696
- return isPlainObject4(wat) && "nativeEvent" in wat && "preventDefault" in wat && "stopPropagation" in wat;
4709
+ return isPlainObject6(wat) && "nativeEvent" in wat && "preventDefault" in wat && "stopPropagation" in wat;
4697
4710
  }
4698
4711
  function isNaN2(wat) {
4699
4712
  return typeof wat === "number" && wat !== wat;
@@ -4716,7 +4729,7 @@ var require_is = __commonJS({
4716
4729
  exports2.isEvent = isEvent;
4717
4730
  exports2.isInstanceOf = isInstanceOf;
4718
4731
  exports2.isNaN = isNaN2;
4719
- exports2.isPlainObject = isPlainObject4;
4732
+ exports2.isPlainObject = isPlainObject6;
4720
4733
  exports2.isPrimitive = isPrimitive;
4721
4734
  exports2.isRegExp = isRegExp;
4722
4735
  exports2.isString = isString;
@@ -6524,7 +6537,7 @@ var require_path = __commonJS({
6524
6537
  function isAbsolute4(path2) {
6525
6538
  return path2.charAt(0) === "/";
6526
6539
  }
6527
- function join33(...args) {
6540
+ function join35(...args) {
6528
6541
  return normalizePath(args.join("/"));
6529
6542
  }
6530
6543
  function dirname10(path2) {
@@ -6549,7 +6562,7 @@ var require_path = __commonJS({
6549
6562
  exports2.basename = basename10;
6550
6563
  exports2.dirname = dirname10;
6551
6564
  exports2.isAbsolute = isAbsolute4;
6552
- exports2.join = join33;
6565
+ exports2.join = join35;
6553
6566
  exports2.normalizePath = normalizePath;
6554
6567
  exports2.relative = relative;
6555
6568
  exports2.resolve = resolve14;
@@ -15497,12 +15510,12 @@ var require_supports_color = __commonJS({
15497
15510
  "use strict";
15498
15511
  var os = require("os");
15499
15512
  var tty = require("tty");
15500
- var hasFlag3 = require_has_flag();
15513
+ var hasFlag4 = require_has_flag();
15501
15514
  var { env } = process;
15502
15515
  var forceColor;
15503
- if (hasFlag3("no-color") || hasFlag3("no-colors") || hasFlag3("color=false") || hasFlag3("color=never")) {
15516
+ if (hasFlag4("no-color") || hasFlag4("no-colors") || hasFlag4("color=false") || hasFlag4("color=never")) {
15504
15517
  forceColor = 0;
15505
- } else if (hasFlag3("color") || hasFlag3("colors") || hasFlag3("color=true") || hasFlag3("color=always")) {
15518
+ } else if (hasFlag4("color") || hasFlag4("colors") || hasFlag4("color=true") || hasFlag4("color=always")) {
15506
15519
  forceColor = 1;
15507
15520
  }
15508
15521
  if ("FORCE_COLOR" in env) {
@@ -15529,10 +15542,10 @@ var require_supports_color = __commonJS({
15529
15542
  if (forceColor === 0) {
15530
15543
  return 0;
15531
15544
  }
15532
- if (hasFlag3("color=16m") || hasFlag3("color=full") || hasFlag3("color=truecolor")) {
15545
+ if (hasFlag4("color=16m") || hasFlag4("color=full") || hasFlag4("color=truecolor")) {
15533
15546
  return 3;
15534
15547
  }
15535
- if (hasFlag3("color=256")) {
15548
+ if (hasFlag4("color=256")) {
15536
15549
  return 2;
15537
15550
  }
15538
15551
  if (haveStream && !streamIsTTY && forceColor === void 0) {
@@ -15783,7 +15796,7 @@ var require_promisify = __commonJS({
15783
15796
  "../../node_modules/agent-base/dist/src/promisify.js"(exports2) {
15784
15797
  "use strict";
15785
15798
  Object.defineProperty(exports2, "__esModule", { value: true });
15786
- function promisify3(fn) {
15799
+ function promisify4(fn) {
15787
15800
  return function(req, opts) {
15788
15801
  return new Promise((resolve14, reject) => {
15789
15802
  fn.call(this, req, opts, (err2, rtn) => {
@@ -15796,7 +15809,7 @@ var require_promisify = __commonJS({
15796
15809
  });
15797
15810
  };
15798
15811
  }
15799
- exports2.default = promisify3;
15812
+ exports2.default = promisify4;
15800
15813
  }
15801
15814
  });
15802
15815
 
@@ -25241,7 +25254,7 @@ var require_websocket2 = __commonJS({
25241
25254
  var http2 = require("http");
25242
25255
  var net = require("net");
25243
25256
  var tls = require("tls");
25244
- var { randomBytes: randomBytes4, createHash: createHash6 } = require("crypto");
25257
+ var { randomBytes: randomBytes4, createHash: createHash7 } = require("crypto");
25245
25258
  var { Duplex, Readable } = require("stream");
25246
25259
  var { URL: URL2 } = require("url");
25247
25260
  var PerMessageDeflate = require_permessage_deflate();
@@ -25901,7 +25914,7 @@ var require_websocket2 = __commonJS({
25901
25914
  abortHandshake(websocket, socket, "Invalid Upgrade header");
25902
25915
  return;
25903
25916
  }
25904
- const digest = createHash6("sha1").update(key + GUID).digest("base64");
25917
+ const digest = createHash7("sha1").update(key + GUID).digest("base64");
25905
25918
  if (res.headers["sec-websocket-accept"] !== digest) {
25906
25919
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
25907
25920
  return;
@@ -26268,7 +26281,7 @@ var require_websocket_server = __commonJS({
26268
26281
  var EventEmitter2 = require("events");
26269
26282
  var http2 = require("http");
26270
26283
  var { Duplex } = require("stream");
26271
- var { createHash: createHash6 } = require("crypto");
26284
+ var { createHash: createHash7 } = require("crypto");
26272
26285
  var extension = require_extension();
26273
26286
  var PerMessageDeflate = require_permessage_deflate();
26274
26287
  var subprotocol = require_subprotocol();
@@ -26569,7 +26582,7 @@ var require_websocket_server = __commonJS({
26569
26582
  );
26570
26583
  }
26571
26584
  if (this._state > RUNNING) return abortHandshake(socket, 503);
26572
- const digest = createHash6("sha1").update(key + GUID).digest("base64");
26585
+ const digest = createHash7("sha1").update(key + GUID).digest("base64");
26573
26586
  const headers = [
26574
26587
  "HTTP/1.1 101 Switching Protocols",
26575
26588
  "Upgrade: websocket",
@@ -26934,7 +26947,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
26934
26947
  client: {
26935
26948
  id: "gateway-client",
26936
26949
  displayName: "okx-a2a-node",
26937
- version: "0.2.9",
26950
+ version: "0.2.10-beta-98689bff7a-260826143751",
26938
26951
  platform: "node",
26939
26952
  mode: "backend",
26940
26953
  instanceId
@@ -26945,7 +26958,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
26945
26958
  commands: [],
26946
26959
  permissions: {},
26947
26960
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
26948
- userAgent: `okx-a2a-node/${"0.2.9"}`,
26961
+ userAgent: `okx-a2a-node/${"0.2.10-beta-98689bff7a-260826143751"}`,
26949
26962
  auth: {
26950
26963
  ...config.token ? { token: config.token } : {},
26951
26964
  ...config.password ? { password: config.password } : {}
@@ -28912,7 +28925,7 @@ var init_sentry_config = __esm({
28912
28925
  environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
28913
28926
  SENTRY_CONFIG = {
28914
28927
  projectName: "okx/openclaw-okx-a2a-extension",
28915
- release: "0.2.9",
28928
+ release: "0.2.10-beta-98689bff7a-260826143751",
28916
28929
  environment,
28917
28930
  runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
28918
28931
  };
@@ -29201,7 +29214,7 @@ var require_BufferList = __commonJS({
29201
29214
  this.head = this.tail = null;
29202
29215
  this.length = 0;
29203
29216
  };
29204
- BufferList.prototype.join = function join33(s) {
29217
+ BufferList.prototype.join = function join35(s) {
29205
29218
  if (this.length === 0) return "";
29206
29219
  var p = this.head;
29207
29220
  var ret = "" + p.data;
@@ -40082,7 +40095,7 @@ async function exportDiagnosticLogs(options) {
40082
40095
  node: process.version,
40083
40096
  platform: process.platform,
40084
40097
  arch: process.arch,
40085
- packageVersion: true ? "0.2.9" : "unknown",
40098
+ packageVersion: true ? "0.2.10-beta-98689bff7a-260826143751" : "unknown",
40086
40099
  sensitiveContentIncluded: options.includeSensitiveContent,
40087
40100
  listenerAndLlmContentIncluded: true,
40088
40101
  credentialsAlwaysRedacted: true,
@@ -65284,6 +65297,463 @@ var init_xmtp_debug = __esm({
65284
65297
  }
65285
65298
  });
65286
65299
 
65300
+ // src/signal-trading/config.ts
65301
+ function isPlainObject2(value) {
65302
+ return !!value && typeof value === "object" && !Array.isArray(value);
65303
+ }
65304
+ function requireObject(value, path2) {
65305
+ if (!isPlainObject2(value)) {
65306
+ throw new Error(`${path2} must be an object`);
65307
+ }
65308
+ return value;
65309
+ }
65310
+ function requireString(value, path2) {
65311
+ if (typeof value !== "string" || value.trim().length === 0) {
65312
+ throw new Error(`${path2} must be a non-empty string`);
65313
+ }
65314
+ return value.trim();
65315
+ }
65316
+ function optionalString(value, path2) {
65317
+ return value === void 0 ? void 0 : requireString(value, path2);
65318
+ }
65319
+ function requireBoolean(value, path2) {
65320
+ if (typeof value !== "boolean") {
65321
+ throw new Error(`${path2} must be a boolean`);
65322
+ }
65323
+ return value;
65324
+ }
65325
+ function requireInteger(value, path2, minimum) {
65326
+ if (typeof value !== "number" || !Number.isInteger(value) || value < minimum) {
65327
+ throw new Error(`${path2} must be an integer >= ${minimum}`);
65328
+ }
65329
+ return value;
65330
+ }
65331
+ function requireArray(value, path2) {
65332
+ if (!Array.isArray(value)) {
65333
+ throw new Error(`${path2} must be an array`);
65334
+ }
65335
+ return value;
65336
+ }
65337
+ function parseStringArray2(value, path2) {
65338
+ return requireArray(value, path2).map((item, index2) => requireString(item, `${path2}[${index2}]`));
65339
+ }
65340
+ function parseProviderRoute(value, index2) {
65341
+ const path2 = `config.provider.routes[${index2}]`;
65342
+ const input = requireObject(value, path2);
65343
+ const myAgentId = optionalString(input.myAgentId, `${path2}.myAgentId`);
65344
+ const toXmtpAddress = optionalString(input.toXmtpAddress, `${path2}.toXmtpAddress`);
65345
+ return {
65346
+ serviceId: requireString(input.serviceId, `${path2}.serviceId`),
65347
+ subscriptionId: requireString(input.subscriptionId, `${path2}.subscriptionId`),
65348
+ jobId: requireString(input.jobId, `${path2}.jobId`),
65349
+ ...myAgentId ? { myAgentId } : {},
65350
+ toAgentId: requireString(input.toAgentId, `${path2}.toAgentId`),
65351
+ ...toXmtpAddress ? { toXmtpAddress } : {}
65352
+ };
65353
+ }
65354
+ function parseBuyerSubscription(value, index2) {
65355
+ const path2 = `config.buyer.subscriptions[${index2}]`;
65356
+ const input = requireObject(value, path2);
65357
+ return {
65358
+ serviceId: requireString(input.serviceId, `${path2}.serviceId`),
65359
+ subscriptionId: requireString(input.subscriptionId, `${path2}.subscriptionId`),
65360
+ jobId: requireString(input.jobId, `${path2}.jobId`),
65361
+ providerAgentId: requireString(input.providerAgentId, `${path2}.providerAgentId`)
65362
+ };
65363
+ }
65364
+ function parseRiskPolicy(value) {
65365
+ const input = requireObject(value, "config.buyer.riskPolicy");
65366
+ const allowedSides = parseStringArray2(input.allowedSides, "config.buyer.riskPolicy.allowedSides");
65367
+ for (const side of allowedSides) {
65368
+ if (side !== "BUY" && side !== "SELL") {
65369
+ throw new Error("config.buyer.riskPolicy.allowedSides supports only BUY and SELL");
65370
+ }
65371
+ }
65372
+ const allowedTokenIds = parseStringArray2(
65373
+ input.allowedTokenIds,
65374
+ "config.buyer.riskPolicy.allowedTokenIds"
65375
+ );
65376
+ if (allowedTokenIds.length === 0) {
65377
+ throw new Error("config.buyer.riskPolicy.allowedTokenIds must not be empty");
65378
+ }
65379
+ return {
65380
+ allowedTokenIds,
65381
+ allowedSides,
65382
+ ...input.minOrderAmount === void 0 ? {} : {
65383
+ minOrderAmount: requireString(
65384
+ input.minOrderAmount,
65385
+ "config.buyer.riskPolicy.minOrderAmount"
65386
+ )
65387
+ },
65388
+ maxOrderAmount: requireString(input.maxOrderAmount, "config.buyer.riskPolicy.maxOrderAmount"),
65389
+ maxSlippageBps: requireInteger(
65390
+ input.maxSlippageBps,
65391
+ "config.buyer.riskPolicy.maxSlippageBps",
65392
+ 0
65393
+ ),
65394
+ maxSignalAgeMs: requireInteger(
65395
+ input.maxSignalAgeMs,
65396
+ "config.buyer.riskPolicy.maxSignalAgeMs",
65397
+ 1
65398
+ ),
65399
+ ...input.minTimeToExpiryMs === void 0 ? {} : {
65400
+ minTimeToExpiryMs: requireInteger(
65401
+ input.minTimeToExpiryMs,
65402
+ "config.buyer.riskPolicy.minTimeToExpiryMs",
65403
+ 0
65404
+ )
65405
+ }
65406
+ };
65407
+ }
65408
+ function parseBuyer(value) {
65409
+ const input = requireObject(value, "config.buyer");
65410
+ const executionMode = requireString(input.executionMode, "config.buyer.executionMode");
65411
+ if (executionMode !== "DRY_RUN" && executionMode !== "LIVE") {
65412
+ throw new Error("config.buyer.executionMode must be DRY_RUN or LIVE");
65413
+ }
65414
+ let polymarket;
65415
+ if (input.polymarket !== void 0) {
65416
+ const polymarketInput = requireObject(input.polymarket, "config.buyer.polymarket");
65417
+ const bin = optionalString(polymarketInput.bin, "config.buyer.polymarket.bin");
65418
+ const timeoutMs = polymarketInput.timeoutMs === void 0 ? void 0 : requireInteger(polymarketInput.timeoutMs, "config.buyer.polymarket.timeoutMs", 1);
65419
+ polymarket = {
65420
+ ...bin ? { bin } : {},
65421
+ ...timeoutMs ? { timeoutMs } : {}
65422
+ };
65423
+ }
65424
+ return {
65425
+ enabled: requireBoolean(input.enabled, "config.buyer.enabled"),
65426
+ executionMode,
65427
+ subscriptions: requireArray(input.subscriptions, "config.buyer.subscriptions").map(parseBuyerSubscription),
65428
+ riskPolicy: parseRiskPolicy(input.riskPolicy),
65429
+ ...polymarket ? { polymarket } : {}
65430
+ };
65431
+ }
65432
+ function parseSignalTradingConfig(value) {
65433
+ const input = requireObject(value, "config");
65434
+ if (input.version !== SIGNAL_TRADING_CONFIG_VERSION) {
65435
+ throw new Error(`config.version must be ${SIGNAL_TRADING_CONFIG_VERSION}`);
65436
+ }
65437
+ let provider;
65438
+ if (input.provider !== void 0) {
65439
+ const providerInput = requireObject(input.provider, "config.provider");
65440
+ provider = {
65441
+ routes: requireArray(providerInput.routes, "config.provider.routes").map(parseProviderRoute)
65442
+ };
65443
+ }
65444
+ const buyer = input.buyer === void 0 ? void 0 : parseBuyer(input.buyer);
65445
+ return {
65446
+ version: SIGNAL_TRADING_CONFIG_VERSION,
65447
+ ...provider ? { provider } : {},
65448
+ ...buyer ? { buyer } : {}
65449
+ };
65450
+ }
65451
+ function resolveSignalTradingDir(homeDir) {
65452
+ return (0, import_node_path30.join)(resolveTaskPaths(homeDir).homeDir, "signal-trading");
65453
+ }
65454
+ function resolveSignalTradingConfigPath(homeDir) {
65455
+ return (0, import_node_path30.join)(resolveSignalTradingDir(homeDir), "config.json");
65456
+ }
65457
+ function loadSignalTradingConfig(homeDir) {
65458
+ const path2 = resolveSignalTradingConfigPath(homeDir);
65459
+ if (!(0, import_node_fs25.existsSync)(path2)) {
65460
+ throw new Error(`signal trading config not found: ${path2}`);
65461
+ }
65462
+ let parsed;
65463
+ try {
65464
+ parsed = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf8"));
65465
+ } catch (error) {
65466
+ throw new Error(
65467
+ `signal trading config is not valid JSON: ${path2}: ${error instanceof Error ? error.message : String(error)}`
65468
+ );
65469
+ }
65470
+ return parseSignalTradingConfig(parsed);
65471
+ }
65472
+ var import_node_fs25, import_node_path30, SIGNAL_TRADING_CONFIG_VERSION;
65473
+ var init_config = __esm({
65474
+ "src/signal-trading/config.ts"() {
65475
+ "use strict";
65476
+ import_node_fs25 = require("node:fs");
65477
+ import_node_path30 = require("node:path");
65478
+ init_paths();
65479
+ SIGNAL_TRADING_CONFIG_VERSION = 1;
65480
+ }
65481
+ });
65482
+
65483
+ // src/signal-trading/protocol.ts
65484
+ function isPlainObject3(value) {
65485
+ return !!value && typeof value === "object" && !Array.isArray(value);
65486
+ }
65487
+ function requireObject2(value, path2) {
65488
+ if (!isPlainObject3(value)) {
65489
+ throw new Error(`${path2} must be an object`);
65490
+ }
65491
+ return value;
65492
+ }
65493
+ function requireString2(value, path2) {
65494
+ if (typeof value !== "string" || value.trim().length === 0) {
65495
+ throw new Error(`${path2} must be a non-empty string`);
65496
+ }
65497
+ return value.trim();
65498
+ }
65499
+ function optionalString2(value, path2) {
65500
+ if (value === void 0) {
65501
+ return void 0;
65502
+ }
65503
+ return requireString2(value, path2);
65504
+ }
65505
+ function requireEnum(value, path2, values) {
65506
+ if (typeof value !== "string" || !values.includes(value)) {
65507
+ throw new Error(`${path2} must be one of ${values.join(", ")}`);
65508
+ }
65509
+ return value;
65510
+ }
65511
+ function requireFiniteNumber(value, path2) {
65512
+ if (typeof value !== "number" || !Number.isFinite(value)) {
65513
+ throw new Error(`${path2} must be a finite number`);
65514
+ }
65515
+ return value;
65516
+ }
65517
+ function requireInteger2(value, path2, minimum = 0) {
65518
+ const parsed = requireFiniteNumber(value, path2);
65519
+ if (!Number.isInteger(parsed) || parsed < minimum) {
65520
+ throw new Error(`${path2} must be an integer >= ${minimum}`);
65521
+ }
65522
+ return parsed;
65523
+ }
65524
+ function requireIsoTimestamp(value, path2) {
65525
+ const timestamp = requireString2(value, path2);
65526
+ if (!Number.isFinite(Date.parse(timestamp))) {
65527
+ throw new Error(`${path2} must be an ISO-8601 timestamp`);
65528
+ }
65529
+ return timestamp;
65530
+ }
65531
+ function readStringRecord2(value, path2) {
65532
+ if (value === void 0) {
65533
+ return void 0;
65534
+ }
65535
+ const input = requireObject2(value, path2);
65536
+ const result = {};
65537
+ for (const [key, item] of Object.entries(input)) {
65538
+ result[key] = requireString2(item, `${path2}.${key}`);
65539
+ }
65540
+ return result;
65541
+ }
65542
+ function parseTradingSignalV1(value) {
65543
+ const input = requireObject2(value, "signal");
65544
+ const specVersion = requireEnum(input.specVersion, "signal.specVersion", [SIGNAL_SPEC_VERSION]);
65545
+ const emittedAt = requireIsoTimestamp(input.emittedAt, "signal.emittedAt");
65546
+ const expiresAt = requireIsoTimestamp(input.expiresAt, "signal.expiresAt");
65547
+ if (Date.parse(expiresAt) <= Date.parse(emittedAt)) {
65548
+ throw new Error("signal.expiresAt must be later than signal.emittedAt");
65549
+ }
65550
+ const instrumentInput = requireObject2(input.instrument, "signal.instrument");
65551
+ const instrument = {
65552
+ symbol: requireString2(instrumentInput.symbol, "signal.instrument.symbol"),
65553
+ marketType: requireEnum(
65554
+ instrumentInput.marketType,
65555
+ "signal.instrument.marketType",
65556
+ ["SPOT", "PERP", "ONCHAIN"]
65557
+ )
65558
+ };
65559
+ const chainId = optionalString2(instrumentInput.chainId, "signal.instrument.chainId");
65560
+ const tokenIn = optionalString2(instrumentInput.tokenIn, "signal.instrument.tokenIn");
65561
+ const tokenOut = optionalString2(instrumentInput.tokenOut, "signal.instrument.tokenOut");
65562
+ if (chainId) {
65563
+ instrument.chainId = chainId;
65564
+ }
65565
+ if (tokenIn) {
65566
+ instrument.tokenIn = tokenIn;
65567
+ }
65568
+ if (tokenOut) {
65569
+ instrument.tokenOut = tokenOut;
65570
+ }
65571
+ const intentInput = requireObject2(input.intent, "signal.intent");
65572
+ const action = requireEnum(
65573
+ intentInput.action,
65574
+ "signal.intent.action",
65575
+ ["ENTER", "EXIT", "REBALANCE", "CANCEL", "NO_TRADE"]
65576
+ );
65577
+ let intent;
65578
+ if (action === "ENTER" || action === "EXIT") {
65579
+ intent = {
65580
+ action,
65581
+ side: requireEnum(intentInput.side, "signal.intent.side", ["BUY", "SELL"]),
65582
+ orderType: requireEnum(
65583
+ intentInput.orderType,
65584
+ "signal.intent.orderType",
65585
+ ["MARKET", "LIMIT"]
65586
+ )
65587
+ };
65588
+ } else if (action === "REBALANCE") {
65589
+ const targetWeightBps = requireInteger2(
65590
+ intentInput.targetWeightBps,
65591
+ "signal.intent.targetWeightBps"
65592
+ );
65593
+ if (targetWeightBps > 1e4) {
65594
+ throw new Error("signal.intent.targetWeightBps must be <= 10000");
65595
+ }
65596
+ intent = { action, targetWeightBps };
65597
+ } else if (action === "CANCEL") {
65598
+ intent = {
65599
+ action,
65600
+ targetSignalId: optionalString2(intentInput.targetSignalId, "signal.intent.targetSignalId"),
65601
+ targetExecutionId: optionalString2(
65602
+ intentInput.targetExecutionId,
65603
+ "signal.intent.targetExecutionId"
65604
+ )
65605
+ };
65606
+ } else {
65607
+ intent = {
65608
+ action,
65609
+ reason: requireString2(intentInput.reason, "signal.intent.reason")
65610
+ };
65611
+ }
65612
+ let sizing;
65613
+ if (input.sizing !== void 0) {
65614
+ const sizingInput = requireObject2(input.sizing, "signal.sizing");
65615
+ sizing = {
65616
+ type: requireEnum(
65617
+ sizingInput.type,
65618
+ "signal.sizing.type",
65619
+ ["FIXED_BASE", "FIXED_QUOTE", "PORTFOLIO_BPS"]
65620
+ ),
65621
+ value: requireString2(sizingInput.value, "signal.sizing.value")
65622
+ };
65623
+ } else if (action === "ENTER" || action === "EXIT") {
65624
+ throw new Error(`signal.sizing is required for ${action} signals`);
65625
+ }
65626
+ let constraints;
65627
+ if (input.constraints !== void 0) {
65628
+ const constraintsInput = requireObject2(input.constraints, "signal.constraints");
65629
+ constraints = {};
65630
+ const limitPrice = optionalString2(constraintsInput.limitPrice, "signal.constraints.limitPrice");
65631
+ if (limitPrice) {
65632
+ constraints.limitPrice = limitPrice;
65633
+ }
65634
+ if (constraintsInput.maxSlippageBps !== void 0) {
65635
+ constraints.maxSlippageBps = requireInteger2(
65636
+ constraintsInput.maxSlippageBps,
65637
+ "signal.constraints.maxSlippageBps"
65638
+ );
65639
+ }
65640
+ if (constraintsInput.timeInForce !== void 0) {
65641
+ constraints.timeInForce = requireEnum(
65642
+ constraintsInput.timeInForce,
65643
+ "signal.constraints.timeInForce",
65644
+ ["GTC", "IOC", "FOK"]
65645
+ );
65646
+ }
65647
+ }
65648
+ return {
65649
+ specVersion,
65650
+ signalId: requireString2(input.signalId, "signal.signalId"),
65651
+ serviceId: requireString2(input.serviceId, "signal.serviceId"),
65652
+ subscriptionId: requireString2(input.subscriptionId, "signal.subscriptionId"),
65653
+ providerAgentId: requireString2(input.providerAgentId, "signal.providerAgentId"),
65654
+ sequence: requireInteger2(input.sequence, "signal.sequence", 1),
65655
+ emittedAt,
65656
+ expiresAt,
65657
+ instrument,
65658
+ intent,
65659
+ ...sizing ? { sizing } : {},
65660
+ ...constraints ? { constraints } : {},
65661
+ ...input.metadata !== void 0 ? { metadata: readStringRecord2(input.metadata, "signal.metadata") } : {}
65662
+ };
65663
+ }
65664
+ function buildSignalEnvelopePayload(signal) {
65665
+ return { type: SIGNAL_PAYLOAD_TYPE, signal };
65666
+ }
65667
+ function extractSignalEnvelopePayload(envelope) {
65668
+ if (!isPlainObject3(envelope) || !isPlainObject3(envelope.payload)) {
65669
+ return null;
65670
+ }
65671
+ if (envelope.payload.type !== SIGNAL_PAYLOAD_TYPE) {
65672
+ return null;
65673
+ }
65674
+ return {
65675
+ type: SIGNAL_PAYLOAD_TYPE,
65676
+ signal: parseTradingSignalV1(envelope.payload.signal)
65677
+ };
65678
+ }
65679
+ function hasSignalEnvelopePayload(envelope) {
65680
+ return isPlainObject3(envelope) && isPlainObject3(envelope.payload) && envelope.payload.type === SIGNAL_PAYLOAD_TYPE;
65681
+ }
65682
+ var SIGNAL_PAYLOAD_TYPE, SIGNAL_SPEC_VERSION;
65683
+ var init_protocol = __esm({
65684
+ "src/signal-trading/protocol.ts"() {
65685
+ "use strict";
65686
+ SIGNAL_PAYLOAD_TYPE = "signal";
65687
+ SIGNAL_SPEC_VERSION = "1.0";
65688
+ }
65689
+ });
65690
+
65691
+ // src/signal-trading/publisher.ts
65692
+ async function handleSignalPublishCommand(params) {
65693
+ const signal = parseTradingSignalV1(params.command.signal);
65694
+ if (params.command.serviceId !== signal.serviceId) {
65695
+ throw new Error(
65696
+ `signal publish --service-id ${params.command.serviceId} does not match signal.serviceId ${signal.serviceId}`
65697
+ );
65698
+ }
65699
+ const config = loadSignalTradingConfig(params.homeDir);
65700
+ const routes = config.provider?.routes.filter((route) => {
65701
+ return route.serviceId === signal.serviceId && route.subscriptionId === signal.subscriptionId;
65702
+ }) ?? [];
65703
+ if (routes.length === 0) {
65704
+ throw new Error(
65705
+ `no provider route configured for serviceId=${signal.serviceId} subscriptionId=${signal.subscriptionId}`
65706
+ );
65707
+ }
65708
+ const deliveries = [];
65709
+ for (const route of routes) {
65710
+ if (route.myAgentId && route.myAgentId !== signal.providerAgentId) {
65711
+ throw new Error(
65712
+ `provider route myAgentId=${route.myAgentId} does not match signal.providerAgentId=${signal.providerAgentId}`
65713
+ );
65714
+ }
65715
+ const childCommand = {
65716
+ id: (0, import_node_crypto14.randomUUID)(),
65717
+ type: "xmtp-send",
65718
+ jobId: route.jobId,
65719
+ message: `Trading signal ${signal.signalId} from service ${signal.serviceId}`,
65720
+ sessionAgentId: route.toAgentId,
65721
+ myAgentId: route.myAgentId ?? signal.providerAgentId,
65722
+ toAgentId: route.toAgentId,
65723
+ toXmtpAddress: route.toXmtpAddress,
65724
+ payload: buildSignalEnvelopePayload(signal),
65725
+ createdAt: params.command.createdAt
65726
+ };
65727
+ const result = await handleXmtpSendCommand({
65728
+ command: childCommand,
65729
+ service: params.service,
65730
+ store: params.store,
65731
+ sessionStore: params.sessionStore
65732
+ });
65733
+ deliveries.push({
65734
+ subscriptionId: route.subscriptionId,
65735
+ jobId: route.jobId,
65736
+ toAgentId: route.toAgentId,
65737
+ messageId: result.messageId
65738
+ });
65739
+ }
65740
+ return {
65741
+ signalId: signal.signalId,
65742
+ serviceId: signal.serviceId,
65743
+ deliveries
65744
+ };
65745
+ }
65746
+ var import_node_crypto14;
65747
+ var init_publisher = __esm({
65748
+ "src/signal-trading/publisher.ts"() {
65749
+ "use strict";
65750
+ import_node_crypto14 = require("node:crypto");
65751
+ init_xmtp_send();
65752
+ init_config();
65753
+ init_protocol();
65754
+ }
65755
+ });
65756
+
65287
65757
  // src/command-processor.ts
65288
65758
  function commandSentryExtra(command, extra = {}) {
65289
65759
  const base = {
@@ -65308,6 +65778,11 @@ function commandSentryExtra(command, extra = {}) {
65308
65778
  base.myAgentId = command.myAgentId ?? "";
65309
65779
  base.toAgentId = command.toAgentId ?? "";
65310
65780
  base.toXmtpAddress = command.toXmtpAddress ?? "";
65781
+ } else if (command.type === "signal-publish") {
65782
+ base.serviceId = command.serviceId;
65783
+ base.signalId = command.signal.signalId;
65784
+ base.subscriptionId = command.signal.subscriptionId;
65785
+ base.agentId = command.signal.providerAgentId;
65311
65786
  } else if (command.type === "xmtp-deny-pending-conversation") {
65312
65787
  base.groupId = command.groupId;
65313
65788
  base.jobId = command.jobId ?? "";
@@ -65560,6 +66035,16 @@ async function handleDaemonCommand(command, params) {
65560
66035
  });
65561
66036
  return { ok: true, messageId: result.messageId };
65562
66037
  }
66038
+ if (command.type === "signal-publish") {
66039
+ const payload = await handleSignalPublishCommand({
66040
+ command,
66041
+ service: params.service,
66042
+ store: params.store,
66043
+ sessionStore: params.sessionStore,
66044
+ homeDir: params.homeDir
66045
+ });
66046
+ return { ok: true, payload };
66047
+ }
65563
66048
  if (command.type === "xmtp-get-pending-list") {
65564
66049
  return { ok: true, payload: await listPendingTaskRequests(params) };
65565
66050
  }
@@ -65642,12 +66127,12 @@ async function listPendingTaskRequests(params) {
65642
66127
  }
65643
66128
  async function denyPendingConversationsByJobId(jobId, params, content2) {
65644
66129
  const pending = await listPendingTaskRequests(params);
65645
- const matched = pending.filter((item) => isPlainObject2(item) && readString4(item.jobId) === jobId);
66130
+ const matched = pending.filter((item) => isPlainObject4(item) && readString4(item.jobId) === jobId);
65646
66131
  const clientAddresses = [...params.service.getClients().keys()];
65647
66132
  const targetsByKey = collectDenyTargetsFromPending(matched, clientAddresses);
65648
66133
  const groupIds = /* @__PURE__ */ new Set();
65649
66134
  for (const item of matched) {
65650
- if (!isPlainObject2(item)) {
66135
+ if (!isPlainObject4(item)) {
65651
66136
  continue;
65652
66137
  }
65653
66138
  const groupId = readString4(item.groupId);
@@ -65674,7 +66159,7 @@ async function denyPendingConversationsByJobId(jobId, params, content2) {
65674
66159
  function collectDenyTargetsFromPending(pending, fallbackAddresses) {
65675
66160
  const targetsByKey = /* @__PURE__ */ new Map();
65676
66161
  for (const item of pending) {
65677
- if (!isPlainObject2(item)) {
66162
+ if (!isPlainObject4(item)) {
65678
66163
  continue;
65679
66164
  }
65680
66165
  const groupId = readString4(item.groupId);
@@ -65699,7 +66184,7 @@ ${groupId}`, {
65699
66184
  async function resolvePendingTargetsByGroupId(groupId, addresses, params) {
65700
66185
  const addressSet = addresses ? new Set(addresses) : null;
65701
66186
  const pending = (await listPendingTaskRequests(params)).filter((item) => {
65702
- if (!isPlainObject2(item) || readString4(item.groupId) !== groupId) {
66187
+ if (!isPlainObject4(item) || readString4(item.groupId) !== groupId) {
65703
66188
  return false;
65704
66189
  }
65705
66190
  const address = readString4(item.myXmtpAddress);
@@ -65819,7 +66304,7 @@ function filterKnownPendingGroups(items, sessionStore) {
65819
66304
  return items;
65820
66305
  }
65821
66306
  return items.filter((item) => {
65822
- if (!isPlainObject2(item)) {
66307
+ if (!isPlainObject4(item)) {
65823
66308
  return true;
65824
66309
  }
65825
66310
  const jobId = readString4(item.jobId);
@@ -65830,7 +66315,7 @@ function filterKnownPendingGroups(items, sessionStore) {
65830
66315
  return sessionStore.querySessions({ jobId, toAgentId, limit: 1 }).length === 0;
65831
66316
  });
65832
66317
  }
65833
- function isPlainObject2(value) {
66318
+ function isPlainObject4(value) {
65834
66319
  return !!value && typeof value === "object" && !Array.isArray(value);
65835
66320
  }
65836
66321
  function readString4(value) {
@@ -65964,6 +66449,11 @@ function formatCommandCompleted(command, result) {
65964
66449
  if (command.type === "xmtp-send") {
65965
66450
  return `[okx-agent-task] xmtp-send command completed id=${command.id} job=${command.jobId} messageId=${result.messageId}`;
65966
66451
  }
66452
+ if (command.type === "signal-publish") {
66453
+ const payload = isPlainObject4(result.payload) ? result.payload : {};
66454
+ const deliveries = Array.isArray(payload.deliveries) ? payload.deliveries.length : 0;
66455
+ return `[signal-trading] signal-publish command completed id=${command.id} service=${command.serviceId} signal=${command.signal.signalId} deliveries=${deliveries}`;
66456
+ }
65967
66457
  if (command.type === "xmtp-get-pending-list") {
65968
66458
  return `[okx-agent-task] xmtp-get-pending-list command completed id=${command.id}`;
65969
66459
  }
@@ -65984,8 +66474,8 @@ function formatCommandCompleted(command, result) {
65984
66474
  return `[okx-agent-task] xmtp-refresh-agents command completed id=${command.id}`;
65985
66475
  }
65986
66476
  function formatXmtpDebugCompleted(command, payload) {
65987
- const record = isPlainObject2(payload) ? payload : {};
65988
- const summary = isPlainObject2(record.summary) ? record.summary : {};
66477
+ const record = isPlainObject4(payload) ? payload : {};
66478
+ const summary = isPlainObject4(record.summary) ? record.summary : {};
65989
66479
  const count = command.action === "group-list" ? record.groupCount ?? 0 : command.action === "group-inspect" ? record.conversationFound ? 1 : 0 : summary.matchedCount ?? 0;
65990
66480
  return `[okx-agent-task] xmtp-debug command completed id=${command.id} action=${command.action} rows=${String(count)}`;
65991
66481
  }
@@ -66139,6 +66629,7 @@ var init_command_processor = __esm({
66139
66629
  init_user_attention_ipc();
66140
66630
  init_sentry_logger();
66141
66631
  init_xmtp_debug();
66632
+ init_publisher();
66142
66633
  DEFAULT_COMMAND_EXECUTION_TIMEOUT_MS = 5e4;
66143
66634
  DEFAULT_COMMAND_STALE_TIMEOUT_MS = 12e4;
66144
66635
  DEFAULT_AI_COMMAND_STALE_TIMEOUT_MS = 30 * 6e4;
@@ -66192,7 +66683,7 @@ function tryMarkProcessed(messageId) {
66192
66683
  }
66193
66684
  return true;
66194
66685
  }
66195
- function isPlainObject3(value) {
66686
+ function isPlainObject5(value) {
66196
66687
  return !!value && typeof value === "object" && !Array.isArray(value);
66197
66688
  }
66198
66689
  function safeStringify(value) {
@@ -66249,9 +66740,9 @@ function readNumber(value) {
66249
66740
  }
66250
66741
  function resolveSessionAgentId(params) {
66251
66742
  const { chatType, payload, myXmtpAddress } = params;
66252
- const payloadObject = isPlainObject3(payload) ? payload : null;
66253
- const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
66254
- const message = isPlainObject3(payloadObject?.message) ? payloadObject.message : null;
66743
+ const payloadObject = isPlainObject5(payload) ? payload : null;
66744
+ const sender = isPlainObject5(payloadObject?.sender) ? payloadObject.sender : null;
66745
+ const message = isPlainObject5(payloadObject?.message) ? payloadObject.message : null;
66255
66746
  const localAgentId = XmtpService.getInstance().getAgentByAddress(myXmtpAddress)?.agentId ?? null;
66256
66747
  if (chatType === "group") {
66257
66748
  return readString5(sender?.agentId) ?? readString5(payloadObject?.receiverAgentId) ?? localAgentId;
@@ -66262,7 +66753,7 @@ function resolveSessionAgentId(params) {
66262
66753
  return localAgentId;
66263
66754
  }
66264
66755
  function routeMessage(chatType, parsed, payload) {
66265
- if (!parsed || !isPlainObject3(payload)) {
66756
+ if (!parsed || !isPlainObject5(payload)) {
66266
66757
  return {
66267
66758
  jobId: BACKUP_JOB_ID,
66268
66759
  route: "backup",
@@ -66274,7 +66765,7 @@ function routeMessage(chatType, parsed, payload) {
66274
66765
  return jobId ? { jobId, route: "job", routeReason: "group-job-id" } : { jobId: BACKUP_JOB_ID, route: "backup", routeReason: "group-missing-job-id" };
66275
66766
  }
66276
66767
  if (chatType === "dm") {
66277
- const message = isPlainObject3(payload.message) ? payload.message : null;
66768
+ const message = isPlainObject5(payload.message) ? payload.message : null;
66278
66769
  const nestedJobId = readString5(message?.jobId);
66279
66770
  const directJobId = readString5(payload.jobId);
66280
66771
  const jobId = nestedJobId ?? directJobId;
@@ -66287,10 +66778,10 @@ function routeMessage(chatType, parsed, payload) {
66287
66778
  return { jobId: BACKUP_JOB_ID, route: "backup", routeReason: "unknown-conversation" };
66288
66779
  }
66289
66780
  function extractDirectToUserNotification(payload) {
66290
- if (!isPlainObject3(payload)) {
66781
+ if (!isPlainObject5(payload)) {
66291
66782
  return { kind: "none" };
66292
66783
  }
66293
- const message = isPlainObject3(payload.message) ? payload.message : null;
66784
+ const message = isPlainObject5(payload.message) ? payload.message : null;
66294
66785
  if (message?.isDirectToUser !== true) {
66295
66786
  return { kind: "none" };
66296
66787
  }
@@ -66314,10 +66805,10 @@ function extractDirectToUserNotification(payload) {
66314
66805
  };
66315
66806
  }
66316
66807
  function extractSystemNotification(payload) {
66317
- if (!isPlainObject3(payload)) {
66808
+ if (!isPlainObject5(payload)) {
66318
66809
  return null;
66319
66810
  }
66320
- const message = isPlainObject3(payload.message) ? payload.message : null;
66811
+ const message = isPlainObject5(payload.message) ? payload.message : null;
66321
66812
  const isDirectCommunication = message?.isDirectCommunication === true;
66322
66813
  if (message?.source !== "system" && !isDirectCommunication) {
66323
66814
  return null;
@@ -66609,7 +67100,7 @@ function maybeNotifyInboundAgentMessage(params) {
66609
67100
  return;
66610
67101
  }
66611
67102
  const content2 = payloadObject.content;
66612
- const sender = isPlainObject3(payloadObject.sender) ? payloadObject.sender : null;
67103
+ const sender = isPlainObject5(payloadObject.sender) ? payloadObject.sender : null;
66613
67104
  const localAgent = XmtpService.getInstance().getAgentByAddress(params.deps.myXmtpAddress);
66614
67105
  void notifyAgentMessageToUserAttention({
66615
67106
  direction: "inbound" /* INBOUND */,
@@ -66640,11 +67131,11 @@ function stringifySystemPayload(payload) {
66640
67131
  }
66641
67132
  }
66642
67133
  function summarizePayloadForLog(payload) {
66643
- if (!isPlainObject3(payload)) {
67134
+ if (!isPlainObject5(payload)) {
66644
67135
  return "payload=non-object";
66645
67136
  }
66646
- const message = isPlainObject3(payload.message) ? payload.message : null;
66647
- const sender = isPlainObject3(payload.sender) ? payload.sender : null;
67137
+ const message = isPlainObject5(payload.message) ? payload.message : null;
67138
+ const sender = isPlainObject5(payload.sender) ? payload.sender : null;
66648
67139
  const jobId = readString5(payload.jobId) ?? readString5(message?.jobId);
66649
67140
  const parts = [
66650
67141
  readString5(payload.msgType) ? `type=${readString5(payload.msgType)}` : null,
@@ -66913,7 +67404,7 @@ async function verifyInboundA2AGroupMessage(params) {
66913
67404
  messageId,
66914
67405
  groupId,
66915
67406
  jobId,
66916
- agentId: readString5(isPlainObject3(payload.sender) ? payload.sender.agentId : null),
67407
+ agentId: readString5(isPlainObject5(payload.sender) ? payload.sender.agentId : null),
66917
67408
  localAgentId: myAgent?.agentId ?? null,
66918
67409
  senderAddress,
66919
67410
  senderInboxId,
@@ -66939,7 +67430,7 @@ async function verifyInboundA2AGroupMessage(params) {
66939
67430
  });
66940
67431
  return false;
66941
67432
  }
66942
- const sender = isPlainObject3(payload.sender) ? payload.sender : null;
67433
+ const sender = isPlainObject5(payload.sender) ? payload.sender : null;
66943
67434
  const senderAgentId = readString5(sender?.agentId);
66944
67435
  const senderRole = readNumber(sender?.role);
66945
67436
  if (!senderAgentId || !myAgent) {
@@ -67163,7 +67654,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67163
67654
  timing.mark("payloadParse", parseStartedAt);
67164
67655
  const directToUser = chatType === "dm" && parseResult.ok ? extractDirectToUserNotification(parseResult.data) : { kind: "none" };
67165
67656
  if (directToUser.kind === "invalid") {
67166
- const droppedMessageId = messageId || `direct-to-user-${(0, import_node_crypto14.randomUUID)()}`;
67657
+ const droppedMessageId = messageId || `direct-to-user-${(0, import_node_crypto15.randomUUID)()}`;
67167
67658
  logger.error(
67168
67659
  LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
67169
67660
  new Error("Invalid direct-to-user system DM"),
@@ -67187,7 +67678,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67187
67678
  await dispatchDirectToUserNotification({
67188
67679
  deps,
67189
67680
  notification: directToUser.notification,
67190
- messageId: messageId || `direct-to-user-${(0, import_node_crypto14.randomUUID)()}`,
67681
+ messageId: messageId || `direct-to-user-${(0, import_node_crypto15.randomUUID)()}`,
67191
67682
  timing,
67192
67683
  source: options.source ?? "live"
67193
67684
  });
@@ -67195,7 +67686,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67195
67686
  }
67196
67687
  const systemNotification = chatType === "dm" && parseResult.ok ? extractSystemNotification(parseResult.data) : null;
67197
67688
  if (systemNotification) {
67198
- const systemMessageId = messageId || `system-${(0, import_node_crypto14.randomUUID)()}`;
67689
+ const systemMessageId = messageId || `system-${(0, import_node_crypto15.randomUUID)()}`;
67199
67690
  logWithTimestamp(
67200
67691
  `[okx-agent-task:${deps.myXmtpAddress}] xmtp_system_message_received agentId=${systemNotification.agentId ?? ""} msg=${shortenLogValue(systemMessageId)} event=${systemNotification.event ?? ""} job=${shortenLogValue(systemNotification.jobId)} conv=${conversationId} source=${options.source ?? "live"} rawBytes=${Buffer.byteLength(rawText, "utf8")} rawPreview=${previewRawEnvelope(rawText)}`
67201
67692
  );
@@ -67394,7 +67885,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67394
67885
  );
67395
67886
  }
67396
67887
  if (route.route === "job" && chatType === "group") {
67397
- const payloadObject = isPlainObject3(parseResult.ok ? parseResult.data : null) ? parseResult.data : null;
67888
+ const payloadObject = isPlainObject5(parseResult.ok ? parseResult.data : null) ? parseResult.data : null;
67398
67889
  const service = XmtpService.getInstance();
67399
67890
  const trustedSystemSender = service.isTrustedSystemAccountSender({
67400
67891
  senderAddress,
@@ -67420,7 +67911,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67420
67911
  });
67421
67912
  return true;
67422
67913
  }
67423
- const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
67914
+ const sender = isPlainObject5(payloadObject?.sender) ? payloadObject.sender : null;
67424
67915
  const localAgent = service.getAgentByAddress(deps.myXmtpAddress);
67425
67916
  const myAgentId = localAgent?.agentId ?? readString5(payloadObject?.receiverAgentId) ?? sessionAgentId ?? null;
67426
67917
  const toAgentId = readString5(sender?.agentId);
@@ -67440,7 +67931,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67440
67931
  if (!accepted) {
67441
67932
  return true;
67442
67933
  }
67443
- const routedMessageId = messageId || `group-${(0, import_node_crypto14.randomUUID)()}`;
67934
+ const routedMessageId = messageId || `group-${(0, import_node_crypto15.randomUUID)()}`;
67444
67935
  const sessionKey = ensureInboundGroupSession(deps, {
67445
67936
  jobId: route.jobId,
67446
67937
  myAgentId,
@@ -67448,6 +67939,35 @@ async function processFileMessage(ctx, deps, options = {}) {
67448
67939
  groupId: conversationId,
67449
67940
  toAgentXmtpAddress: senderAddress || readString5(payloadObject?.fromXmtpAddress)
67450
67941
  });
67942
+ if (hasSignalEnvelopePayload(parseResult.data)) {
67943
+ try {
67944
+ const signalPayload = extractSignalEnvelopePayload(parseResult.data);
67945
+ if (!signalPayload) {
67946
+ throw new Error("signal envelope payload is missing");
67947
+ }
67948
+ if (!toAgentId) {
67949
+ throw new Error("signal envelope sender.agentId is missing");
67950
+ }
67951
+ if (!deps.onSignalTradingSignal) {
67952
+ throw new Error("signal buyer runtime is unavailable");
67953
+ }
67954
+ await deps.onSignalTradingSignal({
67955
+ signal: signalPayload.signal,
67956
+ jobId: route.jobId,
67957
+ senderAgentId: toAgentId,
67958
+ messageId: routedMessageId
67959
+ });
67960
+ logWithTimestamp(
67961
+ `[signal-trading] inbound signal handled signal=${signalPayload.signal.signalId} service=${signalPayload.signal.serviceId} job=${shortenLogValue(route.jobId)} message=${shortenLogValue(routedMessageId)}`
67962
+ );
67963
+ } catch (error) {
67964
+ logWithTimestamp(
67965
+ `[signal-trading] inbound signal rejected job=${shortenLogValue(route.jobId)} message=${shortenLogValue(routedMessageId)}:`,
67966
+ error
67967
+ );
67968
+ }
67969
+ return true;
67970
+ }
67451
67971
  const dispatchStartedAt = Date.now();
67452
67972
  void Promise.resolve(deps.onSessionMessage?.({
67453
67973
  sessionKey,
@@ -67506,7 +68026,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67506
68026
  return true;
67507
68027
  }
67508
68028
  const stored = {
67509
- id: messageId || `local-${(0, import_node_crypto14.randomUUID)()}`,
68029
+ id: messageId || `local-${(0, import_node_crypto15.randomUUID)()}`,
67510
68030
  direction: "inbound",
67511
68031
  route: route.route,
67512
68032
  routeReason: route.routeReason,
@@ -67524,8 +68044,8 @@ async function processFileMessage(ctx, deps, options = {}) {
67524
68044
  await deps.store.append(route.jobId, stored, sessionAgentId);
67525
68045
  timing.mark("storeAppend", storeAppendStartedAt);
67526
68046
  if ((route.route === "job" || parseResult.ok && !isA2AEnvelope(stored.payload)) && !options.skipNotify) {
67527
- const payloadObject = isPlainObject3(stored.payload) ? stored.payload : null;
67528
- const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
68047
+ const payloadObject = isPlainObject5(stored.payload) ? stored.payload : null;
68048
+ const sender = isPlainObject5(payloadObject?.sender) ? payloadObject.sender : null;
67529
68049
  const localAgent = XmtpService.getInstance().getAgentByAddress(deps.myXmtpAddress);
67530
68050
  const sessionKey = route.route === "job" ? buildSessionKey({
67531
68051
  jobId: route.jobId,
@@ -67543,8 +68063,8 @@ async function processFileMessage(ctx, deps, options = {}) {
67543
68063
  });
67544
68064
  }
67545
68065
  if (route.route === "job" && chatType === "group" && conversationId && senderAddress) {
67546
- const payloadObject = isPlainObject3(stored.payload) ? stored.payload : null;
67547
- const sender = isPlainObject3(payloadObject?.sender) ? payloadObject.sender : null;
68066
+ const payloadObject = isPlainObject5(stored.payload) ? stored.payload : null;
68067
+ const sender = isPlainObject5(payloadObject?.sender) ? payloadObject.sender : null;
67548
68068
  await deps.store.updateXmtpSession(route.jobId, {
67549
68069
  xmtpGroupId: conversationId,
67550
68070
  myXmtpAddress: deps.myXmtpAddress,
@@ -67671,7 +68191,8 @@ function createMiddlewareFromCoreDeps(store, deps, extra) {
67671
68191
  allowGroup: deps.allowGroup,
67672
68192
  onMessageProcessed: deps.onMessageProcessed,
67673
68193
  onJobMessageStored: extra?.onJobMessageStored,
67674
- onSessionMessage: extra?.onSessionMessage
68194
+ onSessionMessage: extra?.onSessionMessage,
68195
+ onSignalTradingSignal: extra?.onSignalTradingSignal
67675
68196
  });
67676
68197
  }
67677
68198
  function processOfflineFromCoreDeps(store, ctx, deps, options) {
@@ -67681,13 +68202,14 @@ function processOfflineFromCoreDeps(store, ctx, deps, options) {
67681
68202
  sessionStore: options.sessionStore,
67682
68203
  allowGroup: deps.allowGroup,
67683
68204
  onJobMessageStored: options.onJobMessageStored,
67684
- onSessionMessage: options.onSessionMessage
68205
+ onSessionMessage: options.onSessionMessage,
68206
+ onSignalTradingSignal: options.onSignalTradingSignal
67685
68207
  }, { ...options, source: "replay" });
67686
68208
  }
67687
68209
  function buildSystemStoredMessage(params) {
67688
68210
  const now = Date.now();
67689
68211
  return {
67690
- id: params.id ?? `system-${now}-${(0, import_node_crypto14.randomUUID)()}`,
68212
+ id: params.id ?? `system-${now}-${(0, import_node_crypto15.randomUUID)()}`,
67691
68213
  direction: "system",
67692
68214
  route: "backup",
67693
68215
  routeReason: params.reason,
@@ -67703,14 +68225,14 @@ function buildSystemStoredMessage(params) {
67703
68225
  };
67704
68226
  }
67705
68227
  function isA2AEnvelope(payload) {
67706
- return isPlainObject3(payload) && payload.msgType === A2A_MESSAGE_TYPE;
68228
+ return isPlainObject5(payload) && payload.msgType === A2A_MESSAGE_TYPE;
67707
68229
  }
67708
- var import_node_crypto14, PROCESSED_IDS_MAX, processedMessageIds, INBOUND_TRANSPORT, INBOUND_EVENT_FAMILY, INBOUND_TERMINAL_FIELDS;
68230
+ var import_node_crypto15, PROCESSED_IDS_MAX, processedMessageIds, INBOUND_TRANSPORT, INBOUND_EVENT_FAMILY, INBOUND_TERMINAL_FIELDS;
67709
68231
  var init_message_handler = __esm({
67710
68232
  "src/message-handler.ts"() {
67711
68233
  "use strict";
67712
68234
  init_log();
67713
- import_node_crypto14 = require("node:crypto");
68235
+ import_node_crypto15 = require("node:crypto");
67714
68236
  init_dist2();
67715
68237
  init_a2a();
67716
68238
  init_envelope_shared();
@@ -67725,6 +68247,7 @@ var init_message_handler = __esm({
67725
68247
  init_session_store();
67726
68248
  init_agent_message_notice();
67727
68249
  init_ai_provider();
68250
+ init_protocol();
67728
68251
  PROCESSED_IDS_MAX = 1e3;
67729
68252
  processedMessageIds = /* @__PURE__ */ new Map();
67730
68253
  INBOUND_TRANSPORT = "xmtp";
@@ -67777,7 +68300,7 @@ function isOriginalParentProcessAlive(options) {
67777
68300
  }
67778
68301
  function registerUserAttentionWatcher(options) {
67779
68302
  return options.store.registerUserAttentionWatcher({
67780
- id: options.id ?? (0, import_node_crypto15.randomUUID)(),
68303
+ id: options.id ?? (0, import_node_crypto16.randomUUID)(),
67781
68304
  provider: options.provider,
67782
68305
  jobId: options.jobId,
67783
68306
  nowMs: options.nowMs ?? Date.now(),
@@ -67856,11 +68379,11 @@ function userWatchEventDeliveredSentryExtra(event) {
67856
68379
  hasDecision: String(event.hasDecision)
67857
68380
  };
67858
68381
  }
67859
- var import_node_crypto15, USER_ATTENTION_WATCH_REPLACED_MESSAGE, USER_ATTENTION_WATCHER_SCAN_MS, USER_ATTENTION_WATCHER_TTL_MS, USER_ATTENTION_WATCH_PARENT_CHECK_MS;
68382
+ var import_node_crypto16, USER_ATTENTION_WATCH_REPLACED_MESSAGE, USER_ATTENTION_WATCHER_SCAN_MS, USER_ATTENTION_WATCHER_TTL_MS, USER_ATTENTION_WATCH_PARENT_CHECK_MS;
67860
68383
  var init_user_attention_watchers = __esm({
67861
68384
  "src/user-attention-watchers.ts"() {
67862
68385
  "use strict";
67863
- import_node_crypto15 = require("node:crypto");
68386
+ import_node_crypto16 = require("node:crypto");
67864
68387
  init_sentry_logger();
67865
68388
  USER_ATTENTION_WATCH_REPLACED_MESSAGE = "Another okx-a2a user watch with the same job scope was started, so this watcher has been closed. Do not run this watch command again automatically, because starting another watcher may interrupt a different session that is already monitoring task progress.";
67866
68389
  USER_ATTENTION_WATCHER_SCAN_MS = 500;
@@ -67869,6 +68392,308 @@ var init_user_attention_watchers = __esm({
67869
68392
  }
67870
68393
  });
67871
68394
 
68395
+ // src/signal-trading/execution.ts
68396
+ function defaultPolymarketCommandRunner(bin, args, options) {
68397
+ return execFileAsync3(bin, args, {
68398
+ windowsHide: true,
68399
+ timeout: options.timeoutMs,
68400
+ maxBuffer: MAX_POLYMARKET_OUTPUT_BYTES
68401
+ });
68402
+ }
68403
+ function normalizeDecimal(value, path2) {
68404
+ const trimmed = value.trim();
68405
+ const match = /^(?:0|[1-9]\d*)(?:\.(\d+))?$/.exec(trimmed);
68406
+ if (!match || /^0(?:\.0+)?$/.test(trimmed)) {
68407
+ throw new Error(`${path2} must be a positive decimal string`);
68408
+ }
68409
+ const fraction = match[1] ?? "";
68410
+ return {
68411
+ digits: BigInt(trimmed.replace(".", "")),
68412
+ scale: fraction.length
68413
+ };
68414
+ }
68415
+ function comparePositiveDecimals(left, right) {
68416
+ const a = normalizeDecimal(left, "left decimal");
68417
+ const b = normalizeDecimal(right, "right decimal");
68418
+ const scale = Math.max(a.scale, b.scale);
68419
+ const aScaled = a.digits * 10n ** BigInt(scale - a.scale);
68420
+ const bScaled = b.digits * 10n ** BigInt(scale - b.scale);
68421
+ return aScaled < bScaled ? -1 : aScaled > bScaled ? 1 : 0;
68422
+ }
68423
+ function requireBuyerSubscription(buyer, signal, context) {
68424
+ const subscription = buyer.subscriptions.find((candidate) => {
68425
+ return candidate.serviceId === signal.serviceId && candidate.subscriptionId === signal.subscriptionId && candidate.jobId === context.jobId && candidate.providerAgentId === signal.providerAgentId;
68426
+ });
68427
+ if (!subscription) {
68428
+ throw new Error(
68429
+ `signal subscription is not configured for serviceId=${signal.serviceId} subscriptionId=${signal.subscriptionId} jobId=${context.jobId}`
68430
+ );
68431
+ }
68432
+ if (context.senderAgentId !== signal.providerAgentId) {
68433
+ throw new Error(
68434
+ `signal providerAgentId=${signal.providerAgentId} does not match verified senderAgentId=${context.senderAgentId}`
68435
+ );
68436
+ }
68437
+ }
68438
+ function buildPolymarketExecutionPlan(signalValue, buyer, context, nowMs = Date.now()) {
68439
+ const signal = parseTradingSignalV1(signalValue);
68440
+ validateSignalPreconditions(signal, buyer, context, nowMs);
68441
+ if (signal.intent.action !== "ENTER" && signal.intent.action !== "EXIT") {
68442
+ throw new Error(`Polymarket demo does not execute ${signal.intent.action} signals`);
68443
+ }
68444
+ if (!signal.sizing) {
68445
+ throw new Error(`signal.sizing is required for ${signal.intent.action} signals`);
68446
+ }
68447
+ if (signal.intent.orderType !== "MARKET") {
68448
+ throw new Error("Polymarket demo currently supports MARKET orders only");
68449
+ }
68450
+ if (!buyer.riskPolicy.allowedSides.includes(signal.intent.side)) {
68451
+ throw new Error(`signal side ${signal.intent.side} is not allowed by risk policy`);
68452
+ }
68453
+ const expectedSizing = signal.intent.side === "BUY" ? "FIXED_QUOTE" : "FIXED_BASE";
68454
+ if (signal.sizing.type !== expectedSizing) {
68455
+ throw new Error(`${signal.intent.side} market orders require sizing.type=${expectedSizing}`);
68456
+ }
68457
+ normalizeDecimal(signal.sizing.value, "signal.sizing.value");
68458
+ if (buyer.riskPolicy.minOrderAmount && comparePositiveDecimals(signal.sizing.value, buyer.riskPolicy.minOrderAmount) < 0) {
68459
+ throw new Error(
68460
+ `signal amount ${signal.sizing.value} is below risk minOrderAmount ${buyer.riskPolicy.minOrderAmount}`
68461
+ );
68462
+ }
68463
+ normalizeDecimal(buyer.riskPolicy.maxOrderAmount, "config.buyer.riskPolicy.maxOrderAmount");
68464
+ if (comparePositiveDecimals(signal.sizing.value, buyer.riskPolicy.maxOrderAmount) > 0) {
68465
+ throw new Error(
68466
+ `signal amount ${signal.sizing.value} exceeds risk maxOrderAmount ${buyer.riskPolicy.maxOrderAmount}`
68467
+ );
68468
+ }
68469
+ if (signal.constraints?.maxSlippageBps !== void 0 && signal.constraints.maxSlippageBps > buyer.riskPolicy.maxSlippageBps) {
68470
+ throw new Error(
68471
+ `signal maxSlippageBps ${signal.constraints.maxSlippageBps} exceeds risk policy ${buyer.riskPolicy.maxSlippageBps}`
68472
+ );
68473
+ }
68474
+ const tokenId = signal.metadata?.polymarketTokenId ?? signal.instrument.symbol;
68475
+ if (!buyer.riskPolicy.allowedTokenIds.includes(tokenId)) {
68476
+ throw new Error(`Polymarket token ${tokenId} is not allowlisted`);
68477
+ }
68478
+ const side = signal.intent.side.toLowerCase();
68479
+ return {
68480
+ bin: buyer.polymarket?.bin ?? process.env.POLYMARKET_BIN ?? "polymarket",
68481
+ args: [
68482
+ "-o",
68483
+ "json",
68484
+ "clob",
68485
+ "market-order",
68486
+ "--token",
68487
+ tokenId,
68488
+ "--side",
68489
+ side,
68490
+ "--amount",
68491
+ signal.sizing.value
68492
+ ],
68493
+ tokenId,
68494
+ side,
68495
+ amount: signal.sizing.value
68496
+ };
68497
+ }
68498
+ function validateSignalPreconditions(signal, buyer, context, nowMs) {
68499
+ if (!buyer.enabled) {
68500
+ throw new Error("signal buyer runtime is disabled");
68501
+ }
68502
+ requireBuyerSubscription(buyer, signal, context);
68503
+ const emittedAtMs = Date.parse(signal.emittedAt);
68504
+ const expiresAtMs = Date.parse(signal.expiresAt);
68505
+ if (expiresAtMs <= nowMs) {
68506
+ throw new Error(`signal ${signal.signalId} is expired`);
68507
+ }
68508
+ if (buyer.riskPolicy.minTimeToExpiryMs !== void 0 && expiresAtMs - nowMs < buyer.riskPolicy.minTimeToExpiryMs) {
68509
+ throw new Error(
68510
+ `signal ${signal.signalId} expires too soon for minTimeToExpiryMs=${buyer.riskPolicy.minTimeToExpiryMs}`
68511
+ );
68512
+ }
68513
+ if (emittedAtMs > nowMs + MAX_FUTURE_CLOCK_SKEW_MS) {
68514
+ throw new Error(`signal ${signal.signalId} emittedAt is too far in the future`);
68515
+ }
68516
+ if (nowMs - emittedAtMs > buyer.riskPolicy.maxSignalAgeMs) {
68517
+ throw new Error(`signal ${signal.signalId} exceeds maxSignalAgeMs`);
68518
+ }
68519
+ if (signal.instrument.marketType !== "ONCHAIN") {
68520
+ throw new Error("Polymarket execution requires instrument.marketType=ONCHAIN");
68521
+ }
68522
+ if (signal.metadata?.venue?.toLowerCase() !== "polymarket") {
68523
+ throw new Error("signal.metadata.venue must be polymarket");
68524
+ }
68525
+ }
68526
+ function receiptPath(homeDir, idempotencyKey) {
68527
+ const digest = (0, import_node_crypto17.createHash)("sha256").update(idempotencyKey).digest("hex");
68528
+ return (0, import_node_path31.join)(resolveSignalTradingDir(homeDir), "executions", `${digest}.json`);
68529
+ }
68530
+ function readReceipt(path2) {
68531
+ if (!(0, import_node_fs26.existsSync)(path2)) {
68532
+ return null;
68533
+ }
68534
+ try {
68535
+ return JSON.parse((0, import_node_fs26.readFileSync)(path2, "utf8"));
68536
+ } catch {
68537
+ return null;
68538
+ }
68539
+ }
68540
+ function claimReceipt(path2, receipt) {
68541
+ (0, import_node_fs26.mkdirSync)((0, import_node_path31.join)(path2, ".."), { recursive: true });
68542
+ let fd;
68543
+ try {
68544
+ fd = (0, import_node_fs26.openSync)(path2, "wx", 384);
68545
+ } catch (error) {
68546
+ if (error.code === "EEXIST") {
68547
+ return false;
68548
+ }
68549
+ throw error;
68550
+ }
68551
+ try {
68552
+ (0, import_node_fs26.writeSync)(fd, JSON.stringify(receipt, null, 2));
68553
+ } finally {
68554
+ (0, import_node_fs26.closeSync)(fd);
68555
+ }
68556
+ return true;
68557
+ }
68558
+ function updateReceipt(path2, receipt) {
68559
+ const temporaryPath = `${path2}.${process.pid}.${(0, import_node_crypto17.randomUUID)()}.tmp`;
68560
+ (0, import_node_fs26.writeFileSync)(temporaryPath, JSON.stringify(receipt, null, 2), { mode: 384 });
68561
+ (0, import_node_fs26.renameSync)(temporaryPath, path2);
68562
+ }
68563
+ function boundedOutput(value) {
68564
+ if (typeof value !== "string" || value.length === 0) {
68565
+ return void 0;
68566
+ }
68567
+ return value.slice(0, MAX_RECEIPT_OUTPUT_CHARS);
68568
+ }
68569
+ var import_node_child_process9, import_node_crypto17, import_node_fs26, import_node_path31, import_node_util3, execFileAsync3, DEFAULT_POLYMARKET_TIMEOUT_MS, MAX_POLYMARKET_OUTPUT_BYTES, MAX_RECEIPT_OUTPUT_CHARS, MAX_FUTURE_CLOCK_SKEW_MS, SignalTradingBuyerRuntime;
68570
+ var init_execution = __esm({
68571
+ "src/signal-trading/execution.ts"() {
68572
+ "use strict";
68573
+ import_node_child_process9 = require("node:child_process");
68574
+ import_node_crypto17 = require("node:crypto");
68575
+ import_node_fs26 = require("node:fs");
68576
+ import_node_path31 = require("node:path");
68577
+ import_node_util3 = require("node:util");
68578
+ init_log();
68579
+ init_config();
68580
+ init_protocol();
68581
+ execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process9.execFile);
68582
+ DEFAULT_POLYMARKET_TIMEOUT_MS = 3e4;
68583
+ MAX_POLYMARKET_OUTPUT_BYTES = 1048576;
68584
+ MAX_RECEIPT_OUTPUT_CHARS = 16384;
68585
+ MAX_FUTURE_CLOCK_SKEW_MS = 3e4;
68586
+ SignalTradingBuyerRuntime = class {
68587
+ constructor(homeDir, runner = defaultPolymarketCommandRunner) {
68588
+ this.homeDir = homeDir;
68589
+ this.runner = runner;
68590
+ }
68591
+ homeDir;
68592
+ runner;
68593
+ async process(signalValue, context) {
68594
+ const config = loadSignalTradingConfig(this.homeDir);
68595
+ if (!config.buyer) {
68596
+ throw new Error("signal buyer config is missing");
68597
+ }
68598
+ const signal = parseTradingSignalV1(signalValue);
68599
+ const idempotencyKey = `${signal.providerAgentId}:${signal.subscriptionId}:${signal.signalId}`;
68600
+ const path2 = receiptPath(this.homeDir, idempotencyKey);
68601
+ const now = (/* @__PURE__ */ new Date()).toISOString();
68602
+ if (signal.intent.action === "NO_TRADE") {
68603
+ validateSignalPreconditions(signal, config.buyer, context, Date.now());
68604
+ const receipt = {
68605
+ idempotencyKey,
68606
+ signalId: signal.signalId,
68607
+ serviceId: signal.serviceId,
68608
+ subscriptionId: signal.subscriptionId,
68609
+ providerAgentId: signal.providerAgentId,
68610
+ jobId: context.jobId,
68611
+ messageId: context.messageId,
68612
+ status: "SKIPPED",
68613
+ executionMode: config.buyer.executionMode,
68614
+ skipReason: signal.intent.reason,
68615
+ createdAt: now,
68616
+ updatedAt: now
68617
+ };
68618
+ if (!claimReceipt(path2, receipt)) {
68619
+ const existing = readReceipt(path2);
68620
+ if (!existing) {
68621
+ throw new Error(`signal execution receipt exists but cannot be read: ${path2}`);
68622
+ }
68623
+ return { handled: true, duplicate: true, receipt: existing };
68624
+ }
68625
+ logWithTimestamp(
68626
+ `[signal-trading] skipped NO_TRADE signal=${signal.signalId} service=${signal.serviceId} job=${context.jobId} reason=${signal.intent.reason}`
68627
+ );
68628
+ return { handled: true, duplicate: false, receipt };
68629
+ }
68630
+ const plan = buildPolymarketExecutionPlan(signal, config.buyer, context);
68631
+ const initialReceipt = {
68632
+ idempotencyKey,
68633
+ signalId: signal.signalId,
68634
+ serviceId: signal.serviceId,
68635
+ subscriptionId: signal.subscriptionId,
68636
+ providerAgentId: signal.providerAgentId,
68637
+ jobId: context.jobId,
68638
+ messageId: context.messageId,
68639
+ status: "PROCESSING",
68640
+ executionMode: config.buyer.executionMode,
68641
+ command: { bin: plan.bin, args: plan.args },
68642
+ createdAt: now,
68643
+ updatedAt: now
68644
+ };
68645
+ if (!claimReceipt(path2, initialReceipt)) {
68646
+ const existing = readReceipt(path2);
68647
+ if (!existing) {
68648
+ throw new Error(`signal execution receipt exists but cannot be read: ${path2}`);
68649
+ }
68650
+ return { handled: true, duplicate: true, receipt: existing };
68651
+ }
68652
+ if (config.buyer.executionMode === "DRY_RUN") {
68653
+ const receipt = {
68654
+ ...initialReceipt,
68655
+ status: "DRY_RUN",
68656
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
68657
+ };
68658
+ updateReceipt(path2, receipt);
68659
+ logWithTimestamp(
68660
+ `[signal-trading] dry-run signal=${signal.signalId} service=${signal.serviceId} job=${context.jobId}`
68661
+ );
68662
+ return { handled: true, duplicate: false, receipt };
68663
+ }
68664
+ try {
68665
+ const result = await this.runner(plan.bin, plan.args, {
68666
+ timeoutMs: config.buyer.polymarket?.timeoutMs ?? DEFAULT_POLYMARKET_TIMEOUT_MS
68667
+ });
68668
+ const receipt = {
68669
+ ...initialReceipt,
68670
+ status: "SUBMITTED",
68671
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
68672
+ ...boundedOutput(result.stdout) ? { stdout: boundedOutput(result.stdout) } : {},
68673
+ ...boundedOutput(result.stderr) ? { stderr: boundedOutput(result.stderr) } : {}
68674
+ };
68675
+ updateReceipt(path2, receipt);
68676
+ logWithTimestamp(
68677
+ `[signal-trading] Polymarket order submitted signal=${signal.signalId} service=${signal.serviceId} job=${context.jobId}`
68678
+ );
68679
+ return { handled: true, duplicate: false, receipt };
68680
+ } catch (error) {
68681
+ const receipt = {
68682
+ ...initialReceipt,
68683
+ status: "UNKNOWN",
68684
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
68685
+ error: error instanceof Error ? error.message : String(error)
68686
+ };
68687
+ updateReceipt(path2, receipt);
68688
+ throw new Error(
68689
+ `Polymarket CLI execution became UNKNOWN for signal=${signal.signalId}; automatic retry is disabled: ${receipt.error}`
68690
+ );
68691
+ }
68692
+ }
68693
+ };
68694
+ }
68695
+ });
68696
+
67872
68697
  // src/listener.ts
67873
68698
  var listener_exports = {};
67874
68699
  __export(listener_exports, {
@@ -67931,12 +68756,12 @@ async function isGatewayAvailableForHeartbeat(options) {
67931
68756
  }
67932
68757
  async function getHermesGatewayPluginStatus(options = {}) {
67933
68758
  const env = options.env ?? process.env;
67934
- const hermesHome = env.HERMES_HOME?.trim() || (0, import_node_path30.join)((0, import_node_os11.homedir)(), ".hermes");
67935
- const pluginYamlPath = (0, import_node_path30.join)(hermesHome, "plugins", "platforms", "okx-a2a", "plugin.yaml");
67936
- if (!(0, import_node_fs25.existsSync)(pluginYamlPath)) {
68759
+ const hermesHome = env.HERMES_HOME?.trim() || (0, import_node_path32.join)((0, import_node_os11.homedir)(), ".hermes");
68760
+ const pluginYamlPath = (0, import_node_path32.join)(hermesHome, "plugins", "platforms", "okx-a2a", "plugin.yaml");
68761
+ if (!(0, import_node_fs27.existsSync)(pluginYamlPath)) {
67937
68762
  return { enabled: false, reason: "plugin_yaml_missing", hermesHome, checkedPath: pluginYamlPath };
67938
68763
  }
67939
- const configPath = (0, import_node_path30.join)(hermesHome, "config.yaml");
68764
+ const configPath = (0, import_node_path32.join)(hermesHome, "config.yaml");
67940
68765
  let content2;
67941
68766
  try {
67942
68767
  content2 = await (0, import_promises13.readFile)(configPath, "utf8");
@@ -68097,6 +68922,7 @@ async function runListenerWithLock(options, paths) {
68097
68922
  logWithTimestamp("[okx-agent-task] user_attention watcher coordinator scanning SQLite watcher state");
68098
68923
  let stopping = false;
68099
68924
  const service = XmtpService.getInstance();
68925
+ const signalBuyerRuntime = new SignalTradingBuyerRuntime(options.homeDir);
68100
68926
  const agentRefreshCoordinator = new AgentRefreshCoordinator({
68101
68927
  lookup: (previousFingerprint) => listAllAgentsWithMetadata(previousFingerprint),
68102
68928
  refresh: () => service.refreshAgents(),
@@ -68127,6 +68953,9 @@ async function runListenerWithLock(options, paths) {
68127
68953
  },
68128
68954
  onSessionMessage: async (event) => {
68129
68955
  await enqueueAiSessionMessageDispatch({ commands, event });
68956
+ },
68957
+ onSignalTradingSignal: async (event) => {
68958
+ await signalBuyerRuntime.process(event.signal, event);
68130
68959
  }
68131
68960
  }),
68132
68961
  processOfflineMessage: (ctx, deps, replayOptions) => processOfflineFromCoreDeps(store, ctx, deps, {
@@ -68137,6 +68966,9 @@ async function runListenerWithLock(options, paths) {
68137
68966
  },
68138
68967
  onSessionMessage: async (event) => {
68139
68968
  await enqueueAiSessionMessageDispatch({ commands, event });
68969
+ },
68970
+ onSignalTradingSignal: async (event) => {
68971
+ await signalBuyerRuntime.process(event.signal, event);
68140
68972
  }
68141
68973
  }),
68142
68974
  notifySessionExpired: (command) => {
@@ -68168,12 +69000,12 @@ async function runListenerWithLock(options, paths) {
68168
69000
  });
68169
69001
  }
68170
69002
  });
68171
- service.setPluginVersion("0.2.9");
69003
+ service.setPluginVersion("0.2.10-beta-98689bff7a-260826143751");
68172
69004
  await service.init();
68173
69005
  const pluginVersionStatus = service.pluginVersionStatus;
68174
69006
  if (pluginVersionStatus.unavailable) {
68175
69007
  throw new Error(
68176
- `@okxweb3/a2a-node v${"0.2.9"} is below the required minimum v${pluginVersionStatus.minVersion}`
69008
+ `@okxweb3/a2a-node v${"0.2.10-beta-98689bff7a-260826143751"} is below the required minimum v${pluginVersionStatus.minVersion}`
68177
69009
  );
68178
69010
  }
68179
69011
  const systemConfig = service.getSystemConfig();
@@ -68201,7 +69033,7 @@ async function runListenerWithLock(options, paths) {
68201
69033
  onchainosAgentId: "*",
68202
69034
  reason: "system-config missing sentryDsn",
68203
69035
  pluginId: "@okxweb3/a2a-node",
68204
- pluginVersion: "0.2.9"
69036
+ pluginVersion: "0.2.10-beta-98689bff7a-260826143751"
68205
69037
  });
68206
69038
  }
68207
69039
  logWithTimestamp(
@@ -68631,15 +69463,15 @@ async function timeSettled(fn) {
68631
69463
  return { durationMs: Date.now() - startedAt, error };
68632
69464
  }
68633
69465
  }
68634
- var import_node_fs25, import_promises13, import_node_os11, import_node_path30, DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC, DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC, XMTP_CLIENT_RECYCLE_INTERVAL_ENV, HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS, AUTH_RECOVERY_PROBE_INTERVAL_MS, AUTH_RECOVERY_REFRESH_BACKOFF_MS, AgentRefreshAuthGate, AgentRefreshCoordinator, ListenerDeferredTaskScheduler, ListenerMaintenanceGate, UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY, SHUTDOWN_FORCE_RESOLVE_MS;
69466
+ var import_node_fs27, import_promises13, import_node_os11, import_node_path32, DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC, DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC, XMTP_CLIENT_RECYCLE_INTERVAL_ENV, HEARTBEAT_GATEWAY_CHECK_TIMEOUT_MS, AUTH_RECOVERY_PROBE_INTERVAL_MS, AUTH_RECOVERY_REFRESH_BACKOFF_MS, AgentRefreshAuthGate, AgentRefreshCoordinator, ListenerDeferredTaskScheduler, ListenerMaintenanceGate, UPGRADE_RECOMMENDATION_IDEMPOTENCY_KEY, SHUTDOWN_FORCE_RESOLVE_MS;
68635
69467
  var init_listener = __esm({
68636
69468
  "src/listener.ts"() {
68637
69469
  "use strict";
68638
69470
  init_log();
68639
- import_node_fs25 = require("node:fs");
69471
+ import_node_fs27 = require("node:fs");
68640
69472
  import_promises13 = require("node:fs/promises");
68641
69473
  import_node_os11 = require("node:os");
68642
- import_node_path30 = require("node:path");
69474
+ import_node_path32 = require("node:path");
68643
69475
  init_onchainos();
68644
69476
  init_system_config();
68645
69477
  init_offline_replay_capability();
@@ -68663,6 +69495,7 @@ var init_listener = __esm({
68663
69495
  init_sentry_logger();
68664
69496
  init_runtime_metadata();
68665
69497
  init_sentry_config();
69498
+ init_execution();
68666
69499
  DEFAULT_OFFLINE_REPLAY_INTERVAL_SEC = 300;
68667
69500
  DEFAULT_XMTP_CLIENT_RECYCLE_INTERVAL_SEC = 6 * 60 * 60;
68668
69501
  XMTP_CLIENT_RECYCLE_INTERVAL_ENV = "OKX_A2A_XMTP_CLIENT_RECYCLE_INTERVAL_SEC";
@@ -68884,9 +69717,9 @@ async function handleXmtpTestCommand(args, releaseInfo) {
68884
69717
  async function startXmtpTest(args, releaseInfo) {
68885
69718
  assertKnownOptions(args, /* @__PURE__ */ new Set(["--name", "--run-id", "--json"]));
68886
69719
  const paths = resolveTaskPaths();
68887
- const testsDir = (0, import_node_path31.join)(paths.homeDir, "xmtp-tests");
69720
+ const testsDir = (0, import_node_path33.join)(paths.homeDir, "xmtp-tests");
68888
69721
  await ensurePrivateDir(testsDir);
68889
- const active = await readJsonIfExists((0, import_node_path31.join)(testsDir, ACTIVE_FILE));
69722
+ const active = await readJsonIfExists((0, import_node_path33.join)(testsDir, ACTIVE_FILE));
68890
69723
  if (active?.runId) {
68891
69724
  throw new Error(
68892
69725
  `XMTP test ${active.runId} is already active. Run \`okx-a2a xmtp-test stop\` first.`
@@ -68925,7 +69758,7 @@ async function startXmtpTest(args, releaseInfo) {
68925
69758
  ...releaseInfo
68926
69759
  };
68927
69760
  await writeJson(files.manifestPath, manifest);
68928
- await writeJson((0, import_node_path31.join)(testsDir, ACTIVE_FILE), {
69761
+ await writeJson((0, import_node_path33.join)(testsDir, ACTIVE_FILE), {
68929
69762
  runId,
68930
69763
  startedAt: manifest.startedAt
68931
69764
  });
@@ -68948,7 +69781,7 @@ Run \`okx-a2a xmtp-test watch\` to open the realtime dashboard.`);
68948
69781
  async function stopXmtpTest(args) {
68949
69782
  assertKnownOptions(args, /* @__PURE__ */ new Set(["--json"]));
68950
69783
  const testsDir = resolveTestsDir();
68951
- const activePath = (0, import_node_path31.join)(testsDir, ACTIVE_FILE);
69784
+ const activePath = (0, import_node_path33.join)(testsDir, ACTIVE_FILE);
68952
69785
  const active = await readJsonIfExists(activePath);
68953
69786
  if (!active?.runId) {
68954
69787
  throw new Error("No active XMTP test.");
@@ -69242,17 +70075,17 @@ function formatJobEvent(event) {
69242
70075
  return `${timestamp} ${businessEvent.padEnd(34)} ${role}#${agent} ${source}${timings.length > 0 ? ` ${timings.join(" ")}` : ""}`;
69243
70076
  }
69244
70077
  function resolveTestsDir() {
69245
- return (0, import_node_path31.join)(resolveTaskPaths().homeDir, "xmtp-tests");
70078
+ return (0, import_node_path33.join)(resolveTaskPaths().homeDir, "xmtp-tests");
69246
70079
  }
69247
70080
  function resolveRunFiles(testsDir, runId) {
69248
70081
  validateRunId(runId);
69249
- const runDir = (0, import_node_path31.join)(testsDir, runId);
70082
+ const runDir = (0, import_node_path33.join)(testsDir, runId);
69250
70083
  return {
69251
70084
  testsDir,
69252
70085
  runDir,
69253
- manifestPath: (0, import_node_path31.join)(runDir, "manifest.json"),
69254
- eventsPath: (0, import_node_path31.join)(runDir, "events.jsonl"),
69255
- summaryPath: (0, import_node_path31.join)(runDir, "summary.json")
70086
+ manifestPath: (0, import_node_path33.join)(runDir, "manifest.json"),
70087
+ eventsPath: (0, import_node_path33.join)(runDir, "events.jsonl"),
70088
+ summaryPath: (0, import_node_path33.join)(runDir, "summary.json")
69256
70089
  };
69257
70090
  }
69258
70091
  async function resolveRequestedRunId(testsDir, args, preferActive = false) {
@@ -69260,7 +70093,7 @@ async function resolveRequestedRunId(testsDir, args, preferActive = false) {
69260
70093
  if (requested) {
69261
70094
  return validateRunId(requested);
69262
70095
  }
69263
- const active = await readJsonIfExists((0, import_node_path31.join)(testsDir, ACTIVE_FILE));
70096
+ const active = await readJsonIfExists((0, import_node_path33.join)(testsDir, ACTIVE_FILE));
69264
70097
  if (active?.runId && (preferActive || !args.includes("--latest"))) {
69265
70098
  return validateRunId(active.runId);
69266
70099
  }
@@ -69286,7 +70119,7 @@ async function findLatestRunId(testsDir) {
69286
70119
  continue;
69287
70120
  }
69288
70121
  const manifest = await readJsonIfExists(
69289
- (0, import_node_path31.join)(testsDir, entry.name, "manifest.json")
70122
+ (0, import_node_path33.join)(testsDir, entry.name, "manifest.json")
69290
70123
  );
69291
70124
  if (manifest?.runId && manifest.startedAt) {
69292
70125
  manifests.push(manifest);
@@ -69521,12 +70354,12 @@ function formatPercent(value) {
69521
70354
  function validTimestamp(value) {
69522
70355
  return typeof value === "string" && Number.isFinite(Date.parse(value));
69523
70356
  }
69524
- var import_promises14, import_node_path31, RUN_ID_PATTERN2, ACTIVE_FILE;
70357
+ var import_promises14, import_node_path33, RUN_ID_PATTERN2, ACTIVE_FILE;
69525
70358
  var init_xmtp_test_cli = __esm({
69526
70359
  "src/xmtp-test-cli.ts"() {
69527
70360
  "use strict";
69528
70361
  import_promises14 = require("node:fs/promises");
69529
- import_node_path31 = require("node:path");
70362
+ import_node_path33 = require("node:path");
69530
70363
  init_daemon();
69531
70364
  init_log_tail();
69532
70365
  init_paths();
@@ -69535,6 +70368,145 @@ var init_xmtp_test_cli = __esm({
69535
70368
  }
69536
70369
  });
69537
70370
 
70371
+ // src/signal-trading/cli.ts
70372
+ var cli_exports = {};
70373
+ __export(cli_exports, {
70374
+ handleSignalCommand: () => handleSignalCommand,
70375
+ printSignalUsage: () => printSignalUsage
70376
+ });
70377
+ function printSignalUsage() {
70378
+ console.log(`Usage: okx-a2a signal publish --service-id <id> (--file <path> | --stdin) [--json]
70379
+
70380
+ Commands:
70381
+ publish Validate a TradingSignalV1 JSON message and ask the daemon to deliver it
70382
+ to the configured job route for serviceId + subscriptionId.
70383
+
70384
+ Options:
70385
+ --service-id <id> Signal service whose configured subscribers should be notified.
70386
+ --file <path> Read one TradingSignalV1 JSON object from a file.
70387
+ --stdin Read one TradingSignalV1 JSON object from standard input.
70388
+ --json Print machine-readable command result JSON.
70389
+ `);
70390
+ }
70391
+ function readOption3(args, name) {
70392
+ const index2 = args.indexOf(name);
70393
+ return index2 < 0 ? void 0 : args[index2 + 1];
70394
+ }
70395
+ function hasFlag(args, name) {
70396
+ return args.includes(name);
70397
+ }
70398
+ function assertKnownPublishOptions(args) {
70399
+ const valueOptions = /* @__PURE__ */ new Set(["--service-id", "--file"]);
70400
+ const flags = /* @__PURE__ */ new Set(["--stdin", "--json", "--help", "-h"]);
70401
+ for (let index2 = 0; index2 < args.length; index2++) {
70402
+ const arg = args[index2];
70403
+ if (flags.has(arg)) {
70404
+ continue;
70405
+ }
70406
+ if (valueOptions.has(arg)) {
70407
+ if (!args[index2 + 1] || args[index2 + 1].startsWith("--")) {
70408
+ throw new Error(`signal publish option ${arg} requires a value`);
70409
+ }
70410
+ index2++;
70411
+ continue;
70412
+ }
70413
+ throw new Error(`signal publish unknown argument: ${arg}`);
70414
+ }
70415
+ }
70416
+ async function readStream(stream) {
70417
+ const chunks = [];
70418
+ for await (const chunk of stream) {
70419
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
70420
+ }
70421
+ return Buffer.concat(chunks).toString("utf8");
70422
+ }
70423
+ async function readSignalJson(args, stdin) {
70424
+ const filePath = readOption3(args, "--file");
70425
+ const fromStdin = hasFlag(args, "--stdin");
70426
+ if (!!filePath === fromStdin) {
70427
+ throw new Error("signal publish requires exactly one of --file <path> or --stdin");
70428
+ }
70429
+ const raw = filePath ? (0, import_node_fs28.readFileSync)(filePath, "utf8") : await readStream(stdin);
70430
+ if (!raw.trim()) {
70431
+ throw new Error("signal publish input is empty");
70432
+ }
70433
+ try {
70434
+ return JSON.parse(raw);
70435
+ } catch (error) {
70436
+ throw new Error(`signal publish input is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
70437
+ }
70438
+ }
70439
+ async function handleSignalCommand(args, options = {}) {
70440
+ const subcommand = args[0];
70441
+ if (!subcommand || subcommand === "help" || args.every((arg) => arg === "--help" || arg === "-h")) {
70442
+ printSignalUsage();
70443
+ return;
70444
+ }
70445
+ if (subcommand !== "publish") {
70446
+ throw new Error(`Unknown signal command: ${subcommand}`);
70447
+ }
70448
+ const commandArgs = args.slice(1);
70449
+ if (hasFlag(commandArgs, "--help") || hasFlag(commandArgs, "-h")) {
70450
+ printSignalUsage();
70451
+ return;
70452
+ }
70453
+ assertKnownPublishOptions(commandArgs);
70454
+ const serviceId = readOption3(commandArgs, "--service-id")?.trim();
70455
+ if (!serviceId) {
70456
+ throw new Error("signal publish requires --service-id <id>");
70457
+ }
70458
+ const signal = parseTradingSignalV1(
70459
+ await readSignalJson(commandArgs, options.stdin ?? process.stdin)
70460
+ );
70461
+ if (signal.serviceId !== serviceId) {
70462
+ throw new Error(
70463
+ `signal publish --service-id ${serviceId} does not match signal.serviceId ${signal.serviceId}`
70464
+ );
70465
+ }
70466
+ await ensureDaemonReady({ commandName: "signal publish", stderr: process.stderr });
70467
+ const commands = new CommandStore(options.homeDir);
70468
+ try {
70469
+ const command = commands.createSignalPublishCommand({ serviceId, signal });
70470
+ await commands.submit(command);
70471
+ const result = await commands.waitForResult(command.id, Number.POSITIVE_INFINITY);
70472
+ const json = hasFlag(commandArgs, "--json");
70473
+ if (!result) {
70474
+ throw new Error("signal publish finished without a daemon result");
70475
+ }
70476
+ if (!result.ok) {
70477
+ if (json) {
70478
+ console.log(JSON.stringify({ ok: false, commandId: command.id, error: result.error ?? null }));
70479
+ }
70480
+ throw new Error(result.error ?? "signal publish failed");
70481
+ }
70482
+ const payload = result.payload;
70483
+ if (json) {
70484
+ console.log(JSON.stringify({ ok: true, commandId: command.id, ...payload }));
70485
+ } else {
70486
+ console.log(
70487
+ `ok=true signal=${payload.signalId} service=${payload.serviceId} deliveries=${payload.deliveries.length}`
70488
+ );
70489
+ for (const delivery of payload.deliveries) {
70490
+ console.log(
70491
+ `jobId=${delivery.jobId} subscriptionId=${delivery.subscriptionId} toAgentId=${delivery.toAgentId} messageId=${delivery.messageId}`
70492
+ );
70493
+ }
70494
+ }
70495
+ } finally {
70496
+ commands.close();
70497
+ }
70498
+ }
70499
+ var import_node_fs28;
70500
+ var init_cli = __esm({
70501
+ "src/signal-trading/cli.ts"() {
70502
+ "use strict";
70503
+ import_node_fs28 = require("node:fs");
70504
+ init_daemon();
70505
+ init_command_store();
70506
+ init_protocol();
70507
+ }
70508
+ });
70509
+
69538
70510
  // ../../node_modules/@xmtp/content-type-primitives/dist/index.js
69539
70511
  var ContentTypeId;
69540
70512
  var init_dist5 = __esm({
@@ -80172,7 +81144,7 @@ var require_mock_interceptor = __commonJS({
80172
81144
  var require_mock_client = __commonJS({
80173
81145
  "../../node_modules/undici/lib/mock/mock-client.js"(exports2, module2) {
80174
81146
  "use strict";
80175
- var { promisify: promisify3 } = require("util");
81147
+ var { promisify: promisify4 } = require("util");
80176
81148
  var Client2 = require_client2();
80177
81149
  var { buildMockDispatch } = require_mock_utils();
80178
81150
  var {
@@ -80212,7 +81184,7 @@ var require_mock_client = __commonJS({
80212
81184
  return new MockInterceptor(opts, this[kDispatches]);
80213
81185
  }
80214
81186
  async [kClose]() {
80215
- await promisify3(this[kOriginalClose])();
81187
+ await promisify4(this[kOriginalClose])();
80216
81188
  this[kConnected] = 0;
80217
81189
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
80218
81190
  }
@@ -80225,7 +81197,7 @@ var require_mock_client = __commonJS({
80225
81197
  var require_mock_pool = __commonJS({
80226
81198
  "../../node_modules/undici/lib/mock/mock-pool.js"(exports2, module2) {
80227
81199
  "use strict";
80228
- var { promisify: promisify3 } = require("util");
81200
+ var { promisify: promisify4 } = require("util");
80229
81201
  var Pool = require_pool();
80230
81202
  var { buildMockDispatch } = require_mock_utils();
80231
81203
  var {
@@ -80265,7 +81237,7 @@ var require_mock_pool = __commonJS({
80265
81237
  return new MockInterceptor(opts, this[kDispatches]);
80266
81238
  }
80267
81239
  async [kClose]() {
80268
- await promisify3(this[kOriginalClose])();
81240
+ await promisify4(this[kOriginalClose])();
80269
81241
  this[kConnected] = 0;
80270
81242
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
80271
81243
  }
@@ -86912,7 +87884,7 @@ var require_fetch_pb = __commonJS({
86912
87884
  }
86913
87885
  });
86914
87886
  }
86915
- function isPlainObject4(value) {
87887
+ function isPlainObject6(value) {
86916
87888
  const isObject = Object.prototype.toString.call(value).slice(8, -1) === "Object";
86917
87889
  const isObjLike = value !== null && isObject;
86918
87890
  if (!isObjLike || !isObject) {
@@ -86935,7 +87907,7 @@ var require_fetch_pb = __commonJS({
86935
87907
  const isNonEmptyPrimitiveArray = Array.isArray(value) && value.every((v) => isPrimitive(v)) && value.length > 0;
86936
87908
  const isNonZeroValuePrimitive = isPrimitive(value) && !isZeroValuePrimitive(value);
86937
87909
  let objectToMerge = {};
86938
- if (isPlainObject4(value)) {
87910
+ if (isPlainObject6(value)) {
86939
87911
  objectToMerge = flattenRequestPayload(value, newPath);
86940
87912
  } else if (isNonZeroValuePrimitive || isNonEmptyPrimitiveArray) {
86941
87913
  objectToMerge = { [newPath]: value };
@@ -112504,10 +113476,10 @@ var require_node4 = __commonJS({
112504
113476
 
112505
113477
  // ../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js
112506
113478
  async function encrypt(plain, secret, additionalData) {
112507
- const salt = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(KDFSaltSize));
112508
- const nonce = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(AESGCMNonceSize));
113479
+ const salt = import_node_crypto18.webcrypto.getRandomValues(new Uint8Array(KDFSaltSize));
113480
+ const nonce = import_node_crypto18.webcrypto.getRandomValues(new Uint8Array(AESGCMNonceSize));
112509
113481
  const key = await hkdf(secret, salt);
112510
- const encrypted = await import_node_crypto16.webcrypto.subtle.encrypt(aesGcmParams(nonce), key, plain);
113482
+ const encrypted = await import_node_crypto18.webcrypto.subtle.encrypt(aesGcmParams(nonce), key, plain);
112511
113483
  return new Ciphertext({
112512
113484
  aes256GcmHkdfSha256: {
112513
113485
  payload: new Uint8Array(encrypted),
@@ -112521,7 +113493,7 @@ async function decrypt(encrypted, secret, additionalData) {
112521
113493
  throw new Error("invalid payload ciphertext");
112522
113494
  }
112523
113495
  const key = await hkdf(secret, encrypted.aes256GcmHkdfSha256.hkdfSalt);
112524
- const decrypted = await import_node_crypto16.webcrypto.subtle.decrypt(aesGcmParams(encrypted.aes256GcmHkdfSha256.gcmNonce), key, encrypted.aes256GcmHkdfSha256.payload);
113496
+ const decrypted = await import_node_crypto18.webcrypto.subtle.decrypt(aesGcmParams(encrypted.aes256GcmHkdfSha256.gcmNonce), key, encrypted.aes256GcmHkdfSha256.payload);
112525
113497
  return new Uint8Array(decrypted);
112526
113498
  }
112527
113499
  function aesGcmParams(nonce, additionalData) {
@@ -112532,18 +113504,18 @@ function aesGcmParams(nonce, additionalData) {
112532
113504
  return spec;
112533
113505
  }
112534
113506
  async function hkdf(secret, salt) {
112535
- const key = await import_node_crypto16.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
113507
+ const key = await import_node_crypto18.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
112536
113508
  "deriveKey"
112537
113509
  ]);
112538
- return import_node_crypto16.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt, info: hkdfNoInfo }, key, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
113510
+ return import_node_crypto18.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt, info: hkdfNoInfo }, key, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
112539
113511
  }
112540
- var import_proto, import_node_crypto16, ContentTypeAttachment, AttachmentCodec, KDFSaltSize, AESGCMNonceSize, AESGCMTagLength, Ciphertext, hkdfNoInfo, ContentTypeRemoteAttachment, RemoteAttachmentCodec;
113512
+ var import_proto, import_node_crypto18, ContentTypeAttachment, AttachmentCodec, KDFSaltSize, AESGCMNonceSize, AESGCMTagLength, Ciphertext, hkdfNoInfo, ContentTypeRemoteAttachment, RemoteAttachmentCodec;
112541
113513
  var init_dist6 = __esm({
112542
113514
  "../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js"() {
112543
113515
  init_dist5();
112544
113516
  init_secp256k12();
112545
113517
  import_proto = __toESM(require_node4(), 1);
112546
- import_node_crypto16 = require("node:crypto");
113518
+ import_node_crypto18 = require("node:crypto");
112547
113519
  ContentTypeAttachment = new ContentTypeId({
112548
113520
  authorityId: "xmtp.org",
112549
113521
  typeId: "attachment",
@@ -112623,7 +113595,7 @@ var init_dist6 = __esm({
112623
113595
  if (payload.length === 0) {
112624
113596
  throw new Error(`no payload for remote attachment at ${remoteAttachment.url}`);
112625
113597
  }
112626
- const digestBytes = new Uint8Array(await import_node_crypto16.webcrypto.subtle.digest("SHA-256", payload));
113598
+ const digestBytes = new Uint8Array(await import_node_crypto18.webcrypto.subtle.digest("SHA-256", payload));
112627
113599
  const digest = etc.bytesToHex(digestBytes);
112628
113600
  if (digest !== remoteAttachment.contentDigest) {
112629
113601
  throw new Error("content digest does not match");
@@ -112647,7 +113619,7 @@ var init_dist6 = __esm({
112647
113619
  return codec.decode(encodedContent, codecRegistry);
112648
113620
  }
112649
113621
  static async encodeEncrypted(content$1, codec) {
112650
- const secret = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(32));
113622
+ const secret = import_node_crypto18.webcrypto.getRandomValues(new Uint8Array(32));
112651
113623
  const encodedContent = import_proto.content.EncodedContent.encode(codec.encode(content$1, {
112652
113624
  codecFor() {
112653
113625
  return void 0;
@@ -112660,7 +113632,7 @@ var init_dist6 = __esm({
112660
113632
  if (!salt || !nonce || !payload) {
112661
113633
  throw new Error("missing encryption key");
112662
113634
  }
112663
- const digestBytes = new Uint8Array(await import_node_crypto16.webcrypto.subtle.digest("SHA-256", payload));
113635
+ const digestBytes = new Uint8Array(await import_node_crypto18.webcrypto.subtle.digest("SHA-256", payload));
112664
113636
  const digest = etc.bytesToHex(digestBytes);
112665
113637
  return {
112666
113638
  digest,
@@ -112715,9 +113687,9 @@ var init_dist6 = __esm({
112715
113687
 
112716
113688
  // ../core/src/file-upload-safety.ts
112717
113689
  function getUnsafeFileUploadReason(filePath, sensitiveUploadReg = []) {
112718
- const expanded = (0, import_node_path32.resolve)(expandHome(filePath));
112719
- const target = (0, import_node_fs26.realpathSync)(expanded);
112720
- const targetName = (0, import_node_path32.basename)(target);
113690
+ const expanded = (0, import_node_path34.resolve)(expandHome(filePath));
113691
+ const target = (0, import_node_fs29.realpathSync)(expanded);
113692
+ const targetName = (0, import_node_path34.basename)(target);
112721
113693
  if (targetName === ".env" || targetName.startsWith(".env.")) {
112722
113694
  return ".env";
112723
113695
  }
@@ -112730,13 +113702,13 @@ function getUnsafeFileUploadReason(filePath, sensitiveUploadReg = []) {
112730
113702
  return null;
112731
113703
  }
112732
113704
  for (const dir of SENSITIVE_HOME_DIRS) {
112733
- const sensitiveDir = safeRealpath((0, import_node_path32.join)(home, dir));
113705
+ const sensitiveDir = safeRealpath((0, import_node_path34.join)(home, dir));
112734
113706
  if (sensitiveDir && isPathInside(target, sensitiveDir)) {
112735
113707
  return `~/${dir}`;
112736
113708
  }
112737
113709
  }
112738
113710
  for (const file of SENSITIVE_HOME_FILES) {
112739
- const sensitiveFile = safeRealpath((0, import_node_path32.join)(home, file));
113711
+ const sensitiveFile = safeRealpath((0, import_node_path34.join)(home, file));
112740
113712
  if (sensitiveFile && target === sensitiveFile) {
112741
113713
  return `~/${file}`;
112742
113714
  }
@@ -112764,27 +113736,27 @@ function expandHome(filePath) {
112764
113736
  if (filePath === "~") {
112765
113737
  return (0, import_node_os12.homedir)();
112766
113738
  }
112767
- if (filePath.startsWith(`~${import_node_path32.sep}`)) {
112768
- return (0, import_node_path32.join)((0, import_node_os12.homedir)(), filePath.slice(2));
113739
+ if (filePath.startsWith(`~${import_node_path34.sep}`)) {
113740
+ return (0, import_node_path34.join)((0, import_node_os12.homedir)(), filePath.slice(2));
112769
113741
  }
112770
113742
  return filePath;
112771
113743
  }
112772
113744
  function safeRealpath(path2) {
112773
- if (!(0, import_node_fs26.existsSync)(path2)) {
113745
+ if (!(0, import_node_fs29.existsSync)(path2)) {
112774
113746
  return null;
112775
113747
  }
112776
- return (0, import_node_fs26.realpathSync)(path2);
113748
+ return (0, import_node_fs29.realpathSync)(path2);
112777
113749
  }
112778
113750
  function isPathInside(target, dir) {
112779
- return target === dir || target.startsWith(`${dir}${import_node_path32.sep}`);
113751
+ return target === dir || target.startsWith(`${dir}${import_node_path34.sep}`);
112780
113752
  }
112781
- var import_node_fs26, import_node_os12, import_node_path32, SENSITIVE_HOME_DIRS, SENSITIVE_HOME_FILES, UNSAFE_FILE_UPLOAD_MESSAGE;
113753
+ var import_node_fs29, import_node_os12, import_node_path34, SENSITIVE_HOME_DIRS, SENSITIVE_HOME_FILES, UNSAFE_FILE_UPLOAD_MESSAGE;
112782
113754
  var init_file_upload_safety = __esm({
112783
113755
  "../core/src/file-upload-safety.ts"() {
112784
113756
  "use strict";
112785
- import_node_fs26 = require("node:fs");
113757
+ import_node_fs29 = require("node:fs");
112786
113758
  import_node_os12 = require("node:os");
112787
- import_node_path32 = require("node:path");
113759
+ import_node_path34 = require("node:path");
112788
113760
  SENSITIVE_HOME_DIRS = [
112789
113761
  ".ssh",
112790
113762
  ".gnupg",
@@ -112792,7 +113764,7 @@ var init_file_upload_safety = __esm({
112792
113764
  ".azure",
112793
113765
  ".kube",
112794
113766
  ".docker",
112795
- (0, import_node_path32.join)(".config", "gcloud")
113767
+ (0, import_node_path34.join)(".config", "gcloud")
112796
113768
  ];
112797
113769
  SENSITIVE_HOME_FILES = [
112798
113770
  ".npmrc",
@@ -112821,8 +113793,8 @@ async function handleFileCommand(args) {
112821
113793
  filePath: readRequiredOption(rest, "--file-path"),
112822
113794
  agentId: readRequiredOption(rest, "--agent-id"),
112823
113795
  jobId: readRequiredOption(rest, "--job-id"),
112824
- filename: readOption3(rest, "--filename"),
112825
- mimeType: readOption3(rest, "--mime-type")
113796
+ filename: readOption4(rest, "--filename"),
113797
+ mimeType: readOption4(rest, "--mime-type")
112826
113798
  });
112827
113799
  return;
112828
113800
  }
@@ -112834,7 +113806,7 @@ async function handleFileCommand(args) {
112834
113806
  salt: readRequiredOption(rest, "--salt"),
112835
113807
  nonce: readRequiredOption(rest, "--nonce"),
112836
113808
  secret: readRequiredOption(rest, "--secret"),
112837
- filename: readOption3(rest, "--filename")
113809
+ filename: readOption4(rest, "--filename")
112838
113810
  });
112839
113811
  return;
112840
113812
  }
@@ -112854,7 +113826,7 @@ function hasHelpFlag(args) {
112854
113826
  return args.some((arg) => arg === "-h" || arg === "--help" || arg === "help");
112855
113827
  }
112856
113828
  async function uploadFile(params) {
112857
- const filename = params.filename || (0, import_node_path33.basename)(params.filePath);
113829
+ const filename = params.filename || (0, import_node_path35.basename)(params.filePath);
112858
113830
  const mimeType = params.mimeType || "application/octet-stream";
112859
113831
  const uploadConfig = readUploadSystemConfig();
112860
113832
  const unsafeReason = getUnsafeFileUploadReason(params.filePath, uploadConfig.sensitiveUploadReg);
@@ -112870,16 +113842,16 @@ async function uploadFile(params) {
112870
113842
  return;
112871
113843
  }
112872
113844
  const maxFileSizeBytes = uploadConfig.maxFileSizeBytes;
112873
- const fileSize = (0, import_node_fs27.statSync)(params.filePath).size;
113845
+ const fileSize = (0, import_node_fs30.statSync)(params.filePath).size;
112874
113846
  if (fileSize > maxFileSizeBytes) {
112875
113847
  throw new Error(formatFileTooLargeMessage(maxFileSizeBytes));
112876
113848
  }
112877
- const data = (0, import_node_fs27.readFileSync)(params.filePath);
113849
+ const data = (0, import_node_fs30.readFileSync)(params.filePath);
112878
113850
  const attachment = { filename, mimeType, data: new Uint8Array(data) };
112879
113851
  const encrypted = await RemoteAttachmentCodec.encodeEncrypted(attachment, new AttachmentCodec());
112880
113852
  ensureFileDirs();
112881
- const encryptedPath = (0, import_node_path33.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto17.randomUUID)()}.enc`);
112882
- (0, import_node_fs27.writeFileSync)(encryptedPath, encrypted.payload);
113853
+ const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto19.randomUUID)()}.enc`);
113854
+ (0, import_node_fs30.writeFileSync)(encryptedPath, encrypted.payload);
112883
113855
  try {
112884
113856
  const stdout = runOnchainos([
112885
113857
  "agent",
@@ -112915,14 +113887,14 @@ async function uploadFile(params) {
112915
113887
  }, null, 2));
112916
113888
  } finally {
112917
113889
  try {
112918
- (0, import_node_fs27.unlinkSync)(encryptedPath);
113890
+ (0, import_node_fs30.unlinkSync)(encryptedPath);
112919
113891
  } catch {
112920
113892
  }
112921
113893
  }
112922
113894
  }
112923
113895
  async function downloadFile(params) {
112924
113896
  ensureFileDirs();
112925
- const encryptedPath = (0, import_node_path33.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto17.randomUUID)()}.enc`);
113897
+ const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto19.randomUUID)()}.enc`);
112926
113898
  try {
112927
113899
  const stdout = runOnchainos([
112928
113900
  "agent",
@@ -112946,8 +113918,8 @@ async function downloadFile(params) {
112946
113918
  }));
112947
113919
  throw new Error(`file download failed: ${stdout}`);
112948
113920
  }
112949
- const payload = new Uint8Array((0, import_node_fs27.readFileSync)(encryptedPath));
112950
- const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
113921
+ const payload = new Uint8Array((0, import_node_fs30.readFileSync)(encryptedPath));
113922
+ const digestBytes = new Uint8Array(await import_node_crypto19.webcrypto.subtle.digest("SHA-256", payload));
112951
113923
  const actualDigest = Array.from(digestBytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
112952
113924
  if (actualDigest !== params.digest) {
112953
113925
  throw new Error(`file download digest verification failed: expected=${params.digest}, actual=${actualDigest}`);
@@ -112955,15 +113927,15 @@ async function downloadFile(params) {
112955
113927
  const decryptedBytes = await decryptAttachmentPayload(payload, params);
112956
113928
  const encodedContent = import_proto2.content.EncodedContent.decode(decryptedBytes);
112957
113929
  const attachment = new AttachmentCodec().decode(encodedContent);
112958
- const outputFilename = params.filename || attachment.filename || `${(0, import_node_crypto17.randomUUID)()}.bin`;
113930
+ const outputFilename = params.filename || attachment.filename || `${(0, import_node_crypto19.randomUUID)()}.bin`;
112959
113931
  const outputDir = DOWNLOADS_DIR;
112960
113932
  ensureA2aTaskDir(outputDir);
112961
- const outputPath = (0, import_node_path33.resolve)(outputDir, (0, import_node_path33.basename)(outputFilename));
112962
- (0, import_node_fs27.writeFileSync)(outputPath, attachment.data);
113933
+ const outputPath = (0, import_node_path35.resolve)(outputDir, (0, import_node_path35.basename)(outputFilename));
113934
+ (0, import_node_fs30.writeFileSync)(outputPath, attachment.data);
112963
113935
  console.log(outputPath);
112964
113936
  } finally {
112965
113937
  try {
112966
- (0, import_node_fs27.unlinkSync)(encryptedPath);
113938
+ (0, import_node_fs30.unlinkSync)(encryptedPath);
112967
113939
  } catch {
112968
113940
  }
112969
113941
  }
@@ -112972,15 +113944,15 @@ async function decryptAttachmentPayload(payload, params) {
112972
113944
  const secretBytes = new Uint8Array(Buffer.from(params.secret, "base64"));
112973
113945
  const saltBytes = new Uint8Array(Buffer.from(params.salt, "base64"));
112974
113946
  const nonceBytes = new Uint8Array(Buffer.from(params.nonce, "base64"));
112975
- const hkdfKey = await import_node_crypto17.webcrypto.subtle.importKey("raw", secretBytes, "HKDF", false, ["deriveKey"]);
112976
- const aesKey = await import_node_crypto17.webcrypto.subtle.deriveKey(
113947
+ const hkdfKey = await import_node_crypto19.webcrypto.subtle.importKey("raw", secretBytes, "HKDF", false, ["deriveKey"]);
113948
+ const aesKey = await import_node_crypto19.webcrypto.subtle.deriveKey(
112977
113949
  { name: "HKDF", hash: "SHA-256", salt: saltBytes, info: new Uint8Array().buffer },
112978
113950
  hkdfKey,
112979
113951
  { name: "AES-GCM", length: 256 },
112980
113952
  false,
112981
113953
  ["decrypt"]
112982
113954
  );
112983
- return new Uint8Array(await import_node_crypto17.webcrypto.subtle.decrypt({ name: "AES-GCM", iv: nonceBytes }, aesKey, toArrayBuffer(payload)));
113955
+ return new Uint8Array(await import_node_crypto19.webcrypto.subtle.decrypt({ name: "AES-GCM", iv: nonceBytes }, aesKey, toArrayBuffer(payload)));
112984
113956
  }
112985
113957
  function toArrayBuffer(bytes) {
112986
113958
  return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
@@ -113060,7 +114032,7 @@ function readUploadSystemConfig() {
113060
114032
  const res = parseCliJson2(stdout, "system-config");
113061
114033
  if (res.data && typeof res.data === "object") {
113062
114034
  ensureA2aTaskDir(OKX_A2A_PATHS.xmtpDir);
113063
- (0, import_node_fs27.writeFileSync)(SYSTEM_CONFIG_PATH, JSON.stringify(res.data));
114035
+ (0, import_node_fs30.writeFileSync)(SYSTEM_CONFIG_PATH, JSON.stringify(res.data));
113064
114036
  }
113065
114037
  return parseUploadSystemConfig(res.data ?? {});
113066
114038
  } catch {
@@ -113083,10 +114055,10 @@ function fileCliSentryExtra(operation, reason, extra = {}) {
113083
114055
  }
113084
114056
  function readSystemConfigFromCache() {
113085
114057
  try {
113086
- if (!(0, import_node_fs27.existsSync)(SYSTEM_CONFIG_PATH)) {
114058
+ if (!(0, import_node_fs30.existsSync)(SYSTEM_CONFIG_PATH)) {
113087
114059
  return null;
113088
114060
  }
113089
- return JSON.parse((0, import_node_fs27.readFileSync)(SYSTEM_CONFIG_PATH, "utf8"));
114061
+ return JSON.parse((0, import_node_fs30.readFileSync)(SYSTEM_CONFIG_PATH, "utf8"));
113090
114062
  } catch {
113091
114063
  return null;
113092
114064
  }
@@ -113106,7 +114078,7 @@ function readCommand(envName, fallback) {
113106
114078
  const raw = process.env[envName] || fallback;
113107
114079
  return raw.match(/(?:[^\s"]+|"[^"]*")+/g)?.map((part) => part.replace(/^"|"$/g, "")) || [fallback];
113108
114080
  }
113109
- function readOption3(args, name) {
114081
+ function readOption4(args, name) {
113110
114082
  const index2 = args.indexOf(name);
113111
114083
  if (index2 === -1) {
113112
114084
  return void 0;
@@ -113114,20 +114086,20 @@ function readOption3(args, name) {
113114
114086
  return args[index2 + 1];
113115
114087
  }
113116
114088
  function readRequiredOption(args, name) {
113117
- const value = readOption3(args, name);
114089
+ const value = readOption4(args, name);
113118
114090
  if (!value) {
113119
114091
  throw new Error(`${name} is required`);
113120
114092
  }
113121
114093
  return value;
113122
114094
  }
113123
- var import_node_crypto17, import_node_fs27, import_node_path33, import_proto2, OKX_A2A_PATHS, OKX_A2A_HOME_DIR, FILE_WORK_DIR, DOWNLOADS_DIR, SYSTEM_CONFIG_PATH;
114095
+ var import_node_crypto19, import_node_fs30, import_node_path35, import_proto2, OKX_A2A_PATHS, OKX_A2A_HOME_DIR, FILE_WORK_DIR, DOWNLOADS_DIR, SYSTEM_CONFIG_PATH;
113124
114096
  var init_file_cli = __esm({
113125
114097
  "src/file-cli.ts"() {
113126
114098
  "use strict";
113127
114099
  init_win_spawn();
113128
- import_node_crypto17 = require("node:crypto");
113129
- import_node_fs27 = require("node:fs");
113130
- import_node_path33 = require("node:path");
114100
+ import_node_crypto19 = require("node:crypto");
114101
+ import_node_fs30 = require("node:fs");
114102
+ import_node_path35 = require("node:path");
113131
114103
  init_dist6();
113132
114104
  import_proto2 = __toESM(require_node4());
113133
114105
  init_a2a_paths();
@@ -113138,7 +114110,7 @@ var init_file_cli = __esm({
113138
114110
  OKX_A2A_HOME_DIR = OKX_A2A_PATHS.homeDir;
113139
114111
  FILE_WORK_DIR = process.env.OKX_A2A_FILE_WORK_DIR || OKX_A2A_PATHS.filesDir;
113140
114112
  DOWNLOADS_DIR = process.env.OKX_A2A_DOWNLOADS_DIR || OKX_A2A_PATHS.downloadsDir;
113141
- SYSTEM_CONFIG_PATH = (0, import_node_path33.resolve)(OKX_A2A_PATHS.xmtpDir, "system-config.json");
114113
+ SYSTEM_CONFIG_PATH = (0, import_node_path35.resolve)(OKX_A2A_PATHS.xmtpDir, "system-config.json");
113142
114114
  }
113143
114115
  });
113144
114116
 
@@ -115701,7 +116673,7 @@ function isPostjectRunnable() {
115701
116673
  function resolvePostjectCommand() {
115702
116674
  try {
115703
116675
  const cliPath = (0, import_node_module.createRequire)(__filename).resolve("postject/dist/cli.js");
115704
- if ((0, import_node_fs28.existsSync)(cliPath)) {
116676
+ if ((0, import_node_fs31.existsSync)(cliPath)) {
115705
116677
  return { command: process.execPath, prefixArgs: [cliPath] };
115706
116678
  }
115707
116679
  } catch {
@@ -115772,37 +116744,37 @@ function buildSeaConfig(entryPath, blobPath) {
115772
116744
  }
115773
116745
  async function installWindowsNativeLauncher(options) {
115774
116746
  const nodeExe = options.nodeExe ?? process.execPath;
115775
- if (!(0, import_node_fs28.existsSync)(options.cliPath)) {
116747
+ if (!(0, import_node_fs31.existsSync)(options.cliPath)) {
115776
116748
  throw new Error(`cannot build okx-a2a.exe: CLI entry not found at ${options.cliPath}`);
115777
116749
  }
115778
- if (!(0, import_node_fs28.existsSync)(nodeExe)) {
116750
+ if (!(0, import_node_fs31.existsSync)(nodeExe)) {
115779
116751
  throw new Error(`cannot build okx-a2a.exe: node executable not found at ${nodeExe}`);
115780
116752
  }
115781
- const exePath = (0, import_node_path34.join)(options.targetDir, NATIVE_LAUNCHER_EXE_NAME);
115782
- (0, import_node_fs28.mkdirSync)(options.targetDir, { recursive: true });
115783
- const work = (0, import_node_fs28.mkdtempSync)((0, import_node_path34.join)((0, import_node_os13.tmpdir)(), "okx-a2a-sea-"));
116753
+ const exePath = (0, import_node_path36.join)(options.targetDir, NATIVE_LAUNCHER_EXE_NAME);
116754
+ (0, import_node_fs31.mkdirSync)(options.targetDir, { recursive: true });
116755
+ const work = (0, import_node_fs31.mkdtempSync)((0, import_node_path36.join)((0, import_node_os13.tmpdir)(), "okx-a2a-sea-"));
115784
116756
  try {
115785
- const entryPath = (0, import_node_path34.join)(work, "launcher-entry.js");
115786
- const blobPath = (0, import_node_path34.join)(work, "okx-a2a.blob");
115787
- const configPath = (0, import_node_path34.join)(work, "sea-config.json");
115788
- (0, import_node_fs28.writeFileSync)(entryPath, buildLauncherEntryJs(options.cliPath), "utf8");
115789
- (0, import_node_fs28.writeFileSync)(configPath, buildSeaConfig(entryPath, blobPath), "utf8");
115790
- (0, import_node_child_process9.execFileSync)(nodeExe, ["--experimental-sea-config", configPath], {
116757
+ const entryPath = (0, import_node_path36.join)(work, "launcher-entry.js");
116758
+ const blobPath = (0, import_node_path36.join)(work, "okx-a2a.blob");
116759
+ const configPath = (0, import_node_path36.join)(work, "sea-config.json");
116760
+ (0, import_node_fs31.writeFileSync)(entryPath, buildLauncherEntryJs(options.cliPath), "utf8");
116761
+ (0, import_node_fs31.writeFileSync)(configPath, buildSeaConfig(entryPath, blobPath), "utf8");
116762
+ (0, import_node_child_process10.execFileSync)(nodeExe, ["--experimental-sea-config", configPath], {
115791
116763
  stdio: "ignore",
115792
116764
  windowsHide: true
115793
116765
  });
115794
- (0, import_node_fs28.copyFileSync)(nodeExe, exePath);
116766
+ (0, import_node_fs31.copyFileSync)(nodeExe, exePath);
115795
116767
  const isMac = process.platform === "darwin";
115796
116768
  if (isMac) {
115797
116769
  try {
115798
- (0, import_node_child_process9.execFileSync)("codesign", ["--remove-signature", exePath], { stdio: "ignore" });
116770
+ (0, import_node_child_process10.execFileSync)("codesign", ["--remove-signature", exePath], { stdio: "ignore" });
115799
116771
  } catch {
115800
116772
  }
115801
116773
  }
115802
116774
  injectSeaBlob(exePath, blobPath, isMac);
115803
116775
  if (isMac) {
115804
116776
  try {
115805
- (0, import_node_child_process9.execFileSync)("codesign", ["--sign", "-", exePath], { stdio: "ignore" });
116777
+ (0, import_node_child_process10.execFileSync)("codesign", ["--sign", "-", exePath], { stdio: "ignore" });
115806
116778
  } catch {
115807
116779
  }
115808
116780
  }
@@ -115811,19 +116783,19 @@ async function installWindowsNativeLauncher(options) {
115811
116783
  );
115812
116784
  return { exePath, cliPath: options.cliPath, nodeExe };
115813
116785
  } finally {
115814
- (0, import_node_fs28.rmSync)(work, { recursive: true, force: true });
116786
+ (0, import_node_fs31.rmSync)(work, { recursive: true, force: true });
115815
116787
  }
115816
116788
  }
115817
- function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 = import_node_fs28.existsSync) {
116789
+ function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 = import_node_fs31.existsSync) {
115818
116790
  const dirs = pathValue.split(";").map((d) => d.trim()).filter(Boolean);
115819
116791
  if (appData) {
115820
- dirs.push((0, import_node_path34.join)(appData, "npm"));
116792
+ dirs.push((0, import_node_path36.join)(appData, "npm"));
115821
116793
  }
115822
116794
  if (userProfile) {
115823
- dirs.push((0, import_node_path34.join)(userProfile, ".local", "bin"));
116795
+ dirs.push((0, import_node_path36.join)(userProfile, ".local", "bin"));
115824
116796
  }
115825
116797
  for (const dir of dirs) {
115826
- const candidate = (0, import_node_path34.join)(dir, NATIVE_LAUNCHER_EXE_NAME);
116798
+ const candidate = (0, import_node_path36.join)(dir, NATIVE_LAUNCHER_EXE_NAME);
115827
116799
  if (fileExists2(candidate)) {
115828
116800
  return candidate;
115829
116801
  }
@@ -115832,11 +116804,11 @@ function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2
115832
116804
  }
115833
116805
  function resolveRunningCliPath() {
115834
116806
  const fromArgv = process.argv[1];
115835
- if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs28.existsSync)(fromArgv)) {
116807
+ if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs31.existsSync)(fromArgv)) {
115836
116808
  return fromArgv;
115837
116809
  }
115838
- const beside = (0, import_node_path34.join)(__dirname, "cli.js");
115839
- if ((0, import_node_fs28.existsSync)(beside)) {
116810
+ const beside = (0, import_node_path36.join)(__dirname, "cli.js");
116811
+ if ((0, import_node_fs31.existsSync)(beside)) {
115840
116812
  return beside;
115841
116813
  }
115842
116814
  if (fromArgv) {
@@ -115854,19 +116826,19 @@ async function ensureWindowsNativeLauncher(options = {}) {
115854
116826
  if (existing) {
115855
116827
  return { exePath: existing, installed: false };
115856
116828
  }
115857
- const targetDir = env.APPDATA ? (0, import_node_path34.join)(env.APPDATA, "npm") : (0, import_node_path34.join)(env.USERPROFILE ?? (0, import_node_os13.homedir)(), ".local", "bin");
116829
+ const targetDir = env.APPDATA ? (0, import_node_path36.join)(env.APPDATA, "npm") : (0, import_node_path36.join)(env.USERPROFILE ?? (0, import_node_os13.homedir)(), ".local", "bin");
115858
116830
  const result = await installWindowsNativeLauncher({ cliPath: resolveRunningCliPath(), targetDir });
115859
116831
  return { exePath: result.exePath, installed: true };
115860
116832
  }
115861
- var import_node_child_process9, import_node_fs28, import_node_module, import_node_os13, import_node_path34, SEA_SENTINEL_FUSE, NATIVE_LAUNCHER_EXE_NAME, POSTJECT_SPEC, POSTJECT_BIN;
116833
+ var import_node_child_process10, import_node_fs31, import_node_module, import_node_os13, import_node_path36, SEA_SENTINEL_FUSE, NATIVE_LAUNCHER_EXE_NAME, POSTJECT_SPEC, POSTJECT_BIN;
115862
116834
  var init_win_native_launcher = __esm({
115863
116835
  "src/win-native-launcher.ts"() {
115864
116836
  "use strict";
115865
- import_node_child_process9 = require("node:child_process");
115866
- import_node_fs28 = require("node:fs");
116837
+ import_node_child_process10 = require("node:child_process");
116838
+ import_node_fs31 = require("node:fs");
115867
116839
  import_node_module = require("node:module");
115868
116840
  import_node_os13 = require("node:os");
115869
- import_node_path34 = require("node:path");
116841
+ import_node_path36 = require("node:path");
115870
116842
  init_win_compat();
115871
116843
  init_win_spawn();
115872
116844
  SEA_SENTINEL_FUSE = "NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2";
@@ -115958,13 +116930,13 @@ function parseUpdateArgs(args) {
115958
116930
  const target = hasExplicitTarget ? first : null;
115959
116931
  const optionArgs = hasExplicitTarget ? args.slice(1) : args;
115960
116932
  assertOnlyKnownUpdateOptions(optionArgs);
115961
- const requestedRelease = readOption4(optionArgs, "--release");
116933
+ const requestedRelease = readOption5(optionArgs, "--release");
115962
116934
  const release = requestedRelease ?? "latest";
115963
116935
  if (!isSupportedRelease(release)) {
115964
116936
  throw new Error(`unsupported release: ${release}`);
115965
116937
  }
115966
- const restart = hasFlag(optionArgs, "--restart");
115967
- const yes = hasFlag(optionArgs, "--yes");
116938
+ const restart = hasFlag2(optionArgs, "--restart");
116939
+ const yes = hasFlag2(optionArgs, "--yes");
115968
116940
  if (restart && !yes) {
115969
116941
  throw new Error("update --restart requires --yes");
115970
116942
  }
@@ -115982,12 +116954,12 @@ function parseSetupArgs(args) {
115982
116954
  const target = hasExplicitTarget ? first : null;
115983
116955
  const optionArgs = hasExplicitTarget ? args.slice(1) : args;
115984
116956
  assertOnlyKnownUpdateOptions(optionArgs, "setup");
115985
- const requestedRelease = readOption4(optionArgs, "--release");
116957
+ const requestedRelease = readOption5(optionArgs, "--release");
115986
116958
  const release = requestedRelease ?? "latest";
115987
116959
  if (!isSupportedRelease(release)) {
115988
116960
  throw new Error(`unsupported release: ${release}`);
115989
116961
  }
115990
- const json = hasFlag(optionArgs, "--json");
116962
+ const json = hasFlag2(optionArgs, "--json");
115991
116963
  return { target, release, releaseExplicit: requestedRelease !== void 0, json };
115992
116964
  }
115993
116965
  function buildNpmPackageSpec(target, release) {
@@ -116050,7 +117022,7 @@ async function handleSetupCommand(args) {
116050
117022
  printSetupUsage();
116051
117023
  return;
116052
117024
  }
116053
- if (hasFlag(args, "--json")) {
117025
+ if (hasFlag2(args, "--json")) {
116054
117026
  await handleSetupJson(args);
116055
117027
  return;
116056
117028
  }
@@ -116608,7 +117580,7 @@ async function getCurrentNodeCliVersion() {
116608
117580
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
116609
117581
  }
116610
117582
  function getBundledNodeCliVersion() {
116611
- return true ? "0.2.9" : null;
117583
+ return true ? "0.2.10-beta-98689bff7a-260826143751" : null;
116612
117584
  }
116613
117585
  function readConfiguredAiProvider() {
116614
117586
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -116793,17 +117765,17 @@ async function updateHermes(release, options) {
116793
117765
  assertNotRunningInsideGateway("hermes");
116794
117766
  }
116795
117767
  const spec = buildNpmPackageSpec("hermes", release);
116796
- const workDir = await (0, import_promises15.mkdtemp)((0, import_node_path35.join)((0, import_node_os14.tmpdir)(), `okx-a2a-${label}-hermes-`));
117768
+ const workDir = await (0, import_promises15.mkdtemp)((0, import_node_path37.join)((0, import_node_os14.tmpdir)(), `okx-a2a-${label}-hermes-`));
116797
117769
  try {
116798
117770
  console.log(`[${label}] downloading ${spec}`);
116799
117771
  const npmTarball = await npmPack(spec, workDir);
116800
- const npmPackageDir = (0, import_node_path35.join)(workDir, "npm-package");
117772
+ const npmPackageDir = (0, import_node_path37.join)(workDir, "npm-package");
116801
117773
  await runCommand("tar", ["-xzf", npmTarball, "-C", npmPackageDir], { ensureDir: npmPackageDir });
116802
- const pluginTarball = await findHermesPluginTarball((0, import_node_path35.join)(npmPackageDir, "package", "dist"));
116803
- const pluginDir = (0, import_node_path35.join)(workDir, "plugin");
117774
+ const pluginTarball = await findHermesPluginTarball((0, import_node_path37.join)(npmPackageDir, "package", "dist"));
117775
+ const pluginDir = (0, import_node_path37.join)(workDir, "plugin");
116804
117776
  await runCommand("tar", ["-xzf", pluginTarball, "-C", pluginDir], { ensureDir: pluginDir });
116805
117777
  const unpackedPluginDir = await findFirstDirectory(pluginDir);
116806
- const installer = (0, import_node_path35.join)(unpackedPluginDir, "scripts", "install-or-upgrade.sh");
117778
+ const installer = (0, import_node_path37.join)(unpackedPluginDir, "scripts", "install-or-upgrade.sh");
116807
117779
  console.log(`[${label}] running ${installer}`);
116808
117780
  await runCommand("bash", [installer, ...options.restart ? ["--restart"] : []], { cwd: unpackedPluginDir });
116809
117781
  await normalizeHermesOkxA2aPluginConfig();
@@ -116818,7 +117790,7 @@ async function updateHermes(release, options) {
116818
117790
  }
116819
117791
  }
116820
117792
  async function installGatewayPluginForDoctor(target) {
116821
- const release = isPrereleaseVersion("0.2.9") ? "beta" : "latest";
117793
+ const release = isPrereleaseVersion("0.2.10-beta-98689bff7a-260826143751") ? "beta" : "latest";
116822
117794
  const insideTargetGateway = detectGatewayInvocation() === target;
116823
117795
  const options = {
116824
117796
  restart: !insideTargetGateway,
@@ -116869,7 +117841,7 @@ async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPa
116869
117841
  if (options.dryRun) {
116870
117842
  return true;
116871
117843
  }
116872
- await (0, import_promises15.mkdir)((0, import_node_path35.resolve)(configFile, ".."), { recursive: true });
117844
+ await (0, import_promises15.mkdir)((0, import_node_path37.resolve)(configFile, ".."), { recursive: true });
116873
117845
  await (0, import_promises15.writeFile)(configFile, "plugins:\n enabled:\n - okx-a2a\n");
116874
117846
  console.log(`[update] added Hermes plugins.enabled okx-a2a entry in ${configFile}`);
116875
117847
  return true;
@@ -117109,7 +118081,7 @@ function findFirstEnabledListItem(lines, startIndex, enabledIndent) {
117109
118081
  return null;
117110
118082
  }
117111
118083
  function resolveHermesConfigPath() {
117112
- return (0, import_node_path35.join)(process.env.HERMES_HOME ?? (0, import_node_path35.join)((0, import_node_os14.homedir)(), ".hermes"), "config.yaml");
118084
+ return (0, import_node_path37.join)(process.env.HERMES_HOME ?? (0, import_node_path37.join)((0, import_node_os14.homedir)(), ".hermes"), "config.yaml");
117113
118085
  }
117114
118086
  function lineIndent(line) {
117115
118087
  const match = line.match(/^\s*/);
@@ -117187,13 +118159,13 @@ async function assertGatewayPluginInstalled(target) {
117187
118159
  );
117188
118160
  }
117189
118161
  function resolveHermesPluginYamlPath() {
117190
- return (0, import_node_path35.join)(process.env.HERMES_HOME ?? (0, import_node_path35.join)((0, import_node_os14.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
118162
+ return (0, import_node_path37.join)(process.env.HERMES_HOME ?? (0, import_node_path37.join)((0, import_node_os14.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
117191
118163
  }
117192
118164
  async function isGatewayPluginInstalled(target) {
117193
118165
  if (target === "openclaw") {
117194
118166
  return (await getInstalledOpenClawPluginInfo()).installed;
117195
118167
  }
117196
- return (0, import_node_fs29.existsSync)(resolveHermesPluginYamlPath());
118168
+ return (0, import_node_fs32.existsSync)(resolveHermesPluginYamlPath());
117197
118169
  }
117198
118170
  async function getInstalledGatewayPluginVersion(target) {
117199
118171
  if (target === "hermes") {
@@ -117280,7 +118252,7 @@ function parsePackageVersionFromText(output5) {
117280
118252
  return output5.match(/@okxweb3\/a2a-openclaw@([0-9A-Za-z.+-]+)/)?.[1] ?? null;
117281
118253
  }
117282
118254
  async function getInstalledHermesPluginVersion() {
117283
- const pluginYaml = (0, import_node_path35.join)(process.env.HERMES_HOME ?? (0, import_node_path35.join)((0, import_node_os14.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
118255
+ const pluginYaml = (0, import_node_path37.join)(process.env.HERMES_HOME ?? (0, import_node_path37.join)((0, import_node_os14.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
117284
118256
  try {
117285
118257
  const content2 = await (0, import_promises15.readFile)(pluginYaml, "utf8");
117286
118258
  return parsePluginYamlVersion(content2);
@@ -117338,7 +118310,7 @@ async function npmPack(spec, destination) {
117338
118310
  if (!tarballName) {
117339
118311
  throw new Error(`Unable to detect npm pack tarball from output: ${output5.trim()}`);
117340
118312
  }
117341
- return (0, import_node_path35.resolve)(destination, (0, import_node_path35.basename)(tarballName));
118313
+ return (0, import_node_path37.resolve)(destination, (0, import_node_path37.basename)(tarballName));
117342
118314
  }
117343
118315
  async function findHermesPluginTarball(distDir) {
117344
118316
  const entries = await (0, import_promises15.readdir)(distDir);
@@ -117346,7 +118318,7 @@ async function findHermesPluginTarball(distDir) {
117346
118318
  if (!tarball) {
117347
118319
  throw new Error(`Hermes npm package did not contain dist/okx-a2a-hermes-plugin-*.tar.gz`);
117348
118320
  }
117349
- return (0, import_node_path35.join)(distDir, tarball);
118321
+ return (0, import_node_path37.join)(distDir, tarball);
117350
118322
  }
117351
118323
  async function findFirstDirectory(parent) {
117352
118324
  const entries = await (0, import_promises15.readdir)(parent, { withFileTypes: true });
@@ -117354,16 +118326,16 @@ async function findFirstDirectory(parent) {
117354
118326
  if (!dir) {
117355
118327
  throw new Error(`No unpacked plugin directory found under ${parent}`);
117356
118328
  }
117357
- return (0, import_node_path35.join)(parent, dir.name);
118329
+ return (0, import_node_path37.join)(parent, dir.name);
117358
118330
  }
117359
- function readOption4(args, name) {
118331
+ function readOption5(args, name) {
117360
118332
  const index2 = args.indexOf(name);
117361
118333
  if (index2 === -1) {
117362
118334
  return void 0;
117363
118335
  }
117364
118336
  return args[index2 + 1];
117365
118337
  }
117366
- function hasFlag(args, name) {
118338
+ function hasFlag2(args, name) {
117367
118339
  return args.includes(name);
117368
118340
  }
117369
118341
  function isHelpArg3(value) {
@@ -117405,7 +118377,7 @@ async function runCommand(command, args, options = {}) {
117405
118377
  await new Promise((resolvePromise, reject) => {
117406
118378
  const invocation = buildExternalCommandInvocation(command, args);
117407
118379
  const redirect = redirectCommandStdoutToStderr || options.redirectStdoutToStderr === true;
117408
- const child = (0, import_node_child_process10.spawn)(invocation.command, invocation.args, {
118380
+ const child = (0, import_node_child_process11.spawn)(invocation.command, invocation.args, {
117409
118381
  cwd: options.cwd,
117410
118382
  stdio: redirect ? [options.inheritStdin ? "inherit" : "ignore", "pipe", "pipe"] : "inherit",
117411
118383
  windowsVerbatimArguments: invocation.windowsVerbatimArguments
@@ -117449,7 +118421,7 @@ async function runCommand(command, args, options = {}) {
117449
118421
  async function runCommandCapture(command, args) {
117450
118422
  return await new Promise((resolvePromise, reject) => {
117451
118423
  const invocation = buildExternalCommandInvocation(command, args);
117452
- const child = (0, import_node_child_process10.spawn)(invocation.command, invocation.args, {
118424
+ const child = (0, import_node_child_process11.spawn)(invocation.command, invocation.args, {
117453
118425
  stdio: ["ignore", "pipe", "pipe"],
117454
118426
  windowsVerbatimArguments: invocation.windowsVerbatimArguments
117455
118427
  });
@@ -117482,7 +118454,7 @@ ${stderr}`));
117482
118454
  async function runCommandCaptureOptional(command, args) {
117483
118455
  return await new Promise((resolvePromise) => {
117484
118456
  const invocation = buildExternalCommandInvocation(command, args);
117485
- const child = (0, import_node_child_process10.spawn)(invocation.command, invocation.args, {
118457
+ const child = (0, import_node_child_process11.spawn)(invocation.command, invocation.args, {
117486
118458
  stdio: ["ignore", "pipe", "ignore"],
117487
118459
  windowsVerbatimArguments: invocation.windowsVerbatimArguments
117488
118460
  });
@@ -117502,7 +118474,7 @@ async function runCommandCaptureOptional(command, args) {
117502
118474
  async function runCommandCaptureStatus(command, args, options = {}) {
117503
118475
  return await new Promise((resolvePromise) => {
117504
118476
  const invocation = buildExternalCommandInvocation(command, args);
117505
- const child = (0, import_node_child_process10.spawn)(invocation.command, invocation.args, {
118477
+ const child = (0, import_node_child_process11.spawn)(invocation.command, invocation.args, {
117506
118478
  stdio: ["ignore", "pipe", "pipe"],
117507
118479
  windowsVerbatimArguments: invocation.windowsVerbatimArguments
117508
118480
  });
@@ -117575,15 +118547,15 @@ function buildExternalCommandInvocation(command, args, platform = process.platfo
117575
118547
  function formatExternalCommand(command, args) {
117576
118548
  return [command, ...args].join(" ");
117577
118549
  }
117578
- var import_node_child_process10, import_node_fs29, import_promises15, import_node_os14, import_node_path35, UPDATE_PACKAGES, CODEX_NPM_PACKAGE, OPENCLAW_FORCE_INSTALL_FLAG, OPENCLAW_UNSAFE_INSTALL_FLAG, OKX_A2A_PLUGIN_ID, OPENCLAW_SESSION_DM_SCOPE_CONFIG_PATH, OPENCLAW_SESSION_DM_SCOPE_CONFIG_VALUE, OPENCLAW_PLUGIN_ALLOW_CONFIG_PATH, OPENCLAW_OKX_A2A_CONVERSATION_HOOK_ACCESS_CONFIG_PATH, DEFAULT_AI_PROVIDER_LOGIN_TIMEOUT_MS, PROVIDER_CLI_AUTH_PROBE_TIMEOUT_MS, SetupBlockedError, redirectCommandStdoutToStderr;
118550
+ var import_node_child_process11, import_node_fs32, import_promises15, import_node_os14, import_node_path37, UPDATE_PACKAGES, CODEX_NPM_PACKAGE, OPENCLAW_FORCE_INSTALL_FLAG, OPENCLAW_UNSAFE_INSTALL_FLAG, OKX_A2A_PLUGIN_ID, OPENCLAW_SESSION_DM_SCOPE_CONFIG_PATH, OPENCLAW_SESSION_DM_SCOPE_CONFIG_VALUE, OPENCLAW_PLUGIN_ALLOW_CONFIG_PATH, OPENCLAW_OKX_A2A_CONVERSATION_HOOK_ACCESS_CONFIG_PATH, DEFAULT_AI_PROVIDER_LOGIN_TIMEOUT_MS, PROVIDER_CLI_AUTH_PROBE_TIMEOUT_MS, SetupBlockedError, redirectCommandStdoutToStderr;
117579
118551
  var init_update_cli = __esm({
117580
118552
  "src/update-cli.ts"() {
117581
118553
  "use strict";
117582
- import_node_child_process10 = require("node:child_process");
117583
- import_node_fs29 = require("node:fs");
118554
+ import_node_child_process11 = require("node:child_process");
118555
+ import_node_fs32 = require("node:fs");
117584
118556
  import_promises15 = require("node:fs/promises");
117585
118557
  import_node_os14 = require("node:os");
117586
- import_node_path35 = require("node:path");
118558
+ import_node_path37 = require("node:path");
117587
118559
  init_ai_command();
117588
118560
  init_win_spawn();
117589
118561
  init_ai_provider();
@@ -117871,7 +118843,7 @@ async function runDoctor(options = {}) {
117871
118843
  platform: options.platform ?? process.platform,
117872
118844
  env: options.env ?? process.env,
117873
118845
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
117874
- cliVersion: options.cliVersion ?? (true ? "0.2.9" : "0.0.0"),
118846
+ cliVersion: options.cliVersion ?? (true ? "0.2.10-beta-98689bff7a-260826143751" : "0.0.0"),
117875
118847
  fixMode: options.fix === true,
117876
118848
  nonInteractive: options.nonInteractive === true,
117877
118849
  packageChanged: false,
@@ -118079,11 +119051,11 @@ async function writeStdoutAndExit(output5, code) {
118079
119051
  });
118080
119052
  process.exit(code);
118081
119053
  }
118082
- var import_node_path36, DOCTOR_MIN_NODE_VERSION, DOCTOR_DAEMON_READY_TIMEOUT_MS, DOCTOR_DAEMON_WAIT_HEARTBEAT_MS, NODE_PACKAGE_SPEC, CODEX_INSTALL_SPEC, CLAUDE_INSTALL_SPEC, nodeVersionChecker, npmChecker, cliVersionChecker, windowsNativeLauncherChecker, providerBindingChecker, providerCliChecker, gatewayPluginChecker, gatewayConfigChecker, daemonChecker, agentRefreshChecker, gatewayReachableChecker, autostartChecker, CHECKERS, STATUS_MARK;
119054
+ var import_node_path38, DOCTOR_MIN_NODE_VERSION, DOCTOR_DAEMON_READY_TIMEOUT_MS, DOCTOR_DAEMON_WAIT_HEARTBEAT_MS, NODE_PACKAGE_SPEC, CODEX_INSTALL_SPEC, CLAUDE_INSTALL_SPEC, nodeVersionChecker, npmChecker, cliVersionChecker, windowsNativeLauncherChecker, providerBindingChecker, providerCliChecker, gatewayPluginChecker, gatewayConfigChecker, daemonChecker, agentRefreshChecker, gatewayReachableChecker, autostartChecker, CHECKERS, STATUS_MARK;
118083
119055
  var init_doctor_cli = __esm({
118084
119056
  "src/doctor-cli.ts"() {
118085
119057
  "use strict";
118086
- import_node_path36 = require("node:path");
119058
+ import_node_path38 = require("node:path");
118087
119059
  init_log();
118088
119060
  init_win_compat();
118089
119061
  init_ai_command();
@@ -118270,7 +119242,7 @@ var init_doctor_cli = __esm({
118270
119242
  command: "okx-a2a doctor --fix"
118271
119243
  },
118272
119244
  data: {
118273
- appDataNpm: ctx.env.APPDATA ? (0, import_node_path36.join)(ctx.env.APPDATA, "npm") : null
119245
+ appDataNpm: ctx.env.APPDATA ? (0, import_node_path38.join)(ctx.env.APPDATA, "npm") : null
118274
119246
  }
118275
119247
  };
118276
119248
  },
@@ -118878,10 +119850,10 @@ var init_doctor_cli = __esm({
118878
119850
  });
118879
119851
 
118880
119852
  // src/cli.ts
118881
- var import_node_child_process11 = require("node:child_process");
118882
- var import_node_fs30 = require("node:fs");
119853
+ var import_node_child_process12 = require("node:child_process");
119854
+ var import_node_fs33 = require("node:fs");
118883
119855
  var import_node_os15 = require("node:os");
118884
- var import_node_path37 = require("node:path");
119856
+ var import_node_path39 = require("node:path");
118885
119857
  init_daemon();
118886
119858
  init_command_store();
118887
119859
  init_file_store();
@@ -118899,7 +119871,7 @@ init_sentry_config();
118899
119871
  init_runtime_metadata();
118900
119872
  var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
118901
119873
  function printUsage3() {
118902
- console.log(`okx-a2a ${"0.2.9"}
119874
+ console.log(`okx-a2a ${"0.2.10-beta-98689bff7a-260826143751"}
118903
119875
 
118904
119876
  Usage:
118905
119877
  okx-a2a <command> [options]
@@ -118929,6 +119901,7 @@ Commands:
118929
119901
  Alias for runtime switch-current
118930
119902
  job-provider Manage job-to-provider bindings
118931
119903
  xmtp-send Queue an XMTP message through the running daemon
119904
+ signal Publish a TradingSignalV1 through configured daemon routes
118932
119905
  capabilities Print machine-readable A2A capability negotiation status (used by OnchainOS)
118933
119906
 
118934
119907
  Global options:
@@ -118939,7 +119912,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
118939
119912
  `);
118940
119913
  }
118941
119914
  function printVersion() {
118942
- console.log("0.2.9");
119915
+ console.log("0.2.10-beta-98689bff7a-260826143751");
118943
119916
  }
118944
119917
  function printDaemonUsage() {
118945
119918
  console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
@@ -119094,6 +120067,10 @@ function printCommandUsage(command) {
119094
120067
  printXmtpSendUsage();
119095
120068
  return true;
119096
120069
  }
120070
+ if (command === "signal") {
120071
+ console.log("Usage: okx-a2a signal publish --service-id <id> (--file <path> | --stdin) [--json]");
120072
+ return true;
120073
+ }
119097
120074
  return false;
119098
120075
  }
119099
120076
  function printUserUsageProxy() {
@@ -119194,18 +120171,18 @@ function isVersionArg(value) {
119194
120171
  function hasVersionFlag(args) {
119195
120172
  return args.some(isVersionArg);
119196
120173
  }
119197
- function readOption5(args, name) {
120174
+ function readOption6(args, name) {
119198
120175
  const index2 = args.indexOf(name);
119199
120176
  if (index2 === -1) {
119200
120177
  return void 0;
119201
120178
  }
119202
120179
  return args[index2 + 1];
119203
120180
  }
119204
- function hasFlag2(args, name) {
120181
+ function hasFlag3(args, name) {
119205
120182
  return args.includes(name);
119206
120183
  }
119207
120184
  function readLifecycleProviderOption(args) {
119208
- return readOption5(args, "--provider") ?? readOption5(args, "--ai-provider");
120185
+ return readOption6(args, "--provider") ?? readOption6(args, "--ai-provider");
119209
120186
  }
119210
120187
  function maybeRedirectDaemonSelfLog() {
119211
120188
  if (process.env.OKX_AGENT_TASK_SELF_LOG !== "1") {
@@ -119213,14 +120190,14 @@ function maybeRedirectDaemonSelfLog() {
119213
120190
  }
119214
120191
  try {
119215
120192
  const logPath = resolveTaskPaths().listenerLogPath;
119216
- (0, import_node_fs30.mkdirSync)((0, import_node_path37.join)(logPath, ".."), { recursive: true });
119217
- const fd = (0, import_node_fs30.openSync)(logPath, "a");
120193
+ (0, import_node_fs33.mkdirSync)((0, import_node_path39.join)(logPath, ".."), { recursive: true });
120194
+ const fd = (0, import_node_fs33.openSync)(logPath, "a");
119218
120195
  const writeToLog = ((chunk, encoding, cb) => {
119219
120196
  try {
119220
120197
  if (typeof chunk === "string") {
119221
- (0, import_node_fs30.writeSync)(fd, chunk);
120198
+ (0, import_node_fs33.writeSync)(fd, chunk);
119222
120199
  } else {
119223
- (0, import_node_fs30.writeSync)(fd, chunk);
120200
+ (0, import_node_fs33.writeSync)(fd, chunk);
119224
120201
  }
119225
120202
  } catch {
119226
120203
  }
@@ -119236,7 +120213,7 @@ function maybeRedirectDaemonSelfLog() {
119236
120213
  }
119237
120214
  }
119238
120215
  function shouldInstallAutostart(args) {
119239
- return !hasFlag2(args, "--no-autostart");
120216
+ return !hasFlag3(args, "--no-autostart");
119240
120217
  }
119241
120218
  function printStopDaemonResult(result) {
119242
120219
  if (result.stopped) {
@@ -119287,7 +120264,7 @@ async function tailLogFile(logPath) {
119287
120264
  fallbackStarted = true;
119288
120265
  tailLogFileWithNode(logPath, reason).then(resolve14, reject);
119289
120266
  };
119290
- const child = (0, import_node_child_process11.spawn)("tail", ["-n", "600", "-f", logPath], { stdio: "inherit" });
120267
+ const child = (0, import_node_child_process12.spawn)("tail", ["-n", "600", "-f", logPath], { stdio: "inherit" });
119291
120268
  child.on("error", (error) => {
119292
120269
  fallback(`tail_spawn_${error.code ?? "error"}`);
119293
120270
  });
@@ -119320,7 +120297,7 @@ async function handleLogs(args) {
119320
120297
  return;
119321
120298
  }
119322
120299
  if (subcommand === "llm") {
119323
- await tailLogFile((0, import_node_path37.join)(paths.logsDir, "llm.log"));
120300
+ await tailLogFile((0, import_node_path39.join)(paths.logsDir, "llm.log"));
119324
120301
  return;
119325
120302
  }
119326
120303
  throw new Error("logs requires <server|llm|export>");
@@ -119366,15 +120343,15 @@ async function queueXmtpSend(args) {
119366
120343
  ]),
119367
120344
  flags: /* @__PURE__ */ new Set(["--json"])
119368
120345
  });
119369
- const json = hasFlag2(args, "--json");
119370
- const explicitJobId = readOption5(args, "--job-id");
119371
- const message = readOption5(args, "--message");
119372
- const replyToMessageId = readOption5(args, "--reply-to");
119373
- const sessionAgentId = readOption5(args, "--session-agent-id") ?? process.env.OKX_AGENT_TASK_CURRENT_SESSION_AGENT_ID;
119374
- const explicitToAgentId = readOption5(args, "--to-agent-id");
119375
- const sessionKey = readOption5(args, "--session-key");
119376
- const toXmtpAddress = readOption5(args, "--to-address") ?? readOption5(args, "--to-xmtp-address");
119377
- const payloadOverride = parseXmtpSendPayloadOption(readOption5(args, "--payload"));
120346
+ const json = hasFlag3(args, "--json");
120347
+ const explicitJobId = readOption6(args, "--job-id");
120348
+ const message = readOption6(args, "--message");
120349
+ const replyToMessageId = readOption6(args, "--reply-to");
120350
+ const sessionAgentId = readOption6(args, "--session-agent-id") ?? process.env.OKX_AGENT_TASK_CURRENT_SESSION_AGENT_ID;
120351
+ const explicitToAgentId = readOption6(args, "--to-agent-id");
120352
+ const sessionKey = readOption6(args, "--session-key");
120353
+ const toXmtpAddress = readOption6(args, "--to-address") ?? readOption6(args, "--to-xmtp-address");
120354
+ const payloadOverride = parseXmtpSendPayloadOption(readOption6(args, "--payload"));
119378
120355
  const target = resolveXmtpSendTarget({
119379
120356
  sessionKey,
119380
120357
  jobId: explicitJobId,
@@ -119554,8 +120531,8 @@ function assertOnlyKnownOptions(args, input) {
119554
120531
  }
119555
120532
  }
119556
120533
  async function queueXmtpDaemonCommand(args, type) {
119557
- const json = hasFlag2(args, "--json");
119558
- const timeoutMsRaw = readOption5(args, "--timeout-ms");
120534
+ const json = hasFlag3(args, "--json");
120535
+ const timeoutMsRaw = readOption6(args, "--timeout-ms");
119559
120536
  const wait3 = type === "xmtp-get-pending-list" || type === "xmtp-deny-pending-conversation" || type === "xmtp-refresh-agents";
119560
120537
  await assertDaemonRunningForQueuedCommand2(type);
119561
120538
  const commands = new CommandStore();
@@ -119635,8 +120612,8 @@ async function handleAgentCommand(args) {
119635
120612
  throw new Error("agent requires <refresh|bypass>");
119636
120613
  }
119637
120614
  function handleAgentBypassCommand(args) {
119638
- const json = hasFlag2(args, "--json");
119639
- const rawMode = readOption5(args, "--mode") ?? args.find((arg) => !arg.startsWith("--"));
120615
+ const json = hasFlag3(args, "--json");
120616
+ const rawMode = readOption6(args, "--mode") ?? args.find((arg) => !arg.startsWith("--"));
119640
120617
  const store = new SessionStore();
119641
120618
  try {
119642
120619
  if (rawMode) {
@@ -119668,16 +120645,16 @@ function outputAgentBypass(json, enabled) {
119668
120645
  console.log(`AI bypass permissions: ${enabled ? "on" : "off"}`);
119669
120646
  }
119670
120647
  function readRequiredOption4(args, name) {
119671
- const value = readOption5(args, name);
120648
+ const value = readOption6(args, name);
119672
120649
  if (!value) {
119673
120650
  throw new Error(`${name} is required`);
119674
120651
  }
119675
120652
  return value;
119676
120653
  }
119677
120654
  function readDenyPendingConversationOptions(args) {
119678
- const jobId = readOption5(args, "--job-id");
119679
- const groupId = readOption5(args, "--group-id");
119680
- const agentId = readOption5(args, "--agent-id");
120655
+ const jobId = readOption6(args, "--job-id");
120656
+ const groupId = readOption6(args, "--group-id");
120657
+ const agentId = readOption6(args, "--agent-id");
119681
120658
  const content2 = readOptionalNonEmptyOption(args, "--content", "task reject --content");
119682
120659
  if (jobId) {
119683
120660
  if (groupId || agentId) {
@@ -119695,10 +120672,10 @@ function readDenyPendingConversationOptions(args) {
119695
120672
  };
119696
120673
  }
119697
120674
  function readOptionalNonEmptyOption(args, name, label) {
119698
- if (!hasFlag2(args, name)) {
120675
+ if (!hasFlag3(args, name)) {
119699
120676
  return void 0;
119700
120677
  }
119701
- const value = readOption5(args, name);
120678
+ const value = readOption6(args, name);
119702
120679
  if (value === void 0 || value.trim().length === 0) {
119703
120680
  throw new Error(`${label} requires a non-empty string`);
119704
120681
  }
@@ -119970,7 +120947,7 @@ async function handleAiProvider(args) {
119970
120947
  return;
119971
120948
  }
119972
120949
  const subcommand = args[0] ?? "status";
119973
- const json = hasFlag2(args, "--json");
120950
+ const json = hasFlag3(args, "--json");
119974
120951
  const store = new SessionStore();
119975
120952
  try {
119976
120953
  if (subcommand === "status") {
@@ -119986,7 +120963,7 @@ async function handleAiProvider(args) {
119986
120963
  return;
119987
120964
  }
119988
120965
  if (subcommand === "set") {
119989
- const rawProvider = readOption5(args, "--provider") ?? args[1];
120966
+ const rawProvider = readOption6(args, "--provider") ?? args[1];
119990
120967
  if (!rawProvider) {
119991
120968
  throw new Error("ai-provider set requires --provider <codex|claude|hermes|openclaw>");
119992
120969
  }
@@ -120043,7 +121020,7 @@ async function handleRuntimeSwitch(args) {
120043
121020
  options: /* @__PURE__ */ new Set(),
120044
121021
  flags: /* @__PURE__ */ new Set(["--json"])
120045
121022
  });
120046
- const json = hasFlag2(args, "--json");
121023
+ const json = hasFlag3(args, "--json");
120047
121024
  const store = new SessionStore();
120048
121025
  try {
120049
121026
  const result = await performRuntimeSwitch(store);
@@ -120097,7 +121074,7 @@ async function handleJobProvider(args) {
120097
121074
  }
120098
121075
  const subcommand = args[0] ?? "get";
120099
121076
  const rest = args.slice(1);
120100
- const json = hasFlag2(rest, "--json");
121077
+ const json = hasFlag3(rest, "--json");
120101
121078
  const store = new SessionStore();
120102
121079
  try {
120103
121080
  if (subcommand === "get") {
@@ -120129,7 +121106,7 @@ async function handleJobProvider(args) {
120129
121106
  }
120130
121107
  if (subcommand === "unset") {
120131
121108
  const jobId = readRequiredOption4(rest, "--job-id");
120132
- const expectedProviderRaw = readOption5(rest, "--provider");
121109
+ const expectedProviderRaw = readOption6(rest, "--provider");
120133
121110
  const expectedProvider = expectedProviderRaw ? normalizeAiProvider(expectedProviderRaw) : null;
120134
121111
  const existing = store.getJobProviderBinding(jobId);
120135
121112
  const providerMatched = !!existing && (!expectedProvider || existing.provider === expectedProvider);
@@ -120168,9 +121145,9 @@ async function handleJobProvider(args) {
120168
121145
  return;
120169
121146
  }
120170
121147
  if (subcommand === "list") {
120171
- const rawProvider = readOption5(rest, "--provider");
121148
+ const rawProvider = readOption6(rest, "--provider");
120172
121149
  const provider = rawProvider ? normalizeAiProvider(rawProvider) : void 0;
120173
- const rawLimit = readOption5(rest, "--limit");
121150
+ const rawLimit = readOption6(rest, "--limit");
120174
121151
  const limit = rawLimit ? Number(rawLimit) : void 0;
120175
121152
  const bindings = store.listJobProviderBindings({ provider, limit });
120176
121153
  if (json) {
@@ -120190,7 +121167,7 @@ async function handleJobProvider(args) {
120190
121167
  async function handleConfig(args) {
120191
121168
  const subcommand = args[0];
120192
121169
  const configArgs = args.slice(1);
120193
- const json = hasFlag2(args, "--json");
121170
+ const json = hasFlag3(args, "--json");
120194
121171
  if (!subcommand || hasHelpFlag5(args)) {
120195
121172
  printConfigUsage();
120196
121173
  return;
@@ -120202,7 +121179,7 @@ async function handleConfig(args) {
120202
121179
  if (subcommand !== "provider") {
120203
121180
  throw new Error(`Unknown config command: ${subcommand}`);
120204
121181
  }
120205
- const rawProvider = readOption5(configArgs, "--provider") ?? configArgs.find((arg) => !arg.startsWith("--"));
121182
+ const rawProvider = readOption6(configArgs, "--provider") ?? configArgs.find((arg) => !arg.startsWith("--"));
120206
121183
  if (json && !rawProvider) {
120207
121184
  throw new Error("config provider --json requires --provider <codex|claude|hermes|openclaw>");
120208
121185
  }
@@ -120241,7 +121218,7 @@ Commands:
120241
121218
  }
120242
121219
  function handleConfigPermissions(args, json) {
120243
121220
  const paths = resolveTaskPaths();
120244
- const rawPreset = readOption5(args, "--preset") ?? args.find((arg) => !arg.startsWith("--"));
121221
+ const rawPreset = readOption6(args, "--preset") ?? args.find((arg) => !arg.startsWith("--"));
120245
121222
  const configPath = resolveTaskConfigPath(paths.homeDir);
120246
121223
  if (rawPreset) {
120247
121224
  const preset2 = writeAiPermissionPresetToConfig(paths.homeDir, rawPreset);
@@ -120279,11 +121256,11 @@ async function initDirectCliSentry() {
120279
121256
  }
120280
121257
  cliSentryInitAttempted = true;
120281
121258
  try {
120282
- const configPath = (0, import_node_path37.join)(resolveTaskHomeForSentryConfig(), "xmtp", "system-config.json");
120283
- if (!(0, import_node_fs30.existsSync)(configPath)) {
121259
+ const configPath = (0, import_node_path39.join)(resolveTaskHomeForSentryConfig(), "xmtp", "system-config.json");
121260
+ if (!(0, import_node_fs33.existsSync)(configPath)) {
120284
121261
  return;
120285
121262
  }
120286
- const config = JSON.parse((0, import_node_fs30.readFileSync)(configPath, "utf8"));
121263
+ const config = JSON.parse((0, import_node_fs33.readFileSync)(configPath, "utf8"));
120287
121264
  if (typeof config.sentryDsn !== "string" || !config.sentryDsn) {
120288
121265
  return;
120289
121266
  }
@@ -120308,11 +121285,11 @@ function resolveTaskHomeForSentryConfig() {
120308
121285
  try {
120309
121286
  const home = (0, import_node_os15.homedir)();
120310
121287
  if (home) {
120311
- return (0, import_node_path37.join)(home, ".okx-agent-task");
121288
+ return (0, import_node_path39.join)(home, ".okx-agent-task");
120312
121289
  }
120313
121290
  } catch {
120314
121291
  }
120315
- return (0, import_node_path37.resolve)(process.cwd(), ".okx-agent-task");
121292
+ return (0, import_node_path39.resolve)(process.cwd(), ".okx-agent-task");
120316
121293
  }
120317
121294
  function directCliSentryExtra(operation, extra = {}) {
120318
121295
  return {
@@ -120420,7 +121397,7 @@ async function main() {
120420
121397
  if (command === "xmtp-test") {
120421
121398
  const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
120422
121399
  await handleXmtpTestCommand2(process.argv.slice(3), {
120423
- packageVersion: "0.2.9",
121400
+ packageVersion: "0.2.10-beta-98689bff7a-260826143751",
120424
121401
  agentSdkVersion: "2.3.0",
120425
121402
  nodeSdkVersion: "6.1.0",
120426
121403
  nodeBindingsVersion: "1.11.0"
@@ -120433,6 +121410,13 @@ async function main() {
120433
121410
  await flushDirectCliSentry();
120434
121411
  return;
120435
121412
  }
121413
+ if (command === "signal") {
121414
+ await initDirectCliSentry();
121415
+ const { handleSignalCommand: handleSignalCommand2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
121416
+ await handleSignalCommand2(process.argv.slice(3));
121417
+ await flushDirectCliSentry();
121418
+ return;
121419
+ }
120436
121420
  if (command === "task") {
120437
121421
  await initDirectCliSentry();
120438
121422
  await handleTaskCommand(process.argv.slice(3));
@@ -120525,7 +121509,7 @@ function shouldDeferHelpToNestedHandler(command, args) {
120525
121509
  if (command === "xmtp-test") {
120526
121510
  return true;
120527
121511
  }
120528
- if (command !== "session" && command !== "user" && command !== "task") {
121512
+ if (command !== "session" && command !== "user" && command !== "task" && command !== "signal") {
120529
121513
  return false;
120530
121514
  }
120531
121515
  return args.some((arg) => !isHelpArg4(arg));