@okx_ai/okx-trade-cli 1.3.1-beta.11 → 1.3.1-beta.13

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 CHANGED
@@ -21,25 +21,28 @@ 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";
24
27
  import fs from "fs";
25
28
  import path from "path";
26
29
  import os from "os";
27
30
  import { writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2 } from "fs";
28
- import { join as join3, resolve, basename, sep } from "path";
31
+ import { join as join4, resolve, basename, sep } from "path";
29
32
  import { randomUUID } from "crypto";
30
33
  import yauzl from "yauzl";
31
34
  import { createWriteStream, mkdirSync as mkdirSync3 } from "fs";
32
35
  import { resolve as resolve2, dirname as dirname2 } from "path";
33
36
  import { readFileSync as readFileSync2, existsSync } from "fs";
34
- import { join as join4 } from "path";
37
+ import { join as join5 } from "path";
35
38
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, existsSync as existsSync2 } from "fs";
36
- import { join as join5, dirname as dirname3 } from "path";
37
- import { homedir as homedir3 } from "os";
38
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "fs";
39
- import { join as join6, dirname as dirname4 } from "path";
39
+ import { join as join6, dirname as dirname3 } from "path";
40
40
  import { homedir as homedir4 } from "os";
41
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "fs";
42
+ import { join as join7, dirname as dirname4 } from "path";
43
+ import { homedir as homedir5 } from "os";
41
44
 
