@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.
- package/dist/cli.js +1435 -277
- package/dist/index.js +149 -66
- 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
|
|
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 =
|
|
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:
|
|
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 =
|
|
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:
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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:
|
|
39578
|
-
const db = new
|
|
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,
|
|
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
|
|
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
|
-
|
|
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.
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
42806
|
+
import_node_fs22 = require("node:fs");
|
|
41723
42807
|
import_node_child_process8 = require("node:child_process");
|
|
41724
|
-
|
|
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,
|
|
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
|
-
|
|
42875
|
+
import_node_crypto10 = require("node:crypto");
|
|
41792
42876
|
init_dist();
|
|
41793
42877
|
import_types = require("node:util/types");
|
|
41794
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
55731
|
-
|
|
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
|
-
|
|
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
|
-
|
|
57181
|
+
import_node_fs23.default.mkdirSync(XMTP_DB_DIRECTORY, { recursive: true, mode: 448 });
|
|
56098
57182
|
initializedOptions.dbPath = (inboxId) => {
|
|
56099
|
-
const dbPath =
|
|
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,
|
|
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,
|
|
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,
|
|
58254
|
+
if (!(0, import_node_fs24.existsSync)(path2)) {
|
|
57171
58255
|
return null;
|
|
57172
58256
|
}
|
|
57173
|
-
const data = JSON.parse((0,
|
|
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,
|
|
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,
|
|
58313
|
+
if (!(0, import_node_fs24.existsSync)(path2)) {
|
|
57230
58314
|
return null;
|
|
57231
58315
|
}
|
|
57232
|
-
const data = JSON.parse((0,
|
|
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,
|
|
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,
|
|
58380
|
+
if (!(0, import_node_fs24.existsSync)(path2)) {
|
|
57297
58381
|
return map;
|
|
57298
58382
|
}
|
|
57299
|
-
const data = JSON.parse((0,
|
|
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,
|
|
58402
|
+
if ((0, import_node_fs24.existsSync)(path2)) {
|
|
57319
58403
|
try {
|
|
57320
|
-
const raw = JSON.parse((0,
|
|
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,
|
|
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
|
|
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
|
-
|
|
57556
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
60812
|
-
|
|
61895
|
+
import_node_fs25 = require("node:fs");
|
|
61896
|
+
import_node_path29 = require("node:path");
|
|
60813
61897
|
init_paths();
|
|
60814
|
-
({ DatabaseSync:
|
|
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,
|
|
60821
|
-
(0,
|
|
60822
|
-
this.db = new
|
|
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,
|
|
62282
|
+
return (0, import_node_crypto12.createHash)("sha256").update(value).digest("hex").slice(0, 24);
|
|
61199
62283
|
}
|
|
61200
|
-
var
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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(
|
|
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,
|
|
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,
|
|
62498
|
-
(0,
|
|
62499
|
-
...env.OKX_A2A_AI_CLAUDE_ADD_DIRS ? env.OKX_A2A_AI_CLAUDE_ADD_DIRS.split(
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
63043
|
-
(0,
|
|
63044
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
64059
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
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,
|
|
68465
|
-
const pluginYamlPath = (0,
|
|
68466
|
-
if (!(0,
|
|
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,
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
70223
|
+
import_node_fs27 = require("node:fs");
|
|
69090
70224
|
import_promises13 = require("node:fs/promises");
|
|
69091
70225
|
import_node_os11 = require("node:os");
|
|
69092
|
-
|
|
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,
|
|
70471
|
+
const testsDir = (0, import_node_path33.join)(paths.homeDir, "xmtp-tests");
|
|
69338
70472
|
await ensurePrivateDir(testsDir);
|
|
69339
|
-
const active = await readJsonIfExists((0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
70833
|
+
const runDir = (0, import_node_path33.join)(testsDir, runId);
|
|
69700
70834
|
return {
|
|
69701
70835
|
testsDir,
|
|
69702
70836
|
runDir,
|
|
69703
|
-
manifestPath: (0,
|
|
69704
|
-
eventsPath: (0,
|
|
69705
|
-
summaryPath: (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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 =
|
|
112958
|
-
const nonce =
|
|
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
|
|
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
|
|
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
|
|
114119
|
+
const key = await import_node_crypto17.webcrypto.subtle.importKey("raw", secret, "HKDF", false, [
|
|
112986
114120
|
"deriveKey"
|
|
112987
114121
|
]);
|
|
112988
|
-
return
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
113169
|
-
const target = (0,
|
|
113170
|
-
const targetName = (0,
|
|
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,
|
|
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,
|
|
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(`~${
|
|
113218
|
-
return (0,
|
|
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,
|
|
114357
|
+
if (!(0, import_node_fs28.existsSync)(path2)) {
|
|
113224
114358
|
return null;
|
|
113225
114359
|
}
|
|
113226
|
-
return (0,
|
|
114360
|
+
return (0, import_node_fs28.realpathSync)(path2);
|
|
113227
114361
|
}
|
|
113228
114362
|
function isPathInside(target, dir) {
|
|
113229
|
-
return target === dir || target.startsWith(`${dir}${
|
|
114363
|
+
return target === dir || target.startsWith(`${dir}${import_node_path34.sep}`);
|
|
113230
114364
|
}
|
|
113231
|
-
var
|
|
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
|
-
|
|
114369
|
+
import_node_fs28 = require("node:fs");
|
|
113236
114370
|
import_node_os12 = require("node:os");
|
|
113237
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
113332
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
113400
|
-
const digestBytes = new Uint8Array(await
|
|
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,
|
|
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,
|
|
113412
|
-
(0,
|
|
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,
|
|
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
|
|
113426
|
-
const aesKey = await
|
|
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
|
|
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,
|
|
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,
|
|
114670
|
+
if (!(0, import_node_fs29.existsSync)(SYSTEM_CONFIG_PATH)) {
|
|
113537
114671
|
return null;
|
|
113538
114672
|
}
|
|
113539
|
-
return JSON.parse((0,
|
|
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
|
|
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
|
-
|
|
113579
|
-
|
|
113580
|
-
|
|
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,
|
|
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(
|
|
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) => !
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
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) => !
|
|
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 =
|
|
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(
|
|
116035
|
+
return args.some(isHelpArg3);
|
|
114902
116036
|
}
|
|
114903
|
-
function
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
116232
|
-
(0,
|
|
116233
|
-
const work = (0,
|
|
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,
|
|
116236
|
-
const blobPath = (0,
|
|
116237
|
-
const configPath = (0,
|
|
116238
|
-
(0,
|
|
116239
|
-
(0,
|
|
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,
|
|
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,
|
|
117398
|
+
(0, import_node_fs30.rmSync)(work, { recursive: true, force: true });
|
|
116265
117399
|
}
|
|
116266
117400
|
}
|
|
116267
|
-
function findWindowsNativeOkxA2aExe(pathValue, appData, userProfile, fileExists2 =
|
|
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,
|
|
117404
|
+
dirs.push((0, import_node_path36.join)(appData, "npm"));
|
|
116271
117405
|
}
|
|
116272
117406
|
if (userProfile) {
|
|
116273
|
-
dirs.push((0,
|
|
117407
|
+
dirs.push((0, import_node_path36.join)(userProfile, ".local", "bin"));
|
|
116274
117408
|
}
|
|
116275
117409
|
for (const dir of dirs) {
|
|
116276
|
-
const candidate = (0,
|
|
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,
|
|
117419
|
+
if (fromArgv && /(?:^|[\\/])cli\.js$/.test(fromArgv) && (0, import_node_fs30.existsSync)(fromArgv)) {
|
|
116286
117420
|
return fromArgv;
|
|
116287
117421
|
}
|
|
116288
|
-
const beside = (0,
|
|
116289
|
-
if ((0,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
117450
|
+
import_node_fs30 = require("node:fs");
|
|
116317
117451
|
import_node_module = require("node:module");
|
|
116318
117452
|
import_node_os13 = require("node:os");
|
|
116319
|
-
|
|
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(
|
|
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(
|
|
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.
|
|
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,
|
|
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,
|
|
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,
|
|
117253
|
-
const pluginDir = (0,
|
|
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,
|
|
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.
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
-
|
|
119167
|
+
import_node_fs31 = require("node:fs");
|
|
118034
119168
|
import_promises15 = require("node:fs/promises");
|
|
118035
119169
|
import_node_os14 = require("node:os");
|
|
118036
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
120465
|
+
var import_node_fs32 = require("node:fs");
|
|
119332
120466
|
var import_node_os15 = require("node:os");
|
|
119333
|
-
var
|
|
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.
|
|
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.
|
|
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
|
|
120841
|
+
function isHelpArg5(value) {
|
|
119692
120842
|
return value === "-h" || value === "--help" || value === "help";
|
|
119693
120843
|
}
|
|
119694
120844
|
function hasHelpFlag5(args) {
|
|
119695
|
-
return args.some(
|
|
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,
|
|
119723
|
-
const fd = (0,
|
|
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,
|
|
120877
|
+
(0, import_node_fs32.writeSync)(fd, chunk);
|
|
119728
120878
|
} else {
|
|
119729
|
-
(0,
|
|
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,
|
|
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(
|
|
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) => !
|
|
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,
|
|
120779
|
-
if (!(0,
|
|
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,
|
|
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,
|
|
121957
|
+
return (0, import_node_path39.join)(home, ".okx-agent-task");
|
|
120808
121958
|
}
|
|
120809
121959
|
} catch {
|
|
120810
121960
|
}
|
|
120811
|
-
return (0,
|
|
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 (
|
|
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.
|
|
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) => !
|
|
122185
|
+
return args.some((arg) => !isHelpArg5(arg));
|
|
121028
122186
|
}
|
|
121029
122187
|
main().then(() => {
|
|
121030
122188
|
if (cliSentryFlushTimedOut) {
|