@okx_ai/okx-trade-cli 1.3.1-beta.8 → 1.3.1-beta.9
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/index.js +124 -717
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +1 -78
package/dist/index.js
CHANGED
|
@@ -21,26 +21,23 @@ import {
|
|
|
21
21
|
import { homedir as homedir2 } from "os";
|
|
22
22
|
import { join as join2, dirname } from "path";
|
|
23
23
|
import { createHmac } from "crypto";
|
|
24
|
-
import { spawn, execFile as execFile2 } from "child_process";
|
|
25
|
-
import { homedir as homedir3 } from "os";
|
|
26
|
-
import { join as join3 } from "path";
|
|
27
24
|
import fs from "fs";
|
|
28
25
|
import path from "path";
|
|
29
26
|
import os from "os";
|
|
30
27
|
import { writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
31
|
-
import { join as
|
|
28
|
+
import { join as join3, resolve, basename, sep } from "path";
|
|
32
29
|
import { randomUUID } from "crypto";
|
|
33
30
|
import yauzl from "yauzl";
|
|
34
31
|
import { createWriteStream, mkdirSync as mkdirSync3 } from "fs";
|
|
35
32
|
import { resolve as resolve2, dirname as dirname2 } from "path";
|
|
36
33
|
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
37
|
-
import { join as
|
|
34
|
+
import { join as join4 } from "path";
|
|
38
35
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, existsSync as existsSync2 } from "fs";
|
|
39
|
-
import { join as
|
|
40
|
-
import { homedir as
|
|
36
|
+
import { join as join5, dirname as dirname3 } from "path";
|
|
37
|
+
import { homedir as homedir3 } from "os";
|
|
41
38
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "fs";
|
|
42
|
-
import { join as
|
|
43
|
-
import { homedir as
|
|
39
|
+
import { join as join6, dirname as dirname4 } from "path";
|
|
40
|
+
import { homedir as homedir4 } from "os";
|
|
44
41
|
|
|
45
42
|
// ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/error.js
|
|
46
43
|
function getLineColFromPtr(string, ptr) {
|
|
@@ -870,8 +867,8 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
|
|
|
870
867
|
|
|
871
868
|
// ../core/dist/index.js
|
|
872
869
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync4 } from "fs";
|
|
873
|
-
import { join as
|
|
874
|
-
import { homedir as
|
|
870
|
+
import { join as join7 } from "path";
|
|
871
|
+
import { homedir as homedir5 } from "os";
|
|
875
872
|
import fs2 from "fs";
|
|
876
873
|
import path2 from "path";
|
|
877
874
|
import os2 from "os";
|
|
@@ -879,18 +876,6 @@ import * as fs3 from "fs";
|
|
|
879
876
|
import * as path3 from "path";
|
|
880
877
|
import * as os3 from "os";
|
|
881
878
|
import { execFileSync } from "child_process";
|
|
882
|
-
import {
|
|
883
|
-
createWriteStream as createWriteStream3,
|
|
884
|
-
mkdirSync as mkdirSync9,
|
|
885
|
-
chmodSync as chmodSync2,
|
|
886
|
-
existsSync as existsSync7,
|
|
887
|
-
unlinkSync as unlinkSync4,
|
|
888
|
-
renameSync as renameSync4
|
|
889
|
-
} from "fs";
|
|
890
|
-
import { homedir as homedir9, platform as platform2 } from "os";
|
|
891
|
-
import { join as join11, dirname as dirname7 } from "path";
|
|
892
|
-
import { get as httpsGet2 } from "https";
|
|
893
|
-
import { get as httpGet2 } from "http";
|
|
894
879
|
import {
|
|
895
880
|
readFileSync as readFileSync7,
|
|
896
881
|
createWriteStream as createWriteStream2,
|
|
@@ -901,8 +886,8 @@ import {
|
|
|
901
886
|
renameSync as renameSync3
|
|
902
887
|
} from "fs";
|
|
903
888
|
import { createHash } from "crypto";
|
|
904
|
-
import { homedir as
|
|
905
|
-
import { join as
|
|
889
|
+
import { homedir as homedir7, platform, arch } from "os";
|
|
890
|
+
import { join as join9, dirname as dirname6 } from "path";
|
|
906
891
|
import { get as httpsGet } from "https";
|
|
907
892
|
import { get as httpGet } from "http";
|
|
908
893
|
var EXEC_TIMEOUT_MS = 3e4;
|
|
@@ -913,7 +898,7 @@ function getDohBinaryPath() {
|
|
|
913
898
|
return process.env.OKX_DOH_BINARY_PATH;
|
|
914
899
|
}
|
|
915
900
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
916
|
-
return join(DOH_BIN_DIR, `okx-
|
|
901
|
+
return join(DOH_BIN_DIR, `okx-pilot${ext}`);
|
|
917
902
|
}
|
|
918
903
|
function execDohBinary(domain, exclude = [], userAgent) {
|
|
919
904
|
if (!ALLOWED_DOMAIN_RE.test(domain)) {
|
|
@@ -1216,11 +1201,6 @@ var ConfigError = class extends OkxMcpError {
|
|
|
1216
1201
|
super("ConfigError", message, { suggestion });
|
|
1217
1202
|
}
|
|
1218
1203
|
};
|
|
1219
|
-
var NotLoggedInError = class extends ConfigError {
|
|
1220
|
-
constructor(suggestion = "Run `okx auth login` to authenticate.") {
|
|
1221
|
-
super("Not logged in.", suggestion);
|
|
1222
|
-
}
|
|
1223
|
-
};
|
|
1224
1204
|
var ValidationError = class extends OkxMcpError {
|
|
1225
1205
|
constructor(message, suggestion) {
|
|
1226
1206
|
super("ValidationError", message, { suggestion });
|
|
@@ -1273,97 +1253,6 @@ function toToolErrorPayload(error, fallbackEndpoint) {
|
|
|
1273
1253
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1274
1254
|
};
|
|
1275
1255
|
}
|
|
1276
|
-
var EXIT_CODES = {
|
|
1277
|
-
SUCCESS: 0,
|
|
1278
|
-
UNAUTHORIZED_CALLER: 1,
|
|
1279
|
-
NOT_LOGGED_IN: 2,
|
|
1280
|
-
REFRESH_FAILED: 3
|
|
1281
|
-
};
|
|
1282
|
-
var EXEC_TIMEOUT_MS2 = 5e3;
|
|
1283
|
-
var AUTH_BIN_DIR = join3(homedir3(), ".okx", "bin");
|
|
1284
|
-
function getAuthBinaryPath() {
|
|
1285
|
-
if (process.env.OKX_AUTH_BIN) {
|
|
1286
|
-
return process.env.OKX_AUTH_BIN;
|
|
1287
|
-
}
|
|
1288
|
-
const ext = process.platform === "win32" ? ".exe" : "";
|
|
1289
|
-
return join3(AUTH_BIN_DIR, `okx-auth${ext}`);
|
|
1290
|
-
}
|
|
1291
|
-
function execAuthToken() {
|
|
1292
|
-
const binPath = getAuthBinaryPath();
|
|
1293
|
-
return new Promise((resolve3, reject) => {
|
|
1294
|
-
const child = spawn(binPath, ["token"], {
|
|
1295
|
-
stdio: ["ignore", "ignore", "inherit", "pipe"]
|
|
1296
|
-
// stdin stdout stderr fd3 (pipe)
|
|
1297
|
-
});
|
|
1298
|
-
const chunks = [];
|
|
1299
|
-
const fd3 = child.stdio[3];
|
|
1300
|
-
fd3.on("data", (chunk) => chunks.push(chunk));
|
|
1301
|
-
child.on("error", (err) => {
|
|
1302
|
-
reject(new ConfigError(
|
|
1303
|
-
`Failed to spawn okx-auth: ${err.message}`,
|
|
1304
|
-
"Ensure the okx-auth binary exists and is executable."
|
|
1305
|
-
));
|
|
1306
|
-
});
|
|
1307
|
-
child.on("close", (code) => {
|
|
1308
|
-
if (code === EXIT_CODES.SUCCESS) {
|
|
1309
|
-
const token = Buffer.concat(chunks).toString("utf-8").trim();
|
|
1310
|
-
if (!token) {
|
|
1311
|
-
reject(new AuthenticationError(
|
|
1312
|
-
"okx-auth returned empty token.",
|
|
1313
|
-
"Run `okx auth login` to re-authenticate."
|
|
1314
|
-
));
|
|
1315
|
-
return;
|
|
1316
|
-
}
|
|
1317
|
-
resolve3(token);
|
|
1318
|
-
return;
|
|
1319
|
-
}
|
|
1320
|
-
if (code === EXIT_CODES.NOT_LOGGED_IN) {
|
|
1321
|
-
reject(new NotLoggedInError());
|
|
1322
|
-
return;
|
|
1323
|
-
}
|
|
1324
|
-
if (code === EXIT_CODES.UNAUTHORIZED_CALLER) {
|
|
1325
|
-
reject(new AuthenticationError(
|
|
1326
|
-
"okx-auth rejected the caller (unauthorized).",
|
|
1327
|
-
"Ensure you are running from a trusted OKX tool."
|
|
1328
|
-
));
|
|
1329
|
-
return;
|
|
1330
|
-
}
|
|
1331
|
-
if (code === EXIT_CODES.REFRESH_FAILED) {
|
|
1332
|
-
reject(new AuthenticationError(
|
|
1333
|
-
"Token refresh failed.",
|
|
1334
|
-
"Run `okx auth login` to re-authenticate."
|
|
1335
|
-
));
|
|
1336
|
-
return;
|
|
1337
|
-
}
|
|
1338
|
-
reject(new AuthenticationError(
|
|
1339
|
-
`okx-auth token exited with code ${code}.`,
|
|
1340
|
-
"Run `okx auth login` to re-authenticate."
|
|
1341
|
-
));
|
|
1342
|
-
});
|
|
1343
|
-
});
|
|
1344
|
-
}
|
|
1345
|
-
function execAuthStatus() {
|
|
1346
|
-
const binPath = getAuthBinaryPath();
|
|
1347
|
-
return new Promise((resolve3) => {
|
|
1348
|
-
execFile2(
|
|
1349
|
-
binPath,
|
|
1350
|
-
["status", "--json"],
|
|
1351
|
-
{ timeout: EXEC_TIMEOUT_MS2, encoding: "utf-8" },
|
|
1352
|
-
(error, stdout) => {
|
|
1353
|
-
if (error) {
|
|
1354
|
-
resolve3(null);
|
|
1355
|
-
return;
|
|
1356
|
-
}
|
|
1357
|
-
try {
|
|
1358
|
-
const result = JSON.parse(stdout);
|
|
1359
|
-
resolve3(result);
|
|
1360
|
-
} catch {
|
|
1361
|
-
resolve3(null);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
);
|
|
1365
|
-
});
|
|
1366
|
-
}
|
|
1367
1256
|
function sleep(ms) {
|
|
1368
1257
|
return new Promise((resolve3) => {
|
|
1369
1258
|
setTimeout(resolve3, ms);
|
|
@@ -1442,10 +1331,10 @@ var OKX_CODE_BEHAVIORS = {
|
|
|
1442
1331
|
"50011": { retry: true, suggestion: "Rate limited. Back off and retry after a delay." },
|
|
1443
1332
|
"50061": { retry: true, suggestion: "Too many connections. Reduce request frequency and retry." },
|
|
1444
1333
|
// Server temporarily unavailable → retryable
|
|
1445
|
-
"50001": { retry: true, suggestion: "
|
|
1446
|
-
"50004": { retry: true, suggestion: "Endpoint
|
|
1334
|
+
"50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
|
|
1335
|
+
"50004": { retry: true, suggestion: "Endpoint request timeout. Retry later." },
|
|
1447
1336
|
"50013": { retry: true, suggestion: "System busy. Retry after 1-2 seconds." },
|
|
1448
|
-
"50026": { retry: true, suggestion: "
|
|
1337
|
+
"50026": { retry: true, suggestion: "System error. Retry in a few minutes." },
|
|
1449
1338
|
// Region / compliance restriction → do not retry
|
|
1450
1339
|
"51155": { retry: false, suggestion: "Feature unavailable in your region (site: {site}). Verify your site setting matches your account registration region. Available sites: global, eea, us. Do not retry." },
|
|
1451
1340
|
"51734": { retry: false, suggestion: "Feature not supported for your KYC country (site: {site}). Verify your site setting matches your account registration region. Available sites: global, eea, us. Do not retry." },
|
|
@@ -1495,7 +1384,6 @@ function maskKey(key) {
|
|
|
1495
1384
|
if (key.length <= 8) return "***";
|
|
1496
1385
|
return `${key.slice(0, 3)}***${key.slice(-3)}`;
|
|
1497
1386
|
}
|
|
1498
|
-
var TOKEN_CACHE_TTL_MS = 6e4;
|
|
1499
1387
|
function vlog2(message) {
|
|
1500
1388
|
process.stderr.write(`[verbose] ${message}
|
|
1501
1389
|
`);
|
|
@@ -1504,8 +1392,6 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1504
1392
|
config;
|
|
1505
1393
|
rateLimiter;
|
|
1506
1394
|
dispatcher;
|
|
1507
|
-
cachedAccessToken;
|
|
1508
|
-
cachedAccessTokenAt = 0;
|
|
1509
1395
|
doh;
|
|
1510
1396
|
constructor(config) {
|
|
1511
1397
|
this.config = config;
|
|
@@ -1520,51 +1406,6 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1520
1406
|
hasCustomProxy: !!config.proxyUrl
|
|
1521
1407
|
});
|
|
1522
1408
|
}
|
|
1523
|
-
/**
|
|
1524
|
-
* Resolve OAuth access token via the okx-auth binary (fd3 pipe).
|
|
1525
|
-
* Caches the token for 60 s to avoid spawning the binary on every
|
|
1526
|
-
* request. The binary handles refresh internally (300s TTL lead),
|
|
1527
|
-
* so periodic re-calls let it serve a fresh token when needed.
|
|
1528
|
-
* Returns null when not logged in.
|
|
1529
|
-
*/
|
|
1530
|
-
async resolveAccessToken() {
|
|
1531
|
-
if (this.cachedAccessToken && Date.now() - this.cachedAccessTokenAt < TOKEN_CACHE_TTL_MS) {
|
|
1532
|
-
return this.cachedAccessToken;
|
|
1533
|
-
}
|
|
1534
|
-
try {
|
|
1535
|
-
const token = await execAuthToken();
|
|
1536
|
-
this.cachedAccessToken = token;
|
|
1537
|
-
this.cachedAccessTokenAt = Date.now();
|
|
1538
|
-
return token;
|
|
1539
|
-
} catch (e) {
|
|
1540
|
-
if (e instanceof NotLoggedInError) {
|
|
1541
|
-
return null;
|
|
1542
|
-
}
|
|
1543
|
-
throw e;
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
/**
|
|
1547
|
-
* Dynamic auth — determines auth method per request.
|
|
1548
|
-
*
|
|
1549
|
-
* 1. API key in config → HMAC signing (no OAuth fallback)
|
|
1550
|
-
* 2. OAuth token via okx-auth binary → Bearer token
|
|
1551
|
-
* 3. Neither → throw ConfigError
|
|
1552
|
-
*/
|
|
1553
|
-
async applyAuth(headers, method, requestPath, bodyJson, timestamp) {
|
|
1554
|
-
if (this.config.apiKey && this.config.secretKey && this.config.passphrase) {
|
|
1555
|
-
this.setAuthHeaders(headers, method, requestPath, bodyJson, timestamp);
|
|
1556
|
-
return;
|
|
1557
|
-
}
|
|
1558
|
-
const accessToken = await this.resolveAccessToken();
|
|
1559
|
-
if (accessToken) {
|
|
1560
|
-
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1561
|
-
return;
|
|
1562
|
-
}
|
|
1563
|
-
throw new ConfigError(
|
|
1564
|
-
"No credentials found.",
|
|
1565
|
-
"Run `okx auth login` to authenticate, or configure API key credentials."
|
|
1566
|
-
);
|
|
1567
|
-
}
|
|
1568
1409
|
/** The canonical base URL for this client (e.g. https://www.okx.com). */
|
|
1569
1410
|
get baseUrl() {
|
|
1570
1411
|
return this.config.baseUrl;
|
|
@@ -1622,6 +1463,18 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1622
1463
|
});
|
|
1623
1464
|
}
|
|
1624
1465
|
setAuthHeaders(headers, method, requestPath, bodyJson, timestamp) {
|
|
1466
|
+
if (!this.config.hasAuth) {
|
|
1467
|
+
throw new ConfigError(
|
|
1468
|
+
"Private endpoint requires API credentials.",
|
|
1469
|
+
"Configure OKX_API_KEY, OKX_SECRET_KEY and OKX_PASSPHRASE."
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
if (!this.config.apiKey || !this.config.secretKey || !this.config.passphrase) {
|
|
1473
|
+
throw new ConfigError(
|
|
1474
|
+
"Invalid private API credentials state.",
|
|
1475
|
+
"Ensure all OKX credentials are set."
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1625
1478
|
const payload = `${timestamp}${method.toUpperCase()}${requestPath}${bodyJson}`;
|
|
1626
1479
|
const signature = signOkxPayload(payload, this.config.secretKey);
|
|
1627
1480
|
headers.set("OK-ACCESS-KEY", this.config.apiKey);
|
|
@@ -1736,7 +1589,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1736
1589
|
const conn = this.doh.getConnectionParams();
|
|
1737
1590
|
this.logRequest("POST", `${conn.baseUrl}${path42}`, "private");
|
|
1738
1591
|
const reqConfig = { method: "POST", path: path42, auth: "private" };
|
|
1739
|
-
const headers =
|
|
1592
|
+
const headers = this.buildHeaders(reqConfig, path42, bodyJson, getNow());
|
|
1740
1593
|
if (conn.userAgent) {
|
|
1741
1594
|
headers.set("User-Agent", conn.userAgent);
|
|
1742
1595
|
}
|
|
@@ -1853,7 +1706,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1853
1706
|
// Header building
|
|
1854
1707
|
// ---------------------------------------------------------------------------
|
|
1855
1708
|
/** Build HTTP headers. reqConfig.extraHeaders must NOT contain auth keys (OK-ACCESS-*). */
|
|
1856
|
-
|
|
1709
|
+
buildHeaders(reqConfig, requestPath, bodyJson, timestamp) {
|
|
1857
1710
|
const headers = new Headers({
|
|
1858
1711
|
"Content-Type": "application/json",
|
|
1859
1712
|
Accept: "application/json"
|
|
@@ -1862,7 +1715,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1862
1715
|
headers.set("User-Agent", this.config.userAgent);
|
|
1863
1716
|
}
|
|
1864
1717
|
if (reqConfig.auth === "private") {
|
|
1865
|
-
|
|
1718
|
+
this.setAuthHeaders(headers, reqConfig.method, requestPath, bodyJson, timestamp);
|
|
1866
1719
|
}
|
|
1867
1720
|
const useSimulated = reqConfig.simulatedTrading !== void 0 ? reqConfig.simulatedTrading : this.config.demo;
|
|
1868
1721
|
if (useSimulated) {
|
|
@@ -1916,7 +1769,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1916
1769
|
if (reqConfig.rateLimit) {
|
|
1917
1770
|
await this.rateLimiter.consume(reqConfig.rateLimit);
|
|
1918
1771
|
}
|
|
1919
|
-
const headers =
|
|
1772
|
+
const headers = this.buildHeaders(reqConfig, requestPath, bodyJson, timestamp);
|
|
1920
1773
|
if (conn.userAgent) {
|
|
1921
1774
|
headers.set("User-Agent", conn.userAgent);
|
|
1922
1775
|
}
|
|
@@ -2339,7 +2192,7 @@ var OKX_SITES = {
|
|
|
2339
2192
|
},
|
|
2340
2193
|
us: {
|
|
2341
2194
|
label: "US",
|
|
2342
|
-
apiBaseUrl: "https://
|
|
2195
|
+
apiBaseUrl: "https://app.okx.com",
|
|
2343
2196
|
webUrl: "https://app.okx.com"
|
|
2344
2197
|
}
|
|
2345
2198
|
};
|
|
@@ -3869,7 +3722,7 @@ function safeWriteFile(targetDir, fileName, data) {
|
|
|
3869
3722
|
throw new Error(`Invalid file name: "${fileName}"`);
|
|
3870
3723
|
}
|
|
3871
3724
|
const resolvedDir = resolve(targetDir);
|
|
3872
|
-
const filePath =
|
|
3725
|
+
const filePath = join3(resolvedDir, safeName);
|
|
3873
3726
|
const resolvedPath = resolve(filePath);
|
|
3874
3727
|
if (!resolvedPath.startsWith(resolvedDir + sep)) {
|
|
3875
3728
|
throw new Error(`Path traversal detected: "${fileName}" resolves outside target directory`);
|
|
@@ -3997,7 +3850,7 @@ async function extractSkillZip(zipPath, targetDir, limits) {
|
|
|
3997
3850
|
});
|
|
3998
3851
|
}
|
|
3999
3852
|
function readMetaJson(contentDir) {
|
|
4000
|
-
const metaPath =
|
|
3853
|
+
const metaPath = join4(contentDir, "_meta.json");
|
|
4001
3854
|
if (!existsSync(metaPath)) {
|
|
4002
3855
|
throw new Error(`_meta.json not found in ${contentDir}. Invalid skill package.`);
|
|
4003
3856
|
}
|
|
@@ -4023,12 +3876,12 @@ function readMetaJson(contentDir) {
|
|
|
4023
3876
|
};
|
|
4024
3877
|
}
|
|
4025
3878
|
function validateSkillMdExists(contentDir) {
|
|
4026
|
-
const skillMdPath =
|
|
3879
|
+
const skillMdPath = join4(contentDir, "SKILL.md");
|
|
4027
3880
|
if (!existsSync(skillMdPath)) {
|
|
4028
3881
|
throw new Error(`SKILL.md not found in ${contentDir}. Invalid skill package.`);
|
|
4029
3882
|
}
|
|
4030
3883
|
}
|
|
4031
|
-
var DEFAULT_REGISTRY_PATH =
|
|
3884
|
+
var DEFAULT_REGISTRY_PATH = join5(homedir3(), ".okx", "skills", "registry.json");
|
|
4032
3885
|
function readRegistry(registryPath = DEFAULT_REGISTRY_PATH) {
|
|
4033
3886
|
if (!existsSync2(registryPath)) {
|
|
4034
3887
|
return { version: 1, skills: {} };
|
|
@@ -5366,7 +5219,7 @@ function registerOnchainEarnTools() {
|
|
|
5366
5219
|
];
|
|
5367
5220
|
}
|
|
5368
5221
|
var DCD_CODE_BEHAVIORS = {
|
|
5369
|
-
"50001": { retry: true, suggestion: "
|
|
5222
|
+
"50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
|
|
5370
5223
|
"50002": { retry: false, suggestion: "Invalid JSON in request body. This is likely a bug \u2014 check request parameters." },
|
|
5371
5224
|
"50014": { retry: false, suggestion: "Missing required parameter. Check that all required fields are provided." },
|
|
5372
5225
|
"50016": { retry: false, suggestion: "notionalCcy does not match productId option type. Use baseCcy for CALL, quoteCcy for PUT." },
|
|
@@ -7984,10 +7837,10 @@ var NEWS_DETAIL = "/api/v5/orbit/news-detail";
|
|
|
7984
7837
|
var NEWS_DOMAINS = "/api/v5/orbit/news-platform";
|
|
7985
7838
|
var SENTIMENT_QUERY = "/api/v5/orbit/currency-sentiment-query";
|
|
7986
7839
|
var SENTIMENT_RANKING = "/api/v5/orbit/currency-sentiment-ranking";
|
|
7987
|
-
var NEWS_LANGUAGE = ["
|
|
7840
|
+
var NEWS_LANGUAGE = ["en-US", "zh-CN"];
|
|
7988
7841
|
function langHeader(lang) {
|
|
7989
|
-
|
|
7990
|
-
return { "Accept-Language":
|
|
7842
|
+
if (lang === "zh-CN" || lang === "zh_CN") return { "Accept-Language": "zh-CN" };
|
|
7843
|
+
return { "Accept-Language": "en-US" };
|
|
7991
7844
|
}
|
|
7992
7845
|
var NEWS_DETAIL_LVL = ["brief", "summary", "full"];
|
|
7993
7846
|
var NEWS_IMPORTANCE = ["high", "medium", "low"];
|
|
@@ -7996,7 +7849,7 @@ var NEWS_SORT = ["latest", "relevant"];
|
|
|
7996
7849
|
var SENTIMENT_PERIOD = ["1h", "4h", "24h"];
|
|
7997
7850
|
var D_COINS_NEWS = 'Comma-separated uppercase ticker symbols (e.g. "BTC,ETH"). Normalize names/aliases to standard tickers.';
|
|
7998
7851
|
var D_COINS_SENTIMENT = 'Comma-separated uppercase ticker symbols, max 20 (e.g. "BTC,ETH"). Normalize names/aliases to standard tickers.';
|
|
7999
|
-
var D_LANGUAGE = "Content language:
|
|
7852
|
+
var D_LANGUAGE = "Content language: zh-CN or en-US. Infer from user's message. No server default.";
|
|
8000
7853
|
var D_BEGIN = "Start time, Unix epoch milliseconds. Parse relative time if given (e.g. 'yesterday', 'last 7 days').";
|
|
8001
7854
|
var D_END = "End time, Unix epoch milliseconds. Parse relative time if given. Omit for no upper bound.";
|
|
8002
7855
|
var D_IMPORTANCE = "Importance filter: high (server default), medium, low. Omit unless user wants broader coverage.";
|
|
@@ -9793,7 +9646,7 @@ function createToolRunner(client, config) {
|
|
|
9793
9646
|
};
|
|
9794
9647
|
}
|
|
9795
9648
|
function configFilePath() {
|
|
9796
|
-
return
|
|
9649
|
+
return join6(homedir4(), ".okx", "config.toml");
|
|
9797
9650
|
}
|
|
9798
9651
|
function readFullConfig() {
|
|
9799
9652
|
const path42 = configFilePath();
|
|
@@ -9812,6 +9665,11 @@ Or re-run: okx config init`
|
|
|
9812
9665
|
);
|
|
9813
9666
|
}
|
|
9814
9667
|
}
|
|
9668
|
+
function readTomlProfile(profileName) {
|
|
9669
|
+
const config = readFullConfig();
|
|
9670
|
+
const name = profileName ?? config.default_profile ?? "default";
|
|
9671
|
+
return config.profiles?.[name] ?? {};
|
|
9672
|
+
}
|
|
9815
9673
|
var CONFIG_HEADER = `# OKX Trade Kit Configuration
|
|
9816
9674
|
# If editing manually, wrap values containing special chars in quotes:
|
|
9817
9675
|
# passphrase = 'value' (if value contains # \\ ")
|
|
@@ -9860,24 +9718,18 @@ function parseModuleList(rawModules) {
|
|
|
9860
9718
|
}
|
|
9861
9719
|
return Array.from(deduped);
|
|
9862
9720
|
}
|
|
9863
|
-
|
|
9721
|
+
function loadCredentials(toml) {
|
|
9864
9722
|
const apiKey = process.env.OKX_API_KEY?.trim() ?? toml.api_key;
|
|
9865
9723
|
const secretKey = process.env.OKX_SECRET_KEY?.trim() ?? toml.secret_key;
|
|
9866
9724
|
const passphrase = process.env.OKX_PASSPHRASE?.trim() ?? toml.passphrase;
|
|
9867
|
-
const
|
|
9725
|
+
const hasAuth = Boolean(apiKey && secretKey && passphrase);
|
|
9868
9726
|
const partialAuth = Boolean(apiKey) || Boolean(secretKey) || Boolean(passphrase);
|
|
9869
|
-
if (partialAuth && !
|
|
9727
|
+
if (partialAuth && !hasAuth) {
|
|
9870
9728
|
throw new ConfigError(
|
|
9871
9729
|
"Partial API credentials detected.",
|
|
9872
9730
|
"Set OKX_API_KEY, OKX_SECRET_KEY and OKX_PASSPHRASE together (env vars or config.toml profile)."
|
|
9873
9731
|
);
|
|
9874
9732
|
}
|
|
9875
|
-
let hasOAuth = false;
|
|
9876
|
-
if (!hasApiKey) {
|
|
9877
|
-
const status = await execAuthStatus();
|
|
9878
|
-
hasOAuth = status?.status === "logged_in";
|
|
9879
|
-
}
|
|
9880
|
-
const hasAuth = hasOAuth || hasApiKey;
|
|
9881
9733
|
return { apiKey, secretKey, passphrase, hasAuth };
|
|
9882
9734
|
}
|
|
9883
9735
|
function resolveSite(cliSite, tomlSite) {
|
|
@@ -9911,11 +9763,9 @@ function resolveDemo(cli, toml) {
|
|
|
9911
9763
|
if (cli.demo === true) return true;
|
|
9912
9764
|
return process.env.OKX_DEMO === "1" || process.env.OKX_DEMO === "true" || (toml.demo ?? false);
|
|
9913
9765
|
}
|
|
9914
|
-
|
|
9915
|
-
const
|
|
9916
|
-
const
|
|
9917
|
-
const toml = config.profiles?.[profileName] ?? {};
|
|
9918
|
-
const creds = await loadCredentials(toml);
|
|
9766
|
+
function loadConfig(cli) {
|
|
9767
|
+
const toml = readTomlProfile(cli.profile);
|
|
9768
|
+
const creds = loadCredentials(toml);
|
|
9919
9769
|
const demo = resolveDemo(cli, toml);
|
|
9920
9770
|
const site = resolveSite(cli.site, toml.site);
|
|
9921
9771
|
const baseUrl = resolveBaseUrl(site, toml.base_url);
|
|
@@ -9935,7 +9785,6 @@ async function loadConfig(cli) {
|
|
|
9935
9785
|
}
|
|
9936
9786
|
return {
|
|
9937
9787
|
...creds,
|
|
9938
|
-
profile: profileName,
|
|
9939
9788
|
baseUrl,
|
|
9940
9789
|
timeoutMs: Math.floor(rawTimeout),
|
|
9941
9790
|
modules: parseModuleList(cli.modules),
|
|
@@ -9948,7 +9797,7 @@ async function loadConfig(cli) {
|
|
|
9948
9797
|
verbose: cli.verbose ?? false
|
|
9949
9798
|
};
|
|
9950
9799
|
}
|
|
9951
|
-
var CACHE_FILE =
|
|
9800
|
+
var CACHE_FILE = join7(homedir5(), ".okx", "update-check.json");
|
|
9952
9801
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
9953
9802
|
function readCache2() {
|
|
9954
9803
|
try {
|
|
@@ -9961,7 +9810,7 @@ function readCache2() {
|
|
|
9961
9810
|
}
|
|
9962
9811
|
function writeCache2(cache) {
|
|
9963
9812
|
try {
|
|
9964
|
-
mkdirSync6(
|
|
9813
|
+
mkdirSync6(join7(homedir5(), ".okx"), { recursive: true });
|
|
9965
9814
|
writeFileSync5(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
9966
9815
|
} catch {
|
|
9967
9816
|
}
|
|
@@ -10131,13 +9980,13 @@ function findMsStoreClaudePath() {
|
|
|
10131
9980
|
}
|
|
10132
9981
|
function getConfigPath(client) {
|
|
10133
9982
|
const home = os3.homedir();
|
|
10134
|
-
const
|
|
9983
|
+
const platform2 = process.platform;
|
|
10135
9984
|
switch (client) {
|
|
10136
9985
|
case "claude-desktop":
|
|
10137
|
-
if (
|
|
9986
|
+
if (platform2 === "win32") {
|
|
10138
9987
|
return findMsStoreClaudePath() ?? path3.join(appData(), "Claude", CLAUDE_CONFIG_FILE);
|
|
10139
9988
|
}
|
|
10140
|
-
if (
|
|
9989
|
+
if (platform2 === "darwin") {
|
|
10141
9990
|
return path3.join(home, "Library", "Application Support", "Claude", CLAUDE_CONFIG_FILE);
|
|
10142
9991
|
}
|
|
10143
9992
|
return path3.join(process.env.XDG_CONFIG_HOME ?? path3.join(home, ".config"), "Claude", CLAUDE_CONFIG_FILE);
|
|
@@ -10258,7 +10107,7 @@ function getPlatformDir() {
|
|
|
10258
10107
|
return map[`${p}-${a}`] ?? null;
|
|
10259
10108
|
}
|
|
10260
10109
|
function getBinaryName() {
|
|
10261
|
-
return platform() === "win32" ? "okx-
|
|
10110
|
+
return platform() === "win32" ? "okx-pilot.exe" : "okx-pilot";
|
|
10262
10111
|
}
|
|
10263
10112
|
function hashFile(filePath) {
|
|
10264
10113
|
const buf = readFileSync7(filePath);
|
|
@@ -10379,7 +10228,7 @@ async function installDohBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
|
10379
10228
|
if (earlyResult) return earlyResult;
|
|
10380
10229
|
const platformDir = getPlatformDir();
|
|
10381
10230
|
const binaryName = getBinaryName();
|
|
10382
|
-
const resolvedDest = destPath ??
|
|
10231
|
+
const resolvedDest = destPath ?? join9(homedir7(), ".okx", "bin", binaryName);
|
|
10383
10232
|
const tmpPath = resolvedDest + ".tmp";
|
|
10384
10233
|
mkdirSync8(dirname6(resolvedDest), { recursive: true });
|
|
10385
10234
|
const localHash = existsSync6(resolvedDest) ? hashFile(resolvedDest) : null;
|
|
@@ -10502,224 +10351,16 @@ function downloadText(url, timeoutMs) {
|
|
|
10502
10351
|
})
|
|
10503
10352
|
);
|
|
10504
10353
|
}
|
|
10505
|
-
var AUTH_CDN_PATH_PREFIX = "/upgradeapp/tools/oauth";
|
|
10506
|
-
function getAuthBinaryName() {
|
|
10507
|
-
return platform2() === "win32" ? "okx-auth.exe" : "okx-auth";
|
|
10508
|
-
}
|
|
10509
|
-
function getAuthStatus(binaryPath, opts) {
|
|
10510
|
-
const resolvedPath = binaryPath ?? getAuthBinaryPath();
|
|
10511
|
-
const platformDir = getPlatformDir();
|
|
10512
|
-
if (!existsSync7(resolvedPath)) {
|
|
10513
|
-
return { binaryPath: resolvedPath, exists: false, platform: platformDir };
|
|
10514
|
-
}
|
|
10515
|
-
if (opts?.skipHash) {
|
|
10516
|
-
return { binaryPath: resolvedPath, exists: true, platform: platformDir };
|
|
10517
|
-
}
|
|
10518
|
-
const { size, sha256 } = hashFile(resolvedPath);
|
|
10519
|
-
return { binaryPath: resolvedPath, exists: true, platform: platformDir, fileSize: size, sha256 };
|
|
10520
|
-
}
|
|
10521
|
-
async function fetchAuthCdnChecksum(sources = CDN_SOURCES, timeoutMs = DOWNLOAD_TIMEOUT_MS) {
|
|
10522
|
-
const platformDir = getPlatformDir();
|
|
10523
|
-
if (!platformDir) return null;
|
|
10524
|
-
const checksumPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
|
|
10525
|
-
for (const { host, protocol } of sources) {
|
|
10526
|
-
try {
|
|
10527
|
-
const url = `${protocol}://${host}${checksumPath}`;
|
|
10528
|
-
const raw = await downloadText2(url, timeoutMs);
|
|
10529
|
-
const data = JSON.parse(raw);
|
|
10530
|
-
if (typeof data.sha256 !== "string" || typeof data.size !== "number" || typeof data.target !== "string") {
|
|
10531
|
-
continue;
|
|
10532
|
-
}
|
|
10533
|
-
return { sha256: data.sha256, size: data.size, target: data.target, source: host };
|
|
10534
|
-
} catch {
|
|
10535
|
-
}
|
|
10536
|
-
}
|
|
10537
|
-
return null;
|
|
10538
|
-
}
|
|
10539
|
-
async function fetchAndValidateChecksum2(host, protocol, checksumPath, platformDir, timeoutMs, onProgress) {
|
|
10540
|
-
const checksumUrl = `${protocol}://${host}${checksumPath}`;
|
|
10541
|
-
onProgress?.(`Fetching checksum from ${host}...`);
|
|
10542
|
-
const raw = await downloadText2(checksumUrl, timeoutMs);
|
|
10543
|
-
const checksum = JSON.parse(raw);
|
|
10544
|
-
if (typeof checksum.sha256 !== "string" || typeof checksum.size !== "number" || typeof checksum.target !== "string") {
|
|
10545
|
-
throw new Error("Invalid checksum.json: missing sha256, size, or target");
|
|
10546
|
-
}
|
|
10547
|
-
if (checksum.target !== platformDir) {
|
|
10548
|
-
throw new Error(`Target mismatch: expected ${platformDir}, got ${checksum.target}`);
|
|
10549
|
-
}
|
|
10550
|
-
return { sha256: checksum.sha256, size: checksum.size, target: checksum.target };
|
|
10551
|
-
}
|
|
10552
|
-
async function downloadAndVerify2(host, protocol, binaryPath, tmpPath, checksum, timeoutMs, onProgress) {
|
|
10553
|
-
const binaryUrl = `${protocol}://${host}${binaryPath}`;
|
|
10554
|
-
onProgress?.(`Downloading binary from ${host}...`);
|
|
10555
|
-
await download2(binaryUrl, tmpPath, timeoutMs);
|
|
10556
|
-
const actual = hashFile(tmpPath);
|
|
10557
|
-
if (actual.size !== checksum.size) {
|
|
10558
|
-
throw new Error(`Size mismatch: expected ${checksum.size}, got ${actual.size}`);
|
|
10559
|
-
}
|
|
10560
|
-
if (actual.sha256 !== checksum.sha256) {
|
|
10561
|
-
throw new Error(`SHA-256 mismatch: expected ${checksum.sha256}, got ${actual.sha256}`);
|
|
10562
|
-
}
|
|
10563
|
-
}
|
|
10564
|
-
function atomicReplace2(tmpPath, resolvedDest) {
|
|
10565
|
-
if (platform2() === "win32") {
|
|
10566
|
-
try {
|
|
10567
|
-
unlinkSync4(resolvedDest);
|
|
10568
|
-
} catch {
|
|
10569
|
-
}
|
|
10570
|
-
}
|
|
10571
|
-
renameSync4(tmpPath, resolvedDest);
|
|
10572
|
-
if (platform2() !== "win32") {
|
|
10573
|
-
chmodSync2(resolvedDest, 493);
|
|
10574
|
-
}
|
|
10575
|
-
}
|
|
10576
|
-
function installPreChecks2(destPath, sources) {
|
|
10577
|
-
if (!destPath && process.env.OKX_AUTH_BIN) {
|
|
10578
|
-
return { status: "up-to-date", source: "(env override)" };
|
|
10579
|
-
}
|
|
10580
|
-
if (!getPlatformDir()) {
|
|
10581
|
-
return { status: "failed", error: "Unsupported platform" };
|
|
10582
|
-
}
|
|
10583
|
-
if (sources.length === 0) {
|
|
10584
|
-
return { status: "failed", error: "No CDN sources available" };
|
|
10585
|
-
}
|
|
10586
|
-
return null;
|
|
10587
|
-
}
|
|
10588
|
-
function isLocalUpToDate2(localHash, checksum) {
|
|
10589
|
-
return localHash !== null && localHash.size === checksum.size && localHash.sha256 === checksum.sha256;
|
|
10590
|
-
}
|
|
10591
|
-
async function installAuthBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
10592
|
-
const earlyResult = installPreChecks2(destPath, sources);
|
|
10593
|
-
if (earlyResult) return earlyResult;
|
|
10594
|
-
const platformDir = getPlatformDir();
|
|
10595
|
-
const binaryName = getAuthBinaryName();
|
|
10596
|
-
const resolvedDest = destPath ?? join11(homedir9(), ".okx", "bin", binaryName);
|
|
10597
|
-
const tmpPath = resolvedDest + ".tmp";
|
|
10598
|
-
mkdirSync9(dirname7(resolvedDest), { recursive: true });
|
|
10599
|
-
const localHash = existsSync7(resolvedDest) ? hashFile(resolvedDest) : null;
|
|
10600
|
-
const checksumPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
|
|
10601
|
-
const binaryPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/${binaryName}`;
|
|
10602
|
-
const errors = [];
|
|
10603
|
-
for (const { host, protocol } of sources) {
|
|
10604
|
-
try {
|
|
10605
|
-
const checksum = await fetchAndValidateChecksum2(
|
|
10606
|
-
host,
|
|
10607
|
-
protocol,
|
|
10608
|
-
checksumPath,
|
|
10609
|
-
platformDir,
|
|
10610
|
-
DOWNLOAD_TIMEOUT_MS,
|
|
10611
|
-
onProgress
|
|
10612
|
-
);
|
|
10613
|
-
if (isLocalUpToDate2(localHash, checksum)) {
|
|
10614
|
-
onProgress?.("Already up to date (checksum match)");
|
|
10615
|
-
return { status: "up-to-date", source: host };
|
|
10616
|
-
}
|
|
10617
|
-
await downloadAndVerify2(host, protocol, binaryPath, tmpPath, checksum, DOWNLOAD_TIMEOUT_MS, onProgress);
|
|
10618
|
-
atomicReplace2(tmpPath, resolvedDest);
|
|
10619
|
-
onProgress?.(`Downloaded and verified from ${host}`);
|
|
10620
|
-
return { status: "installed", source: host };
|
|
10621
|
-
} catch (err) {
|
|
10622
|
-
try {
|
|
10623
|
-
unlinkSync4(tmpPath);
|
|
10624
|
-
} catch {
|
|
10625
|
-
}
|
|
10626
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
10627
|
-
errors.push(`${host}: ${msg}`);
|
|
10628
|
-
onProgress?.(`${host} failed: ${msg}`);
|
|
10629
|
-
}
|
|
10630
|
-
}
|
|
10631
|
-
return { status: "failed", error: `All CDN sources failed:
|
|
10632
|
-
${errors.join("\n")}` };
|
|
10633
|
-
}
|
|
10634
|
-
function removeAuthBinary(binaryPath) {
|
|
10635
|
-
const resolvedPath = binaryPath ?? getAuthBinaryPath();
|
|
10636
|
-
try {
|
|
10637
|
-
unlinkSync4(resolvedPath);
|
|
10638
|
-
return { status: "removed" };
|
|
10639
|
-
} catch (err) {
|
|
10640
|
-
if (err.code === "ENOENT") {
|
|
10641
|
-
return { status: "not-found" };
|
|
10642
|
-
}
|
|
10643
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
10644
|
-
throw new Error(`Failed to remove ${resolvedPath}: ${msg}`);
|
|
10645
|
-
}
|
|
10646
|
-
}
|
|
10647
|
-
function isRedirect2(statusCode) {
|
|
10648
|
-
return statusCode !== void 0 && statusCode >= 300 && statusCode < 400;
|
|
10649
|
-
}
|
|
10650
|
-
function validateRedirect2(res, requestUrl, redirectCount, maxRedirects) {
|
|
10651
|
-
if (redirectCount > maxRedirects) {
|
|
10652
|
-
throw new Error(`Too many redirects (${maxRedirects})`);
|
|
10653
|
-
}
|
|
10654
|
-
const location = res.headers.location;
|
|
10655
|
-
if (requestUrl.startsWith("https") && !location.startsWith("https")) {
|
|
10656
|
-
throw new Error("Refused HTTPS \u2192 HTTP redirect downgrade");
|
|
10657
|
-
}
|
|
10658
|
-
return location;
|
|
10659
|
-
}
|
|
10660
|
-
function fetchResponse2(url, timeoutMs) {
|
|
10661
|
-
return new Promise((resolve3, reject) => {
|
|
10662
|
-
let redirects = 0;
|
|
10663
|
-
const maxRedirects = 5;
|
|
10664
|
-
function doRequest(requestUrl) {
|
|
10665
|
-
const reqFn = requestUrl.startsWith("https") ? httpsGet2 : httpGet2;
|
|
10666
|
-
const req = reqFn(requestUrl, { timeout: timeoutMs }, (res) => {
|
|
10667
|
-
if (isRedirect2(res.statusCode) && res.headers.location) {
|
|
10668
|
-
redirects++;
|
|
10669
|
-
try {
|
|
10670
|
-
const location = validateRedirect2(res, requestUrl, redirects, maxRedirects);
|
|
10671
|
-
res.resume();
|
|
10672
|
-
doRequest(location);
|
|
10673
|
-
} catch (err) {
|
|
10674
|
-
reject(err);
|
|
10675
|
-
}
|
|
10676
|
-
return;
|
|
10677
|
-
}
|
|
10678
|
-
if (res.statusCode !== 200) {
|
|
10679
|
-
reject(new Error(`HTTP ${res.statusCode ?? "unknown"}`));
|
|
10680
|
-
return;
|
|
10681
|
-
}
|
|
10682
|
-
resolve3(res);
|
|
10683
|
-
});
|
|
10684
|
-
req.on("error", reject);
|
|
10685
|
-
req.on("timeout", () => {
|
|
10686
|
-
req.destroy();
|
|
10687
|
-
reject(new Error("Download timed out"));
|
|
10688
|
-
});
|
|
10689
|
-
}
|
|
10690
|
-
doRequest(url);
|
|
10691
|
-
});
|
|
10692
|
-
}
|
|
10693
|
-
function download2(url, destPath, timeoutMs) {
|
|
10694
|
-
return fetchResponse2(url, timeoutMs).then(
|
|
10695
|
-
(res) => new Promise((resolve3, reject) => {
|
|
10696
|
-
const file = createWriteStream3(destPath);
|
|
10697
|
-
res.pipe(file);
|
|
10698
|
-
file.on("finish", () => file.close(() => resolve3()));
|
|
10699
|
-
file.on("error", (err) => {
|
|
10700
|
-
try {
|
|
10701
|
-
unlinkSync4(destPath);
|
|
10702
|
-
} catch {
|
|
10703
|
-
}
|
|
10704
|
-
reject(err);
|
|
10705
|
-
});
|
|
10706
|
-
})
|
|
10707
|
-
);
|
|
10708
|
-
}
|
|
10709
|
-
function downloadText2(url, timeoutMs) {
|
|
10710
|
-
return fetchResponse2(url, timeoutMs).then(
|
|
10711
|
-
(res) => new Promise((resolve3, reject) => {
|
|
10712
|
-
const chunks = [];
|
|
10713
|
-
res.on("data", (chunk) => chunks.push(chunk));
|
|
10714
|
-
res.on("end", () => resolve3(Buffer.concat(chunks).toString("utf8")));
|
|
10715
|
-
res.on("error", reject);
|
|
10716
|
-
})
|
|
10717
|
-
);
|
|
10718
|
-
}
|
|
10719
10354
|
|
|
10720
|
-
// src/commands/
|
|
10721
|
-
import
|
|
10722
|
-
import
|
|
10355
|
+
// src/commands/diagnose.ts
|
|
10356
|
+
import dns from "dns/promises";
|
|
10357
|
+
import net from "net";
|
|
10358
|
+
import os5 from "os";
|
|
10359
|
+
import tls from "tls";
|
|
10360
|
+
|
|
10361
|
+
// src/commands/diagnose-utils.ts
|
|
10362
|
+
import fs4 from "fs";
|
|
10363
|
+
import { createRequire } from "module";
|
|
10723
10364
|
|
|
10724
10365
|
// src/formatter.ts
|
|
10725
10366
|
import { EOL } from "os";
|
|
@@ -10810,249 +10451,7 @@ function markFailedIfSCodeError(data) {
|
|
|
10810
10451
|
}
|
|
10811
10452
|
}
|
|
10812
10453
|
|
|
10813
|
-
// src/commands/auth.ts
|
|
10814
|
-
function runOkxAuth(args) {
|
|
10815
|
-
const binPath = getAuthBinaryPath();
|
|
10816
|
-
return new Promise((resolve3, reject) => {
|
|
10817
|
-
const child = spawn2(binPath, args, {
|
|
10818
|
-
stdio: "inherit"
|
|
10819
|
-
});
|
|
10820
|
-
child.on("error", (err) => {
|
|
10821
|
-
reject(new Error(`Failed to spawn okx-auth: ${err.message}`));
|
|
10822
|
-
});
|
|
10823
|
-
child.on("close", (code) => {
|
|
10824
|
-
resolve3(code ?? 1);
|
|
10825
|
-
});
|
|
10826
|
-
});
|
|
10827
|
-
}
|
|
10828
|
-
function runOkxAuthCapture(args) {
|
|
10829
|
-
const binPath = getAuthBinaryPath();
|
|
10830
|
-
return new Promise((resolve3, reject) => {
|
|
10831
|
-
const child = spawn2(binPath, args, {
|
|
10832
|
-
stdio: ["inherit", "pipe", "inherit"]
|
|
10833
|
-
});
|
|
10834
|
-
const chunks = [];
|
|
10835
|
-
child.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
10836
|
-
child.on("error", (err) => {
|
|
10837
|
-
reject(new Error(`Failed to spawn okx-auth: ${err.message}`));
|
|
10838
|
-
});
|
|
10839
|
-
child.on("close", (code) => {
|
|
10840
|
-
resolve3({
|
|
10841
|
-
code: code ?? 1,
|
|
10842
|
-
stdout: Buffer.concat(chunks).toString("utf-8")
|
|
10843
|
-
});
|
|
10844
|
-
});
|
|
10845
|
-
});
|
|
10846
|
-
}
|
|
10847
|
-
async function cmdAuthLogin(args) {
|
|
10848
|
-
const cliArgs = ["login"];
|
|
10849
|
-
if (args.site) cliArgs.push("--site", args.site);
|
|
10850
|
-
if (args.manual) cliArgs.push("--manual");
|
|
10851
|
-
const code = await runOkxAuth(cliArgs);
|
|
10852
|
-
if (code !== 0) {
|
|
10853
|
-
process.exitCode = code;
|
|
10854
|
-
}
|
|
10855
|
-
}
|
|
10856
|
-
async function cmdAuthLogout() {
|
|
10857
|
-
const code = await runOkxAuth(["logout"]);
|
|
10858
|
-
if (code !== 0) {
|
|
10859
|
-
process.exitCode = code;
|
|
10860
|
-
}
|
|
10861
|
-
}
|
|
10862
|
-
async function cmdAuthStatus(args) {
|
|
10863
|
-
const cliArgs = ["status"];
|
|
10864
|
-
if (args.json) cliArgs.push("--json");
|
|
10865
|
-
const result = await runOkxAuthCapture(cliArgs);
|
|
10866
|
-
if (result.stdout) {
|
|
10867
|
-
process.stdout.write(result.stdout);
|
|
10868
|
-
}
|
|
10869
|
-
if (result.code !== 0) {
|
|
10870
|
-
process.exitCode = result.code;
|
|
10871
|
-
}
|
|
10872
|
-
}
|
|
10873
|
-
function resolveChecksumMatch(local, cdnChecksum, cdnError) {
|
|
10874
|
-
if (!local.exists) return "not-installed";
|
|
10875
|
-
if (cdnError || !cdnChecksum) return "unavailable";
|
|
10876
|
-
if (cdnChecksum.sha256 === local.sha256) return "match";
|
|
10877
|
-
return "mismatch";
|
|
10878
|
-
}
|
|
10879
|
-
function checksumMatchLabel(match) {
|
|
10880
|
-
if (match === "match") return "\u2713 match";
|
|
10881
|
-
if (match === "mismatch") return "\u2717 mismatch (update available)";
|
|
10882
|
-
return "CDN unreachable";
|
|
10883
|
-
}
|
|
10884
|
-
function formatBytes(bytes) {
|
|
10885
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
10886
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
10887
|
-
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
10888
|
-
}
|
|
10889
|
-
async function cmdAuthInstallStatus(json) {
|
|
10890
|
-
const local = getAuthStatus();
|
|
10891
|
-
let cdnChecksum = null;
|
|
10892
|
-
let cdnError = null;
|
|
10893
|
-
if (local.exists) {
|
|
10894
|
-
try {
|
|
10895
|
-
cdnChecksum = await fetchAuthCdnChecksum(void 0, 5e3);
|
|
10896
|
-
} catch (err) {
|
|
10897
|
-
cdnError = err instanceof Error ? err.message : String(err);
|
|
10898
|
-
}
|
|
10899
|
-
}
|
|
10900
|
-
const checksumMatch = resolveChecksumMatch(local, cdnChecksum, cdnError);
|
|
10901
|
-
if (json) {
|
|
10902
|
-
outputLine(
|
|
10903
|
-
JSON.stringify({
|
|
10904
|
-
binaryPath: local.binaryPath,
|
|
10905
|
-
exists: local.exists,
|
|
10906
|
-
platform: local.platform,
|
|
10907
|
-
fileSize: local.fileSize ?? null,
|
|
10908
|
-
sha256: local.sha256 ?? null,
|
|
10909
|
-
cdnMatch: checksumMatch,
|
|
10910
|
-
cdnSha256: cdnChecksum?.sha256 ?? null,
|
|
10911
|
-
cdnSource: cdnChecksum?.source ?? null
|
|
10912
|
-
})
|
|
10913
|
-
);
|
|
10914
|
-
return;
|
|
10915
|
-
}
|
|
10916
|
-
outputLine("");
|
|
10917
|
-
outputLine(" okx-auth Binary Status");
|
|
10918
|
-
outputLine(" " + "\u2500".repeat(40));
|
|
10919
|
-
outputLine(` Binary path : ${local.binaryPath}`);
|
|
10920
|
-
outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
|
|
10921
|
-
outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
|
|
10922
|
-
if (local.exists) {
|
|
10923
|
-
outputLine(` File size : ${formatBytes(local.fileSize)}`);
|
|
10924
|
-
outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
|
|
10925
|
-
outputLine(` CDN check : ${checksumMatchLabel(checksumMatch)}`);
|
|
10926
|
-
if (cdnChecksum) {
|
|
10927
|
-
outputLine(` CDN source : ${cdnChecksum.source}`);
|
|
10928
|
-
}
|
|
10929
|
-
}
|
|
10930
|
-
outputLine("");
|
|
10931
|
-
}
|
|
10932
|
-
async function cmdAuthInstall(json) {
|
|
10933
|
-
const messages2 = [];
|
|
10934
|
-
const onProgress = (msg) => {
|
|
10935
|
-
if (!json) {
|
|
10936
|
-
outputLine(` ${msg}`);
|
|
10937
|
-
}
|
|
10938
|
-
messages2.push(msg);
|
|
10939
|
-
};
|
|
10940
|
-
if (!json) {
|
|
10941
|
-
outputLine("");
|
|
10942
|
-
outputLine(" Installing okx-auth...");
|
|
10943
|
-
}
|
|
10944
|
-
const result = await installAuthBinary(void 0, void 0, onProgress);
|
|
10945
|
-
if (json) {
|
|
10946
|
-
outputLine(JSON.stringify({ status: result.status, source: result.source ?? null, error: result.error ?? null, messages: messages2 }));
|
|
10947
|
-
if (result.status === "failed") {
|
|
10948
|
-
process.exitCode = 1;
|
|
10949
|
-
}
|
|
10950
|
-
return;
|
|
10951
|
-
}
|
|
10952
|
-
if (result.status === "installed") {
|
|
10953
|
-
outputLine(` \u2713 okx-auth installed successfully (${result.source ?? ""})`);
|
|
10954
|
-
} else if (result.status === "up-to-date") {
|
|
10955
|
-
outputLine(" \u2713 okx-auth is already up to date");
|
|
10956
|
-
} else {
|
|
10957
|
-
errorLine(` \u2717 Installation failed: ${result.error ?? "unknown error"}`);
|
|
10958
|
-
errorLine(" Hint: check network connectivity or try again later");
|
|
10959
|
-
process.exitCode = 1;
|
|
10960
|
-
}
|
|
10961
|
-
outputLine("");
|
|
10962
|
-
}
|
|
10963
|
-
async function cmdAuthRemove(force, json) {
|
|
10964
|
-
const local = getAuthStatus(void 0, { skipHash: true });
|
|
10965
|
-
if (!local.exists) {
|
|
10966
|
-
if (json) {
|
|
10967
|
-
outputLine(JSON.stringify({ status: "not-installed" }));
|
|
10968
|
-
} else {
|
|
10969
|
-
outputLine(" okx-auth is not installed.");
|
|
10970
|
-
}
|
|
10971
|
-
return;
|
|
10972
|
-
}
|
|
10973
|
-
if (!force) {
|
|
10974
|
-
if (!process.stdin.isTTY) {
|
|
10975
|
-
errorLine(" Error: stdin is not a TTY. Use --force to skip confirmation.");
|
|
10976
|
-
process.exitCode = 1;
|
|
10977
|
-
return;
|
|
10978
|
-
}
|
|
10979
|
-
const confirmed = await askConfirmation(
|
|
10980
|
-
` Remove okx-auth at ${local.binaryPath}? [y/N] `
|
|
10981
|
-
);
|
|
10982
|
-
if (!confirmed) {
|
|
10983
|
-
outputLine(" Cancelled.");
|
|
10984
|
-
return;
|
|
10985
|
-
}
|
|
10986
|
-
}
|
|
10987
|
-
let result;
|
|
10988
|
-
try {
|
|
10989
|
-
result = removeAuthBinary();
|
|
10990
|
-
} catch (err) {
|
|
10991
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
10992
|
-
if (json) {
|
|
10993
|
-
outputLine(JSON.stringify({ status: "failed", error: msg }));
|
|
10994
|
-
} else {
|
|
10995
|
-
errorLine(` \u2717 Failed to remove: ${msg}`);
|
|
10996
|
-
}
|
|
10997
|
-
process.exitCode = 1;
|
|
10998
|
-
return;
|
|
10999
|
-
}
|
|
11000
|
-
if (json) {
|
|
11001
|
-
outputLine(JSON.stringify({ status: result.status, path: local.binaryPath }));
|
|
11002
|
-
return;
|
|
11003
|
-
}
|
|
11004
|
-
if (result.status === "removed") {
|
|
11005
|
-
outputLine(` \u2713 Removed: ${local.binaryPath}`);
|
|
11006
|
-
} else {
|
|
11007
|
-
outputLine(" okx-auth is not installed.");
|
|
11008
|
-
}
|
|
11009
|
-
}
|
|
11010
|
-
function askConfirmation(prompt2) {
|
|
11011
|
-
return new Promise((resolve3) => {
|
|
11012
|
-
const rl = readline.createInterface({
|
|
11013
|
-
input: process.stdin,
|
|
11014
|
-
output: process.stdout
|
|
11015
|
-
});
|
|
11016
|
-
rl.question(prompt2, (answer) => {
|
|
11017
|
-
rl.close();
|
|
11018
|
-
resolve3(answer.trim().toLowerCase() === "y");
|
|
11019
|
-
});
|
|
11020
|
-
});
|
|
11021
|
-
}
|
|
11022
|
-
function handleAuthCommand(action, _rest, v) {
|
|
11023
|
-
const site = v.site;
|
|
11024
|
-
const json = v.json;
|
|
11025
|
-
const manual = v.manual;
|
|
11026
|
-
const force = v.force;
|
|
11027
|
-
switch (action) {
|
|
11028
|
-
case "login":
|
|
11029
|
-
return cmdAuthLogin({ site, manual });
|
|
11030
|
-
case "logout":
|
|
11031
|
-
return cmdAuthLogout();
|
|
11032
|
-
case "status":
|
|
11033
|
-
return cmdAuthStatus({ json });
|
|
11034
|
-
case "install":
|
|
11035
|
-
return cmdAuthInstall(json ?? false);
|
|
11036
|
-
case "install-status":
|
|
11037
|
-
return cmdAuthInstallStatus(json ?? false);
|
|
11038
|
-
case "remove":
|
|
11039
|
-
return cmdAuthRemove(force ?? false, json ?? false);
|
|
11040
|
-
default:
|
|
11041
|
-
errorLine(`Unknown auth command: ${action}`);
|
|
11042
|
-
errorLine("Available: login, logout, status, install, install-status, remove");
|
|
11043
|
-
process.exitCode = 1;
|
|
11044
|
-
}
|
|
11045
|
-
}
|
|
11046
|
-
|
|
11047
|
-
// src/commands/diagnose.ts
|
|
11048
|
-
import dns from "dns/promises";
|
|
11049
|
-
import net from "net";
|
|
11050
|
-
import os5 from "os";
|
|
11051
|
-
import tls from "tls";
|
|
11052
|
-
|
|
11053
10454
|
// src/commands/diagnose-utils.ts
|
|
11054
|
-
import fs4 from "fs";
|
|
11055
|
-
import { createRequire } from "module";
|
|
11056
10455
|
var _require = createRequire(import.meta.url);
|
|
11057
10456
|
function readCliVersion() {
|
|
11058
10457
|
for (const rel of ["../package.json", "../../package.json"]) {
|
|
@@ -11138,7 +10537,7 @@ function sanitize2(value) {
|
|
|
11138
10537
|
import fs5 from "fs";
|
|
11139
10538
|
import path4 from "path";
|
|
11140
10539
|
import os4 from "os";
|
|
11141
|
-
import { spawnSync, spawn
|
|
10540
|
+
import { spawnSync, spawn } from "child_process";
|
|
11142
10541
|
import { createRequire as createRequire2 } from "module";
|
|
11143
10542
|
import { fileURLToPath } from "url";
|
|
11144
10543
|
var _require2 = createRequire2(import.meta.url);
|
|
@@ -11472,7 +10871,7 @@ async function checkStdioHandshake(entryPath, report) {
|
|
|
11472
10871
|
clearTimeout(timer);
|
|
11473
10872
|
resolve3(passed);
|
|
11474
10873
|
};
|
|
11475
|
-
const child =
|
|
10874
|
+
const child = spawn(process.execPath, [entryPath], {
|
|
11476
10875
|
stdio: ["pipe", "pipe", "pipe"],
|
|
11477
10876
|
env: { ...process.env }
|
|
11478
10877
|
});
|
|
@@ -11591,7 +10990,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
11591
10990
|
|
|
11592
10991
|
// src/commands/diagnose.ts
|
|
11593
10992
|
var CLI_VERSION = readCliVersion();
|
|
11594
|
-
var GIT_HASH = true ? "
|
|
10993
|
+
var GIT_HASH = true ? "e0312e6" : "dev";
|
|
11595
10994
|
function maskKey2(key) {
|
|
11596
10995
|
if (!key) return "(not set)";
|
|
11597
10996
|
if (key.length <= 8) return "****";
|
|
@@ -11927,13 +11326,13 @@ async function runCliChecks(config, profile, outputPath) {
|
|
|
11927
11326
|
|
|
11928
11327
|
// src/commands/upgrade.ts
|
|
11929
11328
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
11930
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as
|
|
11931
|
-
import { dirname as
|
|
11932
|
-
import { homedir as
|
|
11329
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
|
|
11330
|
+
import { dirname as dirname7, join as join10 } from "path";
|
|
11331
|
+
import { homedir as homedir8 } from "os";
|
|
11933
11332
|
var PACKAGES = ["@okx_ai/okx-trade-mcp", "@okx_ai/okx-trade-cli"];
|
|
11934
|
-
var CACHE_FILE2 =
|
|
11333
|
+
var CACHE_FILE2 = join10(homedir8(), ".okx", "last_check");
|
|
11935
11334
|
var THROTTLE_MS = 12 * 60 * 60 * 1e3;
|
|
11936
|
-
var NPM_BIN =
|
|
11335
|
+
var NPM_BIN = join10(dirname7(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
|
|
11937
11336
|
function readLastCheck() {
|
|
11938
11337
|
try {
|
|
11939
11338
|
return parseInt(readFileSync8(CACHE_FILE2, "utf-8").trim(), 10) || 0;
|
|
@@ -11943,7 +11342,7 @@ function readLastCheck() {
|
|
|
11943
11342
|
}
|
|
11944
11343
|
function writeLastCheck() {
|
|
11945
11344
|
try {
|
|
11946
|
-
|
|
11345
|
+
mkdirSync9(join10(homedir8(), ".okx"), { recursive: true });
|
|
11947
11346
|
writeFileSync7(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
|
|
11948
11347
|
} catch {
|
|
11949
11348
|
}
|
|
@@ -12915,24 +12314,24 @@ var CLI_REGISTRY = {
|
|
|
12915
12314
|
commands: {
|
|
12916
12315
|
latest: {
|
|
12917
12316
|
toolName: "news_get_latest",
|
|
12918
|
-
usage: "okx news latest [--coins BTC,ETH] [--lang
|
|
12317
|
+
usage: "okx news latest [--coins BTC,ETH] [--lang zh-CN] [--limit 20]"
|
|
12919
12318
|
},
|
|
12920
12319
|
important: {
|
|
12921
12320
|
toolName: "news_get_latest",
|
|
12922
|
-
usage: "okx news important [--coins BTC,ETH] [--lang
|
|
12321
|
+
usage: "okx news important [--coins BTC,ETH] [--lang zh-CN] [--limit 20]",
|
|
12923
12322
|
description: "Get important/high-impact crypto news"
|
|
12924
12323
|
},
|
|
12925
12324
|
"by-coin": {
|
|
12926
12325
|
toolName: "news_get_by_coin",
|
|
12927
|
-
usage: "okx news by-coin --coins BTC [--importance high] [--lang
|
|
12326
|
+
usage: "okx news by-coin --coins BTC [--importance high] [--lang zh-CN]"
|
|
12928
12327
|
},
|
|
12929
12328
|
search: {
|
|
12930
12329
|
toolName: "news_search",
|
|
12931
|
-
usage: "okx news search --keyword <term> [--coins BTC] [--sentiment bullish] [--lang
|
|
12330
|
+
usage: "okx news search --keyword <term> [--coins BTC] [--sentiment bullish] [--lang zh-CN]"
|
|
12932
12331
|
},
|
|
12933
12332
|
detail: {
|
|
12934
12333
|
toolName: "news_get_detail",
|
|
12935
|
-
usage: "okx news detail <id> [--lang
|
|
12334
|
+
usage: "okx news detail <id> [--lang zh-CN]"
|
|
12936
12335
|
},
|
|
12937
12336
|
domains: {
|
|
12938
12337
|
toolName: "news_get_domains",
|
|
@@ -13364,7 +12763,7 @@ async function cmdNewsSentimentRank(run, opts) {
|
|
|
13364
12763
|
}
|
|
13365
12764
|
|
|
13366
12765
|
// src/config/loader.ts
|
|
13367
|
-
|
|
12766
|
+
function loadProfileConfig(opts) {
|
|
13368
12767
|
return loadConfig({
|
|
13369
12768
|
profile: opts.profile,
|
|
13370
12769
|
modules: opts.modules,
|
|
@@ -13682,9 +13081,6 @@ var CLI_OPTIONS = {
|
|
|
13682
13081
|
dir: { type: "string" },
|
|
13683
13082
|
page: { type: "string" },
|
|
13684
13083
|
format: { type: "string" },
|
|
13685
|
-
// auth
|
|
13686
|
-
site: { type: "string" },
|
|
13687
|
-
manual: { type: "boolean", default: false },
|
|
13688
13084
|
// event contract
|
|
13689
13085
|
underlying: { type: "string" },
|
|
13690
13086
|
seriesId: { type: "string" },
|
|
@@ -16699,14 +16095,14 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
16699
16095
|
}
|
|
16700
16096
|
|
|
16701
16097
|
// src/commands/skill.ts
|
|
16702
|
-
import { tmpdir, homedir as
|
|
16703
|
-
import { join as
|
|
16704
|
-
import { mkdirSync as
|
|
16098
|
+
import { tmpdir, homedir as homedir10 } from "os";
|
|
16099
|
+
import { join as join12, dirname as dirname8 } from "path";
|
|
16100
|
+
import { mkdirSync as mkdirSync10, rmSync, existsSync as existsSync8, copyFileSync as copyFileSync2 } from "fs";
|
|
16705
16101
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
16706
16102
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
16707
16103
|
function resolveNpx() {
|
|
16708
|
-
const sibling =
|
|
16709
|
-
if (
|
|
16104
|
+
const sibling = join12(dirname8(process.execPath), "npx");
|
|
16105
|
+
if (existsSync8(sibling)) return sibling;
|
|
16710
16106
|
return "npx";
|
|
16711
16107
|
}
|
|
16712
16108
|
var THIRD_PARTY_INSTALL_NOTICE = "Note: This skill was created by a third-party developer, not by OKX. Review SKILL.md before use.";
|
|
@@ -16759,13 +16155,13 @@ async function cmdSkillCategories(run, json) {
|
|
|
16759
16155
|
outputLine("");
|
|
16760
16156
|
}
|
|
16761
16157
|
async function cmdSkillAdd(name, config, json) {
|
|
16762
|
-
const tmpBase =
|
|
16763
|
-
|
|
16158
|
+
const tmpBase = join12(tmpdir(), `okx-skill-${randomUUID2()}`);
|
|
16159
|
+
mkdirSync10(tmpBase, { recursive: true });
|
|
16764
16160
|
try {
|
|
16765
16161
|
outputLine(`Downloading ${name}...`);
|
|
16766
16162
|
const client = new OkxRestClient(config);
|
|
16767
16163
|
const zipPath = await downloadSkillZip(client, name, tmpBase);
|
|
16768
|
-
const contentDir = await extractSkillZip(zipPath,
|
|
16164
|
+
const contentDir = await extractSkillZip(zipPath, join12(tmpBase, "content"));
|
|
16769
16165
|
const meta = readMetaJson(contentDir);
|
|
16770
16166
|
validateSkillMdExists(contentDir);
|
|
16771
16167
|
outputLine("Installing to detected agents...");
|
|
@@ -16775,7 +16171,7 @@ async function cmdSkillAdd(name, config, json) {
|
|
|
16775
16171
|
timeout: 6e4
|
|
16776
16172
|
});
|
|
16777
16173
|
} catch (e) {
|
|
16778
|
-
const savedZip =
|
|
16174
|
+
const savedZip = join12(process.cwd(), `${name}.zip`);
|
|
16779
16175
|
try {
|
|
16780
16176
|
copyFileSync2(zipPath, savedZip);
|
|
16781
16177
|
} catch {
|
|
@@ -16814,7 +16210,7 @@ function cmdSkillRemove(name, json) {
|
|
|
16814
16210
|
timeout: 6e4
|
|
16815
16211
|
});
|
|
16816
16212
|
} catch {
|
|
16817
|
-
const agentsPath =
|
|
16213
|
+
const agentsPath = join12(homedir10(), ".agents", "skills", name);
|
|
16818
16214
|
try {
|
|
16819
16215
|
rmSync(agentsPath, { recursive: true, force: true });
|
|
16820
16216
|
} catch {
|
|
@@ -16888,14 +16284,14 @@ function printSkillInstallResult(meta, json) {
|
|
|
16888
16284
|
}
|
|
16889
16285
|
|
|
16890
16286
|
// src/commands/doh.ts
|
|
16891
|
-
import
|
|
16892
|
-
function
|
|
16287
|
+
import readline from "readline";
|
|
16288
|
+
function resolveChecksumMatch(local, cdnChecksum, cdnError) {
|
|
16893
16289
|
if (!local.exists) return "not-installed";
|
|
16894
16290
|
if (cdnError || !cdnChecksum) return "unavailable";
|
|
16895
16291
|
if (cdnChecksum.sha256 === local.sha256) return "match";
|
|
16896
16292
|
return "mismatch";
|
|
16897
16293
|
}
|
|
16898
|
-
function
|
|
16294
|
+
function checksumMatchLabel(match) {
|
|
16899
16295
|
if (match === "match") return "\u2713 match";
|
|
16900
16296
|
if (match === "mismatch") return "\u2717 mismatch (update available)";
|
|
16901
16297
|
return "CDN unreachable";
|
|
@@ -16908,9 +16304,9 @@ function formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode) {
|
|
|
16908
16304
|
outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
|
|
16909
16305
|
outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
|
|
16910
16306
|
if (local.exists) {
|
|
16911
|
-
outputLine(` File size : ${
|
|
16307
|
+
outputLine(` File size : ${formatBytes(local.fileSize)}`);
|
|
16912
16308
|
outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
|
|
16913
|
-
outputLine(` CDN check : ${
|
|
16309
|
+
outputLine(` CDN check : ${checksumMatchLabel(checksumMatch)}`);
|
|
16914
16310
|
if (cdnChecksum) {
|
|
16915
16311
|
outputLine(` CDN source : ${cdnChecksum.source}`);
|
|
16916
16312
|
}
|
|
@@ -16937,7 +16333,7 @@ async function cmdDohStatus(json, binaryPath) {
|
|
|
16937
16333
|
cdnError = err instanceof Error ? err.message : String(err);
|
|
16938
16334
|
}
|
|
16939
16335
|
}
|
|
16940
|
-
const checksumMatch =
|
|
16336
|
+
const checksumMatch = resolveChecksumMatch(local, cdnChecksum, cdnError);
|
|
16941
16337
|
if (json) {
|
|
16942
16338
|
outputLine(
|
|
16943
16339
|
JSON.stringify({
|
|
@@ -17003,7 +16399,7 @@ async function cmdDohRemove(force, json, binaryPath) {
|
|
|
17003
16399
|
process.exitCode = 1;
|
|
17004
16400
|
return;
|
|
17005
16401
|
}
|
|
17006
|
-
const confirmed = await
|
|
16402
|
+
const confirmed = await askConfirmation(
|
|
17007
16403
|
` Remove DoH resolver at ${local.binaryPath}? [y/N] `
|
|
17008
16404
|
);
|
|
17009
16405
|
if (!confirmed) {
|
|
@@ -17022,14 +16418,14 @@ async function cmdDohRemove(force, json, binaryPath) {
|
|
|
17022
16418
|
outputLine(" DoH resolver is not installed.");
|
|
17023
16419
|
}
|
|
17024
16420
|
}
|
|
17025
|
-
function
|
|
16421
|
+
function formatBytes(bytes) {
|
|
17026
16422
|
if (bytes < 1024) return `${bytes} B`;
|
|
17027
16423
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
17028
16424
|
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
17029
16425
|
}
|
|
17030
|
-
function
|
|
16426
|
+
function askConfirmation(prompt2) {
|
|
17031
16427
|
return new Promise((resolve3) => {
|
|
17032
|
-
const rl =
|
|
16428
|
+
const rl = readline.createInterface({
|
|
17033
16429
|
input: process.stdin,
|
|
17034
16430
|
output: process.stdout
|
|
17035
16431
|
});
|
|
@@ -17486,7 +16882,7 @@ async function cmdEventCancel(run, opts) {
|
|
|
17486
16882
|
// src/index.ts
|
|
17487
16883
|
var _require3 = createRequire3(import.meta.url);
|
|
17488
16884
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
17489
|
-
var GIT_HASH2 = true ? "
|
|
16885
|
+
var GIT_HASH2 = true ? "e0312e6" : "dev";
|
|
17490
16886
|
function handleDohCommand(action, json, force, binaryPath) {
|
|
17491
16887
|
if (action === "status") return cmdDohStatus(json, binaryPath);
|
|
17492
16888
|
if (action === "install") return cmdDohInstall(json, binaryPath);
|
|
@@ -18330,7 +17726,7 @@ function handleNewsCommand(run, action, rest, v, json) {
|
|
|
18330
17726
|
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
18331
17727
|
const begin = v.begin !== void 0 ? Number(v.begin) : void 0;
|
|
18332
17728
|
const end = v.end !== void 0 ? Number(v.end) : void 0;
|
|
18333
|
-
const language = v.lang ?? "
|
|
17729
|
+
const language = v.lang ?? "en-US";
|
|
18334
17730
|
const detailLvl = v["detail-lvl"];
|
|
18335
17731
|
const after = v.after;
|
|
18336
17732
|
const period = v.period;
|
|
@@ -18461,7 +17857,7 @@ function wrapRunnerWithLogger(baseRunner, logger, verbose = false) {
|
|
|
18461
17857
|
async function runDiagnose(v) {
|
|
18462
17858
|
let config;
|
|
18463
17859
|
try {
|
|
18464
|
-
config =
|
|
17860
|
+
config = loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
18465
17861
|
} catch {
|
|
18466
17862
|
}
|
|
18467
17863
|
return cmdDiagnose(config, v.profile ?? "default", { mcp: v.mcp, cli: v.cli, all: v.all, output: v.output });
|
|
@@ -18476,13 +17872,24 @@ function printVersion() {
|
|
|
18476
17872
|
}
|
|
18477
17873
|
}
|
|
18478
17874
|
function routeManagementCommand(module, action, rest, json, v) {
|
|
18479
|
-
if (module === "config")
|
|
18480
|
-
|
|
18481
|
-
|
|
17875
|
+
if (module === "config") {
|
|
17876
|
+
const r = handleConfigCommand(action, rest, json, v.lang, v.force);
|
|
17877
|
+
return r ?? true;
|
|
17878
|
+
}
|
|
17879
|
+
if (module === "setup") {
|
|
17880
|
+
handleSetupCommand(v);
|
|
17881
|
+
return true;
|
|
17882
|
+
}
|
|
18482
17883
|
if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
|
|
18483
|
-
if (module === "doh")
|
|
17884
|
+
if (module === "doh") {
|
|
17885
|
+
const r = handleDohCommand(action, json, v.force ?? false);
|
|
17886
|
+
return r ?? true;
|
|
17887
|
+
}
|
|
18484
17888
|
if (module === "diagnose") return runDiagnose(v);
|
|
18485
|
-
if (module === "list-tools")
|
|
17889
|
+
if (module === "list-tools") {
|
|
17890
|
+
cmdListTools(json);
|
|
17891
|
+
return true;
|
|
17892
|
+
}
|
|
18486
17893
|
return void 0;
|
|
18487
17894
|
}
|
|
18488
17895
|
async function main() {
|
|
@@ -18504,8 +17911,8 @@ async function main() {
|
|
|
18504
17911
|
const v = values;
|
|
18505
17912
|
const json = v.json ?? false;
|
|
18506
17913
|
const mgmt = routeManagementCommand(module, action, rest, json, v);
|
|
18507
|
-
if (mgmt) return mgmt;
|
|
18508
|
-
const config =
|
|
17914
|
+
if (mgmt !== void 0) return mgmt === true ? void 0 : mgmt;
|
|
17915
|
+
const config = loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
18509
17916
|
setEnvContext({ demo: config.demo, profile: v.profile ?? "default" });
|
|
18510
17917
|
setJsonEnvEnabled(v.env ?? false);
|
|
18511
17918
|
const client = new OkxRestClient(config);
|