42
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/error.js
45
+ // ../../node_modules/smol-toml/dist/error.js
43
46
  function getLineColFromPtr(string, ptr) {
44
47
  let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
45
48
  return [lines.length, lines.pop().length + 1];
@@ -79,7 +82,7 @@ ${codeblock}`, options);
79
82
  }
80
83
  };
81
84
 
82
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/util.js
85
+ // ../../node_modules/smol-toml/dist/util.js
83
86
  function isEscaped(str, ptr) {
84
87
  let i = 0;
85
88
  while (str[ptr - ++i] === "\\")
@@ -110,9 +113,14 @@ function skipComment(str, ptr) {
110
113
  }
111
114
  function skipVoid(str, ptr, banNewLines, banComments) {
112
115
  let c;
113
- while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n"))
114
- ptr++;
115
- return banComments || c !== "#" ? ptr : skipVoid(str, skipComment(str, ptr), banNewLines);
116
+ while (1) {
117
+ while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n"))
118
+ ptr++;
119
+ if (banComments || c !== "#")
120
+ break;
121
+ ptr = skipComment(str, ptr);
122
+ }
123
+ return ptr;
116
124
  }
117
125
  function skipUntil(str, ptr, sep2, end, banNewLines = false) {
118
126
  if (!end) {
@@ -153,7 +161,7 @@ function getStringEnd(str, seek) {
153
161
  return seek;
154
162
  }
155
163
 
156
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/date.js
164
+ // ../../node_modules/smol-toml/dist/date.js
157
165
  var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
158
166
  var TomlDate = class _TomlDate extends Date {
159
167
  #hasDate = false;
@@ -245,7 +253,7 @@ var TomlDate = class _TomlDate extends Date {
245
253
  }
246
254
  };
247
255
 
248
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/primitive.js
256
+ // ../../node_modules/smol-toml/dist/primitive.js
249
257
  var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
250
258
  var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
251
259
  var LEADING_ZERO = /^[+-]?0[0-9_]/;
@@ -384,7 +392,7 @@ function parseValue(value, toml, ptr, integersAsBigInt) {
384
392
  return date;
385
393
  }
386
394
 
387
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/extract.js
395
+ // ../../node_modules/smol-toml/dist/extract.js
388
396
  function sliceAndTrimEndOf(str, startPtr, endPtr) {
389
397
  let value = str.slice(startPtr, endPtr);
390
398
  let commentIdx = value.indexOf("#");
@@ -451,7 +459,7 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) {
451
459
  ];
452
460
  }
453
461
 
454
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/struct.js
462
+ // ../../node_modules/smol-toml/dist/struct.js
455
463
  var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
456
464
  function parseKey(str, ptr, end = "=") {
457
465
  let dot = ptr - 1;
@@ -599,7 +607,7 @@ function parseArray(str, ptr, depth, integersAsBigInt) {
599
607
  return [res, ptr];
600
608
  }
601
609
 
602
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/parse.js
610
+ // ../../node_modules/smol-toml/dist/parse.js
603
611
  function peekTable(key, table, meta, type) {
604
612
  let t = table;
605
613
  let m = meta;
@@ -724,7 +732,7 @@ function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
724
732
  return res;
725
733
  }
726
734
 
727
- // ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/stringify.js
735
+ // ../../node_modules/smol-toml/dist/stringify.js
728
736
  var BARE_KEY = /^[a-z0-9-_]+$/i;
729
737
  function extendedTypeOf(obj) {
730
738
  let type = typeof obj;
@@ -867,8 +875,8 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
867
875
 
868
876
  // ../core/dist/index.js
869
877
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync4 } from "fs";
870
- import { join as join7 } from "path";
871
- import { homedir as homedir5 } from "os";
878
+ import { join as join8 } from "path";
879
+ import { homedir as homedir6 } from "os";
872
880
  import fs2 from "fs";
873
881
  import path2 from "path";
874
882
  import os2 from "os";
@@ -876,6 +884,18 @@ import * as fs3 from "fs";
876
884
  import * as path3 from "path";
877
885
  import * as os3 from "os";
878
886
  import { execFileSync } from "child_process";
887
+ import {
888
+ createWriteStream as createWriteStream3,
889
+ mkdirSync as mkdirSync9,
890
+ chmodSync as chmodSync2,
891
+ existsSync as existsSync7,
892
+ unlinkSync as unlinkSync4,
893
+ renameSync as renameSync4
894
+ } from "fs";
895
+ import { homedir as homedir9, platform as platform2 } from "os";
896
+ import { join as join11, dirname as dirname7 } from "path";
897
+ import { get as httpsGet2 } from "https";
898
+ import { get as httpGet2 } from "http";
879
899
  import {
880
900
  readFileSync as readFileSync7,
881
901
  createWriteStream as createWriteStream2,
@@ -886,10 +906,13 @@ import {
886
906
  renameSync as renameSync3
887
907
  } from "fs";
888
908
  import { createHash } from "crypto";
889
- import { homedir as homedir7, platform, arch } from "os";
890
- import { join as join9, dirname as dirname6 } from "path";
909
+ import { homedir as homedir8, platform, arch } from "os";
910
+ import { join as join10, dirname as dirname6 } from "path";
891
911
  import { get as httpsGet } from "https";
892
912
  import { get as httpGet } from "http";
913
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5, existsSync as existsSync8 } from "fs";
914
+ import { join as join12 } from "path";
915
+ import { homedir as homedir10 } from "os";
893
916
  var EXEC_TIMEOUT_MS = 3e4;
894
917
  var ALLOWED_DOMAIN_RE = /^[\w.-]+\.okx\.com$/;
895
918
  var DOH_BIN_DIR = join(homedir(), ".okx", "bin");
@@ -898,7 +921,7 @@ function getDohBinaryPath() {
898
921
  return process.env.OKX_DOH_BINARY_PATH;
899
922
  }
900
923
  const ext = process.platform === "win32" ? ".exe" : "";
901
- return join(DOH_BIN_DIR, `okx-pilot${ext}`);
924
+ return join(DOH_BIN_DIR, `okx-doh-resolver${ext}`);
902
925
  }
903
926
  function execDohBinary(domain, exclude = [], userAgent) {
904
927
  if (!ALLOWED_DOMAIN_RE.test(domain)) {
@@ -969,7 +992,7 @@ function classifyAndCache(node, hostname, failedNodes, cachePath) {
969
992
  if (!node) {
970
993
  return { mode: null, node: null };
971
994
  }
972
- if (node.ip === hostname && node.host === hostname) {
995
+ if (node.ip === hostname || node.host === hostname) {
973
996
  writeCache(hostname, {
974
997
  mode: "direct",
975
998
  node: null,
@@ -1201,6 +1224,11 @@ var ConfigError = class extends OkxMcpError {
1201
1224
  super("ConfigError", message, { suggestion });
1202
1225
  }
1203
1226
  };
1227
+ var NotLoggedInError = class extends ConfigError {
1228
+ constructor(suggestion = "Run `okx auth login` to authenticate.") {
1229
+ super("Not logged in.", suggestion);
1230
+ }
1231
+ };
1204
1232
  var ValidationError = class extends OkxMcpError {
1205
1233
  constructor(message, suggestion) {
1206
1234
  super("ValidationError", message, { suggestion });
@@ -1253,6 +1281,97 @@ function toToolErrorPayload(error, fallbackEndpoint) {
1253
1281
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1254
1282
  };
1255
1283
  }
1284
+ var EXIT_CODES = {
1285
+ SUCCESS: 0,
1286
+ UNAUTHORIZED_CALLER: 1,
1287
+ NOT_LOGGED_IN: 2,
1288
+ REFRESH_FAILED: 3
1289
+ };
1290
+ var EXEC_TIMEOUT_MS2 = 5e3;
1291
+ var AUTH_BIN_DIR = join3(homedir3(), ".okx", "bin");
1292
+ function getAuthBinaryPath() {
1293
+ if (process.env.OKX_AUTH_BIN) {
1294
+ return process.env.OKX_AUTH_BIN;
1295
+ }
1296
+ const ext = process.platform === "win32" ? ".exe" : "";
1297
+ return join3(AUTH_BIN_DIR, `okx-auth${ext}`);
1298
+ }
1299
+ function execAuthToken() {
1300
+ const binPath = getAuthBinaryPath();
1301
+ return new Promise((resolve3, reject) => {
1302
+ const child = spawn(binPath, ["token"], {
1303
+ stdio: ["ignore", "ignore", "inherit", "pipe"]
1304
+ // stdin stdout stderr fd3 (pipe)
1305
+ });
1306
+ const chunks = [];
1307
+ const fd3 = child.stdio[3];
1308
+ fd3.on("data", (chunk) => chunks.push(chunk));
1309
+ child.on("error", (err) => {
1310
+ reject(new ConfigError(
1311
+ `Failed to spawn okx-auth: ${err.message}`,
1312
+ "Ensure the okx-auth binary exists and is executable."
1313
+ ));
1314
+ });
1315
+ child.on("close", (code) => {
1316
+ if (code === EXIT_CODES.SUCCESS) {
1317
+ const token = Buffer.concat(chunks).toString("utf-8").trim();
1318
+ if (!token) {
1319
+ reject(new AuthenticationError(
1320
+ "okx-auth returned empty token.",
1321
+ "Run `okx auth login` to re-authenticate."
1322
+ ));
1323
+ return;
1324
+ }
1325
+ resolve3(token);
1326
+ return;
1327
+ }
1328
+ if (code === EXIT_CODES.NOT_LOGGED_IN) {
1329
+ reject(new NotLoggedInError());
1330
+ return;
1331
+ }
1332
+ if (code === EXIT_CODES.UNAUTHORIZED_CALLER) {
1333
+ reject(new AuthenticationError(
1334
+ "okx-auth rejected the caller (unauthorized).",
1335
+ "Ensure you are running from a trusted OKX tool."
1336
+ ));
1337
+ return;
1338
+ }
1339
+ if (code === EXIT_CODES.REFRESH_FAILED) {
1340
+ reject(new AuthenticationError(
1341
+ "Token refresh failed.",
1342
+ "Run `okx auth login` to re-authenticate."
1343
+ ));
1344
+ return;
1345
+ }
1346
+ reject(new AuthenticationError(
1347
+ `okx-auth token exited with code ${code}.`,
1348
+ "Run `okx auth login` to re-authenticate."
1349
+ ));
1350
+ });
1351
+ });
1352
+ }
1353
+ function execAuthStatus() {
1354
+ const binPath = getAuthBinaryPath();
1355
+ return new Promise((resolve3) => {
1356
+ execFile2(
1357
+ binPath,
1358
+ ["status", "--json"],
1359
+ { timeout: EXEC_TIMEOUT_MS2, encoding: "utf-8" },
1360
+ (error, stdout) => {
1361
+ if (error) {
1362
+ resolve3(null);
1363
+ return;
1364
+ }
1365
+ try {
1366
+ const result = JSON.parse(stdout);
1367
+ resolve3(result);
1368
+ } catch {
1369
+ resolve3(null);
1370
+ }
1371
+ }
1372
+ );
1373
+ });
1374
+ }
1256
1375
  function sleep(ms) {
1257
1376
  return new Promise((resolve3) => {
1258
1377
  setTimeout(resolve3, ms);
@@ -1331,10 +1450,10 @@ var OKX_CODE_BEHAVIORS = {
1331
1450
  "50011": { retry: true, suggestion: "Rate limited. Back off and retry after a delay." },
1332
1451
  "50061": { retry: true, suggestion: "Too many connections. Reduce request frequency and retry." },
1333
1452
  // Server temporarily unavailable → retryable
1334
- "50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
1335
- "50004": { retry: true, suggestion: "Endpoint request timeout. Retry later." },
1453
+ "50001": { retry: true, suggestion: "OKX system upgrade in progress. Retry in a few minutes." },
1454
+ "50004": { retry: true, suggestion: "Endpoint temporarily unavailable. Retry later." },
1336
1455
  "50013": { retry: true, suggestion: "System busy. Retry after 1-2 seconds." },
1337
- "50026": { retry: true, suggestion: "System error. Retry in a few minutes." },
1456
+ "50026": { retry: true, suggestion: "Order book system upgrading. Retry in a few minutes." },
1338
1457
  // Region / compliance restriction → do not retry
1339
1458
  "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." },
1340
1459
  "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." },
@@ -1384,6 +1503,7 @@ function maskKey(key) {
1384
1503
  if (key.length <= 8) return "***";
1385
1504
  return `${key.slice(0, 3)}***${key.slice(-3)}`;
1386
1505
  }
1506
+ var TOKEN_CACHE_TTL_MS = 6e4;
1387
1507
  function vlog2(message) {
1388
1508
  process.stderr.write(`[verbose] ${message}
1389
1509
  `);
@@ -1392,6 +1512,8 @@ var OkxRestClient = class _OkxRestClient {
1392
1512
  config;
1393
1513
  rateLimiter;
1394
1514
  dispatcher;
1515
+ cachedAccessToken;
1516
+ cachedAccessTokenAt = 0;
1395
1517
  doh;
1396
1518
  constructor(config) {
1397
1519
  this.config = config;
@@ -1406,6 +1528,51 @@ var OkxRestClient = class _OkxRestClient {
1406
1528
  hasCustomProxy: !!config.proxyUrl
1407
1529
  });
1408
1530
  }
1531
+ /**
1532
+ * Resolve OAuth access token via the okx-auth binary (fd3 pipe).
1533
+ * Caches the token for 60 s to avoid spawning the binary on every
1534
+ * request. The binary handles refresh internally (300s TTL lead),
1535
+ * so periodic re-calls let it serve a fresh token when needed.
1536
+ * Returns null when not logged in.
1537
+ */
1538
+ async resolveAccessToken() {
1539
+ if (this.cachedAccessToken && Date.now() - this.cachedAccessTokenAt < TOKEN_CACHE_TTL_MS) {
1540
+ return this.cachedAccessToken;
1541
+ }
1542
+ try {
1543
+ const token = await execAuthToken();
1544
+ this.cachedAccessToken = token;
1545
+ this.cachedAccessTokenAt = Date.now();
1546
+ return token;
1547
+ } catch (e) {
1548
+ if (e instanceof NotLoggedInError) {
1549
+ return null;
1550
+ }
1551
+ throw e;
1552
+ }
1553
+ }
1554
+ /**
1555
+ * Dynamic auth — determines auth method per request.
1556
+ *
1557
+ * 1. API key in config → HMAC signing (no OAuth fallback)
1558
+ * 2. OAuth token via okx-auth binary → Bearer token
1559
+ * 3. Neither → throw ConfigError
1560
+ */
1561
+ async applyAuth(headers, method, requestPath, bodyJson, timestamp) {
1562
+ if (this.config.apiKey && this.config.secretKey && this.config.passphrase) {
1563
+ this.setAuthHeaders(headers, method, requestPath, bodyJson, timestamp);
1564
+ return;
1565
+ }
1566
+ const accessToken = await this.resolveAccessToken();
1567
+ if (accessToken) {
1568
+ headers.set("Authorization", `Bearer ${accessToken}`);
1569
+ return;
1570
+ }
1571
+ throw new ConfigError(
1572
+ "No credentials found.",
1573
+ "Run `okx auth login` to authenticate, or configure API key credentials."
1574
+ );
1575
+ }
1409
1576
  /** The canonical base URL for this client (e.g. https://www.okx.com). */
1410
1577
  get baseUrl() {
1411
1578
  return this.config.baseUrl;
@@ -1463,18 +1630,6 @@ var OkxRestClient = class _OkxRestClient {
1463
1630
  });
1464
1631
  }
1465
1632
  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
- }
1478
1633
  const payload = `${timestamp}${method.toUpperCase()}${requestPath}${bodyJson}`;
1479
1634
  const signature = signOkxPayload(payload, this.config.secretKey);
1480
1635
  headers.set("OK-ACCESS-KEY", this.config.apiKey);
@@ -1589,7 +1744,7 @@ var OkxRestClient = class _OkxRestClient {
1589
1744
  const conn = this.doh.getConnectionParams();
1590
1745
  this.logRequest("POST", `${conn.baseUrl}${path42}`, "private");
1591
1746
  const reqConfig = { method: "POST", path: path42, auth: "private" };
1592
- const headers = this.buildHeaders(reqConfig, path42, bodyJson, getNow());
1747
+ const headers = await this.buildHeaders(reqConfig, path42, bodyJson, getNow());
1593
1748
  if (conn.userAgent) {
1594
1749
  headers.set("User-Agent", conn.userAgent);
1595
1750
  }
@@ -1706,7 +1861,7 @@ var OkxRestClient = class _OkxRestClient {
1706
1861
  // Header building
1707
1862
  // ---------------------------------------------------------------------------
1708
1863
  /** Build HTTP headers. reqConfig.extraHeaders must NOT contain auth keys (OK-ACCESS-*). */
1709
- buildHeaders(reqConfig, requestPath, bodyJson, timestamp) {
1864
+ async buildHeaders(reqConfig, requestPath, bodyJson, timestamp) {
1710
1865
  const headers = new Headers({
1711
1866
  "Content-Type": "application/json",
1712
1867
  Accept: "application/json"
@@ -1715,7 +1870,7 @@ var OkxRestClient = class _OkxRestClient {
1715
1870
  headers.set("User-Agent", this.config.userAgent);
1716
1871
  }
1717
1872
  if (reqConfig.auth === "private") {
1718
- this.setAuthHeaders(headers, reqConfig.method, requestPath, bodyJson, timestamp);
1873
+ await this.applyAuth(headers, reqConfig.method, requestPath, bodyJson, timestamp);
1719
1874
  }
1720
1875
  const useSimulated = reqConfig.simulatedTrading !== void 0 ? reqConfig.simulatedTrading : this.config.demo;
1721
1876
  if (useSimulated) {
@@ -1769,7 +1924,7 @@ var OkxRestClient = class _OkxRestClient {
1769
1924
  if (reqConfig.rateLimit) {
1770
1925
  await this.rateLimiter.consume(reqConfig.rateLimit);
1771
1926
  }
1772
- const headers = this.buildHeaders(reqConfig, requestPath, bodyJson, timestamp);
1927
+ const headers = await this.buildHeaders(reqConfig, requestPath, bodyJson, timestamp);
1773
1928
  if (conn.userAgent) {
1774
1929
  headers.set("User-Agent", conn.userAgent);
1775
1930
  }
@@ -2192,7 +2347,7 @@ var OKX_SITES = {
2192
2347
  },
2193
2348
  us: {
2194
2349
  label: "US",
2195
- apiBaseUrl: "https://app.okx.com",
2350
+ apiBaseUrl: "https://us.okx.com",
2196
2351
  webUrl: "https://app.okx.com"
2197
2352
  }
2198
2353
  };
@@ -3722,7 +3877,7 @@ function safeWriteFile(targetDir, fileName, data) {
3722
3877
  throw new Error(`Invalid file name: "${fileName}"`);
3723
3878
  }
3724
3879
  const resolvedDir = resolve(targetDir);
3725
- const filePath = join3(resolvedDir, safeName);
3880
+ const filePath = join4(resolvedDir, safeName);
3726
3881
  const resolvedPath = resolve(filePath);
3727
3882
  if (!resolvedPath.startsWith(resolvedDir + sep)) {
3728
3883
  throw new Error(`Path traversal detected: "${fileName}" resolves outside target directory`);
@@ -3850,7 +4005,7 @@ async function extractSkillZip(zipPath, targetDir, limits) {
3850
4005
  });
3851
4006
  }
3852
4007
  function readMetaJson(contentDir) {
3853
- const metaPath = join4(contentDir, "_meta.json");
4008
+ const metaPath = join5(contentDir, "_meta.json");
3854
4009
  if (!existsSync(metaPath)) {
3855
4010
  throw new Error(`_meta.json not found in ${contentDir}. Invalid skill package.`);
3856
4011
  }
@@ -3876,12 +4031,12 @@ function readMetaJson(contentDir) {
3876
4031
  };
3877
4032
  }
3878
4033
  function validateSkillMdExists(contentDir) {
3879
- const skillMdPath = join4(contentDir, "SKILL.md");
4034
+ const skillMdPath = join5(contentDir, "SKILL.md");
3880
4035
  if (!existsSync(skillMdPath)) {
3881
4036
  throw new Error(`SKILL.md not found in ${contentDir}. Invalid skill package.`);
3882
4037
  }
3883
4038
  }
3884
- var DEFAULT_REGISTRY_PATH = join5(homedir3(), ".okx", "skills", "registry.json");
4039
+ var DEFAULT_REGISTRY_PATH = join6(homedir4(), ".okx", "skills", "registry.json");
3885
4040
  function readRegistry(registryPath = DEFAULT_REGISTRY_PATH) {
3886
4041
  if (!existsSync2(registryPath)) {
3887
4042
  return { version: 1, skills: {} };
@@ -5219,7 +5374,7 @@ function registerOnchainEarnTools() {
5219
5374
  ];
5220
5375
  }
5221
5376
  var DCD_CODE_BEHAVIORS = {
5222
- "50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
5377
+ "50001": { retry: true, suggestion: "DCD service is down. Retry in a few minutes." },
5223
5378
  "50002": { retry: false, suggestion: "Invalid JSON in request body. This is likely a bug \u2014 check request parameters." },
5224
5379
  "50014": { retry: false, suggestion: "Missing required parameter. Check that all required fields are provided." },
5225
5380
  "50016": { retry: false, suggestion: "notionalCcy does not match productId option type. Use baseCcy for CALL, quoteCcy for PUT." },
@@ -7837,10 +7992,10 @@ var NEWS_DETAIL = "/api/v5/orbit/news-detail";
7837
7992
  var NEWS_DOMAINS = "/api/v5/orbit/news-platform";
7838
7993
  var SENTIMENT_QUERY = "/api/v5/orbit/currency-sentiment-query";
7839
7994
  var SENTIMENT_RANKING = "/api/v5/orbit/currency-sentiment-ranking";
7840
- var NEWS_LANGUAGE = ["en-US", "zh-CN"];
7995
+ var NEWS_LANGUAGE = ["en_US", "zh_CN"];
7841
7996
  function langHeader(lang) {
7842
- if (lang === "zh-CN" || lang === "zh_CN") return { "Accept-Language": "zh-CN" };
7843
- return { "Accept-Language": "en-US" };
7997
+ const resolved = lang === "zh_CN" ? "zh_CN" : "en_US";
7998
+ return { "Accept-Language": resolved };
7844
7999
  }
7845
8000
  var NEWS_DETAIL_LVL = ["brief", "summary", "full"];
7846
8001
  var NEWS_IMPORTANCE = ["high", "medium", "low"];
@@ -7849,7 +8004,7 @@ var NEWS_SORT = ["latest", "relevant"];
7849
8004
  var SENTIMENT_PERIOD = ["1h", "4h", "24h"];
7850
8005
  var D_COINS_NEWS = 'Comma-separated uppercase ticker symbols (e.g. "BTC,ETH"). Normalize names/aliases to standard tickers.';
7851
8006
  var D_COINS_SENTIMENT = 'Comma-separated uppercase ticker symbols, max 20 (e.g. "BTC,ETH"). Normalize names/aliases to standard tickers.';
7852
- var D_LANGUAGE = "Content language: zh-CN or en-US. Infer from user's message. No server default.";
8007
+ var D_LANGUAGE = "Content language: zh_CN or en_US. Infer from user's message. No server default.";
7853
8008
  var D_BEGIN = "Start time, Unix epoch milliseconds. Parse relative time if given (e.g. 'yesterday', 'last 7 days').";
7854
8009
  var D_END = "End time, Unix epoch milliseconds. Parse relative time if given. Omit for no upper bound.";
7855
8010
  var D_IMPORTANCE = "Importance filter: high (server default), medium, low. Omit unless user wants broader coverage.";
@@ -9646,7 +9801,7 @@ function createToolRunner(client, config) {
9646
9801
  };
9647
9802
  }
9648
9803
  function configFilePath() {
9649
- return join6(homedir4(), ".okx", "config.toml");
9804
+ return join7(homedir5(), ".okx", "config.toml");
9650
9805
  }
9651
9806
  function readFullConfig() {
9652
9807
  const path42 = configFilePath();
@@ -9665,11 +9820,6 @@ Or re-run: okx config init`
9665
9820
  );
