@@ -17,5 +17,8 @@ "use strict"; | ||
| json: core_1.Flags.boolean({ description: "Output raw response data as JSON." }), | ||
| "base-url": core_1.Flags.string({ description: "PMXT API base URL. Defaults to the hosted PMXT API." }), | ||
| local: core_1.Flags.boolean({ description: "Use a local PMXT instance." }), | ||
| hosted: core_1.Flags.boolean({ description: "Use the hosted PMXT API." }), | ||
| "base-url": core_1.Flags.string({ description: "Advanced: override the PMXT API base URL." }), | ||
| "pmxt-api-key": core_1.Flags.string({ description: "PMXT API key. Precedence: flags > env > auth store. Env: PMXT_API_KEY." }), | ||
| "auth-store": core_1.Flags.string({ description: "Path to a PMXT CLI auth store JSON file." }), | ||
| "no-suggest-hosted": core_1.Flags.boolean({ description: "Do not show hosted PMXT suggestions when using local mode." }), | ||
| }; | ||
@@ -22,0 +25,0 @@ exports.credentialFlags = { |
+11
-2
@@ -18,2 +18,7 @@ "use strict"; | ||
| MODES | ||
| Hosted PMXT is used when an API key is configured. | ||
| Without hosted auth, commands use a local PMXT instance. | ||
| Use --hosted or --local to force a mode. | ||
| COMMON COMMANDS | ||
@@ -37,7 +42,9 @@ pmxt <exchange> markets Search markets | ||
| pmxt enterprise Run Enterprise matched-market and SQL commands | ||
| pmxt server Manage an installed local pmxt-core sidecar | ||
| pmxt server Manage a local PMXT instance | ||
| FLAGS | ||
| --pmxt-api-key <key> One-shot hosted PMXT API key | ||
| --base-url <url> Override PMXT API base URL | ||
| --local Use a local PMXT instance | ||
| --hosted Use the hosted PMXT API | ||
| --base-url <url> Advanced PMXT API base URL override | ||
| --json Print raw JSON | ||
@@ -48,2 +55,4 @@ --help Show command help | ||
| pmxt polymarket markets --query Trump --limit 5 | ||
| pmxt polymarket markets --local --query Trump --limit 5 | ||
| pmxt polymarket markets --hosted --query Trump --limit 5 | ||
| pmxt kalshi events --query "NBA" --limit 5 --json | ||
@@ -50,0 +59,0 @@ pmxt polymarket orderbook <outcome-id> --limit 20 |
+133
-13
@@ -48,6 +48,7 @@ "use strict"; | ||
| const constants_js_1 = require("./constants.js"); | ||
| const server_manager_js_1 = require("./server-manager.js"); | ||
| exports.ALLOWED_EXCHANGES = new Set([ | ||
| "polymarket", "kalshi", "kalshi-demo", "limitless", "probable", "baozi", | ||
| "myriad", "opinion", "metaculus", "smarkets", "polymarket_us", | ||
| "gemini-titan", "hyperliquid", "mock", "router", | ||
| "gemini-titan", "hyperliquid", "suibets", "mock", "router", | ||
| ]); | ||
@@ -282,4 +283,14 @@ exports.ALLOWED_VENUE_METHODS = new Set([ | ||
| const pmxtApiKey = firstString(flags["pmxt-api-key"], env.PMXT_API_KEY, store.pmxtApiKey, store.pmxt?.apiKey); | ||
| const baseUrl = trimTrailingSlash(firstString(flags["base-url"], env.PMXT_BASE_URL, store.baseUrl, store.pmxt?.baseUrl) ?? constants_js_1.HOSTED_URL); | ||
| return { baseUrl, exchange, pmxtApiKey, credentials: resolveCredentials(flags, env, store, exchange, options) }; | ||
| const explicitBaseUrl = firstString(flags["base-url"], env.PMXT_BASE_URL, store.baseUrl, store.pmxt?.baseUrl); | ||
| const local = Boolean(flags.local); | ||
| const hosted = Boolean(flags.hosted); | ||
| if (local && hosted) { | ||
| throw new Error("Choose either --local or --hosted, not both."); | ||
| } | ||
| if (explicitBaseUrl && (local || hosted)) { | ||
| throw new Error("Use either --base-url or --local/--hosted, not both."); | ||
| } | ||
| const mode = explicitBaseUrl ? "custom" : local ? "local" : hosted || pmxtApiKey ? "hosted" : "local"; | ||
| const baseUrl = trimTrailingSlash(explicitBaseUrl ?? (mode === "local" ? constants_js_1.LOCAL_URL : constants_js_1.HOSTED_URL)); | ||
| return { baseUrl, exchange, mode, pmxtApiKey, credentials: resolveCredentials(flags, env, store, exchange, options) }; | ||
| } | ||
@@ -293,3 +304,10 @@ function assertAllowedMethod(method, allowed, label) { | ||
| function authHeaders(config) { | ||
| return config.pmxtApiKey ? { Authorization: `Bearer ${config.pmxtApiKey}` } : {}; | ||
| const headers = {}; | ||
| if (shouldSendHostedAuth(config)) { | ||
| headers.Authorization = `Bearer ${config.pmxtApiKey}`; | ||
| } | ||
| if (config.localAccessToken) { | ||
| headers["x-pmxt-access-token"] = config.localAccessToken; | ||
| } | ||
| return headers; | ||
| } | ||
@@ -303,15 +321,117 @@ function responseErrorMessage(parsed, fallback) { | ||
| const message = responseErrorMessage(parsed, response.statusText); | ||
| if (config.mode === "local") { | ||
| return [ | ||
| `Local PMXT rejected the request: ${message ?? "missing or invalid local access token"}.`, | ||
| "", | ||
| `Endpoint: ${config.baseUrl}`, | ||
| "", | ||
| "Try restarting the local PMXT instance:", | ||
| " pmxt server restart", | ||
| "", | ||
| "Or use hosted PMXT:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted", | ||
| ].join("\n"); | ||
| } | ||
| const heading = config.mode === "hosted" | ||
| ? "Hosted PMXT needs an API key" | ||
| : "PMXT endpoint needs authentication"; | ||
| return [ | ||
| `Unauthorized: ${message ?? "the PMXT API key was missing or rejected"}.`, | ||
| `${heading}: ${message ?? "the key was missing or rejected"}.`, | ||
| "", | ||
| `Endpoint: ${config.baseUrl}`, | ||
| "", | ||
| "Fix one of these ways:", | ||
| "Hosted:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " PMXT_API_KEY=<pmxt_api_key> pmxt <exchange> <command>", | ||
| " pmxt <exchange> <command> --pmxt-api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted --pmxt-api-key <pmxt_api_key>", | ||
| "", | ||
| "Check current auth with: pmxt auth status", | ||
| "Local:", | ||
| " pmxt <exchange> <command> --local", | ||
| " npm install -g pmxt-core", | ||
| "", | ||
| "Check auth with: pmxt auth status", | ||
| ].join("\n"); | ||
| } | ||
| function hostedMissingAuthMessage(config) { | ||
| return authErrorMessage({ statusText: "missing api key" }, { error: { message: "missing api key" } }, config); | ||
| } | ||
| function localUnavailableMessage(error) { | ||
| const detail = error instanceof Error ? error.message : String(error); | ||
| return [ | ||
| "Local PMXT instance is not available.", | ||
| "", | ||
| detail, | ||
| "", | ||
| "Use hosted PMXT instead:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted", | ||
| "", | ||
| "Hosted PMXT is faster for indexed search, router matches, and enterprise data.", | ||
| ].join("\n"); | ||
| } | ||
| function isLoopbackUrl(baseUrl) { | ||
| try { | ||
| const parsed = new URL(baseUrl); | ||
| return parsed.protocol === "http:" | ||
| && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "::1"); | ||
| } | ||
| catch { | ||
| return false; | ||
| } | ||
| } | ||
| function shouldSendHostedAuth(config) { | ||
| if (!config.pmxtApiKey || config.mode === "local") | ||
| return false; | ||
| return config.mode === "hosted" || !isLoopbackUrl(config.baseUrl); | ||
| } | ||
| async function prepareRuntimeConfig(config, flags = {}, env = process.env) { | ||
| if (config.mode === "hosted" && config.baseUrl === constants_js_1.HOSTED_URL && !config.pmxtApiKey) { | ||
| throw new Error(hostedMissingAuthMessage(config)); | ||
| } | ||
| if (config.mode === "local") { | ||
| const manager = new server_manager_js_1.ServerManager(); | ||
| try { | ||
| await manager.ensureServerRunning(); | ||
| } | ||
| catch (error) { | ||
| throw new Error(localUnavailableMessage(error)); | ||
| } | ||
| maybeSuggestHosted(flags, env); | ||
| return { | ||
| ...config, | ||
| baseUrl: `http://localhost:${manager.getRunningPort()}`, | ||
| localAccessToken: manager.getAccessToken(), | ||
| }; | ||
| } | ||
| return config; | ||
| } | ||
| function shouldSuggestHosted(flags = {}, env = process.env) { | ||
| if (flags.json || flags["no-suggest-hosted"]) | ||
| return false; | ||
| if (env.CI || env.PMXT_NO_SUGGEST_HOSTED || env.PMXT_CLI_NO_SUGGEST_HOSTED) | ||
| return false; | ||
| return Boolean(process.stderr.isTTY); | ||
| } | ||
| function maybeSuggestHosted(flags = {}, env = process.env) { | ||
| if (!shouldSuggestHosted(flags, env)) | ||
| return; | ||
| const hintPath = path.join(env.HOME || os.homedir(), ".pmxt", "cli-hints.json"); | ||
| try { | ||
| const parsed = fs.existsSync(hintPath) ? JSON.parse(fs.readFileSync(hintPath, "utf8")) : {}; | ||
| if (parsed.suggestedHosted) | ||
| return; | ||
| fs.mkdirSync(path.dirname(hintPath), { recursive: true, mode: 0o700 }); | ||
| fs.writeFileSync(hintPath, `${JSON.stringify({ ...parsed, suggestedHosted: new Date().toISOString() }, null, 2)}\n`, { mode: 0o600 }); | ||
| } | ||
| catch { | ||
| // Hint persistence is best-effort. | ||
| } | ||
| process.stderr.write([ | ||
| "Using local PMXT instance.", | ||
| "Hosted PMXT is faster for indexed search, router matches, and enterprise data:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| "", | ||
| ].join("\n")); | ||
| } | ||
| function throwForResponse(response, parsed, config) { | ||
@@ -390,5 +510,5 @@ if (response.status === 401 || response.status === 403) { | ||
| assertAllowedMethod(method, exports.ALLOWED_VENUE_METHODS, "venue"); | ||
| const config = resolveRuntimeConfig(flags, process.env, undefined, { | ||
| const config = await prepareRuntimeConfig(resolveRuntimeConfig(flags, process.env, undefined, { | ||
| ignoreAmbientCredentials: PUBLIC_READ_METHODS.has(method) && !hasExplicitCredentialInput(flags), | ||
| }); | ||
| }), flags); | ||
| return postJson(`${config.baseUrl}/api/${config.exchange}/${method}`, { args, credentials: config.credentials }, config); | ||
@@ -398,3 +518,3 @@ } | ||
| assertAllowedMethod(method, exports.ALLOWED_ROUTER_METHODS, "router"); | ||
| const config = resolveRuntimeConfig(flags, process.env, "router"); | ||
| const config = await prepareRuntimeConfig(resolveRuntimeConfig(flags, process.env, "router"), flags); | ||
| return postJson(`${config.baseUrl}/api/router/${method}`, { args, credentials: config.credentials }, config); | ||
@@ -405,7 +525,7 @@ } | ||
| throw new Error(`Enterprise path must start with /v0/: ${path}`); | ||
| const config = resolveRuntimeConfig(flags); | ||
| const config = await prepareRuntimeConfig(resolveRuntimeConfig(flags), flags); | ||
| return getJson(`${config.baseUrl}${path}`, params, config); | ||
| } | ||
| async function runEnterpriseSql(query, flags = {}) { | ||
| const config = resolveRuntimeConfig(flags); | ||
| const config = await prepareRuntimeConfig(resolveRuntimeConfig(flags), flags); | ||
| return postJson(`${config.baseUrl}/v0/sql`, { query }, config); | ||
@@ -412,0 +532,0 @@ } |
@@ -6,5 +6,5 @@ "use strict"; | ||
| const { existsSync, readFileSync, unlinkSync } = require("node:fs"); | ||
| const { accessSync, constants: fsConstants, existsSync, readFileSync, unlinkSync } = require("node:fs"); | ||
| const { homedir } = require("node:os"); | ||
| const { dirname, join } = require("node:path"); | ||
| const { delimiter, dirname, join } = require("node:path"); | ||
| const { spawn } = require("node:child_process"); | ||
@@ -96,2 +96,5 @@ | ||
| const launcherPath = this.resolveLauncherPath(); | ||
| if (!launcherPath) { | ||
| throw new Error(localInstallMessage()); | ||
| } | ||
| const spawnCmd = launcherPath.endsWith(".js") ? process.execPath : launcherPath; | ||
@@ -101,4 +104,10 @@ const spawnArgs = launcherPath.endsWith(".js") ? [launcherPath] : []; | ||
| try { | ||
| const proc = spawn(spawnCmd, spawnArgs, { detached: true, stdio: "ignore" }); | ||
| proc.unref(); | ||
| await new Promise((resolve, reject) => { | ||
| const proc = spawn(spawnCmd, spawnArgs, { detached: true, stdio: "ignore" }); | ||
| proc.once("error", reject); | ||
| proc.once("spawn", () => { | ||
| proc.unref(); | ||
| resolve(); | ||
| }); | ||
| }); | ||
| await this.waitForServer(); | ||
@@ -108,5 +117,5 @@ } catch (error) { | ||
| throw new Error([ | ||
| `Failed to start PMXT local server: ${detail}`, | ||
| `Failed to start local PMXT instance: ${detail}`, | ||
| "", | ||
| "Local server commands require pmxt-core to be installed.", | ||
| "Local PMXT commands require pmxt-core to be installed.", | ||
| "Install it with: npm install -g pmxt-core", | ||
@@ -127,3 +136,3 @@ "Or use the hosted API with: pmxt auth login --api-key <pmxt_api_key>", | ||
| } | ||
| return launcherName; | ||
| return findExecutableOnPath(launcherName); | ||
| } | ||
@@ -221,2 +230,38 @@ | ||
| function findExecutableOnPath(command) { | ||
| const pathValue = process.env.PATH || ""; | ||
| const extensions = process.platform === "win32" | ||
| ? (process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM").split(";") | ||
| : [""]; | ||
| const candidates = process.platform === "win32" && !/\.[^\\/]+$/.test(command) | ||
| ? extensions.map((ext) => `${command}${ext}`) | ||
| : [command]; | ||
| for (const dir of pathValue.split(delimiter)) { | ||
| if (!dir) continue; | ||
| for (const name of candidates) { | ||
| const candidate = join(dir, name); | ||
| try { | ||
| accessSync(candidate, fsConstants.X_OK); | ||
| return candidate; | ||
| } catch { | ||
| // Keep searching. | ||
| } | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| function localInstallMessage() { | ||
| return [ | ||
| "Local PMXT is not installed.", | ||
| "", | ||
| "Install the local runtime:", | ||
| " npm install -g pmxt-core", | ||
| "", | ||
| "Or use hosted PMXT:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted", | ||
| ].join("\n"); | ||
| } | ||
| exports.ServerManager = ServerManager; |
+6
-6
@@ -37,19 +37,19 @@ "use strict"; | ||
| case "start": | ||
| return "PMXT server started"; | ||
| return "Local PMXT instance started"; | ||
| case "stop": | ||
| return "PMXT server stopped"; | ||
| return "Local PMXT instance stopped"; | ||
| case "restart": | ||
| return "PMXT server restarted"; | ||
| return "Local PMXT instance restarted"; | ||
| case "status": | ||
| return formatStatus(result); | ||
| case "health": | ||
| return result.healthy ? "PMXT server healthy" : "PMXT server unhealthy"; | ||
| return result.healthy ? "Local PMXT instance healthy" : "Local PMXT instance unhealthy"; | ||
| case "logs": | ||
| return result.lines.length > 0 | ||
| ? result.lines.join("\n") | ||
| : "No PMXT server logs found"; | ||
| : "No local PMXT logs found"; | ||
| } | ||
| } | ||
| function formatStatus(status) { | ||
| const lines = [`PMXT server ${status.running ? "running" : "stopped"}`]; | ||
| const lines = [`Local PMXT instance ${status.running ? "running" : "stopped"}`]; | ||
| if (status.pid !== null) | ||
@@ -56,0 +56,0 @@ lines.push(`pid: ${status.pid}`); |
+103
-13
@@ -42,5 +42,11 @@ "use strict"; | ||
| "base-url": core_1.Flags.string({ | ||
| description: "PMXT API base URL", | ||
| description: "Advanced: override the PMXT API base URL", | ||
| env: constants_js_1.ENV.BASE_URL, | ||
| }), | ||
| local: core_1.Flags.boolean({ | ||
| description: "Use a local PMXT instance", | ||
| }), | ||
| hosted: core_1.Flags.boolean({ | ||
| description: "Use the hosted PMXT API", | ||
| }), | ||
| "pmxt-api-key": core_1.Flags.string({ | ||
@@ -50,2 +56,5 @@ description: "Hosted PMXT API key", | ||
| }), | ||
| "no-suggest-hosted": core_1.Flags.boolean({ | ||
| description: "Do not show hosted PMXT suggestions when using local mode", | ||
| }), | ||
| }; | ||
@@ -142,2 +151,4 @@ exports.feedHttpFlags = { | ||
| baseUrl: runtime.baseUrl, | ||
| mode: runtime.mode, | ||
| noSuggestHosted: Boolean(flags["no-suggest-hosted"]), | ||
| ...(runtime.pmxtApiKey ? { pmxtApiKey: runtime.pmxtApiKey } : {}), | ||
@@ -148,6 +159,25 @@ ...(options.targetKind === "exchange" && runtime.credentials ? { exchangeCredentials: runtime.credentials } : {}), | ||
| async function fetchPmxtData(pathname, credentials, query = {}) { | ||
| const resolved = (0, constants_js_1.resolvePmxtBaseUrl)({ | ||
| let resolved = (0, constants_js_1.resolvePmxtBaseUrl)({ | ||
| baseUrl: credentials.baseUrl, | ||
| pmxtApiKey: credentials.pmxtApiKey, | ||
| }); | ||
| let localAccessToken; | ||
| if (credentials.mode === "hosted" && resolved.isHosted && !resolved.pmxtApiKey) { | ||
| throw new Error(authErrorMessage("missing api key", resolved.baseUrl, credentials.mode)); | ||
| } | ||
| if (resolved.baseUrl === constants_js_1.LOCAL_URL || credentials.mode === "local") { | ||
| const manager = new server_manager_js_1.ServerManager(); | ||
| try { | ||
| await manager.ensureServerRunning(); | ||
| } | ||
| catch (error) { | ||
| throw new Error(localUnavailableMessage(error)); | ||
| } | ||
| resolved = { | ||
| ...resolved, | ||
| baseUrl: `http://localhost:${manager.getRunningPort()}`, | ||
| isHosted: false, | ||
| }; | ||
| localAccessToken = manager.getAccessToken(); | ||
| } | ||
| const url = new URL(pathname, ensureTrailingSlash(resolved.baseUrl)); | ||
@@ -160,3 +190,6 @@ for (const [key, value] of Object.entries(query)) { | ||
| const response = await fetch(url, { | ||
| headers: resolved.pmxtApiKey ? { Authorization: `Bearer ${resolved.pmxtApiKey}` } : {}, | ||
| headers: { | ||
| ...(shouldSendHostedAuth(resolved, credentials.mode) ? { Authorization: `Bearer ${resolved.pmxtApiKey}` } : {}), | ||
| ...(localAccessToken ? { "x-pmxt-access-token": localAccessToken } : {}), | ||
| }, | ||
| signal: AbortSignal.timeout(30_000), | ||
@@ -167,3 +200,3 @@ }); | ||
| if (response.status === 401 || response.status === 403) { | ||
| throw new Error(authErrorMessage(errorMessage(body) || response.statusText, resolved.baseUrl)); | ||
| throw new Error(authErrorMessage(errorMessage(body) || response.statusText, resolved.baseUrl, credentials.mode)); | ||
| } | ||
@@ -281,3 +314,3 @@ throw new Error(errorMessage(body) || response.statusText); | ||
| if (!resolved.pmxtApiKey) { | ||
| throw new Error(authErrorMessage("missing api key", resolved.baseUrl)); | ||
| throw new Error(authErrorMessage("missing api key", resolved.baseUrl, credentials.mode)); | ||
| } | ||
@@ -288,5 +321,10 @@ return { | ||
| } | ||
| if (resolved.baseUrl === constants_js_1.LOCAL_URL) { | ||
| if (resolved.baseUrl === constants_js_1.LOCAL_URL || credentials.mode === "local") { | ||
| const manager = new server_manager_js_1.ServerManager(); | ||
| await manager.ensureServerRunning(); | ||
| try { | ||
| await manager.ensureServerRunning(); | ||
| } | ||
| catch (error) { | ||
| throw new Error(localUnavailableMessage(error)); | ||
| } | ||
| const token = manager.getAccessToken(); | ||
@@ -298,3 +336,7 @@ const baseUrl = `http://localhost:${manager.getRunningPort()}`; | ||
| } | ||
| return { url: buildWebSocketUrl(resolved.baseUrl) }; | ||
| return { | ||
| url: buildWebSocketUrl(resolved.baseUrl, shouldSendHostedAuth(resolved, credentials.mode) | ||
| ? { name: "apiKey", value: resolved.pmxtApiKey } | ||
| : undefined), | ||
| }; | ||
| } | ||
@@ -310,2 +352,17 @@ function clean(value) { | ||
| } | ||
| function isLoopbackUrl(baseUrl) { | ||
| try { | ||
| const parsed = new URL(baseUrl); | ||
| return parsed.protocol === "http:" | ||
| && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "::1"); | ||
| } | ||
| catch { | ||
| return false; | ||
| } | ||
| } | ||
| function shouldSendHostedAuth(resolved, mode) { | ||
| if (!resolved.pmxtApiKey || mode === "local") | ||
| return false; | ||
| return resolved.isHosted || !isLoopbackUrl(resolved.baseUrl); | ||
| } | ||
| function envPrefix(value) { | ||
@@ -324,16 +381,49 @@ return (value || "EXCHANGE").replace(/[^a-zA-Z0-9]/g, "_").toUpperCase(); | ||
| } | ||
| function authErrorMessage(message, baseUrl) { | ||
| function authErrorMessage(message, baseUrl, mode = "hosted") { | ||
| if (mode === "local") { | ||
| return [ | ||
| `Local PMXT rejected the request: ${message || "missing or invalid local access token"}.`, | ||
| "", | ||
| `Endpoint: ${baseUrl}`, | ||
| "", | ||
| "Try restarting the local PMXT instance:", | ||
| " pmxt server restart", | ||
| "", | ||
| "Or use hosted PMXT:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted", | ||
| ].join("\n"); | ||
| } | ||
| const heading = mode === "hosted" ? "Hosted PMXT needs an API key" : "PMXT endpoint needs authentication"; | ||
| return [ | ||
| `Unauthorized: ${message || "the PMXT API key was missing or rejected"}.`, | ||
| `${heading}: ${message || "the key was missing or rejected"}.`, | ||
| "", | ||
| `Endpoint: ${baseUrl}`, | ||
| "", | ||
| "Fix one of these ways:", | ||
| "Hosted:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " PMXT_API_KEY=<pmxt_api_key> pmxt <exchange> <command>", | ||
| " pmxt <exchange> <command> --pmxt-api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted --pmxt-api-key <pmxt_api_key>", | ||
| "", | ||
| "Check current auth with: pmxt auth status", | ||
| "Local:", | ||
| " pmxt <exchange> <command> --local", | ||
| " npm install -g pmxt-core", | ||
| "", | ||
| "Check auth with: pmxt auth status", | ||
| ].join("\n"); | ||
| } | ||
| function localUnavailableMessage(error) { | ||
| const detail = error instanceof Error ? error.message : String(error); | ||
| return [ | ||
| "Local PMXT instance is not available.", | ||
| "", | ||
| detail, | ||
| "", | ||
| "Use hosted PMXT instead:", | ||
| " pmxt auth login --api-key <pmxt_api_key>", | ||
| " pmxt <exchange> <command> --hosted", | ||
| "", | ||
| "Hosted PMXT is faster for indexed search, router matches, and enterprise data.", | ||
| ].join("\n"); | ||
| } | ||
| function getStoreBuckets(store, profile, options) { | ||
@@ -340,0 +430,0 @@ const buckets = []; |
@@ -8,4 +8,4 @@ "use strict"; | ||
| static enableJsonFlag = true; | ||
| static summary = "Check PMXT sidecar server health"; | ||
| static description = "Check whether the PMXT sidecar server is healthy without starting it."; | ||
| static summary = "Check local PMXT instance health"; | ||
| static description = "Check whether the local PMXT instance is healthy without starting it."; | ||
| async run() { | ||
@@ -12,0 +12,0 @@ await this.parse(ServerHealth); |
@@ -8,4 +8,4 @@ "use strict"; | ||
| static enableJsonFlag = true; | ||
| static summary = "Show PMXT sidecar server logs"; | ||
| static description = "Show recent PMXT sidecar server log lines."; | ||
| static summary = "Show local PMXT instance logs"; | ||
| static description = "Show recent local PMXT instance log lines."; | ||
| static flags = { | ||
@@ -12,0 +12,0 @@ lines: core_1.Flags.integer({ |
@@ -8,4 +8,4 @@ "use strict"; | ||
| static enableJsonFlag = true; | ||
| static summary = "Restart the PMXT sidecar server"; | ||
| static description = "Stop the current PMXT sidecar server, then start it again."; | ||
| static summary = "Restart the local PMXT instance"; | ||
| static description = "Stop the current local PMXT instance, then start it again."; | ||
| async run() { | ||
@@ -12,0 +12,0 @@ await this.parse(ServerRestart); |
@@ -8,4 +8,4 @@ "use strict"; | ||
| static enableJsonFlag = true; | ||
| static summary = "Start the PMXT sidecar server"; | ||
| static description = "Start the PMXT sidecar server if it is not already running."; | ||
| static summary = "Start the local PMXT instance"; | ||
| static description = "Start the local PMXT instance if it is not already running."; | ||
| async run() { | ||
@@ -12,0 +12,0 @@ await this.parse(ServerStart); |
@@ -8,4 +8,4 @@ "use strict"; | ||
| static enableJsonFlag = true; | ||
| static summary = "Show PMXT sidecar server status"; | ||
| static description = "Show the current PMXT sidecar server status without starting it."; | ||
| static summary = "Show local PMXT instance status"; | ||
| static description = "Show the current local PMXT instance status without starting it."; | ||
| async run() { | ||
@@ -12,0 +12,0 @@ await this.parse(ServerStatus); |
@@ -8,4 +8,4 @@ "use strict"; | ||
| static enableJsonFlag = true; | ||
| static summary = "Stop the PMXT sidecar server"; | ||
| static description = "Stop the PMXT sidecar server and clean up the server lock file."; | ||
| static summary = "Stop the local PMXT instance"; | ||
| static description = "Stop the local PMXT instance and clean up the server lock file."; | ||
| async run() { | ||
@@ -12,0 +12,0 @@ await this.parse(ServerStop); |
+3
-3
| { | ||
| "name": "@pmxt/cli", | ||
| "version": "2.46.0", | ||
| "version": "2.46.1", | ||
| "description": "Command-line interface for PMXT prediction market APIs", | ||
@@ -41,3 +41,3 @@ "author": "PMXT Contributors", | ||
| "server": { | ||
| "description": "Manage an installed local pmxt-core sidecar." | ||
| "description": "Manage a local PMXT instance." | ||
| }, | ||
@@ -58,3 +58,3 @@ "watch": { | ||
| "prepack": "npm run build", | ||
| "test": "node scripts/validate.js && node scripts/verify-argv-alias-normalizer.js && node scripts/verify-root-help.js && node scripts/verify-runtime-errors.js" | ||
| "test": "node scripts/validate.js && node scripts/verify-argv-alias-normalizer.js && node scripts/verify-root-help.js && node scripts/verify-runtime-errors.js && node scripts/verify-feed-cli.js && node scripts/verify-enterprise-cli.js && node scripts/verify-production-copy.js" | ||
| }, | ||
@@ -61,0 +61,0 @@ "keywords": [ |
+7
-4
@@ -19,3 +19,3 @@ # @pmxt/cli | ||
| Hosted PMXT API calls require a PMXT API key: | ||
| PMXT uses hosted mode when an API key is configured. Without hosted auth, commands use a local PMXT instance. | ||
@@ -54,10 +54,13 @@ ```bash | ||
| PMXT_API_KEY=pmxt_... pmxt markets --limit 5 | ||
| pmxt markets --pmxt-api-key pmxt_... --limit 5 | ||
| pmxt markets --hosted --pmxt-api-key pmxt_... --limit 5 | ||
| ``` | ||
| Local sidecar usage is explicit: | ||
| Local usage is explicit when you want to force it: | ||
| ```bash | ||
| npm install -g pmxt-core | ||
| pmxt server status | ||
| pmxt markets --base-url http://localhost:3847 --limit 5 | ||
| pmxt markets --local --limit 5 | ||
| ``` | ||
| Use `--base-url` only for custom PMXT deployments. |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
265221
4.05%6761
4.06%65
4.84%28
21.74%