@okxweb3/a2a-node 0.2.11 → 0.2.12-beta-7449a77b9d-260909165309

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/cli.js +1435 -277
  2. package/dist/index.js +149 -66
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -108,6 +108,7 @@ function resolveTaskPaths(homeDir = resolveTaskHome()) {
108
108
  workspaceDir: (0, import_node_path2.join)(homeDir, "workspace"),
109
109
  xmtpDir: (0, import_node_path2.join)(homeDir, "xmtp"),
110
110
  sqliteDir: (0, import_node_path2.join)(homeDir, "sqlite"),
111
+ bzRecordsDir: (0, import_node_path2.join)(homeDir, "bz-records"),
111
112
  pendingCommandsDir: (0, import_node_path2.join)(homeDir, "commands", "pending"),
112
113
  processingCommandsDir: (0, import_node_path2.join)(homeDir, "commands", "processing"),
113
114
  completedCommandsDir: (0, import_node_path2.join)(homeDir, "commands", "completed"),
@@ -713,6 +714,7 @@ var init_session_store = __esm({
713
714
  PRIMARY KEY(session_key, provider)
714
715
  )
715
716
  `);
717
+ this.db.exec("DROP TRIGGER IF EXISTS a2a_ai_sessions_delete_guard");
716
718
  this.db.exec(`
717
719
  CREATE TABLE IF NOT EXISTS job_provider_bindings (
718
720
  job_id TEXT PRIMARY KEY,
@@ -6524,7 +6526,7 @@ var require_path = __commonJS({
6524
6526
  function isAbsolute4(path2) {
6525
6527
  return path2.charAt(0) === "/";
6526
6528
  }
6527
- function join33(...args) {
6529
+ function join34(...args) {
6528
6530
  return normalizePath(args.join("/"));
6529
6531
  }
6530
6532
  function dirname11(path2) {
@@ -6549,7 +6551,7 @@ var require_path = __commonJS({
6549
6551
  exports2.basename = basename11;
6550
6552
  exports2.dirname = dirname11;
6551
6553
  exports2.isAbsolute = isAbsolute4;
6552
- exports2.join = join33;
6554
+ exports2.join = join34;
6553
6555
  exports2.normalizePath = normalizePath;
6554
6556
  exports2.relative = relative;
6555
6557
  exports2.resolve = resolve14;
@@ -19902,6 +19904,7 @@ var init_events = __esm({
19902
19904
  INBOUND_BLOCKED_INELIGIBLE: "Inbound blocked: message-eligible check failed",
19903
19905
  INBOUND_DROP_EMPTY_CONTENT: "Inbound drop: empty content",
19904
19906
  INBOUND_DROP_MISSING_JOBID: "Inbound drop: missing jobId",
19907
+ INBOUND_DROP_INVALID_JOBID: "Inbound drop: invalid jobId",
19905
19908
  INBOUND_DROP_UNSUPPORTED_MSGTYPE: "Inbound drop: unsupported msgType",
19906
19909
  INBOUND_DROP_DM_NON_SYSTEM: "Inbound drop: DM sender not in system whitelist",
19907
19910
  INBOUND_DROP_DM_INVALID_PAYLOAD: "Inbound drop: DM payload invalid",
@@ -20835,6 +20838,7 @@ var init_sentry_logger = __esm({
20835
20838
  LogEvent.INBOUND_DROP_DM_UNKNOWN_AGENT,
20836
20839
  LogEvent.INBOUND_DROP_EMPTY_CONTENT,
20837
20840
  LogEvent.INBOUND_DROP_MISSING_JOBID,
20841
+ LogEvent.INBOUND_DROP_INVALID_JOBID,
20838
20842
  LogEvent.INBOUND_DROP_UNSUPPORTED_MSGTYPE,
20839
20843
  LogEvent.DM_DELIVERED,
20840
20844
  LogEvent.DM_FALLBACK_TO_BACKUP,
@@ -25241,7 +25245,7 @@ var require_websocket2 = __commonJS({
25241
25245
  var http2 = require("http");
25242
25246
  var net = require("net");
25243
25247
  var tls = require("tls");
25244
- var { randomBytes: randomBytes4, createHash: createHash6 } = require("crypto");
25248
+ var { randomBytes: randomBytes4, createHash: createHash7 } = require("crypto");
25245
25249
  var { Duplex, Readable } = require("stream");
25246
25250
  var { URL: URL2 } = require("url");
25247
25251
  var PerMessageDeflate = require_permessage_deflate();
@@ -25901,7 +25905,7 @@ var require_websocket2 = __commonJS({
25901
25905
  abortHandshake(websocket, socket, "Invalid Upgrade header");
25902
25906
  return;
25903
25907
  }
25904
- const digest = createHash6("sha1").update(key + GUID).digest("base64");
25908
+ const digest = createHash7("sha1").update(key + GUID).digest("base64");
25905
25909
  if (res.headers["sec-websocket-accept"] !== digest) {
25906
25910
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
25907
25911
  return;
@@ -26268,7 +26272,7 @@ var require_websocket_server = __commonJS({
26268
26272
  var EventEmitter2 = require("events");
26269
26273
  var http2 = require("http");
26270
26274
  var { Duplex } = require("stream");
26271
- var { createHash: createHash6 } = require("crypto");
26275
+ var { createHash: createHash7 } = require("crypto");
26272
26276
  var extension = require_extension();
26273
26277
  var PerMessageDeflate = require_permessage_deflate();
26274
26278
  var subprotocol = require_subprotocol();
@@ -26569,7 +26573,7 @@ var require_websocket_server = __commonJS({
26569
26573
  );
26570
26574
  }
26571
26575
  if (this._state > RUNNING) return abortHandshake(socket, 503);
26572
- const digest = createHash6("sha1").update(key + GUID).digest("base64");
26576
+ const digest = createHash7("sha1").update(key + GUID).digest("base64");
26573
26577
  const headers = [
26574
26578
  "HTTP/1.1 101 Switching Protocols",
26575
26579
  "Upgrade: websocket",
@@ -26934,7 +26938,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
26934
26938
  client: {
26935
26939
  id: "gateway-client",
26936
26940
  displayName: "okx-a2a-node",
26937
- version: "0.2.11",
26941
+ version: "0.2.12-beta-7449a77b9d-260909165309",
26938
26942
  platform: "node",
26939
26943
  mode: "backend",
26940
26944
  instanceId
@@ -26945,7 +26949,7 @@ function buildConnectParams(config, instanceId, protocolVersion) {
26945
26949
  commands: [],
26946
26950
  permissions: {},
26947
26951
  locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
26948
- userAgent: `okx-a2a-node/${"0.2.11"}`,
26952
+ userAgent: `okx-a2a-node/${"0.2.12-beta-7449a77b9d-260909165309"}`,
26949
26953
  auth: {
26950
26954
  ...config.token ? { token: config.token } : {},
26951
26955
  ...config.password ? { password: config.password } : {}
@@ -29004,7 +29008,7 @@ var init_sentry_config = __esm({
29004
29008
  environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
29005
29009
  SENTRY_CONFIG = {
29006
29010
  projectName: "okx/openclaw-okx-a2a-extension",
29007
- release: "0.2.11",
29011
+ release: "0.2.12-beta-7449a77b9d-260909165309",
29008
29012
  environment,
29009
29013
  runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
29010
29014
  };
@@ -29293,7 +29297,7 @@ var require_BufferList = __commonJS({
29293
29297
  this.head = this.tail = null;
29294
29298
  this.length = 0;
29295
29299
  };
29296
- BufferList.prototype.join = function join33(s) {
29300
+ BufferList.prototype.join = function join34(s) {
29297
29301
  if (this.length === 0) return "";
29298
29302
  var p = this.head;
29299
29303
  var ret = "" + p.data;
@@ -38801,6 +38805,27 @@ var require_lib3 = __commonJS({
38801
38805
  }
38802
38806
  });
38803
38807
 
38808
+ // src/ai-run-log.ts
38809
+ function hashAiRunLogIdentifier(value) {
38810
+ return (0, import_node_crypto7.createHash)("sha256").update(value).digest("hex").slice(0, 24);
38811
+ }
38812
+ function buildAiRunLogFileName(request) {
38813
+ const messageIdHash = hashAiRunLogIdentifier(request.messageId);
38814
+ const jobIdHash = hashAiRunLogIdentifier(request.jobId ?? "unknown");
38815
+ if (request.source === "job-dispatch") {
38816
+ return `ai-job-${jobIdHash}-${messageIdHash}.log`;
38817
+ }
38818
+ const sessionKeyHash = hashAiRunLogIdentifier(request.sessionKey);
38819
+ return `ai-session-job-${jobIdHash}-${sessionKeyHash}-${messageIdHash}.log`;
38820
+ }
38821
+ var import_node_crypto7;
38822
+ var init_ai_run_log = __esm({
38823
+ "src/ai-run-log.ts"() {
38824
+ "use strict";
38825
+ import_node_crypto7 = require("node:crypto");
38826
+ }
38827
+ });
38828
+
38804
38829
  // src/logs-export-filter.ts
38805
38830
  async function readFilteredLog(path2, options, correlationIds, requireCorrelation, includeDiagnosticContent = options.includeSensitiveContent, maxOutputBytes = Math.floor(options.maxSizeMb * 1024 * 1024), recordMode = "generic") {
38806
38831
  try {
@@ -39438,7 +39463,7 @@ async function writeArchiveAtomically(outputPath, archive, overwrite) {
39438
39463
  await (0, import_promises9.mkdir)((0, import_node_path20.dirname)(outputPath), { recursive: true });
39439
39464
  const temporaryPath = (0, import_node_path20.join)(
39440
39465
  (0, import_node_path20.dirname)(outputPath),
39441
- `.${(0, import_node_path20.basename)(outputPath)}.${(0, import_node_crypto7.randomUUID)()}.tmp`
39466
+ `.${(0, import_node_path20.basename)(outputPath)}.${(0, import_node_crypto8.randomUUID)()}.tmp`
39442
39467
  );
39443
39468
  try {
39444
39469
  await (0, import_promises9.writeFile)(temporaryPath, archive, { flag: "wx", mode: 384 });
@@ -39457,16 +39482,16 @@ async function writeArchiveAtomically(outputPath, archive, overwrite) {
39457
39482
  }
39458
39483
  }
39459
39484
  function hashDiagnosticFileContent(content2) {
39460
- return (0, import_node_crypto7.createHash)("sha256").update(content2).digest("hex");
39485
+ return (0, import_node_crypto8.createHash)("sha256").update(content2).digest("hex");
39461
39486
  }
39462
39487
  function isUnavailableError(err2) {
39463
39488
  return !!err2 && typeof err2 === "object" && "diagnosticUnavailable" in err2;
39464
39489
  }
39465
- var import_node_crypto7, import_node_fs16, import_promises9, import_node_path20;
39490
+ var import_node_crypto8, import_node_fs16, import_promises9, import_node_path20;
39466
39491
  var init_logs_export_archive = __esm({
39467
39492
  "src/logs-export-archive.ts"() {
39468
39493
  "use strict";
39469
- import_node_crypto7 = require("node:crypto");
39494
+ import_node_crypto8 = require("node:crypto");
39470
39495
  import_node_fs16 = require("node:fs");
39471
39496
  import_promises9 = require("node:fs/promises");
39472
39497
  import_node_path20 = require("node:path");
@@ -39574,8 +39599,8 @@ function readSqliteRows(dbPath, sql, params = []) {
39574
39599
  if (!(0, import_node_fs17.existsSync)(dbPath)) {
39575
39600
  throw unavailable(`SQLite database not found: ${dbPath}`);
39576
39601
  }
39577
- const { DatabaseSync: DatabaseSync4 } = loadSqlite3();
39578
- const db = new DatabaseSync4(dbPath, { readOnly: true });
39602
+ const { DatabaseSync: DatabaseSync5 } = loadSqlite3();
39603
+ const db = new DatabaseSync5(dbPath, { readOnly: true });
39579
39604
  try {
39580
39605
  return db.prepare(sql).all(...params);
39581
39606
  } finally {
@@ -39839,7 +39864,7 @@ async function assertRegularFile2(path2) {
39839
39864
  }
39840
39865
  async function inspectRegularFile(path2) {
39841
39866
  const file = await assertRegularFile2(path2);
39842
- const hash2 = (0, import_node_crypto8.createHash)("sha256");
39867
+ const hash2 = (0, import_node_crypto9.createHash)("sha256");
39843
39868
  for await (const chunk of (0, import_node_fs18.createReadStream)(path2)) {
39844
39869
  hash2.update(chunk);
39845
39870
  }
@@ -39891,11 +39916,11 @@ function unavailable2(message) {
39891
39916
  function normalizeKey2(value) {
39892
39917
  return value.toLowerCase().replace(/[^a-z0-9]/g, "");
39893
39918
  }
39894
- var import_node_crypto8, import_node_fs18, import_promises10, import_node_path22, MAX_JSON_FILE_BYTES, STRONG_CORRELATION_KEYS, WEAK_CORRELATION_KEYS;
39919
+ var import_node_crypto9, import_node_fs18, import_promises10, import_node_path22, MAX_JSON_FILE_BYTES, STRONG_CORRELATION_KEYS, WEAK_CORRELATION_KEYS;
39895
39920
  var init_logs_export_utils = __esm({
39896
39921
  "src/logs-export-utils.ts"() {
39897
39922
  "use strict";
39898
- import_node_crypto8 = require("node:crypto");
39923
+ import_node_crypto9 = require("node:crypto");
39899
39924
  import_node_fs18 = require("node:fs");
39900
39925
  import_promises10 = require("node:fs/promises");
39901
39926
  import_node_path22 = require("node:path");
@@ -40174,7 +40199,7 @@ async function exportDiagnosticLogs(options) {
40174
40199
  node: process.version,
40175
40200
  platform: process.platform,
40176
40201
  arch: process.arch,
40177
- packageVersion: true ? "0.2.11" : "unknown",
40202
+ packageVersion: true ? "0.2.12-beta-7449a77b9d-260909165309" : "unknown",
40178
40203
  sensitiveContentIncluded: options.includeSensitiveContent,
40179
40204
  listenerAndLlmContentIncluded: true,
40180
40205
  credentialsAlwaysRedacted: true,
@@ -40393,9 +40418,11 @@ async function collectA2aLogs(state, paths, options, sessionKeys, correlationIds
40393
40418
  if (!name.endsWith(".log") || !name.startsWith("ai-") && !name.startsWith("ai-session-")) {
40394
40419
  continue;
40395
40420
  }
40396
- const matchesDirectJob = options.jobId ? name.startsWith(`ai-${encodeURIComponent(options.jobId)}-`) : true;
40421
+ const matchesDirectJob = options.jobId ? name.startsWith(`ai-${encodeURIComponent(options.jobId)}-`) || name.startsWith(`ai-job-${hashAiRunLogIdentifier(options.jobId)}-`) : true;
40397
40422
  const matchesPersistedSession = sessionKeys.some(
40398
- (key) => name.startsWith(`ai-session-${encodeURIComponent(key)}-`)
40423
+ (key) => name.startsWith(`ai-session-${encodeURIComponent(key)}-`) || new RegExp(
40424
+ `^ai-session-job-[0-9a-f]{24}-${hashAiRunLogIdentifier(key)}-`
40425
+ ).test(name)
40399
40426
  );
40400
40427
  const matchesJobSessionFilename = options.jobId ? matchesJobSessionLogFilename(name, options.jobId) : false;
40401
40428
  if (!matchesDirectJob && !matchesPersistedSession && !matchesJobSessionFilename) {
@@ -41008,7 +41035,7 @@ function matchesJobSessionLogFilename(name, jobId) {
41008
41035
  const encodedJobId = encodeURIComponent(jobId);
41009
41036
  const jobSessionPrefix = encodeURIComponent(`job:${encodedJobId}:`);
41010
41037
  const backupSessionKey = encodeURIComponent(`backup:${encodedJobId}`);
41011
- return name.startsWith(`ai-session-${jobSessionPrefix}`) || name.startsWith(`ai-session-${backupSessionKey}-`);
41038
+ return name.startsWith(`ai-session-${jobSessionPrefix}`) || name.startsWith(`ai-session-${backupSessionKey}-`) || name.startsWith(`ai-session-job-${hashAiRunLogIdentifier(jobId)}-`);
41012
41039
  }
41013
41040
  function isOpenClawSessionLogName(name) {
41014
41041
  return name.endsWith(".jsonl") && name !== "sessions.json";
@@ -41042,6 +41069,7 @@ var init_logs_export = __esm({
41042
41069
  import_node_os8 = require("node:os");
41043
41070
  import_node_path23 = require("node:path");
41044
41071
  import_jszip = __toESM(require_lib3());
41072
+ init_ai_run_log();
41045
41073
  init_logs_export_archive();
41046
41074
  init_logs_export_database();
41047
41075
  init_logs_export_filter();
@@ -41068,6 +41096,11 @@ function getA2ACapabilities() {
41068
41096
  ok: true,
41069
41097
  fixCommands: [],
41070
41098
  message: ""
41099
+ },
41100
+ tradeRecordsV1: {
41101
+ ok: true,
41102
+ fixCommands: [],
41103
+ message: ""
41071
41104
  }
41072
41105
  };
41073
41106
  }
@@ -41097,6 +41130,1057 @@ var init_capabilities_cli = __esm({
41097
41130
  }
41098
41131
  });
41099
41132
 
41133
+ // src/trade-records-store.ts
41134
+ function resolveTradeRecordsDbPath(homeDir) {
41135
+ return (0, import_node_path24.join)(resolveTaskPaths(homeDir).bzRecordsDir, TRADE_RECORDS_DB_NAME);
41136
+ }
41137
+ function tradeRecordsDbExists(homeDir) {
41138
+ return (0, import_node_fs20.existsSync)(resolveTradeRecordsDbPath(homeDir));
41139
+ }
41140
+ function encodeTradeRecordCursor(cursor) {
41141
+ return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
41142
+ }
41143
+ function decodeTradeRecordCursor(value) {
41144
+ try {
41145
+ const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
41146
+ if (parsed.version !== 1 || parsed.sortBy !== "createdAt" && parsed.sortBy !== "updatedAt" || parsed.order !== "asc" && parsed.order !== "desc" || typeof parsed.timestamp !== "number" || !Number.isSafeInteger(parsed.timestamp) || parsed.timestamp < 0 || typeof parsed.deliveryId !== "string" || parsed.deliveryId.length === 0) {
41147
+ throw new Error("invalid cursor payload");
41148
+ }
41149
+ return parsed;
41150
+ } catch {
41151
+ throw new TradeRecordsStoreError("INVALID_ARGUMENT", "--cursor is invalid");
41152
+ }
41153
+ }
41154
+ function applyMigrationV1(db) {
41155
+ db.exec(`
41156
+ CREATE TABLE ${TABLE_NAME} (
41157
+ delivery_id TEXT PRIMARY KEY,
41158
+ job_id TEXT NOT NULL,
41159
+ status TEXT NOT NULL,
41160
+ reason TEXT NOT NULL DEFAULT '',
41161
+ extra TEXT NOT NULL DEFAULT '{}',
41162
+ created_at INTEGER NOT NULL,
41163
+ updated_at INTEGER NOT NULL,
41164
+ deleted_at INTEGER,
41165
+ CHECK (length(job_id) > 0),
41166
+ CHECK (length(delivery_id) > 0),
41167
+ CHECK (length(status) > 0),
41168
+ CHECK (json_valid(extra)),
41169
+ CHECK (json_type(extra) = 'object')
41170
+ )
41171
+ `);
41172
+ db.exec(`CREATE INDEX idx_trade_records_job_updated ON ${TABLE_NAME}(job_id, updated_at DESC, delivery_id DESC)`);
41173
+ db.exec(`CREATE INDEX idx_trade_records_status_updated ON ${TABLE_NAME}(status, updated_at DESC, delivery_id DESC)`);
41174
+ db.exec(`CREATE INDEX idx_trade_records_created ON ${TABLE_NAME}(created_at DESC, delivery_id DESC)`);
41175
+ db.exec(`CREATE INDEX idx_trade_records_deleted ON ${TABLE_NAME}(deleted_at, updated_at DESC)`);
41176
+ }
41177
+ function buildWhere(filter2, includeCursor) {
41178
+ const clauses = [];
41179
+ const params = [];
41180
+ const add = (clause, ...values) => {
41181
+ clauses.push(clause);
41182
+ params.push(...values);
41183
+ };
41184
+ if (!filter2.includeDeleted) {
41185
+ add(filter2.onlyDeleted ? "deleted_at IS NOT NULL" : "deleted_at IS NULL");
41186
+ } else if (filter2.onlyDeleted) {
41187
+ add("deleted_at IS NOT NULL");
41188
+ }
41189
+ if (filter2.jobId) add("job_id = ?", filter2.jobId);
41190
+ if (filter2.deliveryId) add("delivery_id = ?", filter2.deliveryId);
41191
+ if (filter2.statuses && filter2.statuses.length > 0) {
41192
+ add(`status IN (${filter2.statuses.map(() => "?").join(", ")})`, ...filter2.statuses);
41193
+ }
41194
+ if (filter2.reason !== void 0) add("reason = ?", filter2.reason);
41195
+ if (filter2.reasonContains !== void 0) {
41196
+ add("reason LIKE ? ESCAPE '\\'", `%${escapeLike(filter2.reasonContains)}%`);
41197
+ }
41198
+ if (filter2.createdFrom !== void 0) add("created_at >= ?", filter2.createdFrom);
41199
+ if (filter2.createdTo !== void 0) add("created_at <= ?", filter2.createdTo);
41200
+ if (filter2.updatedFrom !== void 0) add("updated_at >= ?", filter2.updatedFrom);
41201
+ if (filter2.updatedTo !== void 0) add("updated_at <= ?", filter2.updatedTo);
41202
+ for (const extra of filter2.extraEquals ?? []) {
41203
+ if (extra.value === null) {
41204
+ add("json_type(extra, ?) = 'null'", extra.path);
41205
+ } else {
41206
+ add(
41207
+ "json_extract(extra, ?) = ?",
41208
+ extra.path,
41209
+ typeof extra.value === "boolean" ? extra.value ? 1 : 0 : extra.value
41210
+ );
41211
+ }
41212
+ }
41213
+ if (includeCursor && filter2.cursor) {
41214
+ const column = filter2.sortBy === "createdAt" ? "created_at" : "updated_at";
41215
+ const operator = filter2.order === "asc" ? ">" : "<";
41216
+ add(
41217
+ `(${column} ${operator} ? OR (${column} = ? AND delivery_id ${operator} ?))`,
41218
+ filter2.cursor.timestamp,
41219
+ filter2.cursor.timestamp,
41220
+ filter2.cursor.deliveryId
41221
+ );
41222
+ }
41223
+ return { clauses, params };
41224
+ }
41225
+ function mapRow(row) {
41226
+ const extra = JSON.parse(row.extra);
41227
+ if (!isJsonObject(extra)) {
41228
+ throw new TradeRecordsStoreError("DATABASE_READ_FAILED", "stored trade record extra is not a JSON object");
41229
+ }
41230
+ return {
41231
+ jobId: row.job_id,
41232
+ deliveryId: row.delivery_id,
41233
+ status: row.status,
41234
+ reason: row.reason,
41235
+ extra,
41236
+ createdAt: row.created_at,
41237
+ updatedAt: row.updated_at,
41238
+ deletedAt: row.deleted_at
41239
+ };
41240
+ }
41241
+ function isJsonObject(value) {
41242
+ return typeof value === "object" && value !== null && !Array.isArray(value);
41243
+ }
41244
+ function escapeLike(value) {
41245
+ return value.replace(/[\\%_]/g, (character) => `\\${character}`);
41246
+ }
41247
+ function readPragmaNumber(db, name) {
41248
+ const row = db.prepare(`PRAGMA ${name}`).get();
41249
+ return Number(row[name] ?? 0);
41250
+ }
41251
+ function assertNotSymlink(path2, label) {
41252
+ if (!(0, import_node_fs20.existsSync)(path2)) {
41253
+ return;
41254
+ }
41255
+ if ((0, import_node_fs20.lstatSync)(path2).isSymbolicLink()) {
41256
+ throw new TradeRecordsStoreError("DATABASE_PATH_UNSAFE", `${label} must not be a symbolic link`);
41257
+ }
41258
+ }
41259
+ function assertSafeDatabasePath(dbPath) {
41260
+ assertSafeDatabaseFile(dbPath);
41261
+ for (const suffix of ["-journal", "-wal", "-shm"]) {
41262
+ assertNotSymlink(`${dbPath}${suffix}`, `trade records database sidecar ${suffix}`);
41263
+ }
41264
+ }
41265
+ function assertSafeDatabaseFile(dbPath) {
41266
+ if (!(0, import_node_fs20.existsSync)(dbPath)) {
41267
+ return;
41268
+ }
41269
+ const stat4 = (0, import_node_fs20.lstatSync)(dbPath);
41270
+ if (stat4.isSymbolicLink()) {
41271
+ throw new TradeRecordsStoreError(
41272
+ "DATABASE_PATH_UNSAFE",
41273
+ "trade records database must not be a symbolic link"
41274
+ );
41275
+ }
41276
+ if (!stat4.isFile() || stat4.nlink !== 1) {
41277
+ throw new TradeRecordsStoreError(
41278
+ "DATABASE_PATH_UNSAFE",
41279
+ "trade records database must be a regular file with one hard link"
41280
+ );
41281
+ }
41282
+ }
41283
+ function rollbackQuietly(db) {
41284
+ try {
41285
+ db.exec("ROLLBACK");
41286
+ } catch {
41287
+ }
41288
+ }
41289
+ function withBusyRetry(operation) {
41290
+ for (let attempt = 1; ; attempt += 1) {
41291
+ try {
41292
+ return operation();
41293
+ } catch (error) {
41294
+ if (!isSqliteBusyError(error) || attempt >= WRITE_RETRY_ATTEMPTS) {
41295
+ throw error;
41296
+ }
41297
+ sleepSyncMs2(Math.min(100 * 2 ** (attempt - 1), 1600));
41298
+ }
41299
+ }
41300
+ }
41301
+ function sleepSyncMs2(ms) {
41302
+ const buffer2 = new Int32Array(new SharedArrayBuffer(4));
41303
+ Atomics.wait(buffer2, 0, 0, ms);
41304
+ }
41305
+ function loadSqlite4() {
41306
+ const originalEmitWarning = process.emitWarning;
41307
+ process.emitWarning = ((warning, ...args) => {
41308
+ const message = typeof warning === "string" ? warning : warning.message;
41309
+ if (message.includes("SQLite is an experimental feature") && args.some((arg) => arg === "ExperimentalWarning")) {
41310
+ return;
41311
+ }
41312
+ return originalEmitWarning.call(process, warning, ...args);
41313
+ });
41314
+ try {
41315
+ return require("node:sqlite");
41316
+ } finally {
41317
+ process.emitWarning = originalEmitWarning;
41318
+ }
41319
+ }
41320
+ var import_node_fs20, import_node_path24, DatabaseSync3, TRADE_RECORDS_APPLICATION_ID, TRADE_RECORDS_SCHEMA_VERSION, TRADE_RECORDS_DB_NAME, TABLE_NAME, WRITE_RETRY_ATTEMPTS, TradeRecordsStoreError, TradeRecordsStore;
41321
+ var init_trade_records_store = __esm({
41322
+ "src/trade-records-store.ts"() {
41323
+ "use strict";
41324
+ import_node_fs20 = require("node:fs");
41325
+ import_node_path24 = require("node:path");
41326
+ init_paths();
41327
+ init_session_store();
41328
+ ({ DatabaseSync: DatabaseSync3 } = loadSqlite4());
41329
+ TRADE_RECORDS_APPLICATION_ID = 1329681490;
41330
+ TRADE_RECORDS_SCHEMA_VERSION = 1;
41331
+ TRADE_RECORDS_DB_NAME = "trade-records.sqlite";
41332
+ TABLE_NAME = `"trade-records"`;
41333
+ WRITE_RETRY_ATTEMPTS = 6;
41334
+ TradeRecordsStoreError = class extends Error {
41335
+ code;
41336
+ constructor(code, message) {
41337
+ super(message);
41338
+ this.name = "TradeRecordsStoreError";
41339
+ this.code = code;
41340
+ }
41341
+ };
41342
+ TradeRecordsStore = class _TradeRecordsStore {
41343
+ dbPath;
41344
+ db;
41345
+ constructor(dbPath, db) {
41346
+ this.dbPath = dbPath;
41347
+ this.db = db;
41348
+ }
41349
+ static openForWrite(homeDir) {
41350
+ const paths = resolveTaskPaths(homeDir);
41351
+ assertNotSymlink(paths.bzRecordsDir, "trade records directory");
41352
+ ensureTaskDir(paths.bzRecordsDir);
41353
+ assertNotSymlink(paths.bzRecordsDir, "trade records directory");
41354
+ const dbPath = (0, import_node_path24.join)(paths.bzRecordsDir, TRADE_RECORDS_DB_NAME);
41355
+ assertSafeDatabasePath(dbPath);
41356
+ const db = new DatabaseSync3(dbPath);
41357
+ const store = new _TradeRecordsStore(dbPath, db);
41358
+ try {
41359
+ store.configureConnectionForWrite();
41360
+ store.ensureSchemaForWrite();
41361
+ return store;
41362
+ } catch (error) {
41363
+ db.close();
41364
+ throw error;
41365
+ }
41366
+ }
41367
+ static openForRead(homeDir) {
41368
+ const dbPath = resolveTradeRecordsDbPath(homeDir);
41369
+ if (!(0, import_node_fs20.existsSync)(dbPath)) {
41370
+ return null;
41371
+ }
41372
+ assertSafeDatabaseFile(dbPath);
41373
+ const db = new DatabaseSync3(dbPath, { readOnly: true });
41374
+ const store = new _TradeRecordsStore(dbPath, db);
41375
+ try {
41376
+ db.exec("PRAGMA query_only=ON");
41377
+ store.assertReadableSchema();
41378
+ return store;
41379
+ } catch (error) {
41380
+ db.close();
41381
+ throw error;
41382
+ }
41383
+ }
41384
+ close() {
41385
+ this.db.close();
41386
+ }
41387
+ insert(records) {
41388
+ return this.withWriteTransaction(() => {
41389
+ const existingStatement = this.db.prepare(
41390
+ `SELECT deleted_at FROM ${TABLE_NAME} WHERE delivery_id = ?`
41391
+ );
41392
+ const upsertStatement = this.db.prepare(`
41393
+ INSERT INTO ${TABLE_NAME} (
41394
+ delivery_id, job_id, status, reason, extra, created_at, updated_at, deleted_at
41395
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, NULL)
41396
+ ON CONFLICT(delivery_id) DO UPDATE SET
41397
+ job_id = excluded.job_id,
41398
+ status = excluded.status,
41399
+ reason = excluded.reason,
41400
+ extra = excluded.extra,
41401
+ updated_at = excluded.updated_at,
41402
+ deleted_at = NULL
41403
+ `);
41404
+ const now = Date.now();
41405
+ let insertedCount = 0;
41406
+ let updatedCount = 0;
41407
+ let restoredCount = 0;
41408
+ for (const record of records) {
41409
+ const existing = existingStatement.get(record.deliveryId);
41410
+ if (!existing) {
41411
+ insertedCount += 1;
41412
+ } else if (existing.deleted_at === null) {
41413
+ updatedCount += 1;
41414
+ } else {
41415
+ restoredCount += 1;
41416
+ }
41417
+ upsertStatement.run(
41418
+ record.deliveryId,
41419
+ record.jobId,
41420
+ record.status,
41421
+ record.reason,
41422
+ JSON.stringify(record.extra),
41423
+ now,
41424
+ now
41425
+ );
41426
+ }
41427
+ return { insertedCount, updatedCount, restoredCount };
41428
+ });
41429
+ }
41430
+ delete(deliveryId, jobId) {
41431
+ return this.withWriteTransaction(() => {
41432
+ const existing = this.db.prepare(`
41433
+ SELECT deleted_at FROM ${TABLE_NAME}
41434
+ WHERE delivery_id = ?${jobId ? " AND job_id = ?" : ""}
41435
+ `).get(...jobId ? [deliveryId, jobId] : [deliveryId]);
41436
+ if (!existing) {
41437
+ return { deliveryId, deleted: false, alreadyDeleted: false, notFound: true };
41438
+ }
41439
+ if (existing.deleted_at !== null) {
41440
+ return { deliveryId, deleted: false, alreadyDeleted: true, notFound: false };
41441
+ }
41442
+ const now = Date.now();
41443
+ this.db.prepare(`
41444
+ UPDATE ${TABLE_NAME}
41445
+ SET deleted_at = ?, updated_at = ?
41446
+ WHERE delivery_id = ?${jobId ? " AND job_id = ?" : ""} AND deleted_at IS NULL
41447
+ `).run(...jobId ? [now, now, deliveryId, jobId] : [now, now, deliveryId]);
41448
+ return { deliveryId, deleted: true, alreadyDeleted: false, notFound: false };
41449
+ });
41450
+ }
41451
+ query(filter2) {
41452
+ const base = buildWhere(filter2, false);
41453
+ const page = buildWhere(filter2, true);
41454
+ const sortColumn = filter2.sortBy === "createdAt" ? "created_at" : "updated_at";
41455
+ const direction = filter2.order.toUpperCase();
41456
+ const rows = this.db.prepare(`
41457
+ SELECT delivery_id, job_id, status, reason, extra, created_at, updated_at, deleted_at
41458
+ FROM ${TABLE_NAME}
41459
+ ${page.clauses.length > 0 ? `WHERE ${page.clauses.join(" AND ")}` : ""}
41460
+ ORDER BY ${sortColumn} ${direction}, delivery_id ${direction}
41461
+ LIMIT ?
41462
+ `).all(...page.params, filter2.limit + 1);
41463
+ const hasMore = rows.length > filter2.limit;
41464
+ const visibleRows = hasMore ? rows.slice(0, filter2.limit) : rows;
41465
+ const records = visibleRows.map(mapRow);
41466
+ const last = visibleRows.at(-1);
41467
+ const nextCursor = hasMore && last ? encodeTradeRecordCursor({
41468
+ version: 1,
41469
+ sortBy: filter2.sortBy,
41470
+ order: filter2.order,
41471
+ timestamp: filter2.sortBy === "createdAt" ? last.created_at : last.updated_at,
41472
+ deliveryId: last.delivery_id
41473
+ }) : null;
41474
+ let count;
41475
+ if (filter2.includeCount) {
41476
+ const row = this.db.prepare(`
41477
+ SELECT COUNT(*) AS count
41478
+ FROM ${TABLE_NAME}
41479
+ ${base.clauses.length > 0 ? `WHERE ${base.clauses.join(" AND ")}` : ""}
41480
+ `).get(...base.params);
41481
+ count = Number(row.count);
41482
+ }
41483
+ return { records, nextCursor, ...count === void 0 ? {} : { count } };
41484
+ }
41485
+ configureConnectionForWrite() {
41486
+ this.db.exec("PRAGMA busy_timeout=5000");
41487
+ }
41488
+ ensureSchemaForWrite() {
41489
+ withBusyRetry(() => {
41490
+ this.db.exec("BEGIN IMMEDIATE");
41491
+ try {
41492
+ const applicationId = readPragmaNumber(this.db, "application_id");
41493
+ const userVersion = readPragmaNumber(this.db, "user_version");
41494
+ const hasTables = Boolean(this.db.prepare(
41495
+ "SELECT 1 AS present FROM sqlite_master WHERE type = 'table' LIMIT 1"
41496
+ ).get());
41497
+ if (applicationId === 0 && !hasTables && userVersion === 0) {
41498
+ this.db.exec(`PRAGMA application_id=${TRADE_RECORDS_APPLICATION_ID}`);
41499
+ } else if (applicationId !== TRADE_RECORDS_APPLICATION_ID) {
41500
+ throw new TradeRecordsStoreError(
41501
+ "DATABASE_IDENTITY_MISMATCH",
41502
+ "trade records database identity does not match"
41503
+ );
41504
+ }
41505
+ if (userVersion > TRADE_RECORDS_SCHEMA_VERSION) {
41506
+ throw new TradeRecordsStoreError(
41507
+ "DATABASE_SCHEMA_TOO_NEW",
41508
+ `trade records schema version ${userVersion} is newer than supported ${TRADE_RECORDS_SCHEMA_VERSION}`
41509
+ );
41510
+ }
41511
+ if (userVersion < 1) {
41512
+ applyMigrationV1(this.db);
41513
+ this.db.exec("PRAGMA user_version=1");
41514
+ }
41515
+ this.db.exec("COMMIT");
41516
+ } catch (error) {
41517
+ rollbackQuietly(this.db);
41518
+ throw error;
41519
+ }
41520
+ });
41521
+ withBusyRetry(() => {
41522
+ this.db.exec("PRAGMA journal_mode=WAL");
41523
+ this.db.exec("PRAGMA synchronous=FULL");
41524
+ });
41525
+ }
41526
+ assertReadableSchema() {
41527
+ const applicationId = readPragmaNumber(this.db, "application_id");
41528
+ if (applicationId !== TRADE_RECORDS_APPLICATION_ID) {
41529
+ throw new TradeRecordsStoreError(
41530
+ "DATABASE_IDENTITY_MISMATCH",
41531
+ "trade records database identity does not match"
41532
+ );
41533
+ }
41534
+ const userVersion = readPragmaNumber(this.db, "user_version");
41535
+ if (userVersion > TRADE_RECORDS_SCHEMA_VERSION) {
41536
+ throw new TradeRecordsStoreError(
41537
+ "DATABASE_SCHEMA_TOO_NEW",
41538
+ `trade records schema version ${userVersion} is newer than supported ${TRADE_RECORDS_SCHEMA_VERSION}`
41539
+ );
41540
+ }
41541
+ if (userVersion < TRADE_RECORDS_SCHEMA_VERSION) {
41542
+ throw new TradeRecordsStoreError(
41543
+ "DATABASE_MIGRATION_REQUIRED",
41544
+ "trade records database requires a write command to finish migration"
41545
+ );
41546
+ }
41547
+ }
41548
+ withWriteTransaction(operation) {
41549
+ return withBusyRetry(() => {
41550
+ this.db.exec("BEGIN IMMEDIATE");
41551
+ try {
41552
+ const result = operation();
41553
+ this.db.exec("COMMIT");
41554
+ return result;
41555
+ } catch (error) {
41556
+ rollbackQuietly(this.db);
41557
+ throw error;
41558
+ }
41559
+ });
41560
+ }
41561
+ };
41562
+ }
41563
+ });
41564
+
41565
+ // src/trade-records-cli.ts
41566
+ var trade_records_cli_exports = {};
41567
+ __export(trade_records_cli_exports, {
41568
+ handleTradeRecordsCommand: () => handleTradeRecordsCommand,
41569
+ printTradeRecordsUsage: () => printTradeRecordsUsage
41570
+ });
41571
+ async function handleTradeRecordsCommand(args) {
41572
+ const wantsJson = args.includes("--json");
41573
+ try {
41574
+ const subcommand = args[0];
41575
+ if (!subcommand || isHelpArg(subcommand)) {
41576
+ printTradeRecordsUsage();
41577
+ return;
41578
+ }
41579
+ if (args.slice(1).some(isHelpArg)) {
41580
+ printSubcommandUsage(subcommand);
41581
+ return;
41582
+ }
41583
+ if (subcommand === "insert") {
41584
+ handleInsert(args.slice(1));
41585
+ return;
41586
+ }
41587
+ if (subcommand === "query") {
41588
+ handleQuery(args.slice(1));
41589
+ return;
41590
+ }
41591
+ if (subcommand === "delete") {
41592
+ handleDelete(args.slice(1));
41593
+ return;
41594
+ }
41595
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `Unknown trade-records command: ${subcommand}`);
41596
+ } catch (error) {
41597
+ outputError(wantsJson, normalizeError(error));
41598
+ process.exitCode = 1;
41599
+ }
41600
+ }
41601
+ function printTradeRecordsUsage() {
41602
+ console.log(`Usage: okx-a2a trade-records <insert|query|delete> [options]
41603
+
41604
+ Commands:
41605
+ insert Insert or replace trade records by deliveryId.
41606
+ query Query active or soft-deleted trade records.
41607
+ delete Soft-delete one trade record by deliveryId.
41608
+
41609
+ Run \`okx-a2a trade-records <command> --help\` for command-specific help.`);
41610
+ }
41611
+ function printSubcommandUsage(subcommand) {
41612
+ if (subcommand === "insert") {
41613
+ console.log(`Usage: okx-a2a trade-records insert [options]
41614
+
41615
+ Input modes (choose exactly one):
41616
+ --job-id <id> --delivery-id <id> --status <status> [--reason <text>] [--extra <json-object>]
41617
+ --input-json <json-array>
41618
+ --input-file <path-to-json-array>
41619
+
41620
+ Options:
41621
+ --reason <text> Default: empty string.
41622
+ --extra <json> Complete JSON object. Default: {}.
41623
+ --json Print machine-readable summary.`);
41624
+ return;
41625
+ }
41626
+ if (subcommand === "query") {
41627
+ console.log(`Usage: okx-a2a trade-records query [options]
41628
+
41629
+ Options:
41630
+ --job-id <id> Filter by job id.
41631
+ --delivery-id <id> Filter by delivery id.
41632
+ --status <status> Filter by status; repeatable.
41633
+ --reason <text> Exact reason match.
41634
+ --reason-contains <text> Reason substring match.
41635
+ --created-from <epoch-ms> Inclusive createdAt lower bound.
41636
+ --created-to <epoch-ms> Inclusive createdAt upper bound.
41637
+ --updated-from <epoch-ms> Inclusive updatedAt lower bound.
41638
+ --updated-to <epoch-ms> Inclusive updatedAt upper bound.
41639
+ --extra-eq <path=json> Exact extra field match; repeatable.
41640
+ --include-deleted Include active and deleted records.
41641
+ --only-deleted Return only deleted records.
41642
+ --sort-by <createdAt|updatedAt> Default: updatedAt.
41643
+ --order <asc|desc> Default: desc.
41644
+ --limit <n> Default: 100; maximum: 1000.
41645
+ --cursor <cursor> Continue keyset pagination.
41646
+ --count Include total matching count.
41647
+ --json Print machine-readable output.`);
41648
+ return;
41649
+ }
41650
+ if (subcommand === "delete") {
41651
+ console.log(`Usage: okx-a2a trade-records delete --delivery-id <id> [--job-id <id>] [--json]
41652
+
41653
+ Soft-delete one trade record. Repeated deletes and missing records are idempotent.`);
41654
+ return;
41655
+ }
41656
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `Unknown trade-records command: ${subcommand}`);
41657
+ }
41658
+ function handleInsert(args) {
41659
+ const parsed = parseArgs(args, {
41660
+ command: "trade-records insert",
41661
+ options: /* @__PURE__ */ new Set([...INPUT_FIELD_OPTIONS, "input-json", "input-file"]),
41662
+ flags: /* @__PURE__ */ new Set(["json"])
41663
+ });
41664
+ const json = parsed.flags.has("json");
41665
+ const loaded = loadInsertRecords(parsed);
41666
+ const coalesced = coalesceByLastDeliveryId(loaded.records);
41667
+ const store = TradeRecordsStore.openForWrite();
41668
+ try {
41669
+ const result = store.insert(coalesced.records);
41670
+ const payload = {
41671
+ ok: true,
41672
+ operation: "insert",
41673
+ inputCount: loaded.records.length,
41674
+ finalRecordCount: coalesced.records.length,
41675
+ insertedCount: result.insertedCount,
41676
+ updatedCount: result.updatedCount,
41677
+ restoredCount: result.restoredCount,
41678
+ duplicateInputCount: coalesced.duplicateInputCount
41679
+ };
41680
+ if (json) {
41681
+ console.log(JSON.stringify(payload));
41682
+ return;
41683
+ }
41684
+ if (loaded.records.length === 1) {
41685
+ const operation = result.insertedCount === 1 ? "inserted" : result.restoredCount === 1 ? "restored" : "updated";
41686
+ console.log(`Trade record saved: deliveryId=${coalesced.records[0].deliveryId}, result=${operation}`);
41687
+ return;
41688
+ }
41689
+ console.log(`Trade records saved: ${loaded.records.length} inputs, ${coalesced.records.length} final records`);
41690
+ console.log(
41691
+ `Inserted: ${result.insertedCount}, updated: ${result.updatedCount}, restored: ${result.restoredCount}, duplicate inputs overwritten: ${coalesced.duplicateInputCount}`
41692
+ );
41693
+ } finally {
41694
+ store.close();
41695
+ }
41696
+ }
41697
+ function handleQuery(args) {
41698
+ const parsed = parseArgs(args, {
41699
+ command: "trade-records query",
41700
+ options: /* @__PURE__ */ new Set([
41701
+ "job-id",
41702
+ "delivery-id",
41703
+ "status",
41704
+ "reason",
41705
+ "reason-contains",
41706
+ "created-from",
41707
+ "created-to",
41708
+ "updated-from",
41709
+ "updated-to",
41710
+ "extra-eq",
41711
+ "sort-by",
41712
+ "order",
41713
+ "limit",
41714
+ "cursor"
41715
+ ]),
41716
+ flags: /* @__PURE__ */ new Set(["include-deleted", "only-deleted", "count", "json"]),
41717
+ repeatable: /* @__PURE__ */ new Set(["status", "extra-eq"])
41718
+ });
41719
+ const json = parsed.flags.has("json");
41720
+ if (parsed.flags.has("include-deleted") && parsed.flags.has("only-deleted")) {
41721
+ throw new TradeRecordsCliError(
41722
+ "INVALID_ARGUMENT",
41723
+ "--include-deleted and --only-deleted cannot be used together"
41724
+ );
41725
+ }
41726
+ const sortBy = readChoice(parsed, "sort-by", ["createdAt", "updatedAt"]) ?? "updatedAt";
41727
+ const order = readChoice(parsed, "order", ["asc", "desc"]) ?? "desc";
41728
+ const cursorRaw = readSingle(parsed, "cursor");
41729
+ const cursor = cursorRaw ? decodeTradeRecordCursor(cursorRaw) : void 0;
41730
+ if (cursor && (cursor.sortBy !== sortBy || cursor.order !== order)) {
41731
+ throw new TradeRecordsCliError(
41732
+ "INVALID_ARGUMENT",
41733
+ "--cursor does not match the requested --sort-by and --order"
41734
+ );
41735
+ }
41736
+ const createdFrom = readTimestamp(parsed, "created-from");
41737
+ const createdTo = readTimestamp(parsed, "created-to");
41738
+ const updatedFrom = readTimestamp(parsed, "updated-from");
41739
+ const updatedTo = readTimestamp(parsed, "updated-to");
41740
+ assertRange("created", createdFrom, createdTo);
41741
+ assertRange("updated", updatedFrom, updatedTo);
41742
+ const filter2 = {
41743
+ sortBy,
41744
+ order,
41745
+ limit: readLimit(parsed),
41746
+ statuses: parsed.options.get("status")?.map((value) => requireText(value, "--status", MAX_STATUS_LENGTH)),
41747
+ extraEquals: (parsed.options.get("extra-eq") ?? []).map(parseExtraFilter),
41748
+ includeDeleted: parsed.flags.has("include-deleted"),
41749
+ onlyDeleted: parsed.flags.has("only-deleted"),
41750
+ includeCount: parsed.flags.has("count"),
41751
+ ...readOptionalText(parsed, "job-id", MAX_ID_LENGTH) ? { jobId: readOptionalText(parsed, "job-id", MAX_ID_LENGTH) } : {},
41752
+ ...readOptionalText(parsed, "delivery-id", MAX_ID_LENGTH) ? { deliveryId: readOptionalText(parsed, "delivery-id", MAX_ID_LENGTH) } : {},
41753
+ ...readSingle(parsed, "reason") !== void 0 ? { reason: readSingle(parsed, "reason") } : {},
41754
+ ...readSingle(parsed, "reason-contains") !== void 0 ? { reasonContains: readSingle(parsed, "reason-contains") } : {},
41755
+ ...createdFrom === void 0 ? {} : { createdFrom },
41756
+ ...createdTo === void 0 ? {} : { createdTo },
41757
+ ...updatedFrom === void 0 ? {} : { updatedFrom },
41758
+ ...updatedTo === void 0 ? {} : { updatedTo },
41759
+ ...cursor ? { cursor } : {}
41760
+ };
41761
+ const store = TradeRecordsStore.openForRead();
41762
+ if (!store) {
41763
+ outputQuery(json, [], filter2.limit, null, filter2.includeCount ? 0 : void 0);
41764
+ return;
41765
+ }
41766
+ try {
41767
+ const result = store.query(filter2);
41768
+ outputQuery(json, result.records, filter2.limit, result.nextCursor, result.count);
41769
+ } finally {
41770
+ store.close();
41771
+ }
41772
+ }
41773
+ function handleDelete(args) {
41774
+ const parsed = parseArgs(args, {
41775
+ command: "trade-records delete",
41776
+ options: /* @__PURE__ */ new Set(["delivery-id", "job-id"]),
41777
+ flags: /* @__PURE__ */ new Set(["json"])
41778
+ });
41779
+ const json = parsed.flags.has("json");
41780
+ const deliveryId = requireText(readSingle(parsed, "delivery-id"), "--delivery-id", MAX_ID_LENGTH);
41781
+ const jobId = readOptionalText(parsed, "job-id", MAX_ID_LENGTH);
41782
+ if (!tradeRecordsDbExists()) {
41783
+ outputDelete(json, {
41784
+ deliveryId,
41785
+ deleted: false,
41786
+ alreadyDeleted: false,
41787
+ notFound: true
41788
+ });
41789
+ return;
41790
+ }
41791
+ const store = TradeRecordsStore.openForWrite();
41792
+ try {
41793
+ outputDelete(json, store.delete(deliveryId, jobId));
41794
+ } finally {
41795
+ store.close();
41796
+ }
41797
+ }
41798
+ function loadInsertRecords(parsed) {
41799
+ const inputJson = readSingle(parsed, "input-json");
41800
+ const inputFile = readSingle(parsed, "input-file");
41801
+ const providedFieldOptions = [...INPUT_FIELD_OPTIONS].filter((name) => parsed.options.has(name));
41802
+ const modeCount = Number(inputJson !== void 0) + Number(inputFile !== void 0) + Number(providedFieldOptions.length > 0);
41803
+ if (modeCount !== 1) {
41804
+ throw new TradeRecordsCliError(
41805
+ "INVALID_ARGUMENT",
41806
+ "trade-records insert requires exactly one input mode: field options, --input-json, or --input-file"
41807
+ );
41808
+ }
41809
+ if (inputJson !== void 0) {
41810
+ assertInputSize(inputJson, "--input-json");
41811
+ return { records: parseRecordArray(inputJson, "--input-json") };
41812
+ }
41813
+ if (inputFile !== void 0) {
41814
+ let content2;
41815
+ try {
41816
+ const stat4 = (0, import_node_fs21.statSync)(inputFile);
41817
+ if (!stat4.isFile()) {
41818
+ throw new Error("not a regular file");
41819
+ }
41820
+ if (stat4.size > MAX_INPUT_BYTES) {
41821
+ throw new TradeRecordsCliError("INPUT_TOO_LARGE", `--input-file exceeds ${MAX_INPUT_BYTES} bytes`);
41822
+ }
41823
+ content2 = (0, import_node_fs21.readFileSync)(inputFile, "utf8");
41824
+ } catch (error) {
41825
+ if (error instanceof TradeRecordsCliError) throw error;
41826
+ throw new TradeRecordsCliError("INVALID_INPUT_FILE", `could not read --input-file: ${String(error)}`);
41827
+ }
41828
+ return { records: parseRecordArray(content2, "--input-file") };
41829
+ }
41830
+ const extraRaw = readSingle(parsed, "extra");
41831
+ let extra = {};
41832
+ if (extraRaw !== void 0) {
41833
+ extra = parseJsonObject(extraRaw, "--extra");
41834
+ }
41835
+ return {
41836
+ records: [normalizeRecord({
41837
+ jobId: readSingle(parsed, "job-id"),
41838
+ deliveryId: readSingle(parsed, "delivery-id"),
41839
+ status: readSingle(parsed, "status"),
41840
+ reason: readSingle(parsed, "reason") ?? "",
41841
+ extra
41842
+ }, 0)]
41843
+ };
41844
+ }
41845
+ function parseRecordArray(raw, label) {
41846
+ let parsed;
41847
+ try {
41848
+ parsed = JSON.parse(raw);
41849
+ } catch {
41850
+ throw new TradeRecordsCliError("INVALID_INPUT_JSON", `${label} must contain valid JSON`);
41851
+ }
41852
+ if (!Array.isArray(parsed) || parsed.length === 0) {
41853
+ throw new TradeRecordsCliError("INVALID_INPUT_JSON", `${label} must contain a non-empty JSON array`);
41854
+ }
41855
+ if (parsed.length > MAX_BATCH_RECORDS) {
41856
+ throw new TradeRecordsCliError(
41857
+ "TOO_MANY_RECORDS",
41858
+ `${label} contains ${parsed.length} records; maximum is ${MAX_BATCH_RECORDS}`
41859
+ );
41860
+ }
41861
+ const records = [];
41862
+ const details = [];
41863
+ for (let index2 = 0; index2 < parsed.length; index2 += 1) {
41864
+ try {
41865
+ records.push(normalizeRecord(parsed[index2], index2));
41866
+ } catch (error) {
41867
+ const normalized = normalizeError(error);
41868
+ details.push(...normalized.details ?? [{ index: index2, reason: normalized.message }]);
41869
+ }
41870
+ }
41871
+ if (details.length > 0) {
41872
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "one or more trade records are invalid", details);
41873
+ }
41874
+ return records;
41875
+ }
41876
+ function normalizeRecord(value, index2) {
41877
+ if (!isJsonObject2(value)) {
41878
+ throw invalidField(index2, void 0, "must be a JSON object");
41879
+ }
41880
+ for (const field of Object.keys(value)) {
41881
+ if (FORBIDDEN_RECORD_FIELDS.has(field)) {
41882
+ throw invalidField(index2, field, "business callers must not provide timestamp fields");
41883
+ }
41884
+ if (!ALLOWED_RECORD_FIELDS.has(field)) {
41885
+ throw invalidField(index2, field, "unknown field; put extensible fields inside extra");
41886
+ }
41887
+ }
41888
+ const jobId = requireRecordText(value.jobId, index2, "jobId", MAX_ID_LENGTH);
41889
+ const deliveryId = requireRecordText(value.deliveryId, index2, "deliveryId", MAX_ID_LENGTH);
41890
+ const status = requireRecordText(value.status, index2, "status", MAX_STATUS_LENGTH);
41891
+ const reason = value.reason === void 0 ? "" : requireRecordString(value.reason, index2, "reason", MAX_REASON_LENGTH, true);
41892
+ const extra = value.extra === void 0 ? {} : value.extra;
41893
+ if (!isJsonObject2(extra)) {
41894
+ throw invalidField(index2, "extra", "must be a JSON object");
41895
+ }
41896
+ const serializedExtra = JSON.stringify(extra);
41897
+ if (Buffer.byteLength(serializedExtra, "utf8") > MAX_EXTRA_BYTES) {
41898
+ throw invalidField(index2, "extra", `serialized JSON exceeds ${MAX_EXTRA_BYTES} bytes`);
41899
+ }
41900
+ return { jobId, deliveryId, status, reason, extra };
41901
+ }
41902
+ function coalesceByLastDeliveryId(records) {
41903
+ const lastIndexes = /* @__PURE__ */ new Map();
41904
+ records.forEach((record, index2) => lastIndexes.set(record.deliveryId, index2));
41905
+ const coalesced = records.filter((record, index2) => lastIndexes.get(record.deliveryId) === index2);
41906
+ return { records: coalesced, duplicateInputCount: records.length - coalesced.length };
41907
+ }
41908
+ function parseArgs(args, spec) {
41909
+ const options = /* @__PURE__ */ new Map();
41910
+ const flags = /* @__PURE__ */ new Set();
41911
+ for (let index2 = 0; index2 < args.length; index2 += 1) {
41912
+ const token = args[index2];
41913
+ if (!token.startsWith("--")) {
41914
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${spec.command} unexpected positional argument: ${token}`);
41915
+ }
41916
+ const name = token.slice(2);
41917
+ if (spec.flags.has(name)) {
41918
+ if (flags.has(name)) {
41919
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${token} must not be repeated`);
41920
+ }
41921
+ flags.add(name);
41922
+ continue;
41923
+ }
41924
+ if (!spec.options.has(name)) {
41925
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${spec.command} unknown option ${token}`);
41926
+ }
41927
+ if (index2 + 1 >= args.length) {
41928
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${token} requires a value`);
41929
+ }
41930
+ const value = args[++index2];
41931
+ if (value.startsWith("--")) {
41932
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${token} requires a value`);
41933
+ }
41934
+ const values = options.get(name) ?? [];
41935
+ if (values.length > 0 && !spec.repeatable?.has(name)) {
41936
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${token} must not be repeated`);
41937
+ }
41938
+ values.push(value);
41939
+ options.set(name, values);
41940
+ }
41941
+ return { options, flags };
41942
+ }
41943
+ function readSingle(parsed, name) {
41944
+ return parsed.options.get(name)?.[0];
41945
+ }
41946
+ function readOptionalText(parsed, name, maxLength) {
41947
+ const value = readSingle(parsed, name);
41948
+ return value === void 0 ? void 0 : requireText(value, `--${name}`, maxLength);
41949
+ }
41950
+ function requireText(value, label, maxLength) {
41951
+ if (typeof value !== "string" || value.trim().length === 0) {
41952
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${label} is required and must be a non-empty string`);
41953
+ }
41954
+ const normalized = value.trim();
41955
+ if (normalized.length > maxLength) {
41956
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${label} exceeds ${maxLength} characters`);
41957
+ }
41958
+ return normalized;
41959
+ }
41960
+ function requireRecordText(value, index2, field, maxLength) {
41961
+ if (typeof value !== "string" || value.trim().length === 0) {
41962
+ throw invalidField(index2, field, "must be a non-empty string");
41963
+ }
41964
+ const normalized = value.trim();
41965
+ if (normalized.length > maxLength) {
41966
+ throw invalidField(index2, field, `exceeds ${maxLength} characters`);
41967
+ }
41968
+ return normalized;
41969
+ }
41970
+ function requireRecordString(value, index2, field, maxLength, allowEmpty) {
41971
+ if (typeof value !== "string" || !allowEmpty && value.length === 0) {
41972
+ throw invalidField(index2, field, allowEmpty ? "must be a string" : "must be a non-empty string");
41973
+ }
41974
+ if (value.length > maxLength) {
41975
+ throw invalidField(index2, field, `exceeds ${maxLength} characters`);
41976
+ }
41977
+ return value;
41978
+ }
41979
+ function invalidField(index2, field, reason) {
41980
+ return new TradeRecordsCliError("INVALID_ARGUMENT", `invalid trade record at index ${index2}`, [
41981
+ { index: index2, ...field ? { field } : {}, reason }
41982
+ ]);
41983
+ }
41984
+ function parseJsonObject(raw, label) {
41985
+ let value;
41986
+ try {
41987
+ value = JSON.parse(raw);
41988
+ } catch {
41989
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${label} must be valid JSON`);
41990
+ }
41991
+ if (!isJsonObject2(value)) {
41992
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `${label} must be a JSON object`);
41993
+ }
41994
+ if (Buffer.byteLength(JSON.stringify(value), "utf8") > MAX_EXTRA_BYTES) {
41995
+ throw new TradeRecordsCliError("INPUT_TOO_LARGE", `${label} exceeds ${MAX_EXTRA_BYTES} bytes`);
41996
+ }
41997
+ return value;
41998
+ }
41999
+ function parseExtraFilter(raw) {
42000
+ const separator = raw.indexOf("=");
42001
+ if (separator <= 0 || separator === raw.length - 1) {
42002
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "--extra-eq must use path=jsonValue syntax");
42003
+ }
42004
+ const path2 = raw.slice(0, separator).trim();
42005
+ const segments = path2.split(".");
42006
+ if (segments.some((segment) => !/^[A-Za-z_][A-Za-z0-9_]*$/.test(segment))) {
42007
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `--extra-eq has invalid JSON path: ${path2}`);
42008
+ }
42009
+ let value;
42010
+ try {
42011
+ value = JSON.parse(raw.slice(separator + 1));
42012
+ } catch {
42013
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "--extra-eq value must be a JSON primitive");
42014
+ }
42015
+ if (typeof value === "object" && value !== null) {
42016
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "--extra-eq value must be a JSON primitive");
42017
+ }
42018
+ if (!["string", "number", "boolean"].includes(typeof value) && value !== null) {
42019
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "--extra-eq value must be a JSON primitive");
42020
+ }
42021
+ if (typeof value === "number" && !Number.isFinite(value)) {
42022
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "--extra-eq number must be finite");
42023
+ }
42024
+ return { path: `$.${segments.join(".")}`, value };
42025
+ }
42026
+ function readTimestamp(parsed, name) {
42027
+ const raw = readSingle(parsed, name);
42028
+ if (raw === void 0) return void 0;
42029
+ const value = Number(raw);
42030
+ if (!Number.isSafeInteger(value) || value < 0) {
42031
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `--${name} must be a non-negative integer`);
42032
+ }
42033
+ return value;
42034
+ }
42035
+ function assertRange(label, from, to) {
42036
+ if (from !== void 0 && to !== void 0 && from > to) {
42037
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", `--${label}-from must not exceed --${label}-to`);
42038
+ }
42039
+ }
42040
+ function readLimit(parsed) {
42041
+ const raw = readSingle(parsed, "limit");
42042
+ if (raw === void 0) return 100;
42043
+ const limit = Number(raw);
42044
+ if (!Number.isInteger(limit) || limit < 1 || limit > 1e3) {
42045
+ throw new TradeRecordsCliError("INVALID_ARGUMENT", "--limit must be an integer between 1 and 1000");
42046
+ }
42047
+ return limit;
42048
+ }
42049
+ function readChoice(parsed, name, choices) {
42050
+ const value = readSingle(parsed, name);
42051
+ if (value === void 0) return void 0;
42052
+ if (!choices.includes(value)) {
42053
+ throw new TradeRecordsCliError(
42054
+ "INVALID_ARGUMENT",
42055
+ `--${name} must be one of: ${choices.join(", ")}`
42056
+ );
42057
+ }
42058
+ return value;
42059
+ }
42060
+ function assertInputSize(value, label) {
42061
+ if (Buffer.byteLength(value, "utf8") > MAX_INPUT_BYTES) {
42062
+ throw new TradeRecordsCliError("INPUT_TOO_LARGE", `${label} exceeds ${MAX_INPUT_BYTES} bytes`);
42063
+ }
42064
+ }
42065
+ function outputQuery(json, records, limit, nextCursor, count) {
42066
+ if (json) {
42067
+ console.log(JSON.stringify({
42068
+ ok: true,
42069
+ records,
42070
+ page: { limit, nextCursor },
42071
+ ...count === void 0 ? {} : { count }
42072
+ }));
42073
+ return;
42074
+ }
42075
+ if (records.length === 0) {
42076
+ console.log("No trade records found.");
42077
+ return;
42078
+ }
42079
+ for (const record of records) {
42080
+ console.log(
42081
+ `${record.deliveryId} job=${record.jobId} status=${record.status} reason=${JSON.stringify(record.reason)} extra=${JSON.stringify(record.extra)} createdAt=${record.createdAt} updatedAt=${record.updatedAt} deletedAt=${record.deletedAt ?? ""}`
42082
+ );
42083
+ }
42084
+ if (nextCursor) {
42085
+ console.log(`Next cursor: ${nextCursor}`);
42086
+ }
42087
+ if (count !== void 0) {
42088
+ console.log(`Count: ${count}`);
42089
+ }
42090
+ }
42091
+ function outputDelete(json, result) {
42092
+ if (json) {
42093
+ console.log(JSON.stringify({ ok: true, operation: "delete", ...result }));
42094
+ return;
42095
+ }
42096
+ if (result.deleted) {
42097
+ console.log(`Trade record deleted: deliveryId=${result.deliveryId}`);
42098
+ } else if (result.alreadyDeleted) {
42099
+ console.log(`Trade record already deleted: deliveryId=${result.deliveryId}`);
42100
+ } else {
42101
+ console.log(`Trade record not found: deliveryId=${result.deliveryId}`);
42102
+ }
42103
+ }
42104
+ function outputError(json, error) {
42105
+ if (json) {
42106
+ console.log(JSON.stringify({
42107
+ ok: false,
42108
+ code: error.code,
42109
+ message: error.message,
42110
+ ...error.details ? { details: error.details } : {}
42111
+ }));
42112
+ return;
42113
+ }
42114
+ console.error(`Trade records error [${error.code}]: ${error.message}`);
42115
+ for (const detail of error.details ?? []) {
42116
+ console.error(
42117
+ ` index=${detail.index ?? ""} field=${detail.field ?? ""} reason=${detail.reason}`
42118
+ );
42119
+ }
42120
+ }
42121
+ function normalizeError(error) {
42122
+ if (error instanceof TradeRecordsCliError) return error;
42123
+ if (error instanceof TradeRecordsStoreError) {
42124
+ return new TradeRecordsCliError(error.code, error.message);
42125
+ }
42126
+ if (isBusyError(error)) {
42127
+ return new TradeRecordsCliError("DATABASE_BUSY", "trade records database is busy; retry later");
42128
+ }
42129
+ return new TradeRecordsCliError(
42130
+ "TRADE_RECORDS_FAILED",
42131
+ error instanceof Error ? error.message : String(error)
42132
+ );
42133
+ }
42134
+ function isBusyError(error) {
42135
+ if (!(error instanceof Error)) return false;
42136
+ const code = error.errcode;
42137
+ return typeof code === "number" && ((code & 255) === 5 || (code & 255) === 6) || /database is locked|database table is locked/i.test(error.message);
42138
+ }
42139
+ function isJsonObject2(value) {
42140
+ return typeof value === "object" && value !== null && !Array.isArray(value);
42141
+ }
42142
+ function isHelpArg(value) {
42143
+ return value === "help" || value === "-h" || value === "--help";
42144
+ }
42145
+ var import_node_fs21, MAX_BATCH_RECORDS, MAX_INPUT_BYTES, MAX_EXTRA_BYTES, MAX_ID_LENGTH, MAX_STATUS_LENGTH, MAX_REASON_LENGTH, INPUT_FIELD_OPTIONS, FORBIDDEN_RECORD_FIELDS, ALLOWED_RECORD_FIELDS, TradeRecordsCliError;
42146
+ var init_trade_records_cli = __esm({
42147
+ "src/trade-records-cli.ts"() {
42148
+ "use strict";
42149
+ import_node_fs21 = require("node:fs");
42150
+ init_trade_records_store();
42151
+ MAX_BATCH_RECORDS = 1e3;
42152
+ MAX_INPUT_BYTES = 10 * 1024 * 1024;
42153
+ MAX_EXTRA_BYTES = 256 * 1024;
42154
+ MAX_ID_LENGTH = 512;
42155
+ MAX_STATUS_LENGTH = 128;
42156
+ MAX_REASON_LENGTH = 4096;
42157
+ INPUT_FIELD_OPTIONS = /* @__PURE__ */ new Set(["job-id", "delivery-id", "status", "reason", "extra"]);
42158
+ FORBIDDEN_RECORD_FIELDS = /* @__PURE__ */ new Set([
42159
+ "createdAt",
42160
+ "createAt",
42161
+ "updatedAt",
42162
+ "updateAt",
42163
+ "deletedAt",
42164
+ "created_at",
42165
+ "create_at",
42166
+ "updated_at",
42167
+ "update_at",
42168
+ "deleted_at"
42169
+ ]);
42170
+ ALLOWED_RECORD_FIELDS = /* @__PURE__ */ new Set(["jobId", "deliveryId", "status", "reason", "extra"]);
42171
+ TradeRecordsCliError = class extends Error {
42172
+ code;
42173
+ details;
42174
+ constructor(code, message, details) {
42175
+ super(message);
42176
+ this.name = "TradeRecordsCliError";
42177
+ this.code = code;
42178
+ this.details = details;
42179
+ }
42180
+ };
42181
+ }
42182
+ });
42183
+
41100
42184
  // ../core/src/xmtp-sdk/onchainos/bin.ts
41101
42185
  async function refreshOnchainosVersionMetadata(options = {}) {
41102
42186
  const now = options.now ?? Date.now;
@@ -41216,11 +42300,11 @@ function isResolvedBinUsable(bin) {
41216
42300
  if (!isPathLikeCommand(bin)) {
41217
42301
  return true;
41218
42302
  }
41219
- return process.platform === "win32" ? (0, import_node_fs20.existsSync)(bin) : isExecutable2(bin);
42303
+ return process.platform === "win32" ? (0, import_node_fs22.existsSync)(bin) : isExecutable2(bin);
41220
42304
  }
41221
42305
  function resolvePosixBareCommand(command, pathValue) {
41222
42306
  for (const dir of pathValue.split(":")) {
41223
- const candidate = (0, import_node_path24.join)(dir || ".", command);
42307
+ const candidate = (0, import_node_path25.join)(dir || ".", command);
41224
42308
  if (isExecutable2(candidate)) {
41225
42309
  return candidate;
41226
42310
  }
@@ -41503,12 +42587,12 @@ function buildWin32CandidatePaths(names, pathValue, userProfile) {
41503
42587
  addDir(dir);
41504
42588
  }
41505
42589
  if (userProfile?.trim()) {
41506
- addDir((0, import_node_path24.join)(userProfile, ".local", "bin"));
42590
+ addDir((0, import_node_path25.join)(userProfile, ".local", "bin"));
41507
42591
  }
41508
42592
  const candidates = [];
41509
42593
  for (const dir of dirs) {
41510
42594
  for (const name of names) {
41511
- candidates.push((0, import_node_path24.join)(dir, name));
42595
+ candidates.push((0, import_node_path25.join)(dir, name));
41512
42596
  }
41513
42597
  }
41514
42598
  return candidates;
@@ -41521,7 +42605,7 @@ function buildWin32OnchainosCandidates(pathValue, userProfile) {
41521
42605
  );
41522
42606
  }
41523
42607
  function resolveWin32BareCommandCandidate(command, pathValue, pathExtValue, userProfile) {
41524
- const names = (0, import_node_path24.extname)(command) ? [command] : [
42608
+ const names = (0, import_node_path25.extname)(command) ? [command] : [
41525
42609
  ...new Set(
41526
42610
  pathExtValue.split(";").map((extension) => extension.trim().toLowerCase()).filter(Boolean).map(
41527
42611
  (extension) => `${command}${extension.startsWith(".") ? extension : `.${extension}`}`
@@ -41537,7 +42621,7 @@ function resolveWin32BareCommandCandidate(command, pathValue, pathExtValue, user
41537
42621
  return null;
41538
42622
  }
41539
42623
  function win32CandidatePriority(candidate) {
41540
- const extension = (0, import_node_path24.extname)(candidate).toLowerCase();
42624
+ const extension = (0, import_node_path25.extname)(candidate).toLowerCase();
41541
42625
  if (extension === ".exe") {
41542
42626
  return 0;
41543
42627
  }
@@ -41553,7 +42637,7 @@ function isWindowsAppsAlias(candidate) {
41553
42637
  return candidate.toLowerCase().includes(WINDOWS_APPS_ALIAS_MARKER);
41554
42638
  }
41555
42639
  function win32FileExists(path2) {
41556
- return (0, import_node_fs20.existsSync)(path2);
42640
+ return (0, import_node_fs22.existsSync)(path2);
41557
42641
  }
41558
42642
  function pickOnchainosWin32Candidate(lines, fileExists2 = win32FileExists) {
41559
42643
  const candidates = lines.map((line) => {
@@ -41609,7 +42693,7 @@ function extractExecutablePath(stdout) {
41609
42693
  }
41610
42694
  function isExecutable2(path2) {
41611
42695
  try {
41612
- (0, import_node_fs20.accessSync)(path2, import_node_fs20.constants.X_OK);
42696
+ (0, import_node_fs22.accessSync)(path2, import_node_fs22.constants.X_OK);
41613
42697
  return true;
41614
42698
  } catch {
41615
42699
  return false;
@@ -41714,14 +42798,14 @@ async function exec(args, options = {}) {
41714
42798
  }
41715
42799
  throw new Error("OnchainOS command retry exhausted");
41716
42800
  }
41717
- var import_node_fs20, import_node_child_process8, import_node_path24, import_node_util2, execFileAsync2, resolvedBin, resolvedForEnvBin, resolverRevision, versionProbeInFlight, posixDiscoveryFlights, REDACTED_VALUE_FLAGS, COMMAND_UNAVAILABLE_CODES, ONCHAINOS_VERSION_PROBE_TIMEOUT_MS, ONCHAINOS_BIN_RESOLVE_TIMEOUT_MS, WINDOWS_APPS_ALIAS_MARKER;
42801
+ var import_node_fs22, import_node_child_process8, import_node_path25, import_node_util2, execFileAsync2, resolvedBin, resolvedForEnvBin, resolverRevision, versionProbeInFlight, posixDiscoveryFlights, REDACTED_VALUE_FLAGS, COMMAND_UNAVAILABLE_CODES, ONCHAINOS_VERSION_PROBE_TIMEOUT_MS, ONCHAINOS_BIN_RESOLVE_TIMEOUT_MS, WINDOWS_APPS_ALIAS_MARKER;
41718
42802
  var init_bin = __esm({
41719
42803
  "../core/src/xmtp-sdk/onchainos/bin.ts"() {
41720
42804
  "use strict";
41721
42805
  init_log();
41722
- import_node_fs20 = require("node:fs");
42806
+ import_node_fs22 = require("node:fs");
41723
42807
  import_node_child_process8 = require("node:child_process");
41724
- import_node_path24 = require("node:path");
42808
+ import_node_path25 = require("node:path");
41725
42809
  import_node_util2 = require("node:util");
41726
42810
  init_sentry_logger();
41727
42811
  init_runtime_metadata();
@@ -41783,15 +42867,15 @@ function createAsyncStreamProxy(stream) {
41783
42867
  }
41784
42868
  });
41785
42869
  }
41786
- var import_node_bindings, import_node_bindings2, import_node_crypto9, import_types, import_node_path25, import_node_process, HistorySyncUrls, envMap, reverseEnvMap, envToString, createBackend, InboxReassignError, AccountAlreadyAssociatedError, MissingContentTypeError, SignerUnavailableError, ClientNotInitializedError, StreamFailedError, StreamInvalidRetryAttemptsError, generateInboxId, getInboxIdForIdentifier, isReaction, isReply, isText, isRemoteAttachment, isAttachment, isMultiRemoteAttachment, isTransactionReference, isGroupUpdated, isReadReceipt, isLeaveRequest, isWalletSendCalls, isIntent, isActions, isMarkdown, CodecRegistry, getContentFromDecodedMessageContent, getContentTypeFromDecodedMessageContent, DecodedMessage, AsyncStream, usableProperties, isUsableProperty, wait, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_ATTEMPTS, createStream, Conversation, Dm, Group, Conversations, DebugInformation, Preferences, networkOptionKeys, hasBackend, resolveBackend$1, createClient, resolveBackend, createEphemeralIdentifier, toInboxUpdatesCountMap, Client;
42870
+ var import_node_bindings, import_node_bindings2, import_node_crypto10, import_types, import_node_path26, import_node_process, HistorySyncUrls, envMap, reverseEnvMap, envToString, createBackend, InboxReassignError, AccountAlreadyAssociatedError, MissingContentTypeError, SignerUnavailableError, ClientNotInitializedError, StreamFailedError, StreamInvalidRetryAttemptsError, generateInboxId, getInboxIdForIdentifier, isReaction, isReply, isText, isRemoteAttachment, isAttachment, isMultiRemoteAttachment, isTransactionReference, isGroupUpdated, isReadReceipt, isLeaveRequest, isWalletSendCalls, isIntent, isActions, isMarkdown, CodecRegistry, getContentFromDecodedMessageContent, getContentTypeFromDecodedMessageContent, DecodedMessage, AsyncStream, usableProperties, isUsableProperty, wait, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_ATTEMPTS, createStream, Conversation, Dm, Group, Conversations, DebugInformation, Preferences, networkOptionKeys, hasBackend, resolveBackend$1, createClient, resolveBackend, createEphemeralIdentifier, toInboxUpdatesCountMap, Client;
41787
42871
  var init_dist2 = __esm({
41788
42872
  "../../node_modules/@xmtp/node-sdk/dist/index.js"() {
41789
42873
  import_node_bindings = require("@xmtp/node-bindings");
41790
42874
  import_node_bindings2 = require("@xmtp/node-bindings");
41791
- import_node_crypto9 = require("node:crypto");
42875
+ import_node_crypto10 = require("node:crypto");
41792
42876
  init_dist();
41793
42877
  import_types = require("node:util/types");
41794
- import_node_path25 = require("node:path");
42878
+ import_node_path26 = require("node:path");
41795
42879
  import_node_process = __toESM(require("node:process"), 1);
41796
42880
  HistorySyncUrls = {
41797
42881
  local: "http://localhost:5558",
@@ -43430,7 +44514,7 @@ var init_dist2 = __esm({
43430
44514
  const env = envToString(backend.env);
43431
44515
  let dbPath;
43432
44516
  if (options?.dbPath === void 0) {
43433
- dbPath = (0, import_node_path25.join)(import_node_process.default.cwd(), `xmtp-${env}-${inboxId}.db3`);
44517
+ dbPath = (0, import_node_path26.join)(import_node_process.default.cwd(), `xmtp-${env}-${inboxId}.db3`);
43434
44518
  } else if (typeof options.dbPath === "function") {
43435
44519
  dbPath = options.dbPath(inboxId);
43436
44520
  } else {
@@ -43472,7 +44556,7 @@ var init_dist2 = __esm({
43472
44556
  return createBackend({ env: envOrBackend, gatewayHost });
43473
44557
  };
43474
44558
  createEphemeralIdentifier = () => ({
43475
- identifier: `0x${(0, import_node_crypto9.randomBytes)(20).toString("hex")}`,
44559
+ identifier: `0x${(0, import_node_crypto10.randomBytes)(20).toString("hex")}`,
43476
44560
  identifierKind: 0
43477
44561
  });
43478
44562
  toInboxUpdatesCountMap = (value) => {
@@ -55721,20 +56805,20 @@ async function createRemoteAttachmentFromFile(unencryptedFile, uploadCallback) {
55721
56805
  const fileUrl = await uploadCallback(encryptedAttachment);
55722
56806
  return createRemoteAttachment(encryptedAttachment, fileUrl);
55723
56807
  }
55724
- var import_node_events, import_node_fs21, import_node_path26, import_ts_retry_promise, import_node_crypto10, version2, fromSelf, hasContent, isDM, isGroup, isGroupAdmin, isGroupSuperAdmin, usesCodec, filter, validLogLevels, isLogLevel, getValidLogLevels, parseLogLevel, logDetails, getInstallationInfo, createUser, createIdentifier, createSigner, AgentError, AgentStreamingError, ClientContext, ConversationContext, MessageContext, Agent, CANCEL_ACTION_ID, LimitedMap, cache;
56808
+ var import_node_events, import_node_fs23, import_node_path27, import_ts_retry_promise, import_node_crypto11, version2, fromSelf, hasContent, isDM, isGroup, isGroupAdmin, isGroupSuperAdmin, usesCodec, filter, validLogLevels, isLogLevel, getValidLogLevels, parseLogLevel, logDetails, getInstallationInfo, createUser, createIdentifier, createSigner, AgentError, AgentStreamingError, ClientContext, ConversationContext, MessageContext, Agent, CANCEL_ACTION_ID, LimitedMap, cache;
55725
56809
  var init_dist4 = __esm({
55726
56810
  "../../node_modules/@xmtp/agent-sdk/dist/index.js"() {
55727
56811
  init_dist2();
55728
56812
  init_dist2();
55729
56813
  import_node_events = __toESM(require("node:events"), 1);
55730
- import_node_fs21 = __toESM(require("node:fs"), 1);
55731
- import_node_path26 = __toESM(require("node:path"), 1);
56814
+ import_node_fs23 = __toESM(require("node:fs"), 1);
56815
+ import_node_path27 = __toESM(require("node:path"), 1);
55732
56816
  import_ts_retry_promise = __toESM(require_retry_promise(), 1);
55733
56817
  init_dist3();
55734
56818
  init_esm();
55735
56819
  init_accounts();
55736
56820
  init_chains();
55737
- import_node_crypto10 = require("node:crypto");
56821
+ import_node_crypto11 = require("node:crypto");
55738
56822
  version2 = "2.3.0";
55739
56823
  fromSelf = (message, client) => {
55740
56824
  return message.senderInboxId === client.inboxId;
@@ -56094,9 +57178,9 @@ var init_dist4 = __esm({
56094
57178
  initializedOptions.gatewayHost = XMTP_GATEWAY_HOST;
56095
57179
  }
56096
57180
  if (typeof XMTP_DB_DIRECTORY === "string") {
56097
- import_node_fs21.default.mkdirSync(XMTP_DB_DIRECTORY, { recursive: true, mode: 448 });
57181
+ import_node_fs23.default.mkdirSync(XMTP_DB_DIRECTORY, { recursive: true, mode: 448 });
56098
57182
  initializedOptions.dbPath = (inboxId) => {
56099
- const dbPath = import_node_path26.default.join(XMTP_DB_DIRECTORY, `xmtp-${inboxId}.db3`);
57183
+ const dbPath = import_node_path27.default.join(XMTP_DB_DIRECTORY, `xmtp-${inboxId}.db3`);
56100
57184
  console.info(`Saving local database to "${dbPath}"`);
56101
57185
  return dbPath;
56102
57186
  };
@@ -56404,7 +57488,7 @@ var init_dist4 = __esm({
56404
57488
  return this.#client.accountIdentifier?.identifier;
56405
57489
  }
56406
57490
  };
56407
- CANCEL_ACTION_ID = (0, import_node_crypto10.randomUUID)();
57491
+ CANCEL_ACTION_ID = (0, import_node_crypto11.randomUUID)();
56408
57492
  LimitedMap = class {
56409
57493
  #map = /* @__PURE__ */ new Map();
56410
57494
  #limit;
@@ -57139,7 +58223,7 @@ var init_session_expired = __esm({
57139
58223
 
57140
58224
  // ../core/src/xmtp-sdk/index.ts
57141
58225
  function cachePath(dataDir, fileName) {
57142
- return (0, import_node_path27.join)(dataDir, fileName);
58226
+ return (0, import_node_path28.join)(dataDir, fileName);
57143
58227
  }
57144
58228
  function formatLogTimestamp2(timestampMs) {
57145
58229
  return timestampMs && timestampMs > 0 ? new Date(timestampMs).toISOString() : "(none)";
@@ -57167,10 +58251,10 @@ function ensureCacheDir(dataDir) {
57167
58251
  function loadSensitiveWordsFromCache(dataDir) {
57168
58252
  try {
57169
58253
  const path2 = cachePath(dataDir, "sensitive-words.json");
57170
- if (!(0, import_node_fs22.existsSync)(path2)) {
58254
+ if (!(0, import_node_fs24.existsSync)(path2)) {
57171
58255
  return null;
57172
58256
  }
57173
- const data = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf-8"));
58257
+ const data = JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf-8"));
57174
58258
  if (Array.isArray(data)) {
57175
58259
  return data;
57176
58260
  }
@@ -57184,7 +58268,7 @@ function loadSensitiveWordsFromCache(dataDir) {
57184
58268
  function saveSensitiveWordsToCache(dataDir, words) {
57185
58269
  try {
57186
58270
  ensureCacheDir(dataDir);
57187
- (0, import_node_fs22.writeFileSync)(cachePath(dataDir, "sensitive-words.json"), JSON.stringify(words));
58271
+ (0, import_node_fs24.writeFileSync)(cachePath(dataDir, "sensitive-words.json"), JSON.stringify(words));
57188
58272
  } catch (err2) {
57189
58273
  logWithTimestamp(`[xmtp-sdk] failed to write sensitive-words.json:`, err2);
57190
58274
  logger.error(LogEvent.CACHE_WRITE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "sensitive-words" });
@@ -57226,10 +58310,10 @@ async function loadSensitiveWordsWith(dataDir, fetcher) {
57226
58310
  function loadSystemConfigFromCache(dataDir) {
57227
58311
  try {
57228
58312
  const path2 = cachePath(dataDir, "system-config.json");
57229
- if (!(0, import_node_fs22.existsSync)(path2)) {
58313
+ if (!(0, import_node_fs24.existsSync)(path2)) {
57230
58314
  return null;
57231
58315
  }
57232
- const data = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf-8"));
58316
+ const data = JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf-8"));
57233
58317
  if (data && typeof data === "object" && !Array.isArray(data)) {
57234
58318
  return data;
57235
58319
  }
@@ -57243,7 +58327,7 @@ function loadSystemConfigFromCache(dataDir) {
57243
58327
  function saveSystemConfigToCache(dataDir, config) {
57244
58328
  try {
57245
58329
  ensureCacheDir(dataDir);
57246
- (0, import_node_fs22.writeFileSync)(cachePath(dataDir, "system-config.json"), JSON.stringify(config));
58330
+ (0, import_node_fs24.writeFileSync)(cachePath(dataDir, "system-config.json"), JSON.stringify(config));
57247
58331
  } catch (err2) {
57248
58332
  logWithTimestamp(`[xmtp-sdk] failed to write system-config.json:`, err2);
57249
58333
  logger.error(LogEvent.CACHE_WRITE_FAILED, err2 instanceof Error ? err2 : new Error(String(err2)), { cacheName: "system-config" });
@@ -57293,10 +58377,10 @@ function loadSyncByAddress(dataDir) {
57293
58377
  const map = /* @__PURE__ */ new Map();
57294
58378
  try {
57295
58379
  const path2 = cachePath(dataDir, "last-sync.json");
57296
- if (!(0, import_node_fs22.existsSync)(path2)) {
58380
+ if (!(0, import_node_fs24.existsSync)(path2)) {
57297
58381
  return map;
57298
58382
  }
57299
- const data = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf-8"));
58383
+ const data = JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf-8"));
57300
58384
  const obj = data?.syncByAddress;
57301
58385
  if (obj && typeof obj === "object" && !Array.isArray(obj)) {
57302
58386
  for (const [addr, ts] of Object.entries(obj)) {
@@ -57315,9 +58399,9 @@ function saveSyncForAddress(dataDir, address, timestampMs) {
57315
58399
  try {
57316
58400
  let data = {};
57317
58401
  const path2 = cachePath(dataDir, "last-sync.json");
57318
- if ((0, import_node_fs22.existsSync)(path2)) {
58402
+ if ((0, import_node_fs24.existsSync)(path2)) {
57319
58403
  try {
57320
- const raw = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf-8"));
58404
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf-8"));
57321
58405
  if (raw && typeof raw === "object" && !Array.isArray(raw)) {
57322
58406
  data = raw;
57323
58407
  }
@@ -57328,7 +58412,7 @@ function saveSyncForAddress(dataDir, address, timestampMs) {
57328
58412
  data.syncByAddress = {};
57329
58413
  }
57330
58414
  data.syncByAddress[address] = timestampMs;
57331
- (0, import_node_fs22.writeFileSync)(path2, JSON.stringify(data, null, 2));
58415
+ (0, import_node_fs24.writeFileSync)(path2, JSON.stringify(data, null, 2));
57332
58416
  } catch (err2) {
57333
58417
  logWithTimestamp(
57334
58418
  `[xmtp-sdk] failed to write last-sync.json (address=${address}):`,
@@ -57547,13 +58631,13 @@ function createOfflineReplayAddressSummary(address) {
57547
58631
  durationMs: 0
57548
58632
  };
57549
58633
  }
57550
- var import_node_fs22, import_node_path27, DEFAULT_DATA_DIR, XMTP_INSTALLATION_WARNING_THRESHOLD, XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD, REPLAY_SCAN_INITIAL_BACKOFF_MS, REPLAY_SCAN_MAX_BACKOFF_MS, SENSITIVE_WORDS_LAZY_RETRY_COOLDOWN_MS, InboundReplayGate, SYSTEM_CONFIG_DEFAULTS, STREAM_RECOVERY_ALERT_THRESHOLD_MS, STREAM_RECOVERY_STABILITY_WINDOW_MS, REPLAY_GATE_DRAIN_MAX_ATTEMPTS, REPLAY_GATE_DRAIN_RETRY_DELAY_MS, SEMVER_RE, isRecord5, isPositiveNumber, SYSTEM_CONFIG_VALIDATORS, XmtpService;
58634
+ var import_node_fs24, import_node_path28, DEFAULT_DATA_DIR, XMTP_INSTALLATION_WARNING_THRESHOLD, XMTP_INSTALLATION_NEAR_LIMIT_THRESHOLD, REPLAY_SCAN_INITIAL_BACKOFF_MS, REPLAY_SCAN_MAX_BACKOFF_MS, SENSITIVE_WORDS_LAZY_RETRY_COOLDOWN_MS, InboundReplayGate, SYSTEM_CONFIG_DEFAULTS, STREAM_RECOVERY_ALERT_THRESHOLD_MS, STREAM_RECOVERY_STABILITY_WINDOW_MS, REPLAY_GATE_DRAIN_MAX_ATTEMPTS, REPLAY_GATE_DRAIN_RETRY_DELAY_MS, SEMVER_RE, isRecord5, isPositiveNumber, SYSTEM_CONFIG_VALIDATORS, XmtpService;
57551
58635
  var init_xmtp_sdk = __esm({
57552
58636
  "../core/src/xmtp-sdk/index.ts"() {
57553
58637
  "use strict";
57554
58638
  init_log();
57555
- import_node_fs22 = require("node:fs");
57556
- import_node_path27 = require("node:path");
58639
+ import_node_fs24 = require("node:fs");
58640
+ import_node_path28 = require("node:path");
57557
58641
  init_dist4();
57558
58642
  init_dist2();
57559
58643
  init_sentry_logger();
@@ -60789,7 +61873,7 @@ var init_envelope = __esm({
60789
61873
  });
60790
61874
 
60791
61875
  // src/invalid-message-store.ts
60792
- function loadSqlite4() {
61876
+ function loadSqlite5() {
60793
61877
  const originalEmitWarning = process.emitWarning;
60794
61878
  process.emitWarning = ((warning, ...args) => {
60795
61879
  const message = typeof warning === "string" ? warning : warning.message;
@@ -60804,22 +61888,22 @@ function loadSqlite4() {
60804
61888
  process.emitWarning = originalEmitWarning;
60805
61889
  }
60806
61890
  }
60807
- var import_node_fs23, import_node_path28, DatabaseSync3, InvalidXmtpMessageStore;
61891
+ var import_node_fs25, import_node_path29, DatabaseSync4, InvalidXmtpMessageStore;
60808
61892
  var init_invalid_message_store = __esm({
60809
61893
  "src/invalid-message-store.ts"() {
60810
61894
  "use strict";
60811
- import_node_fs23 = require("node:fs");
60812
- import_node_path28 = require("node:path");
61895
+ import_node_fs25 = require("node:fs");
61896
+ import_node_path29 = require("node:path");
60813
61897
  init_paths();
60814
- ({ DatabaseSync: DatabaseSync3 } = loadSqlite4());
61898
+ ({ DatabaseSync: DatabaseSync4 } = loadSqlite5());
60815
61899
  InvalidXmtpMessageStore = class {
60816
61900
  dbPath;
60817
61901
  db;
60818
61902
  constructor(homeDir) {
60819
61903
  const paths = resolveTaskPaths(homeDir);
60820
- this.dbPath = (0, import_node_path28.join)(paths.sqliteDir, "invalid-xmtp-messages.sqlite");
60821
- (0, import_node_fs23.mkdirSync)((0, import_node_path28.dirname)(this.dbPath), { recursive: true });
60822
- this.db = new DatabaseSync3(this.dbPath);
61904
+ this.dbPath = (0, import_node_path29.join)(paths.sqliteDir, "invalid-xmtp-messages.sqlite");
61905
+ (0, import_node_fs25.mkdirSync)((0, import_node_path29.dirname)(this.dbPath), { recursive: true });
61906
+ this.db = new DatabaseSync4(this.dbPath);
60823
61907
  this.ensureReady();
60824
61908
  }
60825
61909
  close() {
@@ -61195,14 +62279,14 @@ function buildSystemMessageIdempotencyKey(input) {
61195
62279
  return `system-message:${identity}`;
61196
62280
  }
61197
62281
  function stableHash(value) {
61198
- return (0, import_node_crypto11.createHash)("sha256").update(value).digest("hex").slice(0, 24);
62282
+ return (0, import_node_crypto12.createHash)("sha256").update(value).digest("hex").slice(0, 24);
61199
62283
  }
61200
- var import_node_crypto11, DIRECTION_PREFIX, CONTENT_SEPARATOR, ADDRESS_SHORT_HEAD, ADDRESS_SHORT_TAIL, JOB_ID_HEAD, JOB_ID_TAIL, ELLIPSIS, CONTENT_MAX_LINES;
62284
+ var import_node_crypto12, DIRECTION_PREFIX, CONTENT_SEPARATOR, ADDRESS_SHORT_HEAD, ADDRESS_SHORT_TAIL, JOB_ID_HEAD, JOB_ID_TAIL, ELLIPSIS, CONTENT_MAX_LINES;
61201
62285
  var init_agent_message_notice = __esm({
61202
62286
  "src/agent-message-notice.ts"() {
61203
62287
  "use strict";
61204
62288
  init_log();
61205
- import_node_crypto11 = require("node:crypto");
62289
+ import_node_crypto12 = require("node:crypto");
61206
62290
  init_session_store();
61207
62291
  init_ai_provider();
61208
62292
  init_outbound_behavior();
@@ -61759,7 +62843,7 @@ async function handleSqliteGroupSendCommand(params) {
61759
62843
  role: senderAgent?.role,
61760
62844
  sendDurationMs: Date.now() - sendStartMs
61761
62845
  });
61762
- const messageId = `outbound-${(0, import_node_crypto12.randomUUID)()}`;
62846
+ const messageId = `outbound-${(0, import_node_crypto13.randomUUID)()}`;
61763
62847
  await notifyAgentMessageToUserAttention({
61764
62848
  direction: "outbound" /* OUTBOUND */,
61765
62849
  sender: {
@@ -61888,7 +62972,7 @@ async function handleGroupSendCommand(params) {
61888
62972
  sendDurationMs: Date.now() - sendStartMs
61889
62973
  });
61890
62974
  const now = Date.now();
61891
- const messageId = `outbound-${(0, import_node_crypto12.randomUUID)()}`;
62975
+ const messageId = `outbound-${(0, import_node_crypto13.randomUUID)()}`;
61892
62976
  const stored = {
61893
62977
  id: messageId,
61894
62978
  direction: "outbound",
@@ -62107,7 +63191,7 @@ async function handleXmtpSendCommand(params) {
62107
63191
  sendDurationMs: Date.now() - sendStartMs
62108
63192
  });
62109
63193
  const now = Date.now();
62110
- const messageId = `outbound-${(0, import_node_crypto12.randomUUID)()}`;
63194
+ const messageId = `outbound-${(0, import_node_crypto13.randomUUID)()}`;
62111
63195
  const stored = {
62112
63196
  id: messageId,
62113
63197
  direction: "outbound",
@@ -62153,14 +63237,14 @@ async function handleXmtpSendCommand(params) {
62153
63237
  ownedStore?.close();
62154
63238
  }
62155
63239
  }
62156
- var import_node_crypto12, TASK_MIN_VERSION, sqliteGroupSessionPromises, conversationSyncPromises, XMTP_SEND_CHECKPOINT, resolvedAgentByIdCache, resolvedAgentByAddressCache;
63240
+ var import_node_crypto13, TASK_MIN_VERSION, sqliteGroupSessionPromises, conversationSyncPromises, XMTP_SEND_CHECKPOINT, resolvedAgentByIdCache, resolvedAgentByAddressCache;
62157
63241
  var init_xmtp_send = __esm({
62158
63242
  "src/xmtp-send.ts"() {
62159
63243
  "use strict";
62160
63244
  init_log();
62161
63245
  init_sentry_logger();
62162
63246
  init_log_fields();
62163
- import_node_crypto12 = require("node:crypto");
63247
+ import_node_crypto13 = require("node:crypto");
62164
63248
  init_dist2();
62165
63249
  init_envelope();
62166
63250
  init_concurrency2();
@@ -62264,7 +63348,7 @@ function buildAiAdapterCommand(options) {
62264
63348
  function readCodexAddDirs(env = process.env) {
62265
63349
  const raw = env.OKX_A2A_AI_CODEX_ADD_DIRS ?? env.OKX_AGENT_TASK_CODEX_ADD_DIRS ?? "";
62266
63350
  const seen = /* @__PURE__ */ new Set();
62267
- return raw.split(import_node_path29.delimiter).map((value) => expandHomePath(value.trim())).filter(Boolean).filter((dir) => {
63351
+ return raw.split(import_node_path30.delimiter).map((value) => expandHomePath(value.trim())).filter(Boolean).filter((dir) => {
62268
63352
  if (seen.has(dir)) {
62269
63353
  return false;
62270
63354
  }
@@ -62277,7 +63361,7 @@ function expandHomePath(value) {
62277
63361
  return (0, import_node_os9.homedir)();
62278
63362
  }
62279
63363
  if (value.startsWith("~/")) {
62280
- return (0, import_node_path29.join)((0, import_node_os9.homedir)(), value.slice(2));
63364
+ return (0, import_node_path30.join)((0, import_node_os9.homedir)(), value.slice(2));
62281
63365
  }
62282
63366
  return value;
62283
63367
  }
@@ -62494,9 +63578,9 @@ function formatOpenClawSessionKey(sessionKey, agentId) {
62494
63578
  function buildClaudeAddDirArgs(homeDir, env) {
62495
63579
  const dirs = [
62496
63580
  homeDir,
62497
- (0, import_node_path29.join)((0, import_node_os9.homedir)(), ".agents"),
62498
- (0, import_node_path29.join)(__dirname, ".."),
62499
- ...env.OKX_A2A_AI_CLAUDE_ADD_DIRS ? env.OKX_A2A_AI_CLAUDE_ADD_DIRS.split(import_node_path29.delimiter).filter(Boolean) : []
63581
+ (0, import_node_path30.join)((0, import_node_os9.homedir)(), ".agents"),
63582
+ (0, import_node_path30.join)(__dirname, ".."),
63583
+ ...env.OKX_A2A_AI_CLAUDE_ADD_DIRS ? env.OKX_A2A_AI_CLAUDE_ADD_DIRS.split(import_node_path30.delimiter).filter(Boolean) : []
62500
63584
  ];
62501
63585
  return ["--add-dir", ...[...new Set(dirs)]];
62502
63586
  }
@@ -62548,16 +63632,16 @@ function applyArgTemplate(template, options) {
62548
63632
  const homeDir = options.homeDir ?? resolveTaskPaths().homeDir;
62549
63633
  const cwd = options.cwd ?? process.cwd();
62550
63634
  return template.map((arg) => {
62551
- return arg.replaceAll("{prompt}", options.prompt).replaceAll("{sessionId}", options.sessionId ?? "").replaceAll("{homeDir}", homeDir).replaceAll("{cwd}", cwd).replaceAll("{repoCli}", (0, import_node_path29.join)(__dirname, "cli.js"));
63635
+ return arg.replaceAll("{prompt}", options.prompt).replaceAll("{sessionId}", options.sessionId ?? "").replaceAll("{homeDir}", homeDir).replaceAll("{cwd}", cwd).replaceAll("{repoCli}", (0, import_node_path30.join)(__dirname, "cli.js"));
62552
63636
  });
62553
63637
  }
62554
- var import_node_os9, import_node_path29, CLAUDE_ALLOWED_TOOLS, CLAUDE_PERMISSION_MODES, CODEX_SANDBOX_MODES, CODEX_APPROVAL_POLICIES;
63638
+ var import_node_os9, import_node_path30, CLAUDE_ALLOWED_TOOLS, CLAUDE_PERMISSION_MODES, CODEX_SANDBOX_MODES, CODEX_APPROVAL_POLICIES;
62555
63639
  var init_ai_adapter = __esm({
62556
63640
  "src/ai-adapter.ts"() {
62557
63641
  "use strict";
62558
63642
  init_log();
62559
63643
  import_node_os9 = require("node:os");
62560
- import_node_path29 = require("node:path");
63644
+ import_node_path30 = require("node:path");
62561
63645
  init_ai_command();
62562
63646
  init_paths();
62563
63647
  init_session_store();
@@ -62617,7 +63701,7 @@ function aiRunSentryExtra(input) {
62617
63701
  closeSignal: input.closeSignal ?? "",
62618
63702
  timedOut: input.timedOut === void 0 ? "" : String(input.timedOut),
62619
63703
  aiSessionId: input.aiSessionId ?? "",
62620
- aiLogFile: input.logPath ? (0, import_node_path30.basename)(input.logPath) : "",
63704
+ aiLogFile: input.logPath ? (0, import_node_path31.basename)(input.logPath) : "",
62621
63705
  commandPendingMs: input.commandPendingMs ?? "",
62622
63706
  queueWaitMs: input.queueWaitMs ?? "",
62623
63707
  storeReadMs: input.storeReadMs ?? "",
@@ -62645,7 +63729,7 @@ function resolveProviderCommandWithSelfHeal(options) {
62645
63729
  const env = options.env ?? process.env;
62646
63730
  const storedCommand = options.provider === "codex" ? options.store.getAiProviderCommand(options.provider) : null;
62647
63731
  const resolved = resolveAiProviderCommandWithSource(options.provider, env, storedCommand, options.platform);
62648
- if (options.provider === "codex" && resolved.source !== "explicit_override" && resolved.command !== storedCommand && (0, import_node_path30.isAbsolute)(resolved.command)) {
63732
+ if (options.provider === "codex" && resolved.source !== "explicit_override" && resolved.command !== storedCommand && (0, import_node_path31.isAbsolute)(resolved.command)) {
62649
63733
  options.store.setAiProviderCommand(options.provider, resolved.command);
62650
63734
  }
62651
63735
  return { command: resolved.command, commandSource: resolved.source };
@@ -62677,7 +63761,7 @@ function aiRunToolFailureSentryExtra(failure, context) {
62677
63761
  closeSignal: context.closeSignal ?? "",
62678
63762
  timedOut: String(context.timedOut),
62679
63763
  aiSessionId: context.aiSessionId ?? "",
62680
- aiLogFile: (0, import_node_path30.basename)(context.logPath)
63764
+ aiLogFile: (0, import_node_path31.basename)(context.logPath)
62681
63765
  }).filter(([, value]) => value !== "");
62682
63766
  return entries.reduce((out, [key, value]) => {
62683
63767
  out[key] = String(value);
@@ -62700,7 +63784,7 @@ function safeProcessCwd() {
62700
63784
  }
62701
63785
  function isDirectory(path2) {
62702
63786
  try {
62703
- return (0, import_node_fs24.statSync)(path2).isDirectory();
63787
+ return (0, import_node_fs26.statSync)(path2).isDirectory();
62704
63788
  } catch {
62705
63789
  return false;
62706
63790
  }
@@ -63039,9 +64123,9 @@ function getPreferredCodexWritableRoot(target) {
63039
64123
  const expanded = expandHomePath2(target);
63040
64124
  const home = (0, import_node_os10.homedir)();
63041
64125
  const appRoots = [
63042
- (0, import_node_path30.join)(home, ".onchainos", "task"),
63043
- (0, import_node_path30.join)(home, ".onchainos", "deliverables"),
63044
- (0, import_node_path30.join)(home, ".okx-agent-task")
64126
+ (0, import_node_path31.join)(home, ".onchainos", "task"),
64127
+ (0, import_node_path31.join)(home, ".onchainos", "deliverables"),
64128
+ (0, import_node_path31.join)(home, ".okx-agent-task")
63045
64129
  ];
63046
64130
  for (const root of appRoots) {
63047
64131
  if (expanded === root || expanded.startsWith(`${root}/`)) {
@@ -63056,7 +64140,7 @@ function inferAppOwnedCodexWritableRoot(failure) {
63056
64140
  return void 0;
63057
64141
  }
63058
64142
  if (containsOnchainosCommand(command) && /\b0x[0-9a-fA-F]{16,}\b/.test(command)) {
63059
- return (0, import_node_path30.join)((0, import_node_os10.homedir)(), ".onchainos", "task");
64143
+ return (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".onchainos", "task");
63060
64144
  }
63061
64145
  return void 0;
63062
64146
  }
@@ -63065,7 +64149,7 @@ function expandHomePath2(value) {
63065
64149
  return (0, import_node_os10.homedir)();
63066
64150
  }
63067
64151
  if (value.startsWith("~/")) {
63068
- return (0, import_node_path30.join)((0, import_node_os10.homedir)(), value.slice(2));
64152
+ return (0, import_node_path31.join)((0, import_node_os10.homedir)(), value.slice(2));
63069
64153
  }
63070
64154
  return value;
63071
64155
  }
@@ -64026,7 +65110,7 @@ function normalizeAttentionProvider(provider) {
64026
65110
  return provider === "unknown" ? null : provider;
64027
65111
  }
64028
65112
  function stableHash2(value) {
64029
- return (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex").slice(0, 24);
65113
+ return (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex").slice(0, 24);
64030
65114
  }
64031
65115
  function formatCommand(args) {
64032
65116
  return args.map(shellQuote).join(" ");
@@ -64050,16 +65134,16 @@ function shortenJobId2(jobId) {
64050
65134
  }
64051
65135
  return `${jobId.slice(0, 6)}\u2026${jobId.slice(-4)}`;
64052
65136
  }
64053
- var import_node_crypto13, import_node_fs24, import_promises12, import_node_os10, import_node_path30, AiRunner, CODEX_TOOL_FAILURE_MARKER;
65137
+ var import_node_crypto14, import_node_fs26, import_promises12, import_node_os10, import_node_path31, AiRunner, CODEX_TOOL_FAILURE_MARKER;
64054
65138
  var init_ai_runner = __esm({
64055
65139
  "src/ai-runner.ts"() {
64056
65140
  "use strict";
64057
65141
  init_log();
64058
- import_node_crypto13 = require("node:crypto");
64059
- import_node_fs24 = require("node:fs");
65142
+ import_node_crypto14 = require("node:crypto");
65143
+ import_node_fs26 = require("node:fs");
64060
65144
  import_promises12 = require("node:fs/promises");
64061
65145
  import_node_os10 = require("node:os");
64062
- import_node_path30 = require("node:path");
65146
+ import_node_path31 = require("node:path");
64063
65147
  init_ai_command();
64064
65148
  init_paths();
64065
65149
  init_file_store();
@@ -64067,6 +65151,7 @@ var init_ai_runner = __esm({
64067
65151
  init_ai_adapter();
64068
65152
  init_task_config();
64069
65153
  init_win_spawn();
65154
+ init_ai_run_log();
64070
65155
  init_session_store();
64071
65156
  init_user_attention_ipc();
64072
65157
  init_sentry_logger();
@@ -64204,7 +65289,7 @@ var init_ai_runner = __esm({
64204
65289
  ensureTaskDir(this.logsDir);
64205
65290
  const lifecycleLogsEnabled = isAiLifecycleLoggingEnabled();
64206
65291
  const logPath = lifecycleLogsEnabled ? this.buildRunLogPath(request) : "";
64207
- const log = lifecycleLogsEnabled ? (0, import_node_fs24.createWriteStream)(logPath, { flags: "a" }) : null;
65292
+ const log = lifecycleLogsEnabled ? (0, import_node_fs26.createWriteStream)(logPath, { flags: "a" }) : null;
64208
65293
  let existing = null;
64209
65294
  let storeReadStartedAt;
64210
65295
  let storeReadEndedAt;
@@ -64688,13 +65773,7 @@ var init_ai_runner = __esm({
64688
65773
  );
64689
65774
  }
64690
65775
  buildRunLogPath(request) {
64691
- const safeMessageId = encodeURIComponent(request.messageId);
64692
- if (request.source === "job-dispatch") {
64693
- const safeJobId = encodeURIComponent(request.jobId ?? "unknown");
64694
- return (0, import_node_path30.join)(this.logsDir, `ai-${safeJobId}-${safeMessageId}.log`);
64695
- }
64696
- const safeSessionKey = encodeURIComponent(request.sessionKey);
64697
- return (0, import_node_path30.join)(this.logsDir, `ai-session-${safeSessionKey}-${safeMessageId}.log`);
65776
+ return (0, import_node_path31.join)(this.logsDir, buildAiRunLogFileName(request));
64698
65777
  }
64699
65778
  readRunAiSessionId(provider, request, file, sessionMeta) {
64700
65779
  if (request.source === "job-dispatch" && request.jobId) {
@@ -65033,7 +66112,7 @@ var init_ai_runner = __esm({
65033
66112
  async appendLlmLog(entry) {
65034
66113
  try {
65035
66114
  ensureTaskDir(this.logsDir);
65036
- await (0, import_promises12.appendFile)((0, import_node_path30.join)(this.logsDir, "llm.log"), formatLlmLogEntry(entry), "utf8");
66115
+ await (0, import_promises12.appendFile)((0, import_node_path31.join)(this.logsDir, "llm.log"), formatLlmLogEntry(entry), "utf8");
65037
66116
  } catch (err2) {
65038
66117
  errorWithTimestamp("[okx-agent-task] failed to append llm.log:", err2);
65039
66118
  }
@@ -66774,6 +67853,9 @@ function parseJson2(rawText) {
66774
67853
  function readString5(value) {
66775
67854
  return typeof value === "string" && value.length > 0 ? value : null;
66776
67855
  }
67856
+ function isValidExternalJobId(value) {
67857
+ return typeof value === "string" && EXTERNAL_JOB_ID_PATTERN.test(value);
67858
+ }
66777
67859
  function readNumber(value) {
66778
67860
  return typeof value === "number" && Number.isFinite(value) ? value : null;
66779
67861
  }
@@ -67693,7 +68775,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67693
68775
  timing.mark("payloadParse", parseStartedAt);
67694
68776
  const directToUser = chatType === "dm" && parseResult.ok ? extractDirectToUserNotification(parseResult.data) : { kind: "none" };
67695
68777
  if (directToUser.kind === "invalid") {
67696
- const droppedMessageId = messageId || `direct-to-user-${(0, import_node_crypto14.randomUUID)()}`;
68778
+ const droppedMessageId = messageId || `direct-to-user-${(0, import_node_crypto15.randomUUID)()}`;
67697
68779
  logger.error(
67698
68780
  LogEvent.INBOUND_DROP_DM_INVALID_PAYLOAD,
67699
68781
  new Error("Invalid direct-to-user system DM"),
@@ -67717,7 +68799,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67717
68799
  await dispatchDirectToUserNotification({
67718
68800
  deps,
67719
68801
  notification: directToUser.notification,
67720
- messageId: messageId || `direct-to-user-${(0, import_node_crypto14.randomUUID)()}`,
68802
+ messageId: messageId || `direct-to-user-${(0, import_node_crypto15.randomUUID)()}`,
67721
68803
  timing,
67722
68804
  source: options.source ?? "live"
67723
68805
  });
@@ -67725,7 +68807,7 @@ async function processFileMessage(ctx, deps, options = {}) {
67725
68807
  }
67726
68808
  const systemNotification = chatType === "dm" && parseResult.ok ? extractSystemNotification(parseResult.data) : null;
67727
68809
  if (systemNotification) {
67728
- const systemMessageId = messageId || `system-${(0, import_node_crypto14.randomUUID)()}`;
68810
+ const systemMessageId = messageId || `system-${(0, import_node_crypto15.randomUUID)()}`;
67729
68811
  logWithTimestamp(
67730
68812
  `[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)}`
67731
68813
  );
@@ -67884,7 +68966,38 @@ async function processFileMessage(ctx, deps, options = {}) {
67884
68966
  const routeStartedAt = Date.now();
67885
68967
  const route = routeMessage(chatType, parseResult.ok, parseResult.data);
67886
68968
  timing.mark("routeResolve", routeStartedAt);
67887
- if (route.route === "job") {
68969
+ if (route.route === "job" && parseResult.ok && isA2AEnvelope(parseResult.data) && !isValidExternalJobId(route.jobId)) {
68970
+ const payloadObject = parseResult.data;
68971
+ const sender = isPlainObject3(payloadObject.sender) ? payloadObject.sender : null;
68972
+ logWithTimestamp(
68973
+ `[okx-agent-task:${deps.myXmtpAddress}] inbound A2A message has invalid jobId, dropping: jobLength=${route.jobId.length} group=${conversationId}`
68974
+ );
68975
+ logger.info(LogEvent.INBOUND_DROP_INVALID_JOBID, timing.extras({
68976
+ ...agentExtras({ walletAddress: deps.myXmtpAddress }),
68977
+ peerWalletAddress: "",
68978
+ peerInboxId: ctx.message.senderInboxId ?? "",
68979
+ peerAgentId: readString5(sender?.agentId) ?? "",
68980
+ conversationId,
68981
+ messageId,
68982
+ chatType,
68983
+ ...inboundStageExtras("inbound/job_id_validation", "dropped"),
68984
+ reason: "invalid_job_id_format"
68985
+ }));
68986
+ recordInvalidXmtpMessageBestEffort({
68987
+ messageId,
68988
+ groupId: conversationId,
68989
+ jobId: null,
68990
+ agentId: readString5(sender?.agentId),
68991
+ localAgentId: XmtpService.getInstance().getAgentByAddress(deps.myXmtpAddress)?.agentId ?? null,
68992
+ senderAddress: null,
68993
+ senderInboxId: ctx.message.senderInboxId ?? "",
68994
+ reason: "invalid_job_id_format",
68995
+ stage: "inbound/job_id_validation",
68996
+ logTag: `[okx-agent-task:${deps.myXmtpAddress}]`
68997
+ });
68998
+ return true;
68999
+ }
69000
+ if (route.route === "job" && chatType !== "group") {
67888
69001
  const providerBindStartedAt = Date.now();
67889
69002
  const providerGate = await bindMessageJobProviderToCurrentDefault(deps, route.jobId, "inbound-xmtp");
67890
69003
  timing.mark("providerBind", providerBindStartedAt);
@@ -67970,7 +69083,27 @@ async function processFileMessage(ctx, deps, options = {}) {
67970
69083
  if (!accepted) {
67971
69084
  return true;
67972
69085
  }
67973
- const routedMessageId = messageId || `group-${(0, import_node_crypto14.randomUUID)()}`;
69086
+ const providerBindStartedAt = Date.now();
69087
+ const providerGate = await bindMessageJobProviderToCurrentDefault(deps, route.jobId, "inbound-xmtp");
69088
+ timing.mark("providerBind", providerBindStartedAt);
69089
+ if (!providerGate.allowed) {
69090
+ logger.info(LogEvent.INBOUND_IGNORED_NON_BUSINESS, timing.extras({
69091
+ ...buildInboundTerminalExtras({
69092
+ terminalState: "provider_gate_denied",
69093
+ myXmtpAddress: deps.myXmtpAddress,
69094
+ messageId,
69095
+ conversationId,
69096
+ chatType,
69097
+ jobId: route.jobId,
69098
+ route: route.route,
69099
+ reason: "job_provider_gate_denied"
69100
+ }),
69101
+ routeReason: route.routeReason,
69102
+ providerBinding: providerGate.provider ?? ""
69103
+ }));
69104
+ return true;
69105
+ }
69106
+ const routedMessageId = messageId || `group-${(0, import_node_crypto15.randomUUID)()}`;
67974
69107
  const sessionKey = ensureInboundGroupSession(deps, {
67975
69108
  jobId: route.jobId,
67976
69109
  myAgentId,
@@ -68036,7 +69169,7 @@ async function processFileMessage(ctx, deps, options = {}) {
68036
69169
  return true;
68037
69170
  }
68038
69171
  const stored = {
68039
- id: messageId || `local-${(0, import_node_crypto14.randomUUID)()}`,
69172
+ id: messageId || `local-${(0, import_node_crypto15.randomUUID)()}`,
68040
69173
  direction: "inbound",
68041
69174
  route: route.route,
68042
69175
  routeReason: route.routeReason,
@@ -68217,7 +69350,7 @@ function processOfflineFromCoreDeps(store, ctx, deps, options) {
68217
69350
  function buildSystemStoredMessage(params) {
68218
69351
  const now = Date.now();
68219
69352
  return {
68220
- id: params.id ?? `system-${now}-${(0, import_node_crypto14.randomUUID)()}`,
69353
+ id: params.id ?? `system-${now}-${(0, import_node_crypto15.randomUUID)()}`,
68221
69354
  direction: "system",
68222
69355
  route: "backup",
68223
69356
  routeReason: params.reason,
@@ -68235,12 +69368,12 @@ function buildSystemStoredMessage(params) {
68235
69368
  function isA2AEnvelope(payload) {
68236
69369
  return isPlainObject3(payload) && payload.msgType === A2A_MESSAGE_TYPE;
68237
69370
  }
68238
- var import_node_crypto14, PROCESSED_IDS_MAX, processedMessageIds, INBOUND_TRANSPORT, INBOUND_EVENT_FAMILY, INBOUND_TERMINAL_FIELDS;
69371
+ var import_node_crypto15, PROCESSED_IDS_MAX, processedMessageIds, EXTERNAL_JOB_ID_PATTERN, INBOUND_TRANSPORT, INBOUND_EVENT_FAMILY, INBOUND_TERMINAL_FIELDS;
68239
69372
  var init_message_handler = __esm({
68240
69373
  "src/message-handler.ts"() {
68241
69374
  "use strict";
68242
69375
  init_log();
68243
- import_node_crypto14 = require("node:crypto");
69376
+ import_node_crypto15 = require("node:crypto");
68244
69377
  init_dist2();
68245
69378
  init_a2a();
68246
69379
  init_envelope_shared();
@@ -68257,6 +69390,7 @@ var init_message_handler = __esm({
68257
69390
  init_ai_provider();
68258
69391
  PROCESSED_IDS_MAX = 1e3;
68259
69392
  processedMessageIds = /* @__PURE__ */ new Map();
69393
+ EXTERNAL_JOB_ID_PATTERN = /^0x[0-9a-fA-F]{64}$/;
68260
69394
  INBOUND_TRANSPORT = "xmtp";
68261
69395
  INBOUND_EVENT_FAMILY = "inbound";
68262
69396
  INBOUND_TERMINAL_FIELDS = {
@@ -68307,7 +69441,7 @@ function isOriginalParentProcessAlive(options) {
68307
69441
  }
68308
69442
  function registerUserAttentionWatcher(options) {
68309
69443
  return options.store.registerUserAttentionWatcher({
68310
- id: options.id ?? (0, import_node_crypto15.randomUUID)(),
69444
+ id: options.id ?? (0, import_node_crypto16.randomUUID)(),
68311
69445
  provider: options.provider,
68312
69446
  jobId: options.jobId,
68313
69447
  nowMs: options.nowMs ?? Date.now(),
@@ -68386,11 +69520,11 @@ function userWatchEventDeliveredSentryExtra(event) {
68386
69520
  hasDecision: String(event.hasDecision)
68387
69521
  };
68388
69522
  }
68389
- 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;
69523
+ 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;
68390
69524
  var init_user_attention_watchers = __esm({
68391
69525
  "src/user-attention-watchers.ts"() {
68392
69526
  "use strict";
68393
- import_node_crypto15 = require("node:crypto");
69527
+ import_node_crypto16 = require("node:crypto");
68394
69528
  init_sentry_logger();
68395
69529
  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.";
68396
69530
  USER_ATTENTION_WATCHER_SCAN_MS = 500;
@@ -68461,12 +69595,12 @@ async function isGatewayAvailableForHeartbeat(options) {
68461
69595
  }
68462
69596
  async function getHermesGatewayPluginStatus(options = {}) {
68463
69597
  const env = options.env ?? process.env;
68464
- const hermesHome = env.HERMES_HOME?.trim() || (0, import_node_path31.join)((0, import_node_os11.homedir)(), ".hermes");
68465
- const pluginYamlPath = (0, import_node_path31.join)(hermesHome, "plugins", "platforms", "okx-a2a", "plugin.yaml");
68466
- if (!(0, import_node_fs25.existsSync)(pluginYamlPath)) {
69598
+ const hermesHome = env.HERMES_HOME?.trim() || (0, import_node_path32.join)((0, import_node_os11.homedir)(), ".hermes");
69599
+ const pluginYamlPath = (0, import_node_path32.join)(hermesHome, "plugins", "platforms", "okx-a2a", "plugin.yaml");
69600
+ if (!(0, import_node_fs27.existsSync)(pluginYamlPath)) {
68467
69601
  return { enabled: false, reason: "plugin_yaml_missing", hermesHome, checkedPath: pluginYamlPath };
68468
69602
  }
68469
- const configPath = (0, import_node_path31.join)(hermesHome, "config.yaml");
69603
+ const configPath = (0, import_node_path32.join)(hermesHome, "config.yaml");
68470
69604
  let content2;
68471
69605
  try {
68472
69606
  content2 = await (0, import_promises13.readFile)(configPath, "utf8");
@@ -68698,12 +69832,12 @@ async function runListenerWithLock(options, paths) {
68698
69832
  });
68699
69833
  }
68700
69834
  });
68701
- service.setPluginVersion("0.2.11");
69835
+ service.setPluginVersion("0.2.12-beta-7449a77b9d-260909165309");
68702
69836
  await service.init();
68703
69837
  const pluginVersionStatus = service.pluginVersionStatus;
68704
69838
  if (pluginVersionStatus.unavailable) {
68705
69839
  throw new Error(
68706
- `@okxweb3/a2a-node v${"0.2.11"} is below the required minimum v${pluginVersionStatus.minVersion}`
69840
+ `@okxweb3/a2a-node v${"0.2.12-beta-7449a77b9d-260909165309"} is below the required minimum v${pluginVersionStatus.minVersion}`
68707
69841
  );
68708
69842
  }
68709
69843
  const systemConfig = service.getSystemConfig();
@@ -68731,7 +69865,7 @@ async function runListenerWithLock(options, paths) {
68731
69865
  onchainosAgentId: "*",
68732
69866
  reason: "system-config missing sentryDsn",
68733
69867
  pluginId: "@okxweb3/a2a-node",
68734
- pluginVersion: "0.2.11"
69868
+ pluginVersion: "0.2.12-beta-7449a77b9d-260909165309"
68735
69869
  });
68736
69870
  }
68737
69871
  logWithTimestamp(
@@ -69081,15 +70215,15 @@ async function timeSettled(fn) {
69081
70215
  return { durationMs: Date.now() - startedAt, error };
69082
70216
  }
69083
70217
  }
69084
- var import_node_fs25, import_promises13, import_node_os11, import_node_path31, 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;
70218
+ 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;
69085
70219
  var init_listener = __esm({
69086
70220
  "src/listener.ts"() {
69087
70221
  "use strict";
69088
70222
  init_log();
69089
- import_node_fs25 = require("node:fs");
70223
+ import_node_fs27 = require("node:fs");
69090
70224
  import_promises13 = require("node:fs/promises");
69091
70225
  import_node_os11 = require("node:os");
69092
- import_node_path31 = require("node:path");
70226
+ import_node_path32 = require("node:path");
69093
70227
  init_onchainos();
69094
70228
  init_system_config();
69095
70229
  init_offline_replay_capability();
@@ -69334,9 +70468,9 @@ async function handleXmtpTestCommand(args, releaseInfo) {
69334
70468
  async function startXmtpTest(args, releaseInfo) {
69335
70469
  assertKnownOptions(args, /* @__PURE__ */ new Set(["--name", "--run-id", "--json"]));
69336
70470
  const paths = resolveTaskPaths();
69337
- const testsDir = (0, import_node_path32.join)(paths.homeDir, "xmtp-tests");
70471
+ const testsDir = (0, import_node_path33.join)(paths.homeDir, "xmtp-tests");
69338
70472
  await ensurePrivateDir(testsDir);
69339
- const active = await readJsonIfExists((0, import_node_path32.join)(testsDir, ACTIVE_FILE));
70473
+ const active = await readJsonIfExists((0, import_node_path33.join)(testsDir, ACTIVE_FILE));
69340
70474
  if (active?.runId) {
69341
70475
  throw new Error(
69342
70476
  `XMTP test ${active.runId} is already active. Run \`okx-a2a xmtp-test stop\` first.`
@@ -69375,7 +70509,7 @@ async function startXmtpTest(args, releaseInfo) {
69375
70509
  ...releaseInfo
69376
70510
  };
69377
70511
  await writeJson(files.manifestPath, manifest);
69378
- await writeJson((0, import_node_path32.join)(testsDir, ACTIVE_FILE), {
70512
+ await writeJson((0, import_node_path33.join)(testsDir, ACTIVE_FILE), {
69379
70513
  runId,
69380
70514
  startedAt: manifest.startedAt
69381
70515
  });
@@ -69398,7 +70532,7 @@ Run \`okx-a2a xmtp-test watch\` to open the realtime dashboard.`);
69398
70532
  async function stopXmtpTest(args) {
69399
70533
  assertKnownOptions(args, /* @__PURE__ */ new Set(["--json"]));
69400
70534
  const testsDir = resolveTestsDir();
69401
- const activePath = (0, import_node_path32.join)(testsDir, ACTIVE_FILE);
70535
+ const activePath = (0, import_node_path33.join)(testsDir, ACTIVE_FILE);
69402
70536
  const active = await readJsonIfExists(activePath);
69403
70537
  if (!active?.runId) {
69404
70538
  throw new Error("No active XMTP test.");
@@ -69692,17 +70826,17 @@ function formatJobEvent(event) {
69692
70826
  return `${timestamp} ${businessEvent.padEnd(34)} ${role}#${agent} ${source}${timings.length > 0 ? ` ${timings.join(" ")}` : ""}`;
69693
70827
  }
69694
70828
  function resolveTestsDir() {
69695
- return (0, import_node_path32.join)(resolveTaskPaths().homeDir, "xmtp-tests");
70829
+ return (0, import_node_path33.join)(resolveTaskPaths().homeDir, "xmtp-tests");
69696
70830
  }
69697
70831
  function resolveRunFiles(testsDir, runId) {
69698
70832
  validateRunId(runId);
69699
- const runDir = (0, import_node_path32.join)(testsDir, runId);
70833
+ const runDir = (0, import_node_path33.join)(testsDir, runId);
69700
70834
  return {
69701
70835
  testsDir,
69702
70836
  runDir,
69703
- manifestPath: (0, import_node_path32.join)(runDir, "manifest.json"),
69704
- eventsPath: (0, import_node_path32.join)(runDir, "events.jsonl"),
69705
- summaryPath: (0, import_node_path32.join)(runDir, "summary.json")
70837
+ manifestPath: (0, import_node_path33.join)(runDir, "manifest.json"),
70838
+ eventsPath: (0, import_node_path33.join)(runDir, "events.jsonl"),
70839
+ summaryPath: (0, import_node_path33.join)(runDir, "summary.json")
69706
70840
  };
69707
70841
  }
69708
70842
  async function resolveRequestedRunId(testsDir, args, preferActive = false) {
@@ -69710,7 +70844,7 @@ async function resolveRequestedRunId(testsDir, args, preferActive = false) {
69710
70844
  if (requested) {
69711
70845
  return validateRunId(requested);
69712
70846
  }
69713
- const active = await readJsonIfExists((0, import_node_path32.join)(testsDir, ACTIVE_FILE));
70847
+ const active = await readJsonIfExists((0, import_node_path33.join)(testsDir, ACTIVE_FILE));
69714
70848
  if (active?.runId && (preferActive || !args.includes("--latest"))) {
69715
70849
  return validateRunId(active.runId);
69716
70850
  }
@@ -69736,7 +70870,7 @@ async function findLatestRunId(testsDir) {
69736
70870
  continue;
69737
70871
  }
69738
70872
  const manifest = await readJsonIfExists(
69739
- (0, import_node_path32.join)(testsDir, entry.name, "manifest.json")
70873
+ (0, import_node_path33.join)(testsDir, entry.name, "manifest.json")
69740
70874
  );
69741
70875
  if (manifest?.runId && manifest.startedAt) {
69742
70876
  manifests.push(manifest);
@@ -69971,12 +71105,12 @@ function formatPercent(value) {
69971
71105
  function validTimestamp(value) {
69972
71106
  return typeof value === "string" && Number.isFinite(Date.parse(value));
69973
71107
  }
69974
- var import_promises14, import_node_path32, RUN_ID_PATTERN2, ACTIVE_FILE;
71108
+ var import_promises14, import_node_path33, RUN_ID_PATTERN2, ACTIVE_FILE;
69975
71109
  var init_xmtp_test_cli = __esm({
69976
71110
  "src/xmtp-test-cli.ts"() {
69977
71111
  "use strict";
69978
71112
  import_promises14 = require("node:fs/promises");
69979
- import_node_path32 = require("node:path");
71113
+ import_node_path33 = require("node:path");
69980
71114
  init_daemon();
69981
71115
  init_log_tail();
69982
71116
  init_paths();
@@ -112954,10 +114088,10 @@ var require_node4 = __commonJS({
112954
114088
 
112955
114089
  // ../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js
112956
114090
  async function encrypt(plain, secret, additionalData) {
112957
- const salt = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(KDFSaltSize));
112958
- const nonce = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(AESGCMNonceSize));
114091
+ const salt = import_node_crypto17.webcrypto.getRandomValues(new Uint8Array(KDFSaltSize));
114092
+ const nonce = import_node_crypto17.webcrypto.getRandomValues(new Uint8Array(AESGCMNonceSize));
112959
114093
  const key = await hkdf(secret, salt);
112960
- const encrypted = await import_node_crypto16.webcrypto.subtle.encrypt(aesGcmParams(nonce), key, plain);
114094
+ const encrypted = await import_node_crypto17.webcrypto.subtle.encrypt(aesGcmParams(nonce), key, plain);
112961
114095
  return new Ciphertext({
112962
114096
  aes256GcmHkdfSha256: {
112963
114097
  payload: new Uint8Array(encrypted),
@@ -112971,7 +114105,7 @@ async function decrypt(encrypted, secret, additionalData) {
112971
114105
  throw new Error("invalid payload ciphertext");
112972
114106
  }
112973
114107
  const key = await hkdf(secret, encrypted.aes256GcmHkdfSha256.hkdfSalt);
112974
- const decrypted = await import_node_crypto16.webcrypto.subtle.decrypt(aesGcmParams(encrypted.aes256GcmHkdfSha256.gcmNonce), key, encrypted.aes256GcmHkdfSha256.payload);
114108
+ const decrypted = await import_node_crypto17.webcrypto.subtle.decrypt(aesGcmParams(encrypted.aes256GcmHkdfSha256.gcmNonce), key, encrypted.aes256GcmHkdfSha256.payload);
112975
114109
  return new Uint8Array(decrypted);
112976
114110
  }
112977
114111
  function aesGcmParams(nonce, additionalData) {
@@ -112982,18 +114116,18 @@ function aesGcmParams(nonce, additionalData) {
112982
114116
  return spec;
112983
114117
  }
112984
114118
  async function hkdf(secret, salt) {
112985
- const key = await import_node_crypto16.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
114119
+ const key = await import_node_crypto17.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
112986
114120
  "deriveKey"
112987
114121
  ]);
112988
- return import_node_crypto16.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt, info: hkdfNoInfo }, key, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
114122
+ return import_node_crypto17.webcrypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt, info: hkdfNoInfo }, key, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
112989
114123
  }
112990
- var import_proto, import_node_crypto16, ContentTypeAttachment, AttachmentCodec, KDFSaltSize, AESGCMNonceSize, AESGCMTagLength, Ciphertext, hkdfNoInfo, ContentTypeRemoteAttachment, RemoteAttachmentCodec;
114124
+ var import_proto, import_node_crypto17, ContentTypeAttachment, AttachmentCodec, KDFSaltSize, AESGCMNonceSize, AESGCMTagLength, Ciphertext, hkdfNoInfo, ContentTypeRemoteAttachment, RemoteAttachmentCodec;
112991
114125
  var init_dist6 = __esm({
112992
114126
  "../../node_modules/@xmtp/content-type-remote-attachment/dist/index.js"() {
112993
114127
  init_dist5();
112994
114128
  init_secp256k12();
112995
114129
  import_proto = __toESM(require_node4(), 1);
112996
- import_node_crypto16 = require("node:crypto");
114130
+ import_node_crypto17 = require("node:crypto");
112997
114131
  ContentTypeAttachment = new ContentTypeId({
112998
114132
  authorityId: "xmtp.org",
112999
114133
  typeId: "attachment",
@@ -113073,7 +114207,7 @@ var init_dist6 = __esm({
113073
114207
  if (payload.length === 0) {
113074
114208
  throw new Error(`no payload for remote attachment at ${remoteAttachment.url}`);
113075
114209
  }
113076
- const digestBytes = new Uint8Array(await import_node_crypto16.webcrypto.subtle.digest("SHA-256", payload));
114210
+ const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
113077
114211
  const digest = etc.bytesToHex(digestBytes);
113078
114212
  if (digest !== remoteAttachment.contentDigest) {
113079
114213
  throw new Error("content digest does not match");
@@ -113097,7 +114231,7 @@ var init_dist6 = __esm({
113097
114231
  return codec.decode(encodedContent, codecRegistry);
113098
114232
  }
113099
114233
  static async encodeEncrypted(content$1, codec) {
113100
- const secret = import_node_crypto16.webcrypto.getRandomValues(new Uint8Array(32));
114234
+ const secret = import_node_crypto17.webcrypto.getRandomValues(new Uint8Array(32));
113101
114235
  const encodedContent = import_proto.content.EncodedContent.encode(codec.encode(content$1, {
113102
114236
  codecFor() {
113103
114237
  return void 0;
@@ -113110,7 +114244,7 @@ var init_dist6 = __esm({
113110
114244
  if (!salt || !nonce || !payload) {
113111
114245
  throw new Error("missing encryption key");
113112
114246
  }
113113
- const digestBytes = new Uint8Array(await import_node_crypto16.webcrypto.subtle.digest("SHA-256", payload));
114247
+ const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
113114
114248
  const digest = etc.bytesToHex(digestBytes);
113115
114249
  return {
113116
114250
  digest,
@@ -113165,9 +114299,9 @@ var init_dist6 = __esm({
113165
114299
 
113166
114300
  // ../core/src/file-upload-safety.ts
113167
114301
  function getUnsafeFileUploadReason(filePath, sensitiveUploadReg = []) {
113168
- const expanded = (0, import_node_path33.resolve)(expandHome(filePath));
113169
- const target = (0, import_node_fs26.realpathSync)(expanded);
113170
- const targetName = (0, import_node_path33.basename)(target);
114302
+ const expanded = (0, import_node_path34.resolve)(expandHome(filePath));
114303
+ const target = (0, import_node_fs28.realpathSync)(expanded);
114304
+ const targetName = (0, import_node_path34.basename)(target);
113171
114305
  if (targetName === ".env" || targetName.startsWith(".env.")) {
113172
114306
  return ".env";
113173
114307
  }
@@ -113180,13 +114314,13 @@ function getUnsafeFileUploadReason(filePath, sensitiveUploadReg = []) {
113180
114314
  return null;
113181
114315
  }
113182
114316
  for (const dir of SENSITIVE_HOME_DIRS) {
113183
- const sensitiveDir = safeRealpath((0, import_node_path33.join)(home, dir));
114317
+ const sensitiveDir = safeRealpath((0, import_node_path34.join)(home, dir));
113184
114318
  if (sensitiveDir && isPathInside(target, sensitiveDir)) {
113185
114319
  return `~/${dir}`;
113186
114320
  }
113187
114321
  }
113188
114322
  for (const file of SENSITIVE_HOME_FILES) {
113189
- const sensitiveFile = safeRealpath((0, import_node_path33.join)(home, file));
114323
+ const sensitiveFile = safeRealpath((0, import_node_path34.join)(home, file));
113190
114324
  if (sensitiveFile && target === sensitiveFile) {
113191
114325
  return `~/${file}`;
113192
114326
  }
@@ -113214,27 +114348,27 @@ function expandHome(filePath) {
113214
114348
  if (filePath === "~") {
113215
114349
  return (0, import_node_os12.homedir)();
113216
114350
  }
113217
- if (filePath.startsWith(`~${import_node_path33.sep}`)) {
113218
- return (0, import_node_path33.join)((0, import_node_os12.homedir)(), filePath.slice(2));
114351
+ if (filePath.startsWith(`~${import_node_path34.sep}`)) {
114352
+ return (0, import_node_path34.join)((0, import_node_os12.homedir)(), filePath.slice(2));
113219
114353
  }
113220
114354
  return filePath;
113221
114355
  }
113222
114356
  function safeRealpath(path2) {
113223
- if (!(0, import_node_fs26.existsSync)(path2)) {
114357
+ if (!(0, import_node_fs28.existsSync)(path2)) {
113224
114358
  return null;
113225
114359
  }
113226
- return (0, import_node_fs26.realpathSync)(path2);
114360
+ return (0, import_node_fs28.realpathSync)(path2);
113227
114361
  }
113228
114362
  function isPathInside(target, dir) {
113229
- return target === dir || target.startsWith(`${dir}${import_node_path33.sep}`);
114363
+ return target === dir || target.startsWith(`${dir}${import_node_path34.sep}`);
113230
114364
  }
113231
- var import_node_fs26, import_node_os12, import_node_path33, SENSITIVE_HOME_DIRS, SENSITIVE_HOME_FILES, UNSAFE_FILE_UPLOAD_MESSAGE;
114365
+ var import_node_fs28, import_node_os12, import_node_path34, SENSITIVE_HOME_DIRS, SENSITIVE_HOME_FILES, UNSAFE_FILE_UPLOAD_MESSAGE;
113232
114366
  var init_file_upload_safety = __esm({
113233
114367
  "../core/src/file-upload-safety.ts"() {
113234
114368
  "use strict";
113235
- import_node_fs26 = require("node:fs");
114369
+ import_node_fs28 = require("node:fs");
113236
114370
  import_node_os12 = require("node:os");
113237
- import_node_path33 = require("node:path");
114371
+ import_node_path34 = require("node:path");
113238
114372
  SENSITIVE_HOME_DIRS = [
113239
114373
  ".ssh",
113240
114374
  ".gnupg",
@@ -113242,7 +114376,7 @@ var init_file_upload_safety = __esm({
113242
114376
  ".azure",
113243
114377
  ".kube",
113244
114378
  ".docker",
113245
- (0, import_node_path33.join)(".config", "gcloud")
114379
+ (0, import_node_path34.join)(".config", "gcloud")
113246
114380
  ];
113247
114381
  SENSITIVE_HOME_FILES = [
113248
114382
  ".npmrc",
@@ -113304,7 +114438,7 @@ function hasHelpFlag(args) {
113304
114438
  return args.some((arg) => arg === "-h" || arg === "--help" || arg === "help");
113305
114439
  }
113306
114440
  async function uploadFile(params) {
113307
- const filename = params.filename || (0, import_node_path34.basename)(params.filePath);
114441
+ const filename = params.filename || (0, import_node_path35.basename)(params.filePath);
113308
114442
  const mimeType = params.mimeType || "application/octet-stream";
113309
114443
  const uploadConfig = readUploadSystemConfig();
113310
114444
  const unsafeReason = getUnsafeFileUploadReason(params.filePath, uploadConfig.sensitiveUploadReg);
@@ -113320,16 +114454,16 @@ async function uploadFile(params) {
113320
114454
  return;
113321
114455
  }
113322
114456
  const maxFileSizeBytes = uploadConfig.maxFileSizeBytes;
113323
- const fileSize = (0, import_node_fs27.statSync)(params.filePath).size;
114457
+ const fileSize = (0, import_node_fs29.statSync)(params.filePath).size;
113324
114458
  if (fileSize > maxFileSizeBytes) {
113325
114459
  throw new Error(formatFileTooLargeMessage(maxFileSizeBytes));
113326
114460
  }
113327
- const data = (0, import_node_fs27.readFileSync)(params.filePath);
114461
+ const data = (0, import_node_fs29.readFileSync)(params.filePath);
113328
114462
  const attachment = { filename, mimeType, data: new Uint8Array(data) };
113329
114463
  const encrypted = await RemoteAttachmentCodec.encodeEncrypted(attachment, new AttachmentCodec());
113330
114464
  ensureFileDirs();
113331
- const encryptedPath = (0, import_node_path34.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto17.randomUUID)()}.enc`);
113332
- (0, import_node_fs27.writeFileSync)(encryptedPath, encrypted.payload);
114465
+ const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto18.randomUUID)()}.enc`);
114466
+ (0, import_node_fs29.writeFileSync)(encryptedPath, encrypted.payload);
113333
114467
  try {
113334
114468
  const stdout = runOnchainos([
113335
114469
  "agent",
@@ -113365,14 +114499,14 @@ async function uploadFile(params) {
113365
114499
  }, null, 2));
113366
114500
  } finally {
113367
114501
  try {
113368
- (0, import_node_fs27.unlinkSync)(encryptedPath);
114502
+ (0, import_node_fs29.unlinkSync)(encryptedPath);
113369
114503
  } catch {
113370
114504
  }
113371
114505
  }
113372
114506
  }
113373
114507
  async function downloadFile(params) {
113374
114508
  ensureFileDirs();
113375
- const encryptedPath = (0, import_node_path34.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto17.randomUUID)()}.enc`);
114509
+ const encryptedPath = (0, import_node_path35.resolve)(FILE_WORK_DIR, `${(0, import_node_crypto18.randomUUID)()}.enc`);
113376
114510
  try {
113377
114511
  const stdout = runOnchainos([
113378
114512
  "agent",
@@ -113396,8 +114530,8 @@ async function downloadFile(params) {
113396
114530
  }));
113397
114531
  throw new Error(`file download failed: ${stdout}`);
113398
114532
  }
113399
- const payload = new Uint8Array((0, import_node_fs27.readFileSync)(encryptedPath));
113400
- const digestBytes = new Uint8Array(await import_node_crypto17.webcrypto.subtle.digest("SHA-256", payload));
114533
+ const payload = new Uint8Array((0, import_node_fs29.readFileSync)(encryptedPath));
114534
+ const digestBytes = new Uint8Array(await import_node_crypto18.webcrypto.subtle.digest("SHA-256", payload));
113401
114535
  const actualDigest = Array.from(digestBytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
113402
114536
  if (actualDigest !== params.digest) {
113403
114537
  throw new Error(`file download digest verification failed: expected=${params.digest}, actual=${actualDigest}`);
@@ -113405,15 +114539,15 @@ async function downloadFile(params) {
113405
114539
  const decryptedBytes = await decryptAttachmentPayload(payload, params);
113406
114540
  const encodedContent = import_proto2.content.EncodedContent.decode(decryptedBytes);
113407
114541
  const attachment = new AttachmentCodec().decode(encodedContent);
113408
- const outputFilename = params.filename || attachment.filename || `${(0, import_node_crypto17.randomUUID)()}.bin`;
114542
+ const outputFilename = params.filename || attachment.filename || `${(0, import_node_crypto18.randomUUID)()}.bin`;
113409
114543
  const outputDir = DOWNLOADS_DIR;
113410
114544
  ensureA2aTaskDir(outputDir);
113411
- const outputPath = (0, import_node_path34.resolve)(outputDir, (0, import_node_path34.basename)(outputFilename));
113412
- (0, import_node_fs27.writeFileSync)(outputPath, attachment.data);
114545
+ const outputPath = (0, import_node_path35.resolve)(outputDir, (0, import_node_path35.basename)(outputFilename));
114546
+ (0, import_node_fs29.writeFileSync)(outputPath, attachment.data);
113413
114547
  console.log(outputPath);
113414
114548
  } finally {
113415
114549
  try {
113416
- (0, import_node_fs27.unlinkSync)(encryptedPath);
114550
+ (0, import_node_fs29.unlinkSync)(encryptedPath);
113417
114551
  } catch {
113418
114552
  }
113419
114553
  }
@@ -113422,15 +114556,15 @@ async function decryptAttachmentPayload(payload, params) {
113422
114556
  const secretBytes = new Uint8Array(Buffer.from(params.secret, "base64"));
113423
114557
  const saltBytes = new Uint8Array(Buffer.from(params.salt, "base64"));
113424
114558
  const nonceBytes = new Uint8Array(Buffer.from(params.nonce, "base64"));
113425
- const hkdfKey = await import_node_crypto17.webcrypto.subtle.importKey("raw", secretBytes, "HKDF", false, ["deriveKey"]);
113426
- const aesKey = await import_node_crypto17.webcrypto.subtle.deriveKey(
114559
+ const hkdfKey = await import_node_crypto18.webcrypto.subtle.importKey("raw", secretBytes, "HKDF", false, ["deriveKey"]);
114560
+ const aesKey = await import_node_crypto18.webcrypto.subtle.deriveKey(
113427
114561
  { name: "HKDF", hash: "SHA-256", salt: saltBytes, info: new Uint8Array().buffer },
113428
114562
  hkdfKey,
113429
114563
  { name: "AES-GCM", length: 256 },
113430
114564
  false,
113431
114565
  ["decrypt"]
113432
114566
  );
113433
- return new Uint8Array(await import_node_crypto17.webcrypto.subtle.decrypt({ name: "AES-GCM", iv: nonceBytes }, aesKey, toArrayBuffer(payload)));
114567
+ return new Uint8Array(await import_node_crypto18.webcrypto.subtle.decrypt({ name: "AES-GCM", iv: nonceBytes }, aesKey, toArrayBuffer(payload)));
113434
114568
  }
113435
114569
  function toArrayBuffer(bytes) {
113436
114570
  return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
@@ -113510,7 +114644,7 @@ function readUploadSystemConfig() {
113510
114644
  const res = parseCliJson2(stdout, "system-config");
113511
114645
  if (res.data && typeof res.data === "object") {
113512
114646
  ensureA2aTaskDir(OKX_A2A_PATHS.xmtpDir);
113513
- (0, import_node_fs27.writeFileSync)(SYSTEM_CONFIG_PATH, JSON.stringify(res.data));
114647
+ (0, import_node_fs29.writeFileSync)(SYSTEM_CONFIG_PATH, JSON.stringify(res.data));
113514
114648
  }
113515
114649
  return parseUploadSystemConfig(res.data ?? {});
113516
114650
  } catch {
@@ -113533,10 +114667,10 @@ function fileCliSentryExtra(operation, reason, extra = {}) {
113533
114667
  }
113534
114668
  function readSystemConfigFromCache() {
113535
114669
  try {
113536
- if (!(0, import_node_fs27.existsSync)(SYSTEM_CONFIG_PATH)) {
114670
+ if (!(0, import_node_fs29.existsSync)(SYSTEM_CONFIG_PATH)) {
113537
114671
  return null;
113538
114672
  }
113539
- return JSON.parse((0, import_node_fs27.readFileSync)(SYSTEM_CONFIG_PATH, "utf8"));
114673
+ return JSON.parse((0, import_node_fs29.readFileSync)(SYSTEM_CONFIG_PATH, "utf8"));
113540
114674
  } catch {
113541
114675
  return null;
113542
114676
  }
@@ -113570,14 +114704,14 @@ function readRequiredOption(args, name) {
113570
114704
  }
113571
114705
  return value;
113572
114706
  }
113573
- var import_node_crypto17, import_node_fs27, import_node_path34, import_proto2, OKX_A2A_PATHS, OKX_A2A_HOME_DIR, FILE_WORK_DIR, DOWNLOADS_DIR, SYSTEM_CONFIG_PATH;
114707
+ var import_node_crypto18, import_node_fs29, import_node_path35, import_proto2, OKX_A2A_PATHS, OKX_A2A_HOME_DIR, FILE_WORK_DIR, DOWNLOADS_DIR, SYSTEM_CONFIG_PATH;
113574
114708
  var init_file_cli = __esm({
113575
114709
  "src/file-cli.ts"() {
113576
114710
  "use strict";
113577
114711
  init_win_spawn();
113578
- import_node_crypto17 = require("node:crypto");
113579
- import_node_fs27 = require("node:fs");
113580
- import_node_path34 = require("node:path");
114712
+ import_node_crypto18 = require("node:crypto");
114713
+ import_node_fs29 = require("node:fs");
114714
+ import_node_path35 = require("node:path");
113581
114715
  init_dist6();
113582
114716
  import_proto2 = __toESM(require_node4());
113583
114717
  init_a2a_paths();
@@ -113588,7 +114722,7 @@ var init_file_cli = __esm({
113588
114722
  OKX_A2A_HOME_DIR = OKX_A2A_PATHS.homeDir;
113589
114723
  FILE_WORK_DIR = process.env.OKX_A2A_FILE_WORK_DIR || OKX_A2A_PATHS.filesDir;
113590
114724
  DOWNLOADS_DIR = process.env.OKX_A2A_DOWNLOADS_DIR || OKX_A2A_PATHS.downloadsDir;
113591
- SYSTEM_CONFIG_PATH = (0, import_node_path34.resolve)(OKX_A2A_PATHS.xmtpDir, "system-config.json");
114725
+ SYSTEM_CONFIG_PATH = (0, import_node_path35.resolve)(OKX_A2A_PATHS.xmtpDir, "system-config.json");
113592
114726
  }
113593
114727
  });
113594
114728
 
@@ -113599,12 +114733,12 @@ __export(user_attention_cli_exports, {
113599
114733
  });
113600
114734
  async function handleUserCommand(args) {
113601
114735
  const subcommand = args[0];
113602
- if (!subcommand || args.every(isHelpArg)) {
114736
+ if (!subcommand || args.every(isHelpArg2)) {
113603
114737
  printUserUsage();
113604
114738
  return;
113605
114739
  }
113606
114740
  if (subcommand === "help") {
113607
- const helpTarget = args.slice(1).find((arg) => !isHelpArg(arg));
114741
+ const helpTarget = args.slice(1).find((arg) => !isHelpArg2(arg));
113608
114742
  if (!helpTarget) {
113609
114743
  printUserUsage();
113610
114744
  return;
@@ -113621,7 +114755,7 @@ async function handleUserCommand(args) {
113621
114755
  return;
113622
114756
  }
113623
114757
  const commandStartedAt = Date.now();
113624
- const parsed = parseArgs(args.slice(1));
114758
+ const parsed = parseArgs2(args.slice(1));
113625
114759
  const json = parsed.flags.has("json");
113626
114760
  const storeInitStartedAt = Date.now();
113627
114761
  const store = new SessionStore();
@@ -113738,7 +114872,7 @@ async function handleUserCommand(args) {
113738
114872
  function hasHelpFlag2(args) {
113739
114873
  return args.some((arg) => arg === "-h" || arg === "--help");
113740
114874
  }
113741
- function isHelpArg(arg) {
114875
+ function isHelpArg2(arg) {
113742
114876
  return arg === "-h" || arg === "--help" || arg === "help";
113743
114877
  }
113744
114878
  function printUserUsage() {
@@ -114257,7 +115391,7 @@ function runSyncWithoutConsoleOutput(fn) {
114257
115391
  console.error = originalError;
114258
115392
  }
114259
115393
  }
114260
- function parseArgs(args) {
115394
+ function parseArgs2(args) {
114261
115395
  const positional = [];
114262
115396
  const options = /* @__PURE__ */ new Map();
114263
115397
  const flags = /* @__PURE__ */ new Set();
@@ -114711,12 +115845,12 @@ __export(session_cli_exports, {
114711
115845
  });
114712
115846
  async function handleSessionCommand(args) {
114713
115847
  const subcommand = args[0];
114714
- if (!subcommand || args.every(isHelpArg2)) {
115848
+ if (!subcommand || args.every(isHelpArg3)) {
114715
115849
  printSessionUsage();
114716
115850
  return;
114717
115851
  }
114718
115852
  if (subcommand === "help") {
114719
- const helpTarget = args.slice(1).find((arg) => !isHelpArg2(arg));
115853
+ const helpTarget = args.slice(1).find((arg) => !isHelpArg3(arg));
114720
115854
  if (!helpTarget) {
114721
115855
  printSessionUsage();
114722
115856
  return;
@@ -114732,7 +115866,7 @@ async function handleSessionCommand(args) {
114732
115866
  }
114733
115867
  return;
114734
115868
  }
114735
- const parsed = parseArgs2(args.slice(1));
115869
+ const parsed = parseArgs3(args.slice(1));
114736
115870
  const json = parsed.flags.has("json");
114737
115871
  const store = new SessionStore();
114738
115872
  let usedOpenClawGateway = false;
@@ -114898,9 +116032,9 @@ async function handleSessionCommand(args) {
114898
116032
  }
114899
116033
  }
114900
116034
  function hasHelpFlag3(args) {
114901
- return args.some(isHelpArg2);
116035
+ return args.some(isHelpArg3);
114902
116036
  }
114903
- function isHelpArg2(arg) {
116037
+ function isHelpArg3(arg) {
114904
116038
  return arg === "-h" || arg === "--help" || arg === "help";
114905
116039
  }
114906
116040
  function printSessionUsage() {
@@ -115706,7 +116840,7 @@ function normalizeOptionalText4(value) {
115706
116840
  const normalized = value?.trim();
115707
116841
  return normalized ? normalized : null;
115708
116842
  }
115709
- function parseArgs2(args) {
116843
+ function parseArgs3(args) {
115710
116844
  const positional = [];
115711
116845
  const options = /* @__PURE__ */ new Map();
115712
116846
  const flags = /* @__PURE__ */ new Set();
@@ -115789,7 +116923,7 @@ async function handleXmtpDebugCli(args) {
115789
116923
  throw new Error(`Unknown xmtp-debug command: ${subcommand}`);
115790
116924
  }
115791
116925
  const action = subcommand;
115792
- const parsed = parseArgs3(args.slice(1));
116926
+ const parsed = parseArgs4(args.slice(1));
115793
116927
  rejectAccountOverride(parsed);
115794
116928
  const groupId = parsed.options.get("group-id");
115795
116929
  const jobId = parsed.options.get("job-id");
@@ -115883,7 +117017,7 @@ Options:
115883
117017
  --json Print machine-readable JSON.
115884
117018
  `);
115885
117019
  }
115886
- function parseArgs3(args) {
117020
+ function parseArgs4(args) {
115887
117021
  const options = /* @__PURE__ */ new Map();
115888
117022
  const flags = /* @__PURE__ */ new Set();
115889
117023
  for (let index2 = 0; index2 < args.length; index2 += 1) {
@@ -115971,7 +117105,7 @@ async function handleAiCommand(args) {
115971
117105
  return;
115972
117106
  }
115973
117107
  const subcommand = args[0] ?? "status";
115974
- const parsed = parseArgs4(args.slice(1));
117108
+ const parsed = parseArgs5(args.slice(1));
115975
117109
  const json = parsed.flags.has("json");
115976
117110
  const store = new SessionStore();
115977
117111
  try {
@@ -116095,7 +117229,7 @@ function output4(json, payload, human) {
116095
117229
  }
116096
117230
  console.log(human);
116097
117231
  }
116098
- function parseArgs4(args) {
117232
+ function parseArgs5(args) {
116099
117233
  const positional = [];
116100
117234
  const options = /* @__PURE__ */ new Map();
116101
117235
  const flags = /* @__PURE__ */ new Set();
@@ -116151,7 +117285,7 @@ function isPostjectRunnable() {
116151
117285
  function resolvePostjectCommand() {
116152
117286
  try {
116153
117287
  const cliPath = (0, import_node_module.createRequire)(__filename).resolve("postject/dist/cli.js");
116154
- if ((0, import_node_fs28.existsSync)(cliPath)) {
117288
+ if ((0, import_node_fs30.existsSync)(cliPath)) {
116155
117289
  return { command: process.execPath, prefixArgs: [cliPath] };
116156
117290
  }
116157
117291
  } catch {
@@ -116222,26 +117356,26 @@ function buildSeaConfig(entryPath, blobPath) {
116222
117356
  }
116223
117357
  async function installWindowsNativeLauncher(options) {
116224
117358
  const nodeExe = options.nodeExe ?? process.execPath;
116225
- if (!(0, import_node_fs28.existsSync)(options.cliPath)) {
117359
+ if (!(0, import_node_fs30.existsSync)(options.cliPath)) {
116226
117360
  throw new Error(`cannot build okx-a2a.exe: CLI entry not found at ${options.cliPath}`);
116227
117361
  }
116228
- if (!(0, import_node_fs28.existsSync)(nodeExe)) {
117362
+ if (!(0, import_node_fs30.existsSync)(nodeExe)) {
116229
117363
  throw new Error(`cannot build okx-a2a.exe: node executable not found at ${nodeExe}`);
116230
117364
  }
116231
- const exePath = (0, import_node_path35.join)(options.targetDir, NATIVE_LAUNCHER_EXE_NAME);
116232
- (0, import_node_fs28.mkdirSync)(options.targetDir, { recursive: true });
116233
- const work = (0, import_node_fs28.mkdtempSync)((0, import_node_path35.join)((0, import_node_os13.tmpdir)(), "okx-a2a-sea-"));
117365
+ const exePath = (0, import_node_path36.join)(options.targetDir, NATIVE_LAUNCHER_EXE_NAME);
117366
+ (0, import_node_fs30.mkdirSync)(options.targetDir, { recursive: true });
117367
+ const work = (0, import_node_fs30.mkdtempSync)((0, import_node_path36.join)((0, import_node_os13.tmpdir)(), "okx-a2a-sea-"));
116234
117368
  try {
116235
- const entryPath = (0, import_node_path35.join)(work, "launcher-entry.js");
116236
- const blobPath = (0, import_node_path35.join)(work, "okx-a2a.blob");
116237
- const configPath = (0, import_node_path35.join)(work, "sea-config.json");
116238
- (0, import_node_fs28.writeFileSync)(entryPath, buildLauncherEntryJs(options.cliPath), "utf8");
116239
- (0, import_node_fs28.writeFileSync)(configPath, buildSeaConfig(entryPath, blobPath), "utf8");
117369
+ const entryPath = (0, import_node_path36.join)(work, "launcher-entry.js");
117370
+ const blobPath = (0, import_node_path36.join)(work, "okx-a2a.blob");
117371
+ const configPath = (0, import_node_path36.join)(work, "sea-config.json");
117372
+ (0, import_node_fs30.writeFileSync)(entryPath, buildLauncherEntryJs(options.cliPath), "utf8");
117373
+ (0, import_node_fs30.writeFileSync)(configPath, buildSeaConfig(entryPath, blobPath), "utf8");
116240
117374
  (0, import_node_child_process9.execFileSync)(nodeExe, ["--experimental-sea-config", configPath], {
116241
117375
  stdio: "ignore",
116242
117376
  windowsHide: true
116243
117377
  });
116244
- (0, import_node_fs28.copyFileSync)(nodeExe, exePath);
117378
+ (0, import_node_fs30.copyFileSync)(nodeExe, exePath);
116245
117379
  const isMac = process.platform === "darwin";
116246
117380
  if (isMac) {
116247
117381
  try {
@@ -116261,19 +117395,19 @@ async function installWindowsNativeLauncher(options) {
116261
117395
  );
116262
117396
  return { exePath, cliPath: options.cliPath, nodeExe };
116263
117397
  } finally {
116264
- (0, import_node_fs28.rmSync)(work, { recursive: true, force: true });
117398
+ (0, import_node_fs30.rmSync)(work, { recursive: true, force: true });
116265
117399
  }
116266
117400
  }
116267
- function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 = import_node_fs28.existsSync) {
117401
+ function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 = import_node_fs30.existsSync) {
116268
117402
  const dirs = pathValue.split(";").map((d) => d.trim()).filter(Boolean);
116269
117403
  if (appData) {
116270
- dirs.push((0, import_node_path35.join)(appData, "npm"));
117404
+ dirs.push((0, import_node_path36.join)(appData, "npm"));
116271
117405
  }
116272
117406
  if (userProfile) {
116273
- dirs.push((0, import_node_path35.join)(userProfile, ".local", "bin"));
117407
+ dirs.push((0, import_node_path36.join)(userProfile, ".local", "bin"));
116274
117408
  }
116275
117409
  for (const dir of dirs) {
116276
- const candidate = (0, import_node_path35.join)(dir, NATIVE_LAUNCHER_EXE_NAME);
117410
+ const candidate = (0, import_node_path36.join)(dir, NATIVE_LAUNCHER_EXE_NAME);
116277
117411
  if (fileExists2(candidate)) {
116278
117412
  return candidate;
116279
117413
  }
@@ -116282,11 +117416,11 @@ function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2
116282
117416
  }
116283
117417
  function resolveRunningCliPath() {
116284
117418
  const fromArgv = process.argv[1];
116285
- if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs28.existsSync)(fromArgv)) {
117419
+ if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs30.existsSync)(fromArgv)) {
116286
117420
  return fromArgv;
116287
117421
  }
116288
- const beside = (0, import_node_path35.join)(__dirname, "cli.js");
116289
- if ((0, import_node_fs28.existsSync)(beside)) {
117422
+ const beside = (0, import_node_path36.join)(__dirname, "cli.js");
117423
+ if ((0, import_node_fs30.existsSync)(beside)) {
116290
117424
  return beside;
116291
117425
  }
116292
117426
  if (fromArgv) {
@@ -116304,19 +117438,19 @@ async function ensureWindowsNativeLauncher(options = {}) {
116304
117438
  if (existing) {
116305
117439
  return { exePath: existing, installed: false };
116306
117440
  }
116307
- const targetDir = env.APPDATA ? (0, import_node_path35.join)(env.APPDATA, "npm") : (0, import_node_path35.join)(env.USERPROFILE ?? (0, import_node_os13.homedir)(), ".local", "bin");
117441
+ 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");
116308
117442
  const result = await installWindowsNativeLauncher({ cliPath: resolveRunningCliPath(), targetDir });
116309
117443
  return { exePath: result.exePath, installed: true };
116310
117444
  }
116311
- var import_node_child_process9, import_node_fs28, import_node_module, import_node_os13, import_node_path35, SEA_SENTINEL_FUSE, NATIVE_LAUNCHER_EXE_NAME, POSTJECT_SPEC, POSTJECT_BIN;
117445
+ var import_node_child_process9, import_node_fs30, import_node_module, import_node_os13, import_node_path36, SEA_SENTINEL_FUSE, NATIVE_LAUNCHER_EXE_NAME, POSTJECT_SPEC, POSTJECT_BIN;
116312
117446
  var init_win_native_launcher = __esm({
116313
117447
  "src/win-native-launcher.ts"() {
116314
117448
  "use strict";
116315
117449
  import_node_child_process9 = require("node:child_process");
116316
- import_node_fs28 = require("node:fs");
117450
+ import_node_fs30 = require("node:fs");
116317
117451
  import_node_module = require("node:module");
116318
117452
  import_node_os13 = require("node:os");
116319
- import_node_path35 = require("node:path");
117453
+ import_node_path36 = require("node:path");
116320
117454
  init_win_compat();
116321
117455
  init_win_spawn();
116322
117456
  SEA_SENTINEL_FUSE = "NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2";
@@ -116455,7 +117589,7 @@ function buildProviderMismatchWarning(target, provider) {
116455
117589
  ].join("\n");
116456
117590
  }
116457
117591
  async function handleUpdateCommand(args) {
116458
- if (args.some(isHelpArg3)) {
117592
+ if (args.some(isHelpArg4)) {
116459
117593
  printUpdateUsage();
116460
117594
  return;
116461
117595
  }
@@ -116496,7 +117630,7 @@ function resolveUpdateTarget(target) {
116496
117630
  return detectGatewayInvocation() ?? "node";
116497
117631
  }
116498
117632
  async function handleSetupCommand(args) {
116499
- if (args.some(isHelpArg3)) {
117633
+ if (args.some(isHelpArg4)) {
116500
117634
  printSetupUsage();
116501
117635
  return;
116502
117636
  }
@@ -117058,7 +118192,7 @@ async function getCurrentNodeCliVersion() {
117058
118192
  return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
117059
118193
  }
117060
118194
  function getBundledNodeCliVersion() {
117061
- return true ? "0.2.11" : null;
118195
+ return true ? "0.2.12-beta-7449a77b9d-260909165309" : null;
117062
118196
  }
117063
118197
  function readConfiguredAiProvider() {
117064
118198
  const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
@@ -117243,17 +118377,17 @@ async function updateHermes(release, options) {
117243
118377
  assertNotRunningInsideGateway("hermes");
117244
118378
  }
117245
118379
  const spec = buildNpmPackageSpec("hermes", release);
117246
- const workDir = await (0, import_promises15.mkdtemp)((0, import_node_path36.join)((0, import_node_os14.tmpdir)(), `okx-a2a-${label}-hermes-`));
118380
+ const workDir = await (0, import_promises15.mkdtemp)((0, import_node_path37.join)((0, import_node_os14.tmpdir)(), `okx-a2a-${label}-hermes-`));
117247
118381
  try {
117248
118382
  console.log(`[${label}] downloading ${spec}`);
117249
118383
  const npmTarball = await npmPack(spec, workDir);
117250
- const npmPackageDir = (0, import_node_path36.join)(workDir, "npm-package");
118384
+ const npmPackageDir = (0, import_node_path37.join)(workDir, "npm-package");
117251
118385
  await runCommand("tar", ["-xzf", npmTarball, "-C", npmPackageDir], { ensureDir: npmPackageDir });
117252
- const pluginTarball = await findHermesPluginTarball((0, import_node_path36.join)(npmPackageDir, "package", "dist"));
117253
- const pluginDir = (0, import_node_path36.join)(workDir, "plugin");
118386
+ const pluginTarball = await findHermesPluginTarball((0, import_node_path37.join)(npmPackageDir, "package", "dist"));
118387
+ const pluginDir = (0, import_node_path37.join)(workDir, "plugin");
117254
118388
  await runCommand("tar", ["-xzf", pluginTarball, "-C", pluginDir], { ensureDir: pluginDir });
117255
118389
  const unpackedPluginDir = await findFirstDirectory(pluginDir);
117256
- const installer = (0, import_node_path36.join)(unpackedPluginDir, "scripts", "install-or-upgrade.sh");
118390
+ const installer = (0, import_node_path37.join)(unpackedPluginDir, "scripts", "install-or-upgrade.sh");
117257
118391
  console.log(`[${label}] running ${installer}`);
117258
118392
  await runCommand("bash", [installer, ...options.restart ? ["--restart"] : []], { cwd: unpackedPluginDir });
117259
118393
  await normalizeHermesOkxA2aPluginConfig();
@@ -117268,7 +118402,7 @@ async function updateHermes(release, options) {
117268
118402
  }
117269
118403
  }
117270
118404
  async function installGatewayPluginForDoctor(target) {
117271
- const release = isPrereleaseVersion("0.2.11") ? "beta" : "latest";
118405
+ const release = isPrereleaseVersion("0.2.12-beta-7449a77b9d-260909165309") ? "beta" : "latest";
117272
118406
  const insideTargetGateway = detectGatewayInvocation() === target;
117273
118407
  const options = {
117274
118408
  restart: !insideTargetGateway,
@@ -117319,7 +118453,7 @@ async function ensureHermesOkxA2aPluginConfig(configFile = resolveHermesConfigPa
117319
118453
  if (options.dryRun) {
117320
118454
  return true;
117321
118455
  }
117322
- await (0, import_promises15.mkdir)((0, import_node_path36.resolve)(configFile, ".."), { recursive: true });
118456
+ await (0, import_promises15.mkdir)((0, import_node_path37.resolve)(configFile, ".."), { recursive: true });
117323
118457
  await (0, import_promises15.writeFile)(configFile, "plugins:\n enabled:\n - okx-a2a\n");
117324
118458
  console.log(`[update] added Hermes plugins.enabled okx-a2a entry in ${configFile}`);
117325
118459
  return true;
@@ -117559,7 +118693,7 @@ function findFirstEnabledListItem(lines, startIndex, enabledIndent) {
117559
118693
  return null;
117560
118694
  }
117561
118695
  function resolveHermesConfigPath() {
117562
- return (0, import_node_path36.join)(process.env.HERMES_HOME ?? (0, import_node_path36.join)((0, import_node_os14.homedir)(), ".hermes"), "config.yaml");
118696
+ return (0, import_node_path37.join)(process.env.HERMES_HOME ?? (0, import_node_path37.join)((0, import_node_os14.homedir)(), ".hermes"), "config.yaml");
117563
118697
  }
117564
118698
  function lineIndent(line) {
117565
118699
  const match = line.match(/^\s*/);
@@ -117637,13 +118771,13 @@ async function assertGatewayPluginInstalled(target) {
117637
118771
  );
117638
118772
  }
117639
118773
  function resolveHermesPluginYamlPath() {
117640
- return (0, import_node_path36.join)(process.env.HERMES_HOME ?? (0, import_node_path36.join)((0, import_node_os14.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
118774
+ 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");
117641
118775
  }
117642
118776
  async function isGatewayPluginInstalled(target) {
117643
118777
  if (target === "openclaw") {
117644
118778
  return (await getInstalledOpenClawPluginInfo()).installed;
117645
118779
  }
117646
- return (0, import_node_fs29.existsSync)(resolveHermesPluginYamlPath());
118780
+ return (0, import_node_fs31.existsSync)(resolveHermesPluginYamlPath());
117647
118781
  }
117648
118782
  async function getInstalledGatewayPluginVersion(target) {
117649
118783
  if (target === "hermes") {
@@ -117730,7 +118864,7 @@ function parsePackageVersionFromText(output5) {
117730
118864
  return output5.match(/@okxweb3\/a2a-openclaw@([0-9A-Za-z.+-]+)/)?.[1] ?? null;
117731
118865
  }
117732
118866
  async function getInstalledHermesPluginVersion() {
117733
- const pluginYaml = (0, import_node_path36.join)(process.env.HERMES_HOME ?? (0, import_node_path36.join)((0, import_node_os14.homedir)(), ".hermes"), "plugins", "platforms", "okx-a2a", "plugin.yaml");
118867
+ 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");
117734
118868
  try {
117735
118869
  const content2 = await (0, import_promises15.readFile)(pluginYaml, "utf8");
117736
118870
  return parsePluginYamlVersion(content2);
@@ -117788,7 +118922,7 @@ async function npmPack(spec, destination) {
117788
118922
  if (!tarballName) {
117789
118923
  throw new Error(`Unable to detect npm pack tarball from output: ${output5.trim()}`);
117790
118924
  }
117791
- return (0, import_node_path36.resolve)(destination, (0, import_node_path36.basename)(tarballName));
118925
+ return (0, import_node_path37.resolve)(destination, (0, import_node_path37.basename)(tarballName));
117792
118926
  }
117793
118927
  async function findHermesPluginTarball(distDir) {
117794
118928
  const entries = await (0, import_promises15.readdir)(distDir);
@@ -117796,7 +118930,7 @@ async function findHermesPluginTarball(distDir) {
117796
118930
  if (!tarball) {
117797
118931
  throw new Error(`Hermes npm package did not contain dist/okx-a2a-hermes-plugin-*.tar.gz`);
117798
118932
  }
117799
- return (0, import_node_path36.join)(distDir, tarball);
118933
+ return (0, import_node_path37.join)(distDir, tarball);
117800
118934
  }
117801
118935
  async function findFirstDirectory(parent) {
117802
118936
  const entries = await (0, import_promises15.readdir)(parent, { withFileTypes: true });
@@ -117804,7 +118938,7 @@ async function findFirstDirectory(parent) {
117804
118938
  if (!dir) {
117805
118939
  throw new Error(`No unpacked plugin directory found under ${parent}`);
117806
118940
  }
117807
- return (0, import_node_path36.join)(parent, dir.name);
118941
+ return (0, import_node_path37.join)(parent, dir.name);
117808
118942
  }
117809
118943
  function readOption4(args, name) {
117810
118944
  const index2 = args.indexOf(name);
@@ -117816,7 +118950,7 @@ function readOption4(args, name) {
117816
118950
  function hasFlag(args, name) {
117817
118951
  return args.includes(name);
117818
118952
  }
117819
- function isHelpArg3(value) {
118953
+ function isHelpArg4(value) {
117820
118954
  return value === "-h" || value === "--help" || value === "help";
117821
118955
  }
117822
118956
  function isSupportedRelease(value) {
@@ -118025,15 +119159,15 @@ function buildExternalCommandInvocation(command, args, platform = process.platfo
118025
119159
  function formatExternalCommand(command, args) {
118026
119160
  return [command, ...args].join(" ");
118027
119161
  }
118028
- var import_node_child_process10, import_node_fs29, import_promises15, import_node_os14, import_node_path36, 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;
119162
+ var import_node_child_process10, import_node_fs31, 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;
118029
119163
  var init_update_cli = __esm({
118030
119164
  "src/update-cli.ts"() {
118031
119165
  "use strict";
118032
119166
  import_node_child_process10 = require("node:child_process");
118033
- import_node_fs29 = require("node:fs");
119167
+ import_node_fs31 = require("node:fs");
118034
119168
  import_promises15 = require("node:fs/promises");
118035
119169
  import_node_os14 = require("node:os");
118036
- import_node_path36 = require("node:path");
119170
+ import_node_path37 = require("node:path");
118037
119171
  init_ai_command();
118038
119172
  init_win_spawn();
118039
119173
  init_ai_provider();
@@ -118321,7 +119455,7 @@ async function runDoctor(options = {}) {
118321
119455
  platform: options.platform ?? process.platform,
118322
119456
  env: options.env ?? process.env,
118323
119457
  target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
118324
- cliVersion: options.cliVersion ?? (true ? "0.2.11" : "0.0.0"),
119458
+ cliVersion: options.cliVersion ?? (true ? "0.2.12-beta-7449a77b9d-260909165309" : "0.0.0"),
118325
119459
  fixMode: options.fix === true,
118326
119460
  nonInteractive: options.nonInteractive === true,
118327
119461
  packageChanged: false,
@@ -118529,11 +119663,11 @@ async function writeStdoutAndExit(output5, code) {
118529
119663
  });
118530
119664
  process.exit(code);
118531
119665
  }
118532
- var import_node_path37, 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;
119666
+ 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;
118533
119667
  var init_doctor_cli = __esm({
118534
119668
  "src/doctor-cli.ts"() {
118535
119669
  "use strict";
118536
- import_node_path37 = require("node:path");
119670
+ import_node_path38 = require("node:path");
118537
119671
  init_log();
118538
119672
  init_win_compat();
118539
119673
  init_ai_command();
@@ -118720,7 +119854,7 @@ var init_doctor_cli = __esm({
118720
119854
  command: "okx-a2a doctor --fix"
118721
119855
  },
118722
119856
  data: {
118723
- appDataNpm: ctx.env.APPDATA ? (0, import_node_path37.join)(ctx.env.APPDATA, "npm") : null
119857
+ appDataNpm: ctx.env.APPDATA ? (0, import_node_path38.join)(ctx.env.APPDATA, "npm") : null
118724
119858
  }
118725
119859
  };
118726
119860
  },
@@ -119328,9 +120462,9 @@ var init_doctor_cli = __esm({
119328
120462
  });
119329
120463
 
119330
120464
  // src/cli.ts
119331
- var import_node_fs30 = require("node:fs");
120465
+ var import_node_fs32 = require("node:fs");
119332
120466
  var import_node_os15 = require("node:os");
119333
- var import_node_path38 = require("node:path");
120467
+ var import_node_path39 = require("node:path");
119334
120468
  init_daemon();
119335
120469
  init_command_store();
119336
120470
  init_file_store();
@@ -119398,7 +120532,7 @@ init_sentry_config();
119398
120532
  init_runtime_metadata();
119399
120533
  var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
119400
120534
  function printUsage3() {
119401
- console.log(`okx-a2a ${"0.2.11"}
120535
+ console.log(`okx-a2a ${"0.2.12-beta-7449a77b9d-260909165309"}
119402
120536
 
119403
120537
  Usage:
119404
120538
  okx-a2a <command> [options]
@@ -119428,6 +120562,8 @@ Commands:
119428
120562
  Alias for runtime switch-current
119429
120563
  job-provider Manage job-to-provider bindings
119430
120564
  xmtp-send Queue an XMTP message through the running daemon
120565
+ trade-records
120566
+ Insert, query, and soft-delete local business trade records
119431
120567
  capabilities Print machine-readable A2A capability negotiation status (used by OnchainOS)
119432
120568
 
119433
120569
  Global options:
@@ -119438,7 +120574,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
119438
120574
  `);
119439
120575
  }
119440
120576
  function printVersion() {
119441
- console.log("0.2.11");
120577
+ console.log("0.2.12-beta-7449a77b9d-260909165309");
119442
120578
  }
119443
120579
  function printDaemonUsage() {
119444
120580
  console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
@@ -119600,8 +120736,22 @@ function printCommandUsage(command) {
119600
120736
  printXmtpSendUsage();
119601
120737
  return true;
119602
120738
  }
120739
+ if (command === "trade-records") {
120740
+ printTradeRecordsUsageProxy();
120741
+ return true;
120742
+ }
119603
120743
  return false;
119604
120744
  }
120745
+ function printTradeRecordsUsageProxy() {
120746
+ console.log(`Usage: okx-a2a trade-records <insert|query|delete> [options]
120747
+
120748
+ Commands:
120749
+ insert Insert or replace trade records by deliveryId.
120750
+ query Query active or soft-deleted trade records.
120751
+ delete Soft-delete one trade record by deliveryId.
120752
+
120753
+ Run \`okx-a2a trade-records <command> --help\` for command-specific help.`);
120754
+ }
119605
120755
  function printUserUsageProxy() {
119606
120756
  console.log(`Usage: okx-a2a user <notify|decision-request|list|outdated-list|consume|check|watch>
119607
120757
 
@@ -119688,11 +120838,11 @@ Commands:
119688
120838
  Print setup status JSON to stdout. Installer logs are written to stderr.
119689
120839
  `);
119690
120840
  }
119691
- function isHelpArg4(value) {
120841
+ function isHelpArg5(value) {
119692
120842
  return value === "-h" || value === "--help" || value === "help";
119693
120843
  }
119694
120844
  function hasHelpFlag5(args) {
119695
- return args.some(isHelpArg4);
120845
+ return args.some(isHelpArg5);
119696
120846
  }
119697
120847
  function isVersionArg(value) {
119698
120848
  return value === "-v" || value === "--version" || value === "version";
@@ -119719,14 +120869,14 @@ function maybeRedirectDaemonSelfLog() {
119719
120869
  }
119720
120870
  try {
119721
120871
  const logPath = resolveTaskPaths().listenerLogPath;
119722
- (0, import_node_fs30.mkdirSync)((0, import_node_path38.join)(logPath, ".."), { recursive: true });
119723
- const fd = (0, import_node_fs30.openSync)(logPath, "a");
120872
+ (0, import_node_fs32.mkdirSync)((0, import_node_path39.join)(logPath, ".."), { recursive: true });
120873
+ const fd = (0, import_node_fs32.openSync)(logPath, "a");
119724
120874
  const writeToLog = ((chunk, encoding, cb) => {
119725
120875
  try {
119726
120876
  if (typeof chunk === "string") {
119727
- (0, import_node_fs30.writeSync)(fd, chunk);
120877
+ (0, import_node_fs32.writeSync)(fd, chunk);
119728
120878
  } else {
119729
- (0, import_node_fs30.writeSync)(fd, chunk);
120879
+ (0, import_node_fs32.writeSync)(fd, chunk);
119730
120880
  }
119731
120881
  } catch {
119732
120882
  }
@@ -119816,7 +120966,7 @@ async function handleLogs(args) {
119816
120966
  return;
119817
120967
  }
119818
120968
  if (subcommand === "llm") {
119819
- await tailLogFile((0, import_node_path38.join)(paths.logsDir, "llm.log"), parseLogsTailArgs(args.slice(1), subcommand));
120969
+ await tailLogFile((0, import_node_path39.join)(paths.logsDir, "llm.log"), parseLogsTailArgs(args.slice(1), subcommand));
119820
120970
  return;
119821
120971
  }
119822
120972
  throw new Error("logs requires <server|llm|export>");
@@ -120082,12 +121232,12 @@ async function queueXmtpDaemonCommand(args, type) {
120082
121232
  }
120083
121233
  async function handleTaskCommand(args) {
120084
121234
  const subcommand = args[0];
120085
- if (!subcommand || args.every(isHelpArg4)) {
121235
+ if (!subcommand || args.every(isHelpArg5)) {
120086
121236
  printTaskUsage();
120087
121237
  return;
120088
121238
  }
120089
121239
  if (subcommand === "help") {
120090
- const helpTarget = args.slice(1).find((arg) => !isHelpArg4(arg));
121240
+ const helpTarget = args.slice(1).find((arg) => !isHelpArg5(arg));
120091
121241
  if (!helpTarget) {
120092
121242
  printTaskUsage();
120093
121243
  return;
@@ -120775,11 +121925,11 @@ async function initDirectCliSentry() {
120775
121925
  }
120776
121926
  cliSentryInitAttempted = true;
120777
121927
  try {
120778
- const configPath = (0, import_node_path38.join)(resolveTaskHomeForSentryConfig(), "xmtp", "system-config.json");
120779
- if (!(0, import_node_fs30.existsSync)(configPath)) {
121928
+ const configPath = (0, import_node_path39.join)(resolveTaskHomeForSentryConfig(), "xmtp", "system-config.json");
121929
+ if (!(0, import_node_fs32.existsSync)(configPath)) {
120780
121930
  return;
120781
121931
  }
120782
- const config = JSON.parse((0, import_node_fs30.readFileSync)(configPath, "utf8"));
121932
+ const config = JSON.parse((0, import_node_fs32.readFileSync)(configPath, "utf8"));
120783
121933
  if (typeof config.sentryDsn !== "string" || !config.sentryDsn) {
120784
121934
  return;
120785
121935
  }
@@ -120804,11 +121954,11 @@ function resolveTaskHomeForSentryConfig() {
120804
121954
  try {
120805
121955
  const home = (0, import_node_os15.homedir)();
120806
121956
  if (home) {
120807
- return (0, import_node_path38.join)(home, ".okx-agent-task");
121957
+ return (0, import_node_path39.join)(home, ".okx-agent-task");
120808
121958
  }
120809
121959
  } catch {
120810
121960
  }
120811
- return (0, import_node_path38.resolve)(process.cwd(), ".okx-agent-task");
121961
+ return (0, import_node_path39.resolve)(process.cwd(), ".okx-agent-task");
120812
121962
  }
120813
121963
  function directCliSentryExtra(operation, extra = {}) {
120814
121964
  return {
@@ -120841,7 +121991,7 @@ async function main() {
120841
121991
  assertSupportedNodeVersion();
120842
121992
  }
120843
121993
  const args = process.argv.slice(3);
120844
- if (isHelpArg4(command)) {
121994
+ if (isHelpArg5(command)) {
120845
121995
  printUsage3();
120846
121996
  return;
120847
121997
  }
@@ -120857,6 +122007,11 @@ async function main() {
120857
122007
  handleCapabilitiesCommand2(process.argv.slice(3));
120858
122008
  return;
120859
122009
  }
122010
+ if (command === "trade-records") {
122011
+ const { handleTradeRecordsCommand: handleTradeRecordsCommand2 } = await Promise.resolve().then(() => (init_trade_records_cli(), trade_records_cli_exports));
122012
+ await handleTradeRecordsCommand2(args);
122013
+ return;
122014
+ }
120860
122015
  if (command === "daemon") {
120861
122016
  if (hasHelpFlag5(args)) {
120862
122017
  printDaemonUsage();
@@ -120916,7 +122071,7 @@ async function main() {
120916
122071
  if (command === "xmtp-test") {
120917
122072
  const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
120918
122073
  await handleXmtpTestCommand2(process.argv.slice(3), {
120919
- packageVersion: "0.2.11",
122074
+ packageVersion: "0.2.12-beta-7449a77b9d-260909165309",
120920
122075
  agentSdkVersion: "2.3.0",
120921
122076
  nodeSdkVersion: "6.1.0",
120922
122077
  nodeBindingsVersion: "1.11.0"
@@ -121021,10 +122176,13 @@ function shouldDeferHelpToNestedHandler(command, args) {
121021
122176
  if (command === "xmtp-test") {
121022
122177
  return true;
121023
122178
  }
122179
+ if (command === "trade-records") {
122180
+ return args.some((arg) => !isHelpArg5(arg));
122181
+ }
121024
122182
  if (command !== "session" && command !== "user" && command !== "task") {
121025
122183
  return false;
121026
122184
  }
121027
- return args.some((arg) => !isHelpArg4(arg));
122185
+ return args.some((arg) => !isHelpArg5(arg));
121028
122186
  }
121029
122187
  main().then(() => {
121030
122188
  if (cliSentryFlushTimedOut) {