9666
9821
  }
9667
9822
  }
9668
- function readTomlProfile(profileName) {
9669
- const config = readFullConfig();
9670
- const name = profileName ?? config.default_profile ?? "default";
9671
- return config.profiles?.[name] ?? {};
9672
- }
9673
9823
  var CONFIG_HEADER = `# OKX Trade Kit Configuration
9674
9824
  # If editing manually, wrap values containing special chars in quotes:
9675
9825
  # passphrase = 'value' (if value contains # \\ ")
@@ -9718,18 +9868,24 @@ function parseModuleList(rawModules) {
9718
9868
  }
9719
9869
  return Array.from(deduped);
9720
9870
  }
9721
- function loadCredentials(toml) {
9871
+ async function loadCredentials(toml) {
9722
9872
  const apiKey = process.env.OKX_API_KEY?.trim() ?? toml.api_key;
9723
9873
  const secretKey = process.env.OKX_SECRET_KEY?.trim() ?? toml.secret_key;
9724
9874
  const passphrase = process.env.OKX_PASSPHRASE?.trim() ?? toml.passphrase;
9725
- const hasAuth = Boolean(apiKey && secretKey && passphrase);
9875
+ const hasApiKey = Boolean(apiKey && secretKey && passphrase);
9726
9876
  const partialAuth = Boolean(apiKey) || Boolean(secretKey) || Boolean(passphrase);
9727
- if (partialAuth && !hasAuth) {
9877
+ if (partialAuth && !hasApiKey) {
9728
9878
  throw new ConfigError(
9729
9879
  "Partial API credentials detected.",
9730
9880
  "Set OKX_API_KEY, OKX_SECRET_KEY and OKX_PASSPHRASE together (env vars or config.toml profile)."
9731
9881
  );
9732
9882
  }
9883
+ let hasOAuth = false;
9884
+ if (!hasApiKey) {
9885
+ const status = await execAuthStatus();
9886
+ hasOAuth = status?.status === "logged_in";
9887
+ }
9888
+ const hasAuth = hasOAuth || hasApiKey;
9733
9889
  return { apiKey, secretKey, passphrase, hasAuth };
9734
9890
  }
9735
9891
  function resolveSite(cliSite, tomlSite) {
@@ -9763,9 +9919,11 @@ function resolveDemo(cli, toml) {
9763
9919
  if (cli.demo === true) return true;
9764
9920
  return process.env.OKX_DEMO === "1" || process.env.OKX_DEMO === "true" || (toml.demo ?? false);
9765
9921
  }
9766
- function loadConfig(cli) {
9767
- const toml = readTomlProfile(cli.profile);
9768
- const creds = loadCredentials(toml);
9922
+ async function loadConfig(cli) {
9923
+ const config = readFullConfig();
9924
+ const profileName = cli.profile ?? config.default_profile ?? "default";
9925
+ const toml = config.profiles?.[profileName] ?? {};
9926
+ const creds = await loadCredentials(toml);
9769
9927
  const demo = resolveDemo(cli, toml);
9770
9928
  const site = resolveSite(cli.site, toml.site);
9771
9929
  const baseUrl = resolveBaseUrl(site, toml.base_url);
@@ -9785,6 +9943,7 @@ function loadConfig(cli) {
9785
9943
  }
9786
9944
  return {
9787
9945
  ...creds,
9946
+ profile: profileName,
9788
9947
  baseUrl,
9789
9948
  timeoutMs: Math.floor(rawTimeout),
9790
9949
  modules: parseModuleList(cli.modules),
@@ -9797,7 +9956,7 @@ function loadConfig(cli) {
9797
9956
  verbose: cli.verbose ?? false
9798
9957
  };
9799
9958
  }
9800
- var CACHE_FILE = join7(homedir5(), ".okx", "update-check.json");
9959
+ var CACHE_FILE = join8(homedir6(), ".okx", "update-check.json");
9801
9960
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
9802
9961
  function readCache2() {
9803
9962
  try {
@@ -9810,7 +9969,7 @@ function readCache2() {
9810
9969
  }
9811
9970
  function writeCache2(cache) {
9812
9971
  try {
9813
- mkdirSync6(join7(homedir5(), ".okx"), { recursive: true });
9972
+ mkdirSync6(join8(homedir6(), ".okx"), { recursive: true });
9814
9973
  writeFileSync5(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
9815
9974
  } catch {
9816
9975
  }
@@ -9980,13 +10139,13 @@ function findMsStoreClaudePath() {
9980
10139
  }
9981
10140
  function getConfigPath(client) {
9982
10141
  const home = os3.homedir();
9983
- const platform2 = process.platform;
10142
+ const platform3 = process.platform;
9984
10143
  switch (client) {
9985
10144
  case "claude-desktop":
9986
- if (platform2 === "win32") {
10145
+ if (platform3 === "win32") {
9987
10146
  return findMsStoreClaudePath() ?? path3.join(appData(), "Claude", CLAUDE_CONFIG_FILE);
9988
10147
  }
9989
- if (platform2 === "darwin") {
10148
+ if (platform3 === "darwin") {
9990
10149
  return path3.join(home, "Library", "Application Support", "Claude", CLAUDE_CONFIG_FILE);
9991
10150
  }
9992
10151
  return path3.join(process.env.XDG_CONFIG_HOME ?? path3.join(home, ".config"), "Claude", CLAUDE_CONFIG_FILE);
@@ -10107,7 +10266,7 @@ function getPlatformDir() {
10107
10266
  return map[`${p}-${a}`] ?? null;
10108
10267
  }
10109
10268
  function getBinaryName() {
10110
- return platform() === "win32" ? "okx-pilot.exe" : "okx-pilot";
10269
+ return platform() === "win32" ? "okx-doh-resolver.exe" : "okx-doh-resolver";
10111
10270
  }
10112
10271
  function hashFile(filePath) {
10113
10272
  const buf = readFileSync7(filePath);
@@ -10228,7 +10387,7 @@ async function installDohBinary(destPath, sources = CDN_SOURCES, onProgress) {
10228
10387
  if (earlyResult) return earlyResult;
10229
10388
  const platformDir = getPlatformDir();
10230
10389
  const binaryName = getBinaryName();
10231
- const resolvedDest = destPath ?? join9(homedir7(), ".okx", "bin", binaryName);
10390
+ const resolvedDest = destPath ?? join10(homedir8(), ".okx", "bin", binaryName);
10232
10391
  const tmpPath = resolvedDest + ".tmp";
10233
10392
  mkdirSync8(dirname6(resolvedDest), { recursive: true });
10234
10393
  const localHash = existsSync6(resolvedDest) ? hashFile(resolvedDest) : null;
@@ -10351,16 +10510,276 @@ function downloadText(url, timeoutMs) {
10351
10510
  })
10352
10511
  );
10353
10512
  }
10513
+ var AUTH_CDN_PATH_PREFIX = "/upgradeapp/tools/oauth";
10514
+ function getAuthBinaryName() {
10515
+ return platform2() === "win32" ? "okx-auth.exe" : "okx-auth";
10516
+ }
10517
+ function getAuthStatus(binaryPath, opts) {
10518
+ const resolvedPath = binaryPath ?? getAuthBinaryPath();
10519
+ const platformDir = getPlatformDir();
10520
+ if (!existsSync7(resolvedPath)) {
10521
+ return { binaryPath: resolvedPath, exists: false, platform: platformDir };
10522
+ }
10523
+ if (opts?.skipHash) {
10524
+ return { binaryPath: resolvedPath, exists: true, platform: platformDir };
10525
+ }
10526
+ const { size, sha256 } = hashFile(resolvedPath);
10527
+ return { binaryPath: resolvedPath, exists: true, platform: platformDir, fileSize: size, sha256 };
10528
+ }
10529
+ async function fetchAuthCdnChecksum(sources = CDN_SOURCES, timeoutMs = DOWNLOAD_TIMEOUT_MS) {
10530
+ const platformDir = getPlatformDir();
10531
+ if (!platformDir) return null;
10532
+ const checksumPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
10533
+ for (const { host, protocol } of sources) {
10534
+ try {
10535
+ const url = `${protocol}://${host}${checksumPath}`;
10536
+ const raw = await downloadText2(url, timeoutMs);
10537
+ const data = JSON.parse(raw);
10538
+ if (typeof data.sha256 !== "string" || typeof data.size !== "number" || typeof data.target !== "string") {
10539
+ continue;
10540
+ }
10541
+ return { sha256: data.sha256, size: data.size, target: data.target, source: host };
10542
+ } catch {
10543
+ }
10544
+ }
10545
+ return null;
10546
+ }
10547
+ async function fetchAndValidateChecksum2(host, protocol, checksumPath, platformDir, timeoutMs, onProgress) {
10548
+ const checksumUrl = `${protocol}://${host}${checksumPath}`;
10549
+ onProgress?.(`Fetching checksum from ${host}...`);
10550
+ const raw = await downloadText2(checksumUrl, timeoutMs);
10551
+ const checksum = JSON.parse(raw);
10552
+ if (typeof checksum.sha256 !== "string" || typeof checksum.size !== "number" || typeof checksum.target !== "string") {
10553
+ throw new Error("Invalid checksum.json: missing sha256, size, or target");
10554
+ }
10555
+ if (checksum.target !== platformDir) {
10556
+ throw new Error(`Target mismatch: expected ${platformDir}, got ${checksum.target}`);
10557
+ }
10558
+ return { sha256: checksum.sha256, size: checksum.size, target: checksum.target };
10559
+ }
10560
+ async function downloadAndVerify2(host, protocol, binaryPath, tmpPath, checksum, timeoutMs, onProgress) {
10561
+ const binaryUrl = `${protocol}://${host}${binaryPath}`;
10562
+ onProgress?.(`Downloading binary from ${host}...`);
10563
+ await download2(binaryUrl, tmpPath, timeoutMs);
10564
+ const actual = hashFile(tmpPath);
10565
+ if (actual.size !== checksum.size) {
10566
+ throw new Error(`Size mismatch: expected ${checksum.size}, got ${actual.size}`);
10567
+ }
10568
+ if (actual.sha256 !== checksum.sha256) {
10569
+ throw new Error(`SHA-256 mismatch: expected ${checksum.sha256}, got ${actual.sha256}`);
10570
+ }
10571
+ }
10572
+ function atomicReplace2(tmpPath, resolvedDest) {
10573
+ if (platform2() === "win32") {
10574
+ try {
10575
+ unlinkSync4(resolvedDest);
10576
+ } catch {
10577
+ }
10578
+ }
10579
+ renameSync4(tmpPath, resolvedDest);
10580
+ if (platform2() !== "win32") {
10581
+ chmodSync2(resolvedDest, 493);
10582
+ }
10583
+ }
10584
+ function installPreChecks2(destPath, sources) {
10585
+ if (!destPath && process.env.OKX_AUTH_BIN) {
10586
+ return { status: "up-to-date", source: "(env override)" };
10587
+ }
10588
+ if (!getPlatformDir()) {
10589
+ return { status: "failed", error: "Unsupported platform" };
10590
+ }
10591
+ if (sources.length === 0) {
10592
+ return { status: "failed", error: "No CDN sources available" };
10593
+ }
10594
+ return null;
10595
+ }
10596
+ function isLocalUpToDate2(localHash, checksum) {
10597
+ return localHash !== null && localHash.size === checksum.size && localHash.sha256 === checksum.sha256;
10598
+ }
10599
+ async function installAuthBinary(destPath, sources = CDN_SOURCES, onProgress) {
10600
+ const earlyResult = installPreChecks2(destPath, sources);
10601
+ if (earlyResult) return earlyResult;
10602
+ const platformDir = getPlatformDir();
10603
+ const binaryName = getAuthBinaryName();
10604
+ const resolvedDest = destPath ?? join11(homedir9(), ".okx", "bin", binaryName);
10605
+ const tmpPath = resolvedDest + ".tmp";
10606
+ mkdirSync9(dirname7(resolvedDest), { recursive: true });
10607
+ const localHash = existsSync7(resolvedDest) ? hashFile(resolvedDest) : null;
10608
+ const checksumPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
10609
+ const binaryPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/${binaryName}`;
10610
+ const errors = [];
10611
+ for (const { host, protocol } of sources) {
10612
+ try {
10613
+ const checksum = await fetchAndValidateChecksum2(
10614
+ host,
10615
+ protocol,
10616
+ checksumPath,
10617
+ platformDir,
10618
+ DOWNLOAD_TIMEOUT_MS,
10619
+ onProgress
10620
+ );
10621
+ if (isLocalUpToDate2(localHash, checksum)) {
10622
+ onProgress?.("Already up to date (checksum match)");
10623
+ return { status: "up-to-date", source: host };
10624
+ }
10625
+ await downloadAndVerify2(host, protocol, binaryPath, tmpPath, checksum, DOWNLOAD_TIMEOUT_MS, onProgress);
10626
+ atomicReplace2(tmpPath, resolvedDest);
10627
+ onProgress?.(`Downloaded and verified from ${host}`);
10628
+ return { status: "installed", source: host };
10629
+ } catch (err) {
10630
+ try {
10631
+ unlinkSync4(tmpPath);
10632
+ } catch {
10633
+ }
10634
+ const msg = err instanceof Error ? err.message : String(err);
10635
+ errors.push(`${host}: ${msg}`);
10636
+ onProgress?.(`${host} failed: ${msg}`);
10637
+ }
10638
+ }
10639
+ return { status: "failed", error: `All CDN sources failed:
10640
+ ${errors.join("\n")}` };
10641
+ }
10642
+ function removeAuthBinary(binaryPath) {
10643
+ const resolvedPath = binaryPath ?? getAuthBinaryPath();
10644
+ try {
10645
+ unlinkSync4(resolvedPath);
10646
+ return { status: "removed" };
10647
+ } catch (err) {
10648
+ if (err.code === "ENOENT") {
10649
+ return { status: "not-found" };
10650
+ }
10651
+ const msg = err instanceof Error ? err.message : String(err);
10652
+ throw new Error(`Failed to remove ${resolvedPath}: ${msg}`);
10653
+ }
10654
+ }
10655
+ function isRedirect2(statusCode) {
10656
+ return statusCode !== void 0 && statusCode >= 300 && statusCode < 400;
10657
+ }
10658
+ function validateRedirect2(res, requestUrl, redirectCount, maxRedirects) {
10659
+ if (redirectCount > maxRedirects) {
10660
+ throw new Error(`Too many redirects (${maxRedirects})`);
10661
+ }
10662
+ const location = res.headers.location;
10663
+ if (requestUrl.startsWith("https") && !location.startsWith("https")) {
10664
+ throw new Error("Refused HTTPS \u2192 HTTP redirect downgrade");
10665
+ }
10666
+ return location;
10667
+ }
10668
+ function fetchResponse2(url, timeoutMs) {
10669
+ return new Promise((resolve3, reject) => {
10670
+ let redirects = 0;
10671
+ const maxRedirects = 5;
10672
+ function doRequest(requestUrl) {
10673
+ const reqFn = requestUrl.startsWith("https") ? httpsGet2 : httpGet2;
10674
+ const req = reqFn(requestUrl, { timeout: timeoutMs }, (res) => {
10675
+ if (isRedirect2(res.statusCode) && res.headers.location) {
10676
+ redirects++;
10677
+ try {
10678
+ const location = validateRedirect2(res, requestUrl, redirects, maxRedirects);
10679
+ res.resume();
10680
+ doRequest(location);
10681
+ } catch (err) {
10682
+ reject(err);
10683
+ }
10684
+ return;
10685
+ }
10686
+ if (res.statusCode !== 200) {
10687
+ reject(new Error(`HTTP ${res.statusCode ?? "unknown"}`));
10688
+ return;
10689
+ }
10690
+ resolve3(res);
10691
+ });
10692
+ req.on("error", reject);
10693
+ req.on("timeout", () => {
10694
+ req.destroy();
10695
+ reject(new Error("Download timed out"));
10696
+ });
10697
+ }
10698
+ doRequest(url);
10699
+ });
10700
+ }
10701
+ function download2(url, destPath, timeoutMs) {
10702
+ return fetchResponse2(url, timeoutMs).then(
10703
+ (res) => new Promise((resolve3, reject) => {
10704
+ const file = createWriteStream3(destPath);
10705
+ res.pipe(file);
10706
+ file.on("finish", () => file.close(() => resolve3()));
10707
+ file.on("error", (err) => {
10708
+ try {
10709
+ unlinkSync4(destPath);
10710
+ } catch {
10711
+ }
10712
+ reject(err);
10713
+ });
10714
+ })
10715
+ );
10716
+ }
10717
+ function downloadText2(url, timeoutMs) {
10718
+ return fetchResponse2(url, timeoutMs).then(
10719
+ (res) => new Promise((resolve3, reject) => {
10720
+ const chunks = [];
10721
+ res.on("data", (chunk) => chunks.push(chunk));
10722
+ res.on("end", () => resolve3(Buffer.concat(chunks).toString("utf8")));
10723
+ res.on("error", reject);
10724
+ })
10725
+ );
10726
+ }
10727
+ var CACHE_PATH = join12(homedir10(), ".okx", "auth-binary-check.json");
10728
+ var CHECK_INTERVAL_MS2 = 2 * 60 * 60 * 1e3;
10729
+ function readCache3() {
10730
+ try {
10731
+ if (!existsSync8(CACHE_PATH)) return null;
10732
+ const data = JSON.parse(readFileSync8(CACHE_PATH, "utf-8"));
10733
+ if (typeof data.cdnSha256 !== "string" || typeof data.checkedAt !== "number") return null;
10734
+ return { cdnSha256: data.cdnSha256, checkedAt: data.checkedAt };
10735
+ } catch {
10736
+ return null;
10737
+ }
10738
+ }
10739
+ function writeCache3(cdnSha256) {
10740
+ try {
10741
+ mkdirSync10(join12(homedir10(), ".okx"), { recursive: true });
10742
+ writeFileSync7(CACHE_PATH, JSON.stringify({ cdnSha256, checkedAt: Date.now() }, null, 2), "utf-8");
10743
+ } catch {
10744
+ }
10745
+ }
10746
+ async function ensureAuthBinaryLatest(onProgress) {
10747
+ if (process.env.OKX_AUTH_BIN) return;
10748
+ const cache = readCache3();
10749
+ if (cache && Date.now() - cache.checkedAt < CHECK_INTERVAL_MS2) return;
10750
+ try {
10751
+ const cdn = await fetchAuthCdnChecksum(void 0, 5e3);
10752
+ if (!cdn) return;
10753
+ const local = getAuthStatus();
10754
+ if (local.exists && local.sha256 === cdn.sha256) {
10755
+ writeCache3(cdn.sha256);
10756
+ return;
10757
+ }
10758
+ onProgress?.("Updating okx-auth binary...");
10759
+ const result = await installAuthBinary(void 0, void 0, onProgress);
10760
+ if (result.status === "installed" || result.status === "up-to-date") {
10761
+ const updated = getAuthStatus();
10762
+ if (updated.sha256) writeCache3(updated.sha256);
10763
+ if (result.status === "installed") {
10764
+ onProgress?.("\u2713 okx-auth updated successfully");
10765
+ }
10766
+ }
10767
+ } catch {
10768
+ }
10769
+ }
10770
+ function updateAuthBinaryCache(sha256) {
10771
+ writeCache3(sha256);
10772
+ }
10773
+ function clearAuthBinaryCache() {
10774
+ try {
10775
+ unlinkSync5(CACHE_PATH);
10776
+ } catch {
10777
+ }
10778
+ }
10354
10779
 
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";
10780
+ // src/commands/auth.ts
10781
+ import { spawn as spawn2 } from "child_process";
10782
+ import readline from "readline";
10364
10783
 
10365
10784
  // src/formatter.ts
10366
10785
  import { EOL } from "os";
@@ -10451,7 +10870,260 @@ function markFailedIfSCodeError(data) {
10451
10870
  }
10452
10871
  }
10453
10872
 
10873
+ // src/commands/auth.ts
10874
+ function runOkxAuth(args) {
10875
+ const binPath = getAuthBinaryPath();
10876
+ return new Promise((resolve3, reject) => {
10877
+ const child = spawn2(binPath, args, {
10878
+ stdio: "inherit"
10879
+ });
10880
+ child.on("error", (err) => {
10881
+ reject(new Error(`Failed to spawn okx-auth: ${err.message}`));
10882
+ });
10883
+ child.on("close", (code) => {
10884
+ resolve3(code ?? 1);
10885
+ });
10886
+ });
10887
+ }
10888
+ function runOkxAuthCapture(args) {
10889
+ const binPath = getAuthBinaryPath();
10890
+ return new Promise((resolve3, reject) => {
10891
+ const child = spawn2(binPath, args, {
10892
+ stdio: ["inherit", "pipe", "inherit"]
10893
+ });
10894
+ const chunks = [];
10895
+ child.stdout.on("data", (chunk) => chunks.push(chunk));
10896
+ child.on("error", (err) => {
10897
+ reject(new Error(`Failed to spawn okx-auth: ${err.message}`));
10898
+ });
10899
+ child.on("close", (code) => {
10900
+ resolve3({
10901
+ code: code ?? 1,
10902
+ stdout: Buffer.concat(chunks).toString("utf-8")
10903
+ });
10904
+ });
10905
+ });
10906
+ }
10907
+ async function cmdAuthLogin(args) {
10908
+ const cliArgs = ["login"];
10909
+ if (args.site) cliArgs.push("--site", args.site);
10910
+ if (args.manual) cliArgs.push("--manual");
10911
+ const code = await runOkxAuth(cliArgs);
10912
+ if (code !== 0) {
10913
+ process.exitCode = code;
10914
+ }
10915
+ }
10916
+ async function cmdAuthLogout() {
10917
+ const code = await runOkxAuth(["logout"]);
10918
+ if (code !== 0) {
10919
+ process.exitCode = code;
10920
+ }
10921
+ }
10922
+ async function cmdAuthStatus(args) {
10923
+ const cliArgs = ["status"];
10924
+ if (args.json) cliArgs.push("--json");
10925
+ const result = await runOkxAuthCapture(cliArgs);
10926
+ if (result.stdout) {
10927
+ process.stdout.write(result.stdout);
10928
+ }
10929
+ if (result.code !== 0) {
10930
+ process.exitCode = result.code;
10931
+ }
10932
+ }
10933
+ function resolveChecksumMatch(local, cdnChecksum, cdnError) {
10934
+ if (!local.exists) return "not-installed";
10935
+ if (cdnError || !cdnChecksum) return "unavailable";
10936
+ if (cdnChecksum.sha256 === local.sha256) return "match";
10937
+ return "mismatch";
10938
+ }
10939
+ function checksumMatchLabel(match) {
10940
+ if (match === "match") return "\u2713 match";
10941
+ if (match === "mismatch") return "\u2717 mismatch (update available)";
10942
+ return "CDN unreachable";
10943
+ }
10944
+ function formatBytes(bytes) {
10945
+ if (bytes < 1024) return `${bytes} B`;
10946
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
10947
+ return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
10948
+ }
10949
+ async function cmdAuthInstallStatus(json) {
10950
+ const local = getAuthStatus();
10951
+ let cdnChecksum = null;
10952
+ let cdnError = null;
10953
+ if (local.exists) {
10954
+ try {
10955
+ cdnChecksum = await fetchAuthCdnChecksum(void 0, 5e3);
10956
+ } catch (err) {
10957
+ cdnError = err instanceof Error ? err.message : String(err);
10958
+ }
10959
+ }
10960
+ const checksumMatch = resolveChecksumMatch(local, cdnChecksum, cdnError);
10961
+ if (json) {
10962
+ outputLine(
10963
+ JSON.stringify({
10964
+ binaryPath: local.binaryPath,
10965
+ exists: local.exists,
10966
+ platform: local.platform,
10967
+ fileSize: local.fileSize ?? null,
10968
+ sha256: local.sha256 ?? null,
10969
+ cdnMatch: checksumMatch,
10970
+ cdnSha256: cdnChecksum?.sha256 ?? null,
10971
+ cdnSource: cdnChecksum?.source ?? null
10972
+ })
10973
+ );
10974
+ return;
10975
+ }
10976
+ outputLine("");
10977
+ outputLine(" okx-auth Binary Status");
10978
+ outputLine(" " + "\u2500".repeat(40));
10979
+ outputLine(` Binary path : ${local.binaryPath}`);
10980
+ outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
10981
+ outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
10982
+ if (local.exists) {
10983
+ outputLine(` File size : ${formatBytes(local.fileSize)}`);
10984
+ outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
10985
+ outputLine(` CDN check : ${checksumMatchLabel(checksumMatch)}`);
10986
+ if (cdnChecksum) {
10987
+ outputLine(` CDN source : ${cdnChecksum.source}`);
10988
+ }
10989
+ }
10990
+ outputLine("");
10991
+ }
10992
+ async function cmdAuthInstall(json) {
10993
+ const messages2 = [];
10994
+ const onProgress = (msg) => {
10995
+ if (!json) {
10996
+ outputLine(` ${msg}`);
10997
+ }
10998
+ messages2.push(msg);
10999
+ };
11000
+ if (!json) {
11001
+ outputLine("");
11002
+ outputLine(" Installing okx-auth...");
11003
+ }
11004
+ const result = await installAuthBinary(void 0, void 0, onProgress);
11005
+ if (json) {
11006
+ outputLine(JSON.stringify({ status: result.status, source: result.source ?? null, error: result.error ?? null, messages: messages2 }));
11007
+ if (result.status === "failed") {
11008
+ process.exitCode = 1;
11009
+ }
11010
+ return;
11011
+ }
11012
+ if (result.status === "installed" || result.status === "up-to-date") {
11013
+ const local = getAuthStatus();
11014
+ if (local.sha256) updateAuthBinaryCache(local.sha256);
11015
+ }
11016
+ if (result.status === "installed") {
11017
+ outputLine(` \u2713 okx-auth installed successfully (${result.source ?? ""})`);
11018
+ } else if (result.status === "up-to-date") {
11019
+ outputLine(" \u2713 okx-auth is already up to date");
11020
+ } else {
11021
+ errorLine(` \u2717 Installation failed: ${result.error ?? "unknown error"}`);
11022
+ errorLine(" Hint: check network connectivity or try again later");
11023
+ process.exitCode = 1;
11024
+ }
11025
+ outputLine("");
11026
+ }
11027
+ async function cmdAuthRemove(force, json) {
11028
+ const local = getAuthStatus(void 0, { skipHash: true });
11029
+ if (!local.exists) {
11030
+ if (json) {
11031
+ outputLine(JSON.stringify({ status: "not-installed" }));
11032
+ } else {
11033
+ outputLine(" okx-auth is not installed.");
11034
+ }
11035
+ return;
11036
+ }
11037
+ if (!await confirmRemoval(force, local.binaryPath)) return;
11038
+ let result;
11039
+ try {
11040
+ result = removeAuthBinary();
11041
+ } catch (err) {
11042
+ const msg = err instanceof Error ? err.message : String(err);
11043
+ if (json) {
11044
+ outputLine(JSON.stringify({ status: "failed", error: msg }));
11045
+ } else {
11046
+ errorLine(` \u2717 Failed to remove: ${msg}`);
11047
+ }
11048
+ process.exitCode = 1;
11049
+ return;
11050
+ }
11051
+ if (json) {
11052
+ outputLine(JSON.stringify({ status: result.status, path: local.binaryPath }));
11053
+ return;
11054
+ }
11055
+ if (result.status === "removed") {
11056
+ clearAuthBinaryCache();
11057
+ outputLine(` \u2713 Removed: ${local.binaryPath}`);
11058
+ } else {
11059
+ outputLine(" okx-auth is not installed.");
11060
+ }
11061
+ }
11062
+ async function confirmRemoval(force, binaryPath) {
11063
+ if (force) return true;
11064
+ if (!process.stdin.isTTY) {
11065
+ errorLine(" Error: stdin is not a TTY. Use --force to skip confirmation.");
11066
+ process.exitCode = 1;
11067
+ return false;
11068
+ }
11069
+ const confirmed = await askConfirmation(
11070
+ ` Remove okx-auth at ${binaryPath}? [y/N] `
11071
+ );
11072
+ if (!confirmed) {
11073
+ outputLine(" Cancelled.");
11074
+ return false;
11075
+ }
11076
+ return true;
11077
+ }
11078
+ function askConfirmation(prompt2) {
11079
+ return new Promise((resolve3) => {
11080
+ const rl = readline.createInterface({
11081
+ input: process.stdin,
11082
+ output: process.stdout
11083
+ });
11084
+ rl.question(prompt2, (answer) => {
11085
+ rl.close();
11086
+ resolve3(answer.trim().toLowerCase() === "y");
11087
+ });
11088
+ });
11089
+ }
11090
+ async function handleAuthCommand(action, _rest, v) {
11091
+ const site = v.site;
11092
+ const json = v.json;
11093
+ const manual = v.manual;
11094
+ const force = v.force;
11095
+ if (["login", "logout", "status"].includes(action)) {
11096
+ await ensureAuthBinaryLatest((msg) => errorLine(` ${msg}`));
11097
+ }
11098
+ switch (action) {
11099
+ case "login":
11100
+ return cmdAuthLogin({ site, manual });
11101
+ case "logout":
11102
+ return cmdAuthLogout();
11103
+ case "status":
11104
+ return cmdAuthStatus({ json });
11105
+ case "install":
11106
+ return cmdAuthInstall(json ?? false);
11107
+ case "install-status":
11108
+ return cmdAuthInstallStatus(json ?? false);
11109
+ case "remove":
11110
+ return cmdAuthRemove(force ?? false, json ?? false);
11111
+ default:
11112
+ errorLine(`Unknown auth command: ${action}`);
11113
+ errorLine("Available: login, logout, status, install, install-status, remove");
11114
+ process.exitCode = 1;
11115
+ }
11116
+ }
11117
+
11118
+ // src/commands/diagnose.ts
11119
+ import dns from "dns/promises";
11120
+ import net from "net";
11121
+ import os5 from "os";
11122
+ import tls from "tls";
11123
+
10454
11124
  // src/commands/diagnose-utils.ts
11125
+ import fs4 from "fs";
11126
+ import { createRequire } from "module";
10455
11127
  var _require = createRequire(import.meta.url);
10456
11128
  function readCliVersion() {
10457
11129
  for (const rel of ["../package.json", "../../package.json"]) {
@@ -10537,7 +11209,7 @@ function sanitize2(value) {
10537
11209
  import fs5 from "fs";
10538
11210
  import path4 from "path";
10539
11211
  import os4 from "os";
10540
- import { spawnSync, spawn } from "child_process";
11212
+ import { spawnSync, spawn as spawn3 } from "child_process";
10541
11213
  import { createRequire as createRequire2 } from "module";
10542
11214
  import { fileURLToPath } from "url";
10543
11215
  var _require2 = createRequire2(import.meta.url);
@@ -10871,7 +11543,7 @@ async function checkStdioHandshake(entryPath, report) {
10871
11543
  clearTimeout(timer);
10872
11544
  resolve3(passed);
10873
11545
  };
10874
- const child = spawn(process.execPath, [entryPath], {
11546
+ const child = spawn3(process.execPath, [entryPath], {
10875
11547
  stdio: ["pipe", "pipe", "pipe"],
10876
11548
  env: { ...process.env }
10877
11549
  });
@@ -10990,7 +11662,7 @@ async function cmdDiagnoseMcp(options = {}) {
10990
11662
 
10991
11663
  // src/commands/diagnose.ts
10992
11664
  var CLI_VERSION = readCliVersion();
10993
- var GIT_HASH = true ? "245ab4e" : "dev";
11665
+ var GIT_HASH = true ? "17e06f4" : "dev";
10994
11666
  function maskKey2(key) {
10995
11667
  if (!key) return "(not set)";
10996
11668
  if (key.length <= 8) return "****";
@@ -11326,24 +11998,24 @@ async function runCliChecks(config, profile, outputPath) {
11326
11998
 
11327
11999
  // src/commands/upgrade.ts
11328
12000
  import { spawnSync as spawnSync2 } from "child_process";
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";
12001
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, mkdirSync as mkdirSync11 } from "fs";
12002
+ import { dirname as dirname8, join as join13 } from "path";
12003
+ import { homedir as homedir11 } from "os";
11332
12004
  var PACKAGES = ["@okx_ai/okx-trade-mcp", "@okx_ai/okx-trade-cli"];
11333
- var CACHE_FILE2 = join10(homedir8(), ".okx", "last_check");
12005
+ var CACHE_FILE2 = join13(homedir11(), ".okx", "last_check");
11334
12006
  var THROTTLE_MS = 12 * 60 * 60 * 1e3;
11335
- var NPM_BIN = join10(dirname7(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
12007
+ var NPM_BIN = join13(dirname8(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
11336
12008
  function readLastCheck() {
11337
12009
  try {
11338
- return parseInt(readFileSync8(CACHE_FILE2, "utf-8").trim(), 10) || 0;
12010
+ return parseInt(readFileSync9(CACHE_FILE2, "utf-8").trim(), 10) || 0;
11339
12011
  } catch {
11340
12012
  return 0;
11341
12013
  }
11342
12014
  }
11343
12015
  function writeLastCheck() {
11344
12016
  try {
11345
- mkdirSync9(join10(homedir8(), ".okx"), { recursive: true });
11346
- writeFileSync7(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
12017
+ mkdirSync11(join13(homedir11(), ".okx"), { recursive: true });
12018
+ writeFileSync8(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
11347
12019
  } catch {
11348
12020
  }
11349
12021
  }
@@ -12314,24 +12986,24 @@ var CLI_REGISTRY = {
12314
12986
  commands: {
12315
12987
  latest: {
12316
12988
  toolName: "news_get_latest",
12317
- usage: "okx news latest [--coins BTC,ETH] [--lang zh-CN] [--limit 20]"
12989
+ usage: "okx news latest [--coins BTC,ETH] [--lang zh_CN] [--limit 20]"
12318
12990
  },
12319
12991
  important: {
12320
12992
  toolName: "news_get_latest",
12321
- usage: "okx news important [--coins BTC,ETH] [--lang zh-CN] [--limit 20]",
12993
+ usage: "okx news important [--coins BTC,ETH] [--lang zh_CN] [--limit 20]",
12322
12994
  description: "Get important/high-impact crypto news"
12323
12995
  },
12324
12996
  "by-coin": {
12325
12997
  toolName: "news_get_by_coin",
12326
- usage: "okx news by-coin --coins BTC [--importance high] [--lang zh-CN]"
12998
+ usage: "okx news by-coin --coins BTC [--importance high] [--lang zh_CN]"
12327
12999
  },
12328
13000
  search: {
12329
13001
  toolName: "news_search",
12330
- usage: "okx news search --keyword <term> [--coins BTC] [--sentiment bullish] [--lang zh-CN]"
13002
+ usage: "okx news search --keyword <term> [--coins BTC] [--sentiment bullish] [--lang zh_CN]"
12331
13003
  },
12332
13004
  detail: {
12333
13005
  toolName: "news_get_detail",
12334
- usage: "okx news detail <id> [--lang zh-CN]"
13006
+ usage: "okx news detail <id> [--lang zh_CN]"
12335
13007
  },
12336
13008
  domains: {
12337
13009
  toolName: "news_get_domains",
@@ -12763,7 +13435,7 @@ async function cmdNewsSentimentRank(run, opts) {
12763
13435
  }
12764
13436
 
12765
13437
  // src/config/loader.ts
12766
- function loadProfileConfig(opts) {
13438
+ async function loadProfileConfig(opts) {
12767
13439
  return loadConfig({
12768
13440
  profile: opts.profile,
12769
13441
  modules: opts.modules,
@@ -13081,6 +13753,9 @@ var CLI_OPTIONS = {
13081
13753
  dir: { type: "string" },
13082
13754
  page: { type: "string" },
13083
13755
  format: { type: "string" },
13756
+ // auth
13757
+ site: { type: "string" },
13758
+ manual: { type: "boolean", default: false },
13084
13759
  // event contract
13085
13760
  underlying: { type: "string" },
13086
13761
  seriesId: { type: "string" },
@@ -16095,14 +16770,14 @@ async function cmdDcdQuoteAndBuy(run, opts) {
16095
16770
  }
16096
16771
 
16097
16772
  // src/commands/skill.ts
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";
16773
+ import { tmpdir, homedir as homedir13 } from "os";
16774
+ import { join as join15, dirname as dirname9 } from "path";
16775
+ import { mkdirSync as mkdirSync12, rmSync, existsSync as existsSync10, copyFileSync as copyFileSync2 } from "fs";
16101
16776
  import { execFileSync as execFileSync2 } from "child_process";
16102
16777
  import { randomUUID as randomUUID2 } from "crypto";
16103
16778
  function resolveNpx() {
16104
- const sibling = join12(dirname8(process.execPath), "npx");
16105
- if (existsSync8(sibling)) return sibling;
16779
+ const sibling = join15(dirname9(process.execPath), "npx");
16780
+ if (existsSync10(sibling)) return sibling;
16106
16781
  return "npx";
16107
16782
  }
16108
16783
  var THIRD_PARTY_INSTALL_NOTICE = "Note: This skill was created by a third-party developer, not by OKX. Review SKILL.md before use.";
@@ -16155,13 +16830,13 @@ async function cmdSkillCategories(run, json) {
16155
16830
  outputLine("");
16156
16831
  }
16157
16832
  async function cmdSkillAdd(name, config, json) {
16158
- const tmpBase = join12(tmpdir(), `okx-skill-${randomUUID2()}`);
16159
- mkdirSync10(tmpBase, { recursive: true });
16833
+ const tmpBase = join15(tmpdir(), `okx-skill-${randomUUID2()}`);
16834
+ mkdirSync12(tmpBase, { recursive: true });
16160
16835
  try {
16161
16836
  outputLine(`Downloading ${name}...`);
16162
16837
  const client = new OkxRestClient(config);
16163
16838
  const zipPath = await downloadSkillZip(client, name, tmpBase);
16164
- const contentDir = await extractSkillZip(zipPath, join12(tmpBase, "content"));
16839
+ const contentDir = await extractSkillZip(zipPath, join15(tmpBase, "content"));
16165
16840
  const meta = readMetaJson(contentDir);
16166
16841
  validateSkillMdExists(contentDir);
16167
16842
  outputLine("Installing to detected agents...");
@@ -16171,7 +16846,7 @@ async function cmdSkillAdd(name, config, json) {
16171
16846
  timeout: 6e4
16172
16847
  });
16173
16848
  } catch (e) {
16174
- const savedZip = join12(process.cwd(), `${name}.zip`);
16849
+ const savedZip = join15(process.cwd(), `${name}.zip`);
16175
16850
  try {
16176
16851
  copyFileSync2(zipPath, savedZip);
16177
16852
  } catch {
@@ -16210,7 +16885,7 @@ function cmdSkillRemove(name, json) {
16210
16885
  timeout: 6e4
16211
16886
  });
16212
16887
  } catch {
16213
- const agentsPath = join12(homedir10(), ".agents", "skills", name);
16888
+ const agentsPath = join15(homedir13(), ".agents", "skills", name);
16214
16889
  try {
16215
16890
  rmSync(agentsPath, { recursive: true, force: true });
16216
16891
  } catch {
@@ -16284,14 +16959,14 @@ function printSkillInstallResult(meta, json) {
16284
16959
  }
16285
16960
 
16286
16961
  // src/commands/doh.ts
16287
- import readline from "readline";
16288
- function resolveChecksumMatch(local, cdnChecksum, cdnError) {
16962
+ import readline2 from "readline";
16963
+ function resolveChecksumMatch2(local, cdnChecksum, cdnError) {
16289
16964
  if (!local.exists) return "not-installed";
16290
16965
  if (cdnError || !cdnChecksum) return "unavailable";
16291
16966
  if (cdnChecksum.sha256 === local.sha256) return "match";
16292
16967
  return "mismatch";
16293
16968
  }
16294
- function checksumMatchLabel(match) {
16969
+ function checksumMatchLabel2(match) {
16295
16970
  if (match === "match") return "\u2713 match";
16296
16971
  if (match === "mismatch") return "\u2717 mismatch (update available)";
16297
16972
  return "CDN unreachable";
@@ -16304,9 +16979,9 @@ function formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode) {
16304
16979
  outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
16305
16980
  outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
16306
16981
  if (local.exists) {
16307
- outputLine(` File size : ${formatBytes(local.fileSize)}`);
16982
+ outputLine(` File size : ${formatBytes2(local.fileSize)}`);
16308
16983
  outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
16309
- outputLine(` CDN check : ${checksumMatchLabel(checksumMatch)}`);
16984
+ outputLine(` CDN check : ${checksumMatchLabel2(checksumMatch)}`);
16310
16985
  if (cdnChecksum) {
16311
16986
  outputLine(` CDN source : ${cdnChecksum.source}`);
16312
16987
  }
@@ -16333,7 +17008,7 @@ async function cmdDohStatus(json, binaryPath) {
16333
17008
  cdnError = err instanceof Error ? err.message : String(err);
16334
17009
  }
16335
17010
  }
16336
- const checksumMatch = resolveChecksumMatch(local, cdnChecksum, cdnError);
17011
+ const checksumMatch = resolveChecksumMatch2(local, cdnChecksum, cdnError);
16337
17012
  if (json) {
16338
17013
  outputLine(
16339
17014
  JSON.stringify({
@@ -16399,7 +17074,7 @@ async function cmdDohRemove(force, json, binaryPath) {
16399
17074
  process.exitCode = 1;
16400
17075
  return;
16401
17076
  }
16402
- const confirmed = await askConfirmation(
17077
+ const confirmed = await askConfirmation2(
16403
17078
  ` Remove DoH resolver at ${local.binaryPath}? [y/N] `
16404
17079
  );
16405
17080
  if (!confirmed) {
@@ -16418,14 +17093,14 @@ async function cmdDohRemove(force, json, binaryPath) {
16418
17093
  outputLine(" DoH resolver is not installed.");
16419
17094
  }
16420
17095
  }
16421
- function formatBytes(bytes) {
17096
+ function formatBytes2(bytes) {
16422
17097
  if (bytes < 1024) return `${bytes} B`;
16423
17098
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
16424
17099
  return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
16425
17100
  }
16426
- function askConfirmation(prompt2) {
17101
+ function askConfirmation2(prompt2) {
16427
17102
  return new Promise((resolve3) => {
16428
- const rl = readline.createInterface({
17103
+ const rl = readline2.createInterface({
16429
17104
  input: process.stdin,
16430
17105
  output: process.stdout
16431
17106
  });
@@ -16882,7 +17557,7 @@ async function cmdEventCancel(run, opts) {
16882
17557
  // src/index.ts
16883
17558
  var _require3 = createRequire3(import.meta.url);
16884
17559
  var CLI_VERSION2 = _require3("../package.json").version;
16885
- var GIT_HASH2 = true ? "245ab4e" : "dev";
17560
+ var GIT_HASH2 = true ? "17e06f4" : "dev";
16886
17561
  function handleDohCommand(action, json, force, binaryPath) {
16887
17562
  if (action === "status") return cmdDohStatus(json, binaryPath);
16888
17563
  if (action === "install") return cmdDohInstall(json, binaryPath);
@@ -17726,7 +18401,7 @@ function handleNewsCommand(run, action, rest, v, json) {
17726
18401
  const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
17727
18402
  const begin = v.begin !== void 0 ? Number(v.begin) : void 0;
17728
18403
  const end = v.end !== void 0 ? Number(v.end) : void 0;
17729
- const language = v.lang ?? "en-US";
18404
+ const language = v.lang ?? "en_US";
17730
18405
  const detailLvl = v["detail-lvl"];
17731
18406
  const after = v.after;
17732
18407
  const period = v.period;
@@ -17857,7 +18532,7 @@ function wrapRunnerWithLogger(baseRunner, logger, verbose = false) {
17857
18532
  async function runDiagnose(v) {
17858
18533
  let config;
17859
18534
  try {
17860
- config = loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
18535
+ config = await loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
17861
18536
  } catch {
17862
18537
  }
17863
18538
  return cmdDiagnose(config, v.profile ?? "default", { mcp: v.mcp, cli: v.cli, all: v.all, output: v.output });
@@ -17872,24 +18547,13 @@ function printVersion() {
17872
18547
  }
17873
18548
  }
17874
18549
  function routeManagementCommand(module, action, rest, json, v) {
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
- }
18550
+ if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
18551
+ if (module === "setup") return handleSetupCommand(v);
18552
+ if (module === "auth") return handleAuthCommand(action, rest, v);
17883
18553
  if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
17884
- if (module === "doh") {
17885
- const r = handleDohCommand(action, json, v.force ?? false);
17886
- return r ?? true;
17887
- }
18554
+ if (module === "doh") return handleDohCommand(action, json, v.force ?? false);
17888
18555
  if (module === "diagnose") return runDiagnose(v);
17889
- if (module === "list-tools") {
17890
- cmdListTools(json);
17891
- return true;
17892
- }
18556
+ if (module === "list-tools") return cmdListTools(json);
17893
18557
  return void 0;
17894
18558
  }
17895
18559
  async function main() {
@@ -17911,8 +18575,8 @@ async function main() {
17911
18575
  const v = values;
17912
18576
  const json = v.json ?? false;
17913
18577
  const mgmt = routeManagementCommand(module, action, rest, json, v);
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" });
18578
+ if (mgmt) return mgmt;
18579
+ const config = await loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
17916
18580
  setEnvContext({ demo: config.demo, profile: v.profile ?? "default" });
17917
18581
  setJsonEnvEnabled(v.env ?? false);
17918
18582
  const client = new OkxRestClient(config);