@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 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 join4, resolve, basename, sep } from "path";
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 join5 } from "path";
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 join6, dirname as dirname3 } from "path";
40
- import { homedir as homedir4 } from "os";
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 join7, dirname as dirname4 } from "path";
43
- import { homedir as homedir5 } from "os";
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 join8 } from "path";
874
- import { homedir as homedir6 } from "os";
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 homedir8, platform, arch } from "os";
905
- import { join as join10, dirname as dirname6 } from "path";
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-doh-resolver${ext}`);
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: "OKX system upgrade in progress. Retry in a few minutes." },
1446
- "50004": { retry: true, suggestion: "Endpoint temporarily unavailable. Retry later." },
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: "Order book system upgrading. Retry in a few minutes." },
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 = await this.buildHeaders(reqConfig, path42, bodyJson, getNow());
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
- async buildHeaders(reqConfig, requestPath, bodyJson, timestamp) {
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
- await this.applyAuth(headers, reqConfig.method, requestPath, bodyJson, timestamp);
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 = await this.buildHeaders(reqConfig, requestPath, bodyJson, timestamp);
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://us.okx.com",
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 = join4(resolvedDir, safeName);
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 = join5(contentDir, "_meta.json");
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 = join5(contentDir, "SKILL.md");
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 = join6(homedir4(), ".okx", "skills", "registry.json");
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: "DCD service is down. Retry in a few minutes." },
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 = ["en_US", "zh_CN"];
7840
+ var NEWS_LANGUAGE = ["en-US", "zh-CN"];
7988
7841
  function langHeader(lang) {
7989
- const resolved = lang === "zh_CN" ? "zh_CN" : "en_US";
7990
- return { "Accept-Language": resolved };
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: zh_CN or en_US. Infer from user's message. No server default.";
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 join7(homedir5(), ".okx", "config.toml");
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
- async function loadCredentials(toml) {
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 hasApiKey = Boolean(apiKey && secretKey && passphrase);
9725
+ const hasAuth = Boolean(apiKey && secretKey && passphrase);
9868
9726
  const partialAuth = Boolean(apiKey) || Boolean(secretKey) || Boolean(passphrase);
9869
- if (partialAuth && !hasApiKey) {
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
- async function loadConfig(cli) {
9915
- const config = readFullConfig();
9916
- const profileName = cli.profile ?? config.default_profile ?? "default";
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 = join8(homedir6(), ".okx", "update-check.json");
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(join8(homedir6(), ".okx"), { recursive: true });
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 platform3 = process.platform;
9983
+ const platform2 = process.platform;
10135
9984
  switch (client) {
10136
9985
  case "claude-desktop":
10137
- if (platform3 === "win32") {
9986
+ if (platform2 === "win32") {
10138
9987
  return findMsStoreClaudePath() ?? path3.join(appData(), "Claude", CLAUDE_CONFIG_FILE);
10139
9988
  }
10140
- if (platform3 === "darwin") {
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-doh-resolver.exe" : "okx-doh-resolver";
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 ?? join10(homedir8(), ".okx", "bin", binaryName);
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/auth.ts
10721
- import { spawn as spawn2 } from "child_process";
10722
- import readline from "readline";
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 as spawn3 } from "child_process";
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 = spawn3(process.execPath, [entryPath], {
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 ? "1431fd4" : "dev";
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 mkdirSync10 } from "fs";
11931
- import { dirname as dirname8, join as join12 } from "path";
11932
- import { homedir as homedir10 } from "os";
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 = join12(homedir10(), ".okx", "last_check");
11333
+ var CACHE_FILE2 = join10(homedir8(), ".okx", "last_check");
11935
11334
  var THROTTLE_MS = 12 * 60 * 60 * 1e3;
11936
- var NPM_BIN = join12(dirname8(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
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
- mkdirSync10(join12(homedir10(), ".okx"), { recursive: true });
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 zh_CN] [--limit 20]"
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 zh_CN] [--limit 20]",
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 zh_CN]"
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 zh_CN]"
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 zh_CN]"
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
- async function loadProfileConfig(opts) {
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 homedir12 } from "os";
16703
- import { join as join14, dirname as dirname9 } from "path";
16704
- import { mkdirSync as mkdirSync11, rmSync, existsSync as existsSync9, copyFileSync as copyFileSync2 } from "fs";
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 = join14(dirname9(process.execPath), "npx");
16709
- if (existsSync9(sibling)) return sibling;
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 = join14(tmpdir(), `okx-skill-${randomUUID2()}`);
16763
- mkdirSync11(tmpBase, { recursive: true });
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, join14(tmpBase, "content"));
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 = join14(process.cwd(), `${name}.zip`);
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 = join14(homedir12(), ".agents", "skills", name);
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 readline2 from "readline";
16892
- function resolveChecksumMatch2(local, cdnChecksum, cdnError) {
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 checksumMatchLabel2(match) {
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 : ${formatBytes2(local.fileSize)}`);
16307
+ outputLine(` File size : ${formatBytes(local.fileSize)}`);
16912
16308
  outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
16913
- outputLine(` CDN check : ${checksumMatchLabel2(checksumMatch)}`);
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 = resolveChecksumMatch2(local, cdnChecksum, cdnError);
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 askConfirmation2(
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 formatBytes2(bytes) {
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 askConfirmation2(prompt2) {
16426
+ function askConfirmation(prompt2) {
17031
16427
  return new Promise((resolve3) => {
17032
- const rl = readline2.createInterface({
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 ? "1431fd4" : "dev";
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 ?? "en_US";
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 = await loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
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") return handleConfigCommand(action, rest, json, v.lang, v.force);
18480
- if (module === "setup") return handleSetupCommand(v);
18481
- if (module === "auth") return handleAuthCommand(action, rest, 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
+ }
18482
17883
  if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
18483
- if (module === "doh") return handleDohCommand(action, json, v.force ?? false);
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") return cmdListTools(json);
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 = await loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
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);