@okx_ai/okx-trade-cli 1.3.8-beta.4 → 1.3.8-beta.6
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 +306 -26
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/LICENSE +0 -21
- package/scripts/postinstall-download.js +0 -152
package/dist/index.js
CHANGED
|
@@ -1003,6 +1003,7 @@ function writeCache(hostname, entry, cachePath = getDefaultCachePath()) {
|
|
|
1003
1003
|
}
|
|
1004
1004
|
}
|
|
1005
1005
|
var FAILED_NODE_TTL_MS = 60 * 60 * 1e3;
|
|
1006
|
+
var MAX_PROXY_CACHE_AGE_MS = 60 * 60 * 1e3;
|
|
1006
1007
|
function classifyAndCache(node, hostname, failedNodes, cachePath) {
|
|
1007
1008
|
if (!node) {
|
|
1008
1009
|
return { mode: null, node: null };
|
|
@@ -1036,6 +1037,10 @@ function resolvePilot(hostname, cachePath) {
|
|
|
1036
1037
|
return { mode: "direct", node: null };
|
|
1037
1038
|
}
|
|
1038
1039
|
if (entry.mode === "proxy" && entry.node) {
|
|
1040
|
+
const effectiveTtlMs = Math.min(entry.node.ttl > 0 ? entry.node.ttl * 1e3 : MAX_PROXY_CACHE_AGE_MS, MAX_PROXY_CACHE_AGE_MS);
|
|
1041
|
+
if (Date.now() - entry.updatedAt > effectiveTtlMs) {
|
|
1042
|
+
return { mode: null, node: null };
|
|
1043
|
+
}
|
|
1039
1044
|
return { mode: "proxy", node: entry.node };
|
|
1040
1045
|
}
|
|
1041
1046
|
}
|
|
@@ -1555,6 +1560,14 @@ var OKX_CODE_BEHAVIORS = {
|
|
|
1555
1560
|
"51022": { retry: false, suggestion: "Instrument not available for trading." },
|
|
1556
1561
|
"51027": { retry: false, suggestion: "Contract has expired." }
|
|
1557
1562
|
};
|
|
1563
|
+
function hasOkxJsonCode(text) {
|
|
1564
|
+
try {
|
|
1565
|
+
const parsed = JSON.parse(text);
|
|
1566
|
+
return typeof parsed.code === "string" && parsed.code.length > 0;
|
|
1567
|
+
} catch {
|
|
1568
|
+
return false;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1558
1571
|
function isDefined(value) {
|
|
1559
1572
|
return value !== void 0 && value !== null;
|
|
1560
1573
|
}
|
|
@@ -2032,6 +2045,12 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
2032
2045
|
const rawText = await response.text();
|
|
2033
2046
|
const elapsed = Date.now() - t0;
|
|
2034
2047
|
const traceId = extractTraceId(response.headers);
|
|
2048
|
+
if (this.pilot.isProxyActive && !response.ok && !hasOkxJsonCode(rawText) && !this.pilot.hasRetried) {
|
|
2049
|
+
const shouldRetry = await this.pilot.handleNetworkFailure();
|
|
2050
|
+
if (shouldRetry && (reqConfig.method === "GET" || reqConfig.retryOnNetworkError)) {
|
|
2051
|
+
return this.request(reqConfig);
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2035
2054
|
this.pilot.cacheDirectIfNeeded();
|
|
2036
2055
|
return this.processResponse(rawText, response, elapsed, traceId, reqConfig, requestPath);
|
|
2037
2056
|
}
|
|
@@ -2506,6 +2525,56 @@ function resolveIndicatorCode(name) {
|
|
|
2506
2525
|
const lower = name.toLowerCase();
|
|
2507
2526
|
return INDICATOR_CODE_OVERRIDES[lower] ?? name.toUpperCase().replace(/-/g, "_");
|
|
2508
2527
|
}
|
|
2528
|
+
var DEFAULT_INDICATOR_PARAMS = {
|
|
2529
|
+
// Moving Averages — PRD example default is [14]
|
|
2530
|
+
ma: [14],
|
|
2531
|
+
ema: [14],
|
|
2532
|
+
wma: [14],
|
|
2533
|
+
dema: [14],
|
|
2534
|
+
tema: [14],
|
|
2535
|
+
zlema: [14],
|
|
2536
|
+
hma: [14],
|
|
2537
|
+
kama: [14],
|
|
2538
|
+
// Trend
|
|
2539
|
+
macd: [12, 26, 9],
|
|
2540
|
+
adx: [14],
|
|
2541
|
+
aroon: [14],
|
|
2542
|
+
cci: [20],
|
|
2543
|
+
dpo: [20],
|
|
2544
|
+
// Momentum
|
|
2545
|
+
rsi: [14],
|
|
2546
|
+
"stoch-rsi": [14],
|
|
2547
|
+
stoch: [14, 3, 3],
|
|
2548
|
+
roc: [12],
|
|
2549
|
+
mom: [10],
|
|
2550
|
+
ppo: [12, 26, 9],
|
|
2551
|
+
trix: [15],
|
|
2552
|
+
uo: [7, 14, 28],
|
|
2553
|
+
wr: [14],
|
|
2554
|
+
// Volatility
|
|
2555
|
+
bb: [20, 2],
|
|
2556
|
+
bbwidth: [20, 2],
|
|
2557
|
+
bbpct: [20, 2],
|
|
2558
|
+
atr: [14],
|
|
2559
|
+
keltner: [20, 2],
|
|
2560
|
+
donchian: [20],
|
|
2561
|
+
hv: [20],
|
|
2562
|
+
stddev: [20],
|
|
2563
|
+
// Volume
|
|
2564
|
+
mvwap: [20],
|
|
2565
|
+
cmf: [20],
|
|
2566
|
+
mfi: [14],
|
|
2567
|
+
// Custom
|
|
2568
|
+
kdj: [9, 3, 3],
|
|
2569
|
+
supertrend: [10, 3]
|
|
2570
|
+
};
|
|
2571
|
+
function getDefaultIndicatorParams(name) {
|
|
2572
|
+
const lower = name.toLowerCase();
|
|
2573
|
+
const direct = DEFAULT_INDICATOR_PARAMS[lower];
|
|
2574
|
+
if (direct !== void 0) return direct;
|
|
2575
|
+
const code = resolveIndicatorCode(lower);
|
|
2576
|
+
return DEFAULT_INDICATOR_PARAMS[code.toLowerCase()];
|
|
2577
|
+
}
|
|
2509
2578
|
function validateIndicatorName(name) {
|
|
2510
2579
|
const lower = name.toLowerCase();
|
|
2511
2580
|
if (VALID_INDICATOR_NAMES.has(lower)) return;
|
|
@@ -2549,7 +2618,7 @@ function registerIndicatorTools() {
|
|
|
2549
2618
|
params: {
|
|
2550
2619
|
type: "array",
|
|
2551
2620
|
items: { type: "number" },
|
|
2552
|
-
description: "Indicator-specific parameters as a number array. Examples: MA/EMA [14] (period), MACD [12,26,9] (fast,slow,signal), BB [20,2] (period,stdDev), RSI [14] (period).
|
|
2621
|
+
description: "Indicator-specific parameters as a number array. Examples: MA/EMA [14] (period), MACD [12,26,9] (fast,slow,signal), BB [20,2] (period,stdDev), RSI [14] (period). For period-based indicators a parameter is required; the CLI applies a sensible default when omitted."
|
|
2553
2622
|
},
|
|
2554
2623
|
returnList: {
|
|
2555
2624
|
type: "boolean",
|
|
@@ -14124,6 +14193,115 @@ async function handleAuthCommand(action, _rest, v) {
|
|
|
14124
14193
|
}
|
|
14125
14194
|
}
|
|
14126
14195
|
|
|
14196
|
+
// src/commands/outcomes.ts
|
|
14197
|
+
import { spawn as spawn4 } from "child_process";
|
|
14198
|
+
import { existsSync as existsSync9 } from "fs";
|
|
14199
|
+
import { delimiter, join as join15 } from "path";
|
|
14200
|
+
var OUTCOMES_BINARY_NAME = process.platform === "win32" ? "okx-outcomes.exe" : "okx-outcomes";
|
|
14201
|
+
function resolveOutcomesBinaryPath() {
|
|
14202
|
+
const override = process.env.OKX_OUTCOMES_BIN;
|
|
14203
|
+
if (override) {
|
|
14204
|
+
if (existsSync9(override)) return override;
|
|
14205
|
+
errorLine(
|
|
14206
|
+
`Warning: OKX_OUTCOMES_BIN is set to '${override}' but no file exists there; falling back to PATH search.`
|
|
14207
|
+
);
|
|
14208
|
+
}
|
|
14209
|
+
const paths = (process.env.PATH ?? "").split(delimiter);
|
|
14210
|
+
for (const dir of paths) {
|
|
14211
|
+
if (!dir) continue;
|
|
14212
|
+
const full = join15(dir, OUTCOMES_BINARY_NAME);
|
|
14213
|
+
if (existsSync9(full)) return full;
|
|
14214
|
+
}
|
|
14215
|
+
return null;
|
|
14216
|
+
}
|
|
14217
|
+
function printInstallHint() {
|
|
14218
|
+
errorLine("Error: okx-outcomes binary not found in PATH.");
|
|
14219
|
+
errorLine("");
|
|
14220
|
+
errorLine("Install (macOS / Linux):");
|
|
14221
|
+
errorLine(" curl -fsSL https://raw.githubusercontent.com/okx/outcomes-cli/main/install.sh | sh");
|
|
14222
|
+
errorLine("");
|
|
14223
|
+
errorLine("Install (Windows): download okx-outcomes.exe from");
|
|
14224
|
+
errorLine(" https://github.com/okx/outcomes-cli/releases");
|
|
14225
|
+
errorLine("and place it on your PATH.");
|
|
14226
|
+
errorLine("");
|
|
14227
|
+
errorLine("Or set OKX_OUTCOMES_BIN env var to a custom binary path.");
|
|
14228
|
+
}
|
|
14229
|
+
function runOkxOutcomes(args) {
|
|
14230
|
+
const binPath = resolveOutcomesBinaryPath();
|
|
14231
|
+
if (!binPath) {
|
|
14232
|
+
printInstallHint();
|
|
14233
|
+
return Promise.resolve(127);
|
|
14234
|
+
}
|
|
14235
|
+
return new Promise((resolve4, reject) => {
|
|
14236
|
+
const child = spawn4(binPath, args, { stdio: "inherit" });
|
|
14237
|
+
child.on(
|
|
14238
|
+
"error",
|
|
14239
|
+
(err) => reject(new Error(`Failed to spawn okx-outcomes: ${err.message}`))
|
|
14240
|
+
);
|
|
14241
|
+
child.on("close", (code) => resolve4(code ?? 1));
|
|
14242
|
+
});
|
|
14243
|
+
}
|
|
14244
|
+
function printOutcomesHelp() {
|
|
14245
|
+
const lines = [
|
|
14246
|
+
"Usage: okx outcomes <command> [args...]",
|
|
14247
|
+
"",
|
|
14248
|
+
"OKX Outcomes - YES/NO event contract trading via the okx-outcomes binary.",
|
|
14249
|
+
"",
|
|
14250
|
+
"Common commands:",
|
|
14251
|
+
" data events List outcome events",
|
|
14252
|
+
" data event <eventId> Get event detail",
|
|
14253
|
+
" data event-markets <eventId> Event + all its markets (returns asset ids)",
|
|
14254
|
+
" data market <marketId> Get single market detail",
|
|
14255
|
+
" data trending List trending events",
|
|
14256
|
+
" data ticker <assetId> 24h ticker for an outcome asset",
|
|
14257
|
+
" data candles <assetId> OHLCV candles for an outcome asset",
|
|
14258
|
+
" search <keyword> Search events/markets",
|
|
14259
|
+
" (Note: events/event/market etc. live UNDER the `data` namespace \u2014 calling them",
|
|
14260
|
+
" as top-level commands prints the binary's help instead of returning JSON.)",
|
|
14261
|
+
"",
|
|
14262
|
+
" clob price/prices/midpoint(s)/spread(s)/book(s) --asset <id>",
|
|
14263
|
+
" CLOB read-side market data",
|
|
14264
|
+
" clob create-order Place limit order (EIP-712 signed)",
|
|
14265
|
+
" clob market-order Cross book immediately (IOC/FOK)",
|
|
14266
|
+
" clob cancel-oid | cancel-all | heartbeat",
|
|
14267
|
+
"",
|
|
14268
|
+
" ctf split/merge/redeem Conditional token operations",
|
|
14269
|
+
"",
|
|
14270
|
+
" account balance/order/orders/positions/trades",
|
|
14271
|
+
" Account queries (OAuth sign-in; closed = positions --status closed)",
|
|
14272
|
+
"",
|
|
14273
|
+
" auth login --manual [--json] OAuth device-code sign-in (prints URL+code; agent-friendly)",
|
|
14274
|
+
" auth login [--site global|us] OAuth sign-in, browser-foreground (user at a terminal)",
|
|
14275
|
+
" auth refresh | auth status Verify/refresh session; show sign-in state",
|
|
14276
|
+
" setup status|region|bind Step-by-step onboarding (all non-interactive; agent-runnable)",
|
|
14277
|
+
"",
|
|
14278
|
+
" wallet show Show derived wallet address",
|
|
14279
|
+
" status Health check",
|
|
14280
|
+
" setup Interactive setup wizard (region -> OAuth -> wallet bind)",
|
|
14281
|
+
"",
|
|
14282
|
+
"Run 'okx outcomes <command> --help' for command-specific help.",
|
|
14283
|
+
"",
|
|
14284
|
+
"Note: place flags after the subcommand, e.g. 'okx outcomes events --json'",
|
|
14285
|
+
" (or before the module: 'okx --json outcomes events'). Writing",
|
|
14286
|
+
" 'okx outcomes --json events' is not supported.",
|
|
14287
|
+
"",
|
|
14288
|
+
"Requires: curl -fsSL https://raw.githubusercontent.com/okx/outcomes-cli/main/install.sh | sh"
|
|
14289
|
+
];
|
|
14290
|
+
for (const line of lines) outputLine(line);
|
|
14291
|
+
}
|
|
14292
|
+
async function handleOutcomesCommand(action, rest, v) {
|
|
14293
|
+
if (!action || action === "--help" || action === "-h" || action === "help") {
|
|
14294
|
+
printOutcomesHelp();
|
|
14295
|
+
return;
|
|
14296
|
+
}
|
|
14297
|
+
const forwardArgs = [action, ...rest];
|
|
14298
|
+
if (v.json && !forwardArgs.includes("--json") && !forwardArgs.includes("-j")) {
|
|
14299
|
+
forwardArgs.push("--json");
|
|
14300
|
+
}
|
|
14301
|
+
const code = await runOkxOutcomes(forwardArgs);
|
|
14302
|
+
if (code !== 0) process.exitCode = code;
|
|
14303
|
+
}
|
|
14304
|
+
|
|
14127
14305
|
// src/commands/diagnose.ts
|
|
14128
14306
|
import dns from "dns/promises";
|
|
14129
14307
|
import net from "net";
|
|
@@ -14218,7 +14396,7 @@ function sanitize2(value) {
|
|
|
14218
14396
|
import fs5 from "fs";
|
|
14219
14397
|
import path4 from "path";
|
|
14220
14398
|
import os4 from "os";
|
|
14221
|
-
import { spawnSync, spawn as
|
|
14399
|
+
import { spawnSync, spawn as spawn5 } from "child_process";
|
|
14222
14400
|
import { createRequire as createRequire2 } from "module";
|
|
14223
14401
|
import { fileURLToPath } from "url";
|
|
14224
14402
|
var _require2 = createRequire2(import.meta.url);
|
|
@@ -14552,7 +14730,7 @@ async function checkStdioHandshake(entryPath, report) {
|
|
|
14552
14730
|
clearTimeout(timer);
|
|
14553
14731
|
resolve4(passed);
|
|
14554
14732
|
};
|
|
14555
|
-
const child =
|
|
14733
|
+
const child = spawn5(process.execPath, [entryPath], {
|
|
14556
14734
|
stdio: ["pipe", "pipe", "pipe"],
|
|
14557
14735
|
env: { ...process.env }
|
|
14558
14736
|
});
|
|
@@ -14671,7 +14849,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
14671
14849
|
|
|
14672
14850
|
// src/commands/diagnose.ts
|
|
14673
14851
|
var CLI_VERSION = readCliVersion();
|
|
14674
|
-
var GIT_HASH = true ? "
|
|
14852
|
+
var GIT_HASH = true ? "e2de3b7e" : "dev";
|
|
14675
14853
|
function maskKey2(key) {
|
|
14676
14854
|
if (!key) return "(not set)";
|
|
14677
14855
|
if (key.length <= 8) return "****";
|
|
@@ -15033,12 +15211,12 @@ function suggestSubcommand(action, knownActions, knownPaths = []) {
|
|
|
15033
15211
|
// src/commands/upgrade.ts
|
|
15034
15212
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
15035
15213
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync11 } from "fs";
|
|
15036
|
-
import { dirname as dirname8, join as
|
|
15214
|
+
import { dirname as dirname8, join as join16 } from "path";
|
|
15037
15215
|
import { homedir as homedir11 } from "os";
|
|
15038
15216
|
var PACKAGES = ["@okx_ai/okx-trade-mcp", "@okx_ai/okx-trade-cli"];
|
|
15039
|
-
var CACHE_FILE2 =
|
|
15217
|
+
var CACHE_FILE2 = join16(homedir11(), ".okx", "last_check");
|
|
15040
15218
|
var THROTTLE_MS = 12 * 60 * 60 * 1e3;
|
|
15041
|
-
var NPM_BIN =
|
|
15219
|
+
var NPM_BIN = join16(dirname8(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
|
|
15042
15220
|
function readLastCheck() {
|
|
15043
15221
|
try {
|
|
15044
15222
|
return parseInt(readFileSync11(CACHE_FILE2, "utf-8").trim(), 10) || 0;
|
|
@@ -15048,7 +15226,7 @@ function readLastCheck() {
|
|
|
15048
15226
|
}
|
|
15049
15227
|
function writeLastCheck() {
|
|
15050
15228
|
try {
|
|
15051
|
-
mkdirSync11(
|
|
15229
|
+
mkdirSync11(join16(homedir11(), ".okx"), { recursive: true });
|
|
15052
15230
|
writeFileSync8(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
|
|
15053
15231
|
} catch {
|
|
15054
15232
|
}
|
|
@@ -16209,6 +16387,68 @@ var CLI_REGISTRY = {
|
|
|
16209
16387
|
description: "Upgrade okx CLI and MCP server to the latest stable version",
|
|
16210
16388
|
usage: "okx upgrade [--check] [--beta] [--force] [--json]"
|
|
16211
16389
|
},
|
|
16390
|
+
// ── outcomes ───────────────────────────────────────────────────────────────
|
|
16391
|
+
// External binary wrapper - forwards to the okx-outcomes binary (formerly okx-predict).
|
|
16392
|
+
// All toolName=null because outcomes commands are not exposed as MCP tools.
|
|
16393
|
+
outcomes: {
|
|
16394
|
+
description: "OKX Outcomes markets (YES/NO event contracts) via external okx-outcomes binary",
|
|
16395
|
+
commands: {
|
|
16396
|
+
// Note: events / event / event-markets / market / trending / ticker /
|
|
16397
|
+
// candles live UNDER the `data` namespace in the upstream binary.
|
|
16398
|
+
// Calling them as top-level commands prints the binary's help text
|
|
16399
|
+
// instead of returning JSON. Always invoke as `okx outcomes data <cmd>`.
|
|
16400
|
+
data: {
|
|
16401
|
+
toolName: null,
|
|
16402
|
+
usage: "okx outcomes data <events|event|event-markets|market|trending|ticker|candles> [args...]",
|
|
16403
|
+
description: "Public market data namespace: events, event(-markets), market, trending, ticker, candles"
|
|
16404
|
+
},
|
|
16405
|
+
search: {
|
|
16406
|
+
toolName: null,
|
|
16407
|
+
usage: "okx outcomes search <keyword> [--limit <n>] [--cursor <c>]",
|
|
16408
|
+
description: "Search events/markets by keyword (OAuth)"
|
|
16409
|
+
},
|
|
16410
|
+
account: {
|
|
16411
|
+
toolName: null,
|
|
16412
|
+
usage: "okx outcomes account <balance|order|orders|positions|trades> (closed = positions --status closed)",
|
|
16413
|
+
description: "Account queries (OAuth)"
|
|
16414
|
+
},
|
|
16415
|
+
auth: {
|
|
16416
|
+
toolName: null,
|
|
16417
|
+
usage: "okx outcomes auth <login|refresh|status> [--manual] [--site global|us] [--json]",
|
|
16418
|
+
description: "OAuth sign-in / token refresh / session status (login --manual = agent-friendly device-code flow)"
|
|
16419
|
+
},
|
|
16420
|
+
clob: {
|
|
16421
|
+
toolName: null,
|
|
16422
|
+
usage: "okx outcomes clob <price|prices|midpoint|midpoints|spread|spreads|book|books|order|orders|trades|create-order|market-order|cancel-oid|cancel-all|heartbeat>",
|
|
16423
|
+
description: "CLOB market data (--asset) + EIP-712 signed order operations"
|
|
16424
|
+
},
|
|
16425
|
+
ctf: {
|
|
16426
|
+
toolName: null,
|
|
16427
|
+
usage: "okx outcomes ctf <split|merge|redeem> --market <id> [--amount <xp>]",
|
|
16428
|
+
description: "Conditional Token Framework: split xp into YES/NO, merge, redeem"
|
|
16429
|
+
},
|
|
16430
|
+
wallet: {
|
|
16431
|
+
toolName: null,
|
|
16432
|
+
usage: "okx outcomes wallet show",
|
|
16433
|
+
description: "Show derived wallet address (from the signing key)"
|
|
16434
|
+
},
|
|
16435
|
+
status: {
|
|
16436
|
+
toolName: null,
|
|
16437
|
+
usage: "okx outcomes status [--json]",
|
|
16438
|
+
description: "Health check: API + balance reachability"
|
|
16439
|
+
},
|
|
16440
|
+
setup: {
|
|
16441
|
+
toolName: null,
|
|
16442
|
+
usage: "okx outcomes setup [status|region|bind]",
|
|
16443
|
+
description: "Setup wizard (region -> OAuth sign-in -> wallet bind); subcommands: status/region/bind"
|
|
16444
|
+
},
|
|
16445
|
+
shell: {
|
|
16446
|
+
toolName: null,
|
|
16447
|
+
usage: "okx outcomes shell",
|
|
16448
|
+
description: "Interactive REPL (do not invoke from agent context)"
|
|
16449
|
+
}
|
|
16450
|
+
}
|
|
16451
|
+
},
|
|
16212
16452
|
// ── list-tools ──────────────────────────────────────────────────────────────
|
|
16213
16453
|
"list-tools": {
|
|
16214
16454
|
description: "List all available tools and their parameters (use --json for machine-readable output)",
|
|
@@ -17083,8 +17323,33 @@ function parseCli(argv) {
|
|
|
17083
17323
|
}
|
|
17084
17324
|
return { values, positionals };
|
|
17085
17325
|
}
|
|
17326
|
+
function peekFirstPositional(argv) {
|
|
17327
|
+
const booleanFlags = /* @__PURE__ */ new Set();
|
|
17328
|
+
for (const [name, opt] of Object.entries(CLI_OPTIONS)) {
|
|
17329
|
+
const o = opt;
|
|
17330
|
+
if (o.type === "boolean") {
|
|
17331
|
+
booleanFlags.add(name);
|
|
17332
|
+
if (o.short) booleanFlags.add(o.short);
|
|
17333
|
+
}
|
|
17334
|
+
}
|
|
17335
|
+
for (let i = 0; i < argv.length; i++) {
|
|
17336
|
+
const tok = argv[i];
|
|
17337
|
+
if (tok === "--") {
|
|
17338
|
+
const next2 = argv[i + 1];
|
|
17339
|
+
return next2 === void 0 ? void 0 : { module: next2, idx: i + 1 };
|
|
17340
|
+
}
|
|
17341
|
+
if (!tok.startsWith("-")) return { module: tok, idx: i };
|
|
17342
|
+
if (tok.includes("=")) continue;
|
|
17343
|
+
const name = tok.replace(/^--?/, "");
|
|
17344
|
+
if (booleanFlags.has(name)) continue;
|
|
17345
|
+
const next = argv[i + 1];
|
|
17346
|
+
if (next !== void 0 && !next.startsWith("-")) i++;
|
|
17347
|
+
}
|
|
17348
|
+
return void 0;
|
|
17349
|
+
}
|
|
17086
17350
|
|
|
17087
17351
|
// src/commands/market.ts
|
|
17352
|
+
var NO_INDICATOR_VALUES_HINT = "No indicator values returned. This indicator may require a period \u2014 try --params (e.g. --params 14).";
|
|
17088
17353
|
function getData2(result) {
|
|
17089
17354
|
return result.data;
|
|
17090
17355
|
}
|
|
@@ -17291,11 +17556,13 @@ function cmdMarketIndicatorList(json) {
|
|
|
17291
17556
|
}
|
|
17292
17557
|
async function cmdMarketIndicator(run, indicator, instId, opts) {
|
|
17293
17558
|
const params = opts.params ? opts.params.split(",").map((p) => Number(p.trim())).filter((n) => !Number.isNaN(n)) : void 0;
|
|
17559
|
+
const explicit = params && params.length > 0 ? params : void 0;
|
|
17560
|
+
const effectiveParams = explicit ?? getDefaultIndicatorParams(indicator);
|
|
17294
17561
|
const result = await run("market_get_indicator", {
|
|
17295
17562
|
instId,
|
|
17296
17563
|
indicator,
|
|
17297
17564
|
bar: opts.bar,
|
|
17298
|
-
params:
|
|
17565
|
+
params: effectiveParams,
|
|
17299
17566
|
returnList: opts.list ?? false,
|
|
17300
17567
|
limit: opts.limit,
|
|
17301
17568
|
backtestTime: opts.backtestTime
|
|
@@ -17303,7 +17570,7 @@ async function cmdMarketIndicator(run, indicator, instId, opts) {
|
|
|
17303
17570
|
const outerArray = getData2(result);
|
|
17304
17571
|
if (opts.json) return printJson(outerArray);
|
|
17305
17572
|
if (!outerArray?.length) {
|
|
17306
|
-
|
|
17573
|
+
outputLine("No data");
|
|
17307
17574
|
return;
|
|
17308
17575
|
}
|
|
17309
17576
|
const apiCode = resolveIndicatorCode(indicator);
|
|
@@ -17312,16 +17579,18 @@ async function cmdMarketIndicator(run, indicator, instId, opts) {
|
|
|
17312
17579
|
const instData = innerArray?.[0];
|
|
17313
17580
|
const timeframes = instData?.["timeframes"];
|
|
17314
17581
|
if (!timeframes) {
|
|
17315
|
-
|
|
17582
|
+
output(JSON.stringify(outerArray, null, 2) + "\n");
|
|
17316
17583
|
return;
|
|
17317
17584
|
}
|
|
17585
|
+
let printed = false;
|
|
17318
17586
|
for (const [tf, tfData] of Object.entries(timeframes)) {
|
|
17319
17587
|
const indicators = tfData?.["indicators"];
|
|
17320
17588
|
const values = indicators?.[apiCode];
|
|
17321
17589
|
if (!values?.length) continue;
|
|
17322
|
-
|
|
17590
|
+
printed = true;
|
|
17591
|
+
output(`${instId} | ${apiCode} | ${tf}
|
|
17323
17592
|
`);
|
|
17324
|
-
|
|
17593
|
+
output("-".repeat(40) + "\n");
|
|
17325
17594
|
if (opts.list) {
|
|
17326
17595
|
const tableRows = values.map((entry) => ({
|
|
17327
17596
|
ts: new Date(Number(entry["ts"])).toLocaleString(),
|
|
@@ -17336,6 +17605,7 @@ async function cmdMarketIndicator(run, indicator, instId, opts) {
|
|
|
17336
17605
|
});
|
|
17337
17606
|
}
|
|
17338
17607
|
}
|
|
17608
|
+
if (!printed) outputLine(NO_INDICATOR_VALUES_HINT);
|
|
17339
17609
|
}
|
|
17340
17610
|
async function cmdMarketInstrumentsByCategory(run, opts) {
|
|
17341
17611
|
const result = await run("market_get_instruments_by_category", {
|
|
@@ -17409,8 +17679,9 @@ async function cmdMarketFilter(run, opts) {
|
|
|
17409
17679
|
sortOrder: opts.sortOrder,
|
|
17410
17680
|
limit: opts.limit
|
|
17411
17681
|
});
|
|
17412
|
-
const
|
|
17413
|
-
if (opts.json) return printJson(
|
|
17682
|
+
const raw = getData2(result);
|
|
17683
|
+
if (opts.json) return printJson(raw);
|
|
17684
|
+
const data = Array.isArray(raw) ? raw[0] : raw;
|
|
17414
17685
|
const rows = data?.["rows"] ?? [];
|
|
17415
17686
|
const total = data?.["total"] ?? rows.length;
|
|
17416
17687
|
outputLine(`Total: ${total}`);
|
|
@@ -20567,20 +20838,20 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
20567
20838
|
|
|
20568
20839
|
// src/commands/skill.ts
|
|
20569
20840
|
import { tmpdir, homedir as homedir13 } from "os";
|
|
20570
|
-
import { join as
|
|
20571
|
-
import { mkdirSync as mkdirSync12, rmSync, existsSync as
|
|
20841
|
+
import { join as join18, dirname as dirname9 } from "path";
|
|
20842
|
+
import { mkdirSync as mkdirSync12, rmSync, existsSync as existsSync11, copyFileSync as copyFileSync2 } from "fs";
|
|
20572
20843
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
20573
20844
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
20574
20845
|
function resolveNpx() {
|
|
20575
|
-
const sibling =
|
|
20576
|
-
if (
|
|
20846
|
+
const sibling = join18(dirname9(process.execPath), "npx");
|
|
20847
|
+
if (existsSync11(sibling)) return sibling;
|
|
20577
20848
|
return "npx";
|
|
20578
20849
|
}
|
|
20579
20850
|
function npxEnv() {
|
|
20580
20851
|
return { ...process.env, NO_COLOR: "1", FORCE_COLOR: "0" };
|
|
20581
20852
|
}
|
|
20582
20853
|
function getSkillContentDir(name) {
|
|
20583
|
-
return
|
|
20854
|
+
return join18(homedir13(), ".agents", "skills", name);
|
|
20584
20855
|
}
|
|
20585
20856
|
var THIRD_PARTY_INSTALL_NOTICE = "Note: This skill was created by a third-party developer, not by OKX. Review SKILL.md before use.";
|
|
20586
20857
|
async function cmdSkillSearch(run, opts) {
|
|
@@ -20646,13 +20917,13 @@ async function wrapVerify(fn) {
|
|
|
20646
20917
|
async function cmdSkillAdd(name, config, json, force = false, exec = execFileSync2, _deps) {
|
|
20647
20918
|
const _download = _deps?.download ?? downloadSkillZip;
|
|
20648
20919
|
const _extract = _deps?.extract ?? extractSkillZip;
|
|
20649
|
-
const tmpBase =
|
|
20920
|
+
const tmpBase = join18(tmpdir(), `okx-skill-${randomUUID2()}`);
|
|
20650
20921
|
mkdirSync12(tmpBase, { recursive: true });
|
|
20651
20922
|
try {
|
|
20652
20923
|
outputLine(`Downloading ${name}...`);
|
|
20653
20924
|
const client = new OkxRestClient(config);
|
|
20654
20925
|
const zipPath = await _download(client, name, tmpBase);
|
|
20655
|
-
const contentDir = await _extract(zipPath,
|
|
20926
|
+
const contentDir = await _extract(zipPath, join18(tmpBase, "content"));
|
|
20656
20927
|
const meta = readMetaJson(contentDir);
|
|
20657
20928
|
validateSkillMdExists(contentDir);
|
|
20658
20929
|
outputLine("Verifying signature...");
|
|
@@ -20689,7 +20960,7 @@ async function cmdSkillAdd(name, config, json, force = false, exec = execFileSyn
|
|
|
20689
20960
|
env: npxEnv()
|
|
20690
20961
|
});
|
|
20691
20962
|
} catch (e) {
|
|
20692
|
-
const savedZip =
|
|
20963
|
+
const savedZip = join18(process.cwd(), `${name}.zip`);
|
|
20693
20964
|
try {
|
|
20694
20965
|
copyFileSync2(zipPath, savedZip);
|
|
20695
20966
|
} catch {
|
|
@@ -20802,7 +21073,7 @@ async function cmdSkillVerify(name, config, json) {
|
|
|
20802
21073
|
return;
|
|
20803
21074
|
}
|
|
20804
21075
|
const contentDir = getSkillContentDir(name);
|
|
20805
|
-
if (!
|
|
21076
|
+
if (!existsSync11(contentDir)) {
|
|
20806
21077
|
errorLine(`Skill content directory not found: ${contentDir}`);
|
|
20807
21078
|
errorLine(`Try reinstalling with: okx skill add ${name}`);
|
|
20808
21079
|
process.exitCode = 1;
|
|
@@ -21467,7 +21738,7 @@ async function cmdEventCancel(run, opts) {
|
|
|
21467
21738
|
// src/index.ts
|
|
21468
21739
|
var _require3 = createRequire3(import.meta.url);
|
|
21469
21740
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
21470
|
-
var GIT_HASH2 = true ? "
|
|
21741
|
+
var GIT_HASH2 = true ? "e2de3b7e" : "dev";
|
|
21471
21742
|
function handlePilotCommand(action, json, force, binaryPath) {
|
|
21472
21743
|
if (action === "status") return cmdPilotStatus(json, binaryPath);
|
|
21473
21744
|
if (action === "install") return cmdPilotInstall(json, binaryPath);
|
|
@@ -22949,7 +23220,16 @@ async function main() {
|
|
|
22949
23220
|
err: (m) => process.stderr.write(m)
|
|
22950
23221
|
});
|
|
22951
23222
|
checkForUpdates("@okx_ai/okx-trade-cli", CLI_VERSION2);
|
|
22952
|
-
const
|
|
23223
|
+
const rawArgv = process.argv.slice(2);
|
|
23224
|
+
const peek = peekFirstPositional(rawArgv);
|
|
23225
|
+
if (peek?.module === "outcomes") {
|
|
23226
|
+
const after = rawArgv.slice(peek.idx + 1);
|
|
23227
|
+
const action2 = after[0];
|
|
23228
|
+
const rest2 = after.slice(1);
|
|
23229
|
+
const json2 = rawArgv.includes("--json") || rawArgv.includes("-j");
|
|
23230
|
+
return handleOutcomesCommand(action2, rest2, { json: json2 });
|
|
23231
|
+
}
|
|
23232
|
+
const { values, positionals } = parseCli(rawArgv);
|
|
22953
23233
|
if (values.version) {
|
|
22954
23234
|
printVersion();
|
|
22955
23235
|
return;
|