@kashdao/cli 0.1.0

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/CONTRIBUTING.md +159 -0
  3. package/LICENSE +21 -0
  4. package/README.md +868 -0
  5. package/SECURITY.md +110 -0
  6. package/dist/account-AVFLEM5D.js +90 -0
  7. package/dist/account-AVFLEM5D.js.map +1 -0
  8. package/dist/auth-GUJCVKTD.js +239 -0
  9. package/dist/auth-GUJCVKTD.js.map +1 -0
  10. package/dist/chunk-BN2CUM42.js +9 -0
  11. package/dist/chunk-BN2CUM42.js.map +1 -0
  12. package/dist/chunk-BRK7KJ4O.js +154 -0
  13. package/dist/chunk-BRK7KJ4O.js.map +1 -0
  14. package/dist/chunk-KMBMQIZ7.js +393 -0
  15. package/dist/chunk-KMBMQIZ7.js.map +1 -0
  16. package/dist/chunk-LBIRQHX5.js +133 -0
  17. package/dist/chunk-LBIRQHX5.js.map +1 -0
  18. package/dist/chunk-MIXOZU2S.js +366 -0
  19. package/dist/chunk-MIXOZU2S.js.map +1 -0
  20. package/dist/chunk-QJMF73M5.js +129 -0
  21. package/dist/chunk-QJMF73M5.js.map +1 -0
  22. package/dist/chunk-UZNSYATZ.js +680 -0
  23. package/dist/chunk-UZNSYATZ.js.map +1 -0
  24. package/dist/chunk-VIADBYFY.js +94 -0
  25. package/dist/chunk-VIADBYFY.js.map +1 -0
  26. package/dist/chunk-YHCG2SUC.js +159 -0
  27. package/dist/chunk-YHCG2SUC.js.map +1 -0
  28. package/dist/chunk-YJX3JJ4M.js +174 -0
  29. package/dist/chunk-YJX3JJ4M.js.map +1 -0
  30. package/dist/client-IOM55ZCS.js +14 -0
  31. package/dist/client-IOM55ZCS.js.map +1 -0
  32. package/dist/completion-ZZGX5BQC.js +100 -0
  33. package/dist/completion-ZZGX5BQC.js.map +1 -0
  34. package/dist/config-XJL5TSYK.js +690 -0
  35. package/dist/config-XJL5TSYK.js.map +1 -0
  36. package/dist/config-store-3ZSYGXMQ.js +44 -0
  37. package/dist/config-store-3ZSYGXMQ.js.map +1 -0
  38. package/dist/docs-MDKKSJDC.js +102 -0
  39. package/dist/docs-MDKKSJDC.js.map +1 -0
  40. package/dist/eoa-IQ72EIHR.js +551 -0
  41. package/dist/eoa-IQ72EIHR.js.map +1 -0
  42. package/dist/errors-WMZIEGQI.js +18 -0
  43. package/dist/errors-WMZIEGQI.js.map +1 -0
  44. package/dist/explain-H4EH3KH3.js +165 -0
  45. package/dist/explain-H4EH3KH3.js.map +1 -0
  46. package/dist/global-options-XOLJUPTT.js +18 -0
  47. package/dist/global-options-XOLJUPTT.js.map +1 -0
  48. package/dist/health-VZEIII74.js +98 -0
  49. package/dist/health-VZEIII74.js.map +1 -0
  50. package/dist/help-footer-GTANVDNP.js +43 -0
  51. package/dist/help-footer-GTANVDNP.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.js +251 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/intro-PQQTYWR7.js +41 -0
  56. package/dist/intro-PQQTYWR7.js.map +1 -0
  57. package/dist/markets-C37JZDPE.js +295 -0
  58. package/dist/markets-C37JZDPE.js.map +1 -0
  59. package/dist/output-VCBZ3FM7.js +22 -0
  60. package/dist/output-VCBZ3FM7.js.map +1 -0
  61. package/dist/portfolio-2AEPIJIG.js +115 -0
  62. package/dist/portfolio-2AEPIJIG.js.map +1 -0
  63. package/dist/protocol-XEQXF2GW.js +1572 -0
  64. package/dist/protocol-XEQXF2GW.js.map +1 -0
  65. package/dist/quote-I4DVJ7ZB.js +144 -0
  66. package/dist/quote-I4DVJ7ZB.js.map +1 -0
  67. package/dist/schema-PIFQ65TS.js +410 -0
  68. package/dist/schema-PIFQ65TS.js.map +1 -0
  69. package/dist/setup-USZ6IODD.js +260 -0
  70. package/dist/setup-USZ6IODD.js.map +1 -0
  71. package/dist/stdin-YW2CEQXU.js +28 -0
  72. package/dist/stdin-YW2CEQXU.js.map +1 -0
  73. package/dist/trace-IZBYTUFO.js +103 -0
  74. package/dist/trace-IZBYTUFO.js.map +1 -0
  75. package/dist/trade-IIZSEXEI.js +586 -0
  76. package/dist/trade-IIZSEXEI.js.map +1 -0
  77. package/dist/version-JDK3PEP5.js +117 -0
  78. package/dist/version-JDK3PEP5.js.map +1 -0
  79. package/dist/version-check-TDCION37.js +138 -0
  80. package/dist/version-check-TDCION37.js.map +1 -0
  81. package/dist/webhooks-PTVRKICZ.js +680 -0
  82. package/dist/webhooks-PTVRKICZ.js.map +1 -0
  83. package/dist/with-retry-4FIZG3A7.js +223 -0
  84. package/dist/with-retry-4FIZG3A7.js.map +1 -0
  85. package/package.json +99 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/trade/index.ts","../src/commands/trade/buy.ts","../src/commands/trade/place.ts","../src/commands/trade/confirm.ts","../src/commands/trade/list.ts","../src/commands/trade/sell.ts","../src/commands/trade/status.ts"],"sourcesContent":["/**\n * `kash trade` — place and manage trades.\n *\n * Every subcommand requires authentication: trades are written to a\n * specific actor (user or organization) determined by the API key's\n * scope. The buy/sell helpers honor `--wait` so scripts can block on\n * settlement without rolling their own poller.\n */\n\nimport { Command } from 'commander';\n\nimport { buyCommand } from './buy.js';\nimport { confirmCommand } from './confirm.js';\nimport { listTradesCommand } from './list.js';\nimport { sellCommand } from './sell.js';\nimport { statusCommand } from './status.js';\n\nexport const tradeCommand = new Command('trade')\n .description('Place trades and inspect their status.')\n .addCommand(buyCommand)\n .addCommand(sellCommand)\n .addCommand(statusCommand)\n .addCommand(listTradesCommand)\n .addCommand(confirmCommand);\n","/**\n * `kash trade buy <marketId>` — purchase outcome tokens.\n */\n\nimport { Command } from 'commander';\n\nimport { readGlobals } from '../../utils/global-options.js';\n\nimport { placeTrade, type PlaceTradeOptions } from './place.js';\n\nexport const buyCommand = new Command('buy')\n .description('Buy outcome tokens for a market.')\n .argument('<marketId>', 'market UUID')\n .requiredOption('-o, --outcome <index>', 'outcome index (0-based)')\n .requiredOption('-a, --amount <usdc>', 'USDC amount as a decimal (max 6 fractional digits)')\n .option('--wait', 'block until the trade reaches a terminal state')\n .option(\n '--wait-timeout-ms, --timeout <ms>',\n 'wait timeout in milliseconds (default 60000) — distinct from the global --timeout-ms (per-HTTP-request)'\n )\n .option(\n '--poll-interval-ms, --poll-interval <ms>',\n 'wait poll interval in milliseconds (default 2000)'\n )\n .option('--idempotency-key <key>', 'sets the Idempotency-Key HTTP header')\n .option(\n '--auto-idempotency-key',\n 'auto-generate an Idempotency-Key (UUID v4) and surface it in the response'\n )\n .option('--client-request-id <id>', 'sets the body-level clientRequestId for replay safety')\n .option(\n '--dry-run',\n 'preview the request without sending — emits the would-be body and resolved headers'\n )\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash trade buy 9f0b... --outcome 0 --amount 10\n $ kash trade buy 9f0b... --outcome 1 --amount 25 --wait\n $ kash trade buy 9f0b... --outcome 0 --amount 5 --auto-idempotency-key --json --quiet\n $ kash trade buy 9f0b... --outcome 0 --amount 10 --dry-run --json\n`\n )\n .action(async (marketId: string, options: PlaceTradeOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n await placeTrade({ marketId, side: 'buy', options, globals });\n });\n","/**\n * Shared \"place a trade\" implementation for `buy` and `sell`.\n *\n * The two commands differ only in the `side` field, so the heavy\n * lifting — input validation, idempotency wiring, optional polling,\n * 202-confirmation rendering — lives here.\n */\n\nimport ora from 'ora';\n\nimport { CliValidationError, toCliError } from '../../errors.js';\nimport { buildClient } from '../../utils/client.js';\nimport { capitalize, colorStatus, formatUsdcDecimal, shortId } from '../../utils/formatting.js';\nimport { parsePositiveInt } from '../../utils/global-options.js';\nimport { isQuiet, log, print, printJson, style } from '../../utils/output.js';\nimport { parseOutcomeIndex, validateUsdcDecimalShape } from '../../utils/trade-input.js';\n\nimport type { GlobalOptions } from '../../utils/global-options.js';\nimport type { KashClient, TradeResource, TradeSide } from '@kashdao/sdk';\n\nexport type PlaceTradeOptions = {\n outcome: string;\n amount: string;\n wait?: boolean;\n idempotencyKey?: string;\n autoIdempotencyKey?: boolean;\n clientRequestId?: string;\n timeout?: string;\n pollInterval?: string;\n dryRun?: boolean;\n};\n\nexport type PlaceTradeArgs = {\n marketId: string;\n side: TradeSide;\n options: PlaceTradeOptions;\n globals: GlobalOptions;\n};\n\nexport async function placeTrade({\n marketId,\n side,\n options,\n globals,\n}: PlaceTradeArgs): Promise<void> {\n const json = globals.json;\n // marketId is enforced as a required positional by Commander; no\n // defensive check needed here. Same for --outcome / --amount, which\n // are `requiredOption`s — but we re-validate their *values* (range,\n // format) below since Commander only enforces presence.\n // Markets carry 2-8 outcomes (per @kashdao/constants), so a valid\n // outcome index is in [0, 7]. Bouncing out-of-range values here\n // gives the agent INVALID_INPUT with a clear field name, instead of\n // a server-side `KashValidationError` half a round-trip later.\n const outcomeIndex = parseOutcomeIndex(options.outcome);\n const amount = options.amount?.trim();\n if (!amount) {\n throw new CliValidationError(\n '--amount is required.',\n 'Use a USDC decimal like \"10\" or \"12.50\".'\n );\n }\n // Shape-only validator — public-API mode ships the decimal string\n // verbatim to the SDK rather than converting to atomic units, so we\n // only need the shape pin here. `validateUsdcDecimalShape` is the\n // shared primitive that backs `decimalToAtomicUsdc` in SA/EOA mode.\n validateUsdcDecimalShape(amount, 'amount');\n\n const timeoutMs = options.timeout ? parsePositiveInt(options.timeout, 'timeout') : 60_000;\n const pollIntervalMs = options.pollInterval\n ? parsePositiveInt(options.pollInterval, 'poll-interval')\n : 2_000;\n\n // Resolve idempotency key. Explicit --idempotency-key wins; otherwise\n // --auto-idempotency-key generates a UUID v4. The resolved value is\n // surfaced on the response so an agent that retries a transient\n // failure can re-use the same key.\n let resolvedIdempotencyKey = options.idempotencyKey;\n if (resolvedIdempotencyKey === undefined && options.autoIdempotencyKey) {\n // `@kashdao/cli` is a published npm package and cannot depend on\n // workspace-only `@kashdao/utils`. `crypto.randomUUID()` is the\n // right primitive here.\n // eslint-disable-next-line no-restricted-properties\n resolvedIdempotencyKey = crypto.randomUUID();\n if (!json) {\n log.detail('Generated Idempotency-Key', resolvedIdempotencyKey);\n }\n }\n\n // --dry-run short-circuits before the network call. We still validate\n // inputs (above) and resolve the idempotency key so the envelope\n // accurately reflects what a real invocation would send. Crucially,\n // we do NOT instantiate the SDK client — `buildClient` would fail on\n // a missing API key, but a dry-run preview should work without auth\n // so agents can plan trades against an unconfigured profile.\n if (options.dryRun === true) {\n const wouldSend = {\n marketId,\n outcomeIndex,\n amount,\n side,\n ...(options.clientRequestId === undefined\n ? {}\n : { clientRequestId: options.clientRequestId }),\n };\n const envelope = {\n wouldSend,\n idempotencyKey: resolvedIdempotencyKey ?? null,\n endpoint: { method: 'POST' as const, path: '/v1/trades' as const },\n };\n if (json) {\n printJson(envelope);\n return;\n }\n print('');\n print(style.bold('Dry run — no request sent.'));\n print(` ${style.dim('Endpoint ')} POST /v1/trades`);\n print(` ${style.dim('Market ')} ${marketId}`);\n print(` ${style.dim('Side ')} ${side}`);\n print(` ${style.dim('Outcome ')} ${String(outcomeIndex)}`);\n print(` ${style.dim('Amount ')} ${amount} USDC`);\n if (options.clientRequestId !== undefined) {\n print(` ${style.dim('Client req ')} ${options.clientRequestId}`);\n }\n if (resolvedIdempotencyKey !== undefined) {\n print(` ${style.dim('Idem. key ')} ${resolvedIdempotencyKey}`);\n }\n print('');\n print(style.dim('Re-run without --dry-run to submit.'));\n return;\n }\n\n let response;\n try {\n const { client } = await buildClient({ requireAuth: true, globals });\n response = await client.trades.create(\n {\n marketId,\n outcomeIndex,\n amount,\n side,\n ...(options.clientRequestId === undefined\n ? {}\n : { clientRequestId: options.clientRequestId }),\n },\n resolvedIdempotencyKey === undefined ? {} : { idempotencyKey: resolvedIdempotencyKey }\n );\n\n // Attach the idempotency key (if we generated one) so agents that\n // retry can re-use it. Empty when neither flag was provided.\n const augment = <T extends object>(payload: T): T & { idempotencyKey?: string } =>\n resolvedIdempotencyKey === undefined\n ? (payload as T & { idempotencyKey?: string })\n : { ...payload, idempotencyKey: resolvedIdempotencyKey };\n\n // The flat result (TradeResource + idempotent + optional confirmation) —\n // see SDK's `TradeCreateResult`.\n if (response.confirmation) {\n if (json) {\n printJson(augment(response));\n return;\n }\n log.warn(\n 'High-value trade — server returned 202. Confirm with `kash trade confirm <id> <token>`.'\n );\n print(` ${style.dim('Trade id ')} ${response.id}`);\n print(` ${style.dim('Status ')} ${colorStatus(response.status)}`);\n print(` ${style.dim('Token ')} ${response.confirmation.token}`);\n print(` ${style.dim('Expires ')} ${response.confirmation.expiresAt}`);\n return;\n }\n\n if (!options.wait) {\n if (json) {\n printJson(augment(response));\n return;\n }\n log.success(\n `${capitalize(side)} accepted${response.idempotent ? ' (idempotent replay)' : ''}: ${shortId(response.id)}`\n );\n print(` ${style.dim('Trade id ')} ${response.id}`);\n print(` ${style.dim('Status ')} ${colorStatus(response.status)}`);\n print(` ${style.dim('Amount ')} ${formatUsdcDecimal(response.amount)}`);\n log.info(\"Run 'kash trade status <id> --poll' to follow it to completion.\");\n return;\n }\n\n // --wait: poll until terminal. Partial-completion guard: the\n // `client.trades.create` above already succeeded — `response.id`\n // is server-assigned and the trade exists in the API. If the\n // poll fails (timeout, transient network), surface the id so\n // the operator can resume via `kash trade status <id> --poll`\n // instead of losing the pointer to a created-but-unconfirmed\n // trade. Symmetric to the SA-mode userop / EOA-mode tx hash\n // partial-completion seams.\n let completed: TradeResource;\n try {\n completed = await waitForCompletion(client, response, {\n timeoutMs,\n pollIntervalMs,\n json,\n });\n } catch (waitCause) {\n if (json) {\n printJson({\n id: response.id,\n status: response.status,\n waited: false,\n partial: true,\n });\n } else {\n log.warn(\n `Trade created but poll did not reach a terminal state. Resume with: kash trade status ${response.id} --poll`\n );\n }\n throw waitCause;\n }\n\n if (json) {\n printJson(augment({ ...completed, idempotent: response.idempotent, waited: true }));\n return;\n }\n renderTerminal(completed);\n } catch (cause) {\n throw toCliError(cause);\n }\n}\n\nasync function waitForCompletion(\n client: KashClient,\n initial: TradeResource,\n opts: { timeoutMs: number; pollIntervalMs: number; json: boolean }\n): Promise<TradeResource> {\n // Wire SIGINT/SIGTERM to abort the in-flight poll cleanly. The\n // shape mirrors `trade status --poll`: register on entry, unwire\n // in the finally block. Without this, Ctrl-C during a 60s wait\n // leaves the in-flight HTTP request stranded — process tear-down\n // works via the global SIGPIPE handler but the SDK fetch never\n // sees the cancellation.\n const ac = new AbortController();\n const onSig = (): void => ac.abort();\n process.on('SIGINT', onSig);\n process.on('SIGTERM', onSig);\n try {\n if (opts.json || isQuiet()) {\n return await client.trades.waitForCompletion(initial.id, {\n timeoutMs: opts.timeoutMs,\n pollIntervalMs: opts.pollIntervalMs,\n signal: ac.signal,\n });\n }\n const spinner = ora({\n text: `Waiting for trade ${shortId(initial.id)}…`,\n stream: process.stderr,\n }).start();\n try {\n const completed = await client.trades.waitForCompletion(initial.id, {\n timeoutMs: opts.timeoutMs,\n pollIntervalMs: opts.pollIntervalMs,\n signal: ac.signal,\n onStatus: (trade) => {\n spinner.text = `Trade ${shortId(trade.id)} — status: ${trade.status}`;\n },\n });\n if (completed.status === 'completed') {\n spinner.succeed(`Trade ${shortId(completed.id)} completed.`);\n } else {\n spinner.fail(`Trade ${shortId(completed.id)} ${completed.status}.`);\n }\n return completed;\n } catch (cause) {\n spinner.fail('Polling stopped.');\n throw cause;\n }\n } finally {\n process.off('SIGINT', onSig);\n process.off('SIGTERM', onSig);\n }\n}\n\nfunction renderTerminal(trade: TradeResource): void {\n print('');\n print(` ${style.dim('Trade id ')} ${trade.id}`);\n print(` ${style.dim('Status ')} ${colorStatus(trade.status)}`);\n print(` ${style.dim('Amount ')} ${formatUsdcDecimal(trade.amount)}`);\n // Use explicit null checks for nullable fields rather than truthy\n // checks. `if (trade.errorMessage)` would silently hide a literal\n // empty-string error (`\"\"`), which the API can return for \"errored\n // but with no human message.\" Same for `tokensOut`/`txHash`: `\"0\"`\n // is a valid string but `Boolean(\"0\") === true`, so truthy checks\n // happen to work today but are accidentally correct.\n if (trade.txHash !== null) {\n print(` ${style.dim('Tx hash ')} ${trade.txHash}`);\n }\n if (trade.tokensOut !== null) {\n print(` ${style.dim('Tokens out ')} ${trade.tokensOut}`);\n }\n if (trade.errorMessage !== null || trade.errorCode !== null) {\n print(\n ` ${style.dim('Error ')} [${trade.errorCode ?? 'UNKNOWN'}] ${trade.errorMessage ?? ''}`\n );\n log.info(`Inspect the full timeline: kash trace ${trade.correlationId}`);\n }\n}\n\n// `parseOutcomeIndex` and `validateUsdcDecimalShape` live in\n// `utils/trade-input.ts` — single source of truth across SA, EOA,\n// and public-API modes. Imports at the top of this file.\n","/**\n * `kash trade confirm <id> [token]` — confirm a high-value trade.\n *\n * High-value trades come back from `POST /v1/trades` with HTTP 202 and\n * a one-time confirmation token. This command POSTs that token to\n * `/v1/trades/{id}/confirm` to release the trade for execution.\n *\n * Token input is sensitive (a captured token plus the trade id is\n * sufficient to release real money), so we support three input\n * paths that don't taint shell history:\n *\n * 1. Positional `<token>` — convenient, but lands in `~/.bash_history`.\n * Kept for backward compat.\n * 2. `--token-stdin` — pipe a token (the natural shape after\n * capturing the 202 envelope into a file or secret store).\n * 3. Interactive prompt — TTY only, prompt goes to stderr so the\n * stdout pipe stays clean.\n */\n\nimport { Command } from 'commander';\n\nimport { CliValidationError, toCliError } from '../../errors.js';\nimport { buildClient } from '../../utils/client.js';\nimport { colorStatus, formatUsdcDecimal } from '../../utils/formatting.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, print, printJson, style } from '../../utils/output.js';\n\ntype ConfirmOptions = {\n tokenStdin?: boolean;\n};\n\nexport const confirmCommand = new Command('confirm')\n .description('Confirm a high-value trade using its one-time token.')\n .argument('<id>', 'trade UUID')\n .argument('[token]', 'confirmation token (omit to read from stdin or prompt)')\n .option('--token-stdin', 'read the confirmation token from stdin')\n .addHelpText(\n 'after',\n `\nExamples:\n # Interactive prompt (no shell history footprint).\n $ kash trade confirm 9f0b...\n\n # Pipe from a captured token.\n $ cat token.txt | kash trade confirm 9f0b... --token-stdin\n\n # Positional (convenient but shows up in ~/.bash_history).\n $ kash trade confirm 9f0b... eyJ...\n $ kash trade confirm 9f0b... eyJ... --json --quiet\n`\n )\n .action(\n async (id: string, positional: string | undefined, options: ConfirmOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n const token = await resolveToken(positional, options);\n\n let trade;\n try {\n const { client } = await buildClient({ requireAuth: true, globals });\n trade = await client.trades.confirm(id, { token });\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson(trade);\n return;\n }\n\n log.success(`Trade ${trade.id} confirmed.`);\n print(` ${style.dim('Status ')} ${colorStatus(trade.status)}`);\n print(` ${style.dim('Amount ')} ${formatUsdcDecimal(trade.amount)}`);\n log.info(\"Run 'kash trade status <id> --poll' to follow it to completion.\");\n }\n );\n\nasync function resolveToken(\n positional: string | undefined,\n options: ConfirmOptions\n): Promise<string> {\n // Mutual-exclusion guard: `kash trade confirm <id> <token> --token-stdin`\n // would silently take the positional and drop the piped value.\n // That's a real footgun on a real-money path — refuse to guess.\n if (positional !== undefined && positional !== '' && options.tokenStdin === true) {\n throw new CliValidationError(\n 'Pass either the positional [token] OR --token-stdin, not both.',\n 'The positional token would silently win and the piped value would be dropped.',\n 'token'\n );\n }\n if (positional !== undefined && positional !== '') {\n return positional;\n }\n if (options.tokenStdin === true) {\n // BOM-aware read — see `utils/stdin.ts` for rationale.\n const { readStdinTrimmed } = await import('../../utils/stdin.js');\n return readStdinTrimmed();\n }\n if (process.stdin.isTTY) {\n // Use the masked-input prompt — confirmation tokens are sensitive\n // (a captured token + the trade id is enough to release real\n // money) and `readline.question` would echo every keystroke.\n const { password } = await import('@inquirer/prompts');\n const answer = await password({\n message: 'Paste the confirmation token:',\n mask: '*',\n });\n return answer.trim();\n }\n throw new CliValidationError(\n 'No confirmation token provided.',\n 'Pass the token positionally, use --token-stdin to read it from a pipe, or run interactively for a prompt.',\n 'token'\n );\n}\n","/**\n * `kash trade list` — list the authenticating user's trades.\n *\n * Status filter is forwarded as-is to the API (the API accepts\n * comma-separated multiplicities, e.g. `pending,completed`).\n */\n\nimport { Command } from 'commander';\n\nimport { CliValidationError, toCliError } from '../../errors.js';\nimport { buildClient } from '../../utils/client.js';\nimport { colorStatus, createTable, formatUsdcDecimal, shortId } from '../../utils/formatting.js';\nimport { parsePositiveInt, readGlobals } from '../../utils/global-options.js';\nimport { log, print, printJson, writeNdjson } from '../../utils/output.js';\n\nimport type { TradeResource } from '@kashdao/sdk';\n\ntype ListOptions = {\n status?: readonly string[];\n market?: string;\n limit?: string;\n cursor?: string;\n all?: boolean;\n ndjson?: boolean;\n};\n\nexport const listTradesCommand = new Command('list')\n .description('List your trades.')\n .option(\n '-s, --status <status...>',\n 'status filter; repeat or comma-separate (e.g. --status pending --status executing | --status pending,executing)'\n )\n .option('-m, --market <id>', 'filter by market id')\n .option('-l, --limit <n>', 'page size (1-100)', '20')\n .option('-c, --cursor <cursor>', 'pagination cursor')\n .option('-a, --all', 'walk every page (use with --json for export)')\n .option(\n '--ndjson',\n 'stream results as newline-delimited JSON (one record per line); implies --all'\n )\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash trade list\n $ kash trade list --status pending,executing --json --quiet\n $ kash trade list --status pending --status executing --json --quiet\n $ kash trade list --market 9f0b... --json --quiet | jq '.data[] | select(.status==\"completed\")'\n $ kash trade list --all --ndjson | while read -r line; do echo \"$line\" | jq -r .id; done\n`\n )\n .action(async (options: ListOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n const limit = options.limit === undefined ? 20 : parsePositiveInt(options.limit, 'limit');\n if (limit < 1 || limit > 100) {\n throw new CliValidationError('--limit must be between 1 and 100.', undefined, 'limit');\n }\n\n // Normalise --status: accept both `--status a,b,c` (single comma-string)\n // and `--status a --status b` (repeated). Both collapse to the\n // same comma-string the API expects. Mirrors `webhooks list`.\n const status = normaliseStatus(options.status);\n\n let response;\n try {\n const { client } = await buildClient({ requireAuth: true, globals });\n response = await client.trades.list({\n limit,\n ...(options.cursor === undefined ? {} : { cursor: options.cursor }),\n ...(status === undefined ? {} : { status }),\n ...(options.market === undefined ? {} : { marketId: options.market }),\n });\n\n if (options.ndjson) {\n for await (const trade of response) {\n writeNdjson(trade);\n }\n return;\n }\n\n if (options.all) {\n const collected: TradeResource[] = [];\n for await (const trade of response) collected.push(trade);\n if (globals.json) {\n // Canonical `{data, pagination, count}` — see markets/list.ts\n // for rationale. Same shape across single-page and walked\n // modes lets agents pin to one schema.\n printJson({\n data: collected,\n pagination: { hasMore: false, cursor: null },\n count: collected.length,\n });\n } else {\n renderTable(collected);\n }\n return;\n }\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson({\n data: response.data,\n pagination: response.pagination,\n count: response.data.length,\n });\n return;\n }\n\n if (response.data.length === 0) {\n log.info('No trades matched the filter.');\n return;\n }\n renderTable(response.data);\n\n if (response.pagination.hasMore && response.pagination.cursor) {\n log.detail('Next page', `--cursor ${response.pagination.cursor}`);\n }\n });\n\n/**\n * Flatten + dedupe `--status`. Each entry may itself be a comma list.\n * Returns the canonical comma-string the API expects, or `undefined`\n * when no values were supplied (preserving the \"no filter\" default).\n */\nfunction normaliseStatus(raw: readonly string[] | undefined): string | undefined {\n if (!raw || raw.length === 0) return undefined;\n const seen = new Set<string>();\n for (const entry of raw) {\n for (const piece of entry.split(',')) {\n const trimmed = piece.trim();\n if (trimmed.length > 0) seen.add(trimmed);\n }\n }\n return seen.size === 0 ? undefined : [...seen].join(',');\n}\n\nfunction renderTable(trades: readonly TradeResource[]): void {\n const table = createTable(['Trade', 'Market', 'Side', 'Out#', 'Amount', 'Status', 'Tx']);\n for (const t of trades) {\n table.push([\n shortId(t.id),\n shortId(t.marketId),\n t.side,\n String(t.outcomeIndex),\n formatUsdcDecimal(t.amount),\n colorStatus(t.status),\n t.txHash ? shortId(t.txHash, 10) : '-',\n ]);\n }\n print(table.toString());\n}\n","/**\n * `kash trade sell <marketId>` — sell outcome tokens back to the AMM.\n */\n\nimport { Command } from 'commander';\n\nimport { readGlobals } from '../../utils/global-options.js';\n\nimport { placeTrade, type PlaceTradeOptions } from './place.js';\n\nexport const sellCommand = new Command('sell')\n .description('Sell outcome tokens back to the market (Kash-orchestrated / hosted-API flow).')\n .argument('<marketId>', 'market UUID')\n .requiredOption('-o, --outcome <index>', 'outcome index (0-based)')\n .requiredOption(\n '-a, --amount <usdc>',\n 'target USDC to receive (decimal, max 6 fractional digits) — NOT tokens-in. ' +\n 'Use `kash quote sell --tokens <n>` if you have a tokens-in figure and want a USDC quote first.'\n )\n .option('--wait', 'block until the trade reaches a terminal state')\n .option(\n '--wait-timeout-ms, --timeout <ms>',\n 'wait timeout in milliseconds (default 60000) — distinct from the global --timeout-ms (per-HTTP-request)'\n )\n .option(\n '--poll-interval-ms, --poll-interval <ms>',\n 'wait poll interval in milliseconds (default 2000)'\n )\n .option('--idempotency-key <key>', 'sets the Idempotency-Key HTTP header')\n .option(\n '--auto-idempotency-key',\n 'auto-generate an Idempotency-Key (UUID v4) and surface it in the response'\n )\n .option('--client-request-id <id>', 'sets the body-level clientRequestId for replay safety')\n .option(\n '--dry-run',\n 'preview the request without sending — emits the would-be body and resolved headers'\n )\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash trade sell 9f0b... --outcome 0 --amount 10 # target $10 USDC out\n $ kash trade sell 9f0b... --outcome 1 --amount 25 --wait\n $ kash trade sell 9f0b... --outcome 0 --amount 5 --auto-idempotency-key --json --quiet\n $ kash trade sell 9f0b... --outcome 0 --amount 10 --dry-run --json\n\nNotes:\n --amount is in USDC for both buy AND sell:\n BUY — USDC you spend (input).\n SELL — USDC you target receiving (output).\n This is the API contract, not a CLI choice — \\`kash quote sell --tokens N\\`\n takes a tokens-in figure if that's the shape you have on hand.\n`\n )\n .action(async (marketId: string, options: PlaceTradeOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n await placeTrade({ marketId, side: 'sell', options, globals });\n });\n","/**\n * `kash trade status <id>` — fetch a single trade. With `--poll`, block\n * until the trade reaches a terminal state (uses the SDK's polling\n * helper).\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\n\nimport { toCliError } from '../../errors.js';\nimport { buildClient } from '../../utils/client.js';\nimport { colorStatus, formatDate, formatUsdcDecimal, shortId } from '../../utils/formatting.js';\nimport { parsePositiveInt, readGlobals } from '../../utils/global-options.js';\nimport { isQuiet, log, print, printJson, style } from '../../utils/output.js';\n\nimport type { TradeResource } from '@kashdao/sdk';\n\ntype StatusOptions = {\n poll?: boolean;\n timeout?: string;\n pollInterval?: string;\n};\n\nexport const statusCommand = new Command('status')\n .description('Show the status of a trade. Use --poll to block until terminal.')\n .argument('<id>', 'trade UUID')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash trade status 9f0b...\n $ kash trade status 9f0b... --poll\n $ kash trade status 9f0b... --poll --json --quiet | jq -r '.txHash'\n`\n )\n .option('--poll', 'poll until the trade reaches a terminal state')\n .option(\n '--wait-timeout-ms, --timeout <ms>',\n 'poll timeout in milliseconds (default 60000) — distinct from the global --timeout-ms (per-HTTP-request)'\n )\n .option(\n '--poll-interval-ms, --poll-interval <ms>',\n 'poll interval in milliseconds (default 2000)'\n )\n .action(async (id: string, options: StatusOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n let trade: TradeResource;\n try {\n const { client } = await buildClient({ requireAuth: true, globals });\n if (options.poll) {\n const timeoutMs = options.timeout ? parsePositiveInt(options.timeout, 'timeout') : 60_000;\n const pollIntervalMs = options.pollInterval\n ? parsePositiveInt(options.pollInterval, 'poll-interval')\n : 2_000;\n\n // Wire SIGINT/SIGTERM to abort the in-flight poll cleanly.\n // Without this, Ctrl-C during a 60s wait leaves the SDK\n // mid-fetch — the polling loop's own signal-handler tears\n // down the process, but any in-flight HTTP request stays\n // unaborted. Pattern mirrors `kash protocol watch`.\n const ac = new AbortController();\n const onSig = (): void => ac.abort();\n process.on('SIGINT', onSig);\n process.on('SIGTERM', onSig);\n try {\n if (globals.json || isQuiet()) {\n trade = await client.trades.waitForCompletion(id, {\n timeoutMs,\n pollIntervalMs,\n signal: ac.signal,\n });\n } else {\n const spinner = ora({\n text: `Polling trade ${shortId(id)}…`,\n stream: process.stderr,\n }).start();\n try {\n trade = await client.trades.waitForCompletion(id, {\n timeoutMs,\n pollIntervalMs,\n signal: ac.signal,\n onStatus: (current) => {\n spinner.text = `Trade ${shortId(current.id)} — status: ${current.status}`;\n },\n });\n if (trade.status === 'completed') {\n spinner.succeed(`Trade ${shortId(trade.id)} completed.`);\n } else {\n spinner.fail(`Trade ${shortId(trade.id)} ${trade.status}.`);\n }\n } catch (cause) {\n spinner.fail('Polling stopped.');\n throw cause;\n }\n }\n } finally {\n process.off('SIGINT', onSig);\n process.off('SIGTERM', onSig);\n }\n } else {\n trade = await client.trades.get(id);\n }\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson(trade);\n return;\n }\n\n print('');\n print(` ${style.dim('Trade id ')} ${trade.id}`);\n print(` ${style.dim('Market id ')} ${trade.marketId}`);\n print(` ${style.dim('Side ')} ${trade.side}`);\n print(` ${style.dim('Outcome idx ')} ${String(trade.outcomeIndex)}`);\n print(` ${style.dim('Amount ')} ${formatUsdcDecimal(trade.amount)}`);\n print(` ${style.dim('Status ')} ${colorStatus(trade.status)}`);\n // Use explicit null checks rather than truthy checks — empty\n // strings are valid SDK values that we'd otherwise silently hide.\n if (trade.txHash !== null) {\n print(` ${style.dim('Tx hash ')} ${trade.txHash}`);\n }\n if (trade.tokensOut !== null) {\n print(` ${style.dim('Tokens out ')} ${trade.tokensOut}`);\n }\n if (trade.errorCode !== null || trade.errorMessage !== null) {\n print(\n ` ${style.dim('Error ')} [${trade.errorCode ?? 'UNKNOWN'}] ${trade.errorMessage ?? ''}`\n );\n // Cross-link to the correlation timeline so an operator\n // diagnosing a failure can see every event the API and the\n // execution engine emitted for this trade.\n log.info(`Inspect the full timeline: kash trace ${trade.correlationId}`);\n }\n print(` ${style.dim('Created ')} ${formatDate(trade.createdAt)}`);\n print(` ${style.dim('Updated ')} ${formatDate(trade.updatedAt)}`);\n if (trade.webhookDelivery !== null) {\n // Surface webhook delivery state when present — agents and\n // humans both need this to debug \"did the integration receive\n // the event?\" without dropping into JSON mode.\n const wh = trade.webhookDelivery;\n const failure = wh.lastFailureCode === null ? '' : ` (${wh.lastFailureCode})`;\n const httpStatus = wh.lastStatusCode === null ? '' : ` HTTP ${String(wh.lastStatusCode)}`;\n print(\n ` ${style.dim('Webhook ')} ${colorStatus(wh.status)} attempts=${String(wh.attempts)}${httpStatus}${failure}`\n );\n if (wh.lastAttemptedAt !== null) {\n print(` ${style.dim(' Last try ')} ${formatDate(wh.lastAttemptedAt)}`);\n }\n }\n if (trade.status === 'pending_confirmation') {\n log.warn('Trade is awaiting high-value confirmation. Run `kash trade confirm <id> <token>`.');\n }\n });\n"],"mappings":"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","names":["Command","Command","Command","Command","Command","Command","Command","Command","ora","Command","ora","Command"]}
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ CLI_VERSION
4
+ } from "./chunk-BN2CUM42.js";
5
+ import {
6
+ readGlobals
7
+ } from "./chunk-LBIRQHX5.js";
8
+ import {
9
+ print,
10
+ printJson,
11
+ style
12
+ } from "./chunk-VIADBYFY.js";
13
+ import "./chunk-MIXOZU2S.js";
14
+ import "./chunk-UZNSYATZ.js";
15
+
16
+ // src/commands/version.ts
17
+ import { createRequire } from "module";
18
+ import { arch, platform, release } from "os";
19
+ import { Command } from "commander";
20
+ var ADVERTISED_CAPABILITIES = [
21
+ "json-envelope",
22
+ "json-quiet",
23
+ "fields-projection",
24
+ "filter-dsl",
25
+ "ndjson-streaming",
26
+ "kash-explain",
27
+ "structured-actions",
28
+ "trade-place",
29
+ "protocol-trade",
30
+ "eoa-trade",
31
+ "protocol-userop",
32
+ "protocol-watch",
33
+ "partial-completion-records",
34
+ "webhooks-replay",
35
+ "webhooks-replay-dry-run",
36
+ "webhooks-replay-refuse-private"
37
+ ];
38
+ function resolveSdkVersion() {
39
+ try {
40
+ const require2 = createRequire(import.meta.url);
41
+ const pkg = require2("@kashdao/sdk/package.json");
42
+ return pkg.version ?? "unknown";
43
+ } catch {
44
+ return "unknown";
45
+ }
46
+ }
47
+ function buildVersionManifest() {
48
+ return {
49
+ cli: CLI_VERSION,
50
+ sdk: resolveSdkVersion(),
51
+ node: process.version,
52
+ platform: platform(),
53
+ release: release(),
54
+ arch: arch(),
55
+ capabilities: [...ADVERTISED_CAPABILITIES]
56
+ };
57
+ }
58
+ var versionCommand = new Command("version").description("Show CLI version and runtime environment.").option("--check", "probe npm for a newer @kashdao/cli release (cached for 24h)").addHelpText(
59
+ "after",
60
+ `
61
+ Examples:
62
+ $ kash version
63
+ $ kash version --json
64
+ $ kash version --check # check npm for a newer release
65
+ $ kash version --check --json # structured update info
66
+ $ kash --version --json # short alias for \`kash version --json\`
67
+
68
+ # Agent feature detection \u2014 \`capabilities\` is an additive token list.
69
+ $ kash version --json --quiet | jq '.capabilities | contains(["webhooks-replay-dry-run"])'
70
+ $ kash version --json --quiet | jq -r '.capabilities[]'
71
+ `
72
+ ).action(async (options, cmd) => {
73
+ const globals = readGlobals(cmd);
74
+ const manifest = buildVersionManifest();
75
+ let updateInfo = null;
76
+ if (options.check) {
77
+ const { checkLatestVersion } = await import("./version-check-TDCION37.js");
78
+ updateInfo = await checkLatestVersion(manifest.cli);
79
+ }
80
+ if (globals.json) {
81
+ printJson({
82
+ ...manifest,
83
+ ...updateInfo === null ? {} : { update: updateInfo }
84
+ });
85
+ return;
86
+ }
87
+ print(`${style.bold("@kashdao/cli")} ${manifest.cli}`);
88
+ print(`${style.dim("@kashdao/sdk")} ${manifest.sdk}`);
89
+ print(`${style.dim("Node.js ")} ${manifest.node}`);
90
+ print(
91
+ `${style.dim("OS ")} ${manifest.platform} ${manifest.release} (${manifest.arch})`
92
+ );
93
+ if (manifest.capabilities && manifest.capabilities.length > 0) {
94
+ print(
95
+ `${style.dim("Capabilities")} ${String(manifest.capabilities.length)} (\`kash version --json --quiet | jq -r '.capabilities[]'\` for the list)`
96
+ );
97
+ }
98
+ if (updateInfo === null) return;
99
+ if (updateInfo.isOutdated && updateInfo.latestVersion) {
100
+ print("");
101
+ print(
102
+ `${style.warn("\u26A0")} A newer @kashdao/cli is available: ${style.bold(updateInfo.latestVersion)} (current: ${manifest.cli})`
103
+ );
104
+ print(`${style.dim(" Update with")} ${style.cyan("npm install -g @kashdao/cli@latest")}`);
105
+ } else if (updateInfo.latestVersion) {
106
+ print("");
107
+ print(`${style.dim("You\u2019re on the latest @kashdao/cli release.")}`);
108
+ } else {
109
+ print("");
110
+ print(`${style.dim("Could not reach npm to check for updates.")}`);
111
+ }
112
+ });
113
+ export {
114
+ buildVersionManifest,
115
+ versionCommand
116
+ };
117
+ //# sourceMappingURL=version-JDK3PEP5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/version.ts"],"sourcesContent":["/**\n * `kash version` — emit the full version manifest.\n *\n * The default Commander `--version` flag prints just the CLI version\n * as a bare string. That's right for humans (`kash --version` →\n * `0.1.0`) but useless for AI agents reporting issues, since they\n * also need to know which SDK, Node, OS, and arch they're running\n * against.\n *\n * `kash version --json` (and the equivalent `kash --version --json`\n * intercept in index.ts) emits a structured manifest with every\n * field an issue triage might want.\n */\n\nimport { createRequire } from 'node:module';\nimport { arch, platform, release } from 'node:os';\n\nimport { Command } from 'commander';\n\nimport { readGlobals } from '../utils/global-options.js';\nimport { print, printJson, style } from '../utils/output.js';\nimport { CLI_VERSION } from '../version.js';\n\nimport type { CliCapability, VersionManifest } from '../cli-schemas.js';\nimport type { VersionCheckResult } from '../utils/version-check.js';\n\n// Re-export the canonical types so call sites that import them from\n// this file (e.g. agents importing `VersionManifest` alongside\n// `buildVersionManifest`) keep working.\nexport type { CliCapability, VersionManifest };\n\n/**\n * The capabilities this CLI release advertises. Each entry maps to a\n * documented feature in `cli-schemas.ts:CliCapabilitySchema`. Adding\n * a token is additive (consumers do containment checks); removing a\n * token is a SemVer-breaking event. Tokens that depend on a deferred\n * feature (e.g. `mcp-server`) are intentionally absent until the\n * feature ships — `kash version --json | jq '.capabilities | contains([\"mcp-server\"])'`\n * is the canonical agent feature-detection probe.\n */\nconst ADVERTISED_CAPABILITIES: readonly CliCapability[] = [\n 'json-envelope',\n 'json-quiet',\n 'fields-projection',\n 'filter-dsl',\n 'ndjson-streaming',\n 'kash-explain',\n 'structured-actions',\n 'trade-place',\n 'protocol-trade',\n 'eoa-trade',\n 'protocol-userop',\n 'protocol-watch',\n 'partial-completion-records',\n 'webhooks-replay',\n 'webhooks-replay-dry-run',\n 'webhooks-replay-refuse-private',\n];\n\n/**\n * Resolve the SDK version at runtime. Reads `@kashdao/sdk/package.json`\n * via Node's module resolution rather than re-exporting a constant\n * from the SDK so the value tracks whatever the consumer actually\n * has installed (handy for downstream npm publishes that pin to\n * different SDK versions across linked releases).\n */\nfunction resolveSdkVersion(): string {\n try {\n const require = createRequire(import.meta.url);\n const pkg = require('@kashdao/sdk/package.json') as { version?: string };\n return pkg.version ?? 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nexport function buildVersionManifest(): VersionManifest {\n return {\n cli: CLI_VERSION,\n sdk: resolveSdkVersion(),\n node: process.version,\n platform: platform(),\n release: release(),\n arch: arch(),\n capabilities: [...ADVERTISED_CAPABILITIES],\n };\n}\n\ntype VersionOptions = {\n check?: boolean;\n};\n\nexport const versionCommand = new Command('version')\n .description('Show CLI version and runtime environment.')\n .option('--check', 'probe npm for a newer @kashdao/cli release (cached for 24h)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash version\n $ kash version --json\n $ kash version --check # check npm for a newer release\n $ kash version --check --json # structured update info\n $ kash --version --json # short alias for \\`kash version --json\\`\n\n # Agent feature detection — \\`capabilities\\` is an additive token list.\n $ kash version --json --quiet | jq '.capabilities | contains([\"webhooks-replay-dry-run\"])'\n $ kash version --json --quiet | jq -r '.capabilities[]'\n`\n )\n .action(async (options: VersionOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n const manifest = buildVersionManifest();\n\n // Lazy-load the version-check helper so the default `kash version`\n // path doesn't pay for the fetch + cache file IO.\n let updateInfo: VersionCheckResult | null = null;\n if (options.check) {\n const { checkLatestVersion } = await import('../utils/version-check.js');\n updateInfo = await checkLatestVersion(manifest.cli);\n }\n\n if (globals.json) {\n printJson({\n ...manifest,\n ...(updateInfo === null ? {} : { update: updateInfo }),\n });\n return;\n }\n print(`${style.bold('@kashdao/cli')} ${manifest.cli}`);\n print(`${style.dim('@kashdao/sdk')} ${manifest.sdk}`);\n print(`${style.dim('Node.js ')} ${manifest.node}`);\n print(\n `${style.dim('OS ')} ${manifest.platform} ${manifest.release} (${manifest.arch})`\n );\n if (manifest.capabilities && manifest.capabilities.length > 0) {\n print(\n `${style.dim('Capabilities')} ${String(manifest.capabilities.length)} (\\`kash version --json --quiet | jq -r '.capabilities[]'\\` for the list)`\n );\n }\n\n if (updateInfo === null) return;\n if (updateInfo.isOutdated && updateInfo.latestVersion) {\n print('');\n print(\n `${style.warn('⚠')} A newer @kashdao/cli is available: ${style.bold(updateInfo.latestVersion)} (current: ${manifest.cli})`\n );\n print(`${style.dim(' Update with')} ${style.cyan('npm install -g @kashdao/cli@latest')}`);\n } else if (updateInfo.latestVersion) {\n print('');\n print(`${style.dim('You\\u2019re on the latest @kashdao/cli release.')}`);\n } else {\n print('');\n print(`${style.dim('Could not reach npm to check for updates.')}`);\n }\n });\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,SAAS,qBAAqB;AAC9B,SAAS,MAAM,UAAU,eAAe;AAExC,SAAS,eAAe;AAuBxB,IAAM,0BAAoD;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AASA,SAAS,oBAA4B;AACnC,MAAI;AACF,UAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,UAAM,MAAMA,SAAQ,2BAA2B;AAC/C,WAAO,IAAI,WAAW;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAwC;AACtD,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK,kBAAkB;AAAA,IACvB,MAAM,QAAQ;AAAA,IACd,UAAU,SAAS;AAAA,IACnB,SAAS,QAAQ;AAAA,IACjB,MAAM,KAAK;AAAA,IACX,cAAc,CAAC,GAAG,uBAAuB;AAAA,EAC3C;AACF;AAMO,IAAM,iBAAiB,IAAI,QAAQ,SAAS,EAChD,YAAY,2CAA2C,EACvD,OAAO,WAAW,6DAA6D,EAC/E;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,EACC,OAAO,OAAO,SAAyB,QAAiB;AACvD,QAAM,UAAU,YAAY,GAAG;AAC/B,QAAM,WAAW,qBAAqB;AAItC,MAAI,aAAwC;AAC5C,MAAI,QAAQ,OAAO;AACjB,UAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,6BAA2B;AACvE,iBAAa,MAAM,mBAAmB,SAAS,GAAG;AAAA,EACpD;AAEA,MAAI,QAAQ,MAAM;AAChB,cAAU;AAAA,MACR,GAAG;AAAA,MACH,GAAI,eAAe,OAAO,CAAC,IAAI,EAAE,QAAQ,WAAW;AAAA,IACtD,CAAC;AACD;AAAA,EACF;AACA,QAAM,GAAG,MAAM,KAAK,cAAc,CAAC,OAAO,SAAS,GAAG,EAAE;AACxD,QAAM,GAAG,MAAM,IAAI,cAAc,CAAC,OAAO,SAAS,GAAG,EAAE;AACvD,QAAM,GAAG,MAAM,IAAI,cAAc,CAAC,OAAO,SAAS,IAAI,EAAE;AACxD;AAAA,IACE,GAAG,MAAM,IAAI,cAAc,CAAC,OAAO,SAAS,QAAQ,IAAI,SAAS,OAAO,KAAK,SAAS,IAAI;AAAA,EAC5F;AACA,MAAI,SAAS,gBAAgB,SAAS,aAAa,SAAS,GAAG;AAC7D;AAAA,MACE,GAAG,MAAM,IAAI,cAAc,CAAC,OAAO,OAAO,SAAS,aAAa,MAAM,CAAC;AAAA,IACzE;AAAA,EACF;AAEA,MAAI,eAAe,KAAM;AACzB,MAAI,WAAW,cAAc,WAAW,eAAe;AACrD,UAAM,EAAE;AACR;AAAA,MACE,GAAG,MAAM,KAAK,QAAG,CAAC,uCAAuC,MAAM,KAAK,WAAW,aAAa,CAAC,cAAc,SAAS,GAAG;AAAA,IACzH;AACA,UAAM,GAAG,MAAM,IAAI,eAAe,CAAC,IAAI,MAAM,KAAK,oCAAoC,CAAC,EAAE;AAAA,EAC3F,WAAW,WAAW,eAAe;AACnC,UAAM,EAAE;AACR,UAAM,GAAG,MAAM,IAAI,iDAAiD,CAAC,EAAE;AAAA,EACzE,OAAO;AACL,UAAM,EAAE;AACR,UAAM,GAAG,MAAM,IAAI,2CAA2C,CAAC,EAAE;AAAA,EACnE;AACF,CAAC;","names":["require"]}
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveConfigPathsForOverride
4
+ } from "./chunk-KMBMQIZ7.js";
5
+ import "./chunk-YHCG2SUC.js";
6
+ import "./chunk-UZNSYATZ.js";
7
+
8
+ // src/utils/version-check.ts
9
+ import { existsSync } from "fs";
10
+ import { mkdir, readFile, writeFile } from "fs/promises";
11
+ import { dirname, join } from "path";
12
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@kashdao/cli/latest";
13
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
14
+ var FETCH_TIMEOUT_MS = 5e3;
15
+ function cachePath() {
16
+ const { file } = resolveConfigPathsForOverride(void 0);
17
+ return join(dirname(file), "version-check.json");
18
+ }
19
+ async function readCache() {
20
+ const path = cachePath();
21
+ if (!existsSync(path)) return null;
22
+ try {
23
+ const raw = await readFile(path, "utf8");
24
+ const parsed = JSON.parse(raw);
25
+ if (typeof parsed.checkedAt === "string" && typeof parsed.latestVersion === "string") {
26
+ return { checkedAt: parsed.checkedAt, latestVersion: parsed.latestVersion };
27
+ }
28
+ return null;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ async function writeCache(latestVersion) {
34
+ const path = cachePath();
35
+ try {
36
+ await mkdir(dirname(path), { recursive: true });
37
+ const payload = {
38
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
39
+ latestVersion
40
+ };
41
+ await writeFile(path, JSON.stringify(payload, null, 2), "utf8");
42
+ } catch {
43
+ }
44
+ }
45
+ async function fetchLatest(signal) {
46
+ try {
47
+ const response = await /* eslint-disable-line @kashdao/no-bare-fetch */
48
+ fetch(
49
+ NPM_REGISTRY_URL,
50
+ {
51
+ signal,
52
+ headers: { accept: "application/json" }
53
+ }
54
+ );
55
+ if (!response.ok) return null;
56
+ const body = await response.json();
57
+ if (typeof body.version === "string" && body.version.length > 0) {
58
+ return body.version;
59
+ }
60
+ return null;
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ function compareVersions(a, b) {
66
+ const re = /^(\d+)\.(\d+)\.(\d+)/;
67
+ const ma = re.exec(a);
68
+ const mb = re.exec(b);
69
+ if (!ma || !mb) return 0;
70
+ for (let i = 1; i <= 3; i++) {
71
+ const ai = Number.parseInt(ma[i], 10);
72
+ const bi = Number.parseInt(mb[i], 10);
73
+ if (ai > bi) return 1;
74
+ if (ai < bi) return -1;
75
+ }
76
+ return 0;
77
+ }
78
+ function isOptedOut() {
79
+ const v = process.env["KASH_NO_UPDATE_CHECK"];
80
+ if (typeof v !== "string") return false;
81
+ const t = v.trim().toLowerCase();
82
+ return t === "1" || t === "true" || t === "yes" || t === "on";
83
+ }
84
+ async function checkLatestVersion(current) {
85
+ if (isOptedOut()) {
86
+ return {
87
+ current,
88
+ latestVersion: null,
89
+ isOutdated: false,
90
+ lastCheckedAt: null,
91
+ fromCache: false
92
+ };
93
+ }
94
+ const cached = await readCache();
95
+ if (cached) {
96
+ const age = Date.now() - new Date(cached.checkedAt).getTime();
97
+ if (Number.isFinite(age) && age >= 0 && age < CACHE_TTL_MS) {
98
+ return {
99
+ current,
100
+ latestVersion: cached.latestVersion,
101
+ isOutdated: compareVersions(cached.latestVersion, current) === 1,
102
+ lastCheckedAt: cached.checkedAt,
103
+ fromCache: true
104
+ };
105
+ }
106
+ }
107
+ const controller = new AbortController();
108
+ const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
109
+ let latest;
110
+ try {
111
+ latest = await fetchLatest(controller.signal);
112
+ } finally {
113
+ clearTimeout(timer);
114
+ }
115
+ if (latest === null) {
116
+ return {
117
+ current,
118
+ latestVersion: cached?.latestVersion ?? null,
119
+ isOutdated: cached ? compareVersions(cached.latestVersion, current) === 1 : false,
120
+ lastCheckedAt: cached?.checkedAt ?? null,
121
+ fromCache: cached !== null
122
+ };
123
+ }
124
+ await writeCache(latest);
125
+ return {
126
+ current,
127
+ latestVersion: latest,
128
+ isOutdated: compareVersions(latest, current) === 1,
129
+ lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString(),
130
+ fromCache: false
131
+ };
132
+ }
133
+ export {
134
+ checkLatestVersion,
135
+ compareVersions,
136
+ isOptedOut
137
+ };
138
+ //# sourceMappingURL=version-check-TDCION37.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/version-check.ts"],"sourcesContent":["/**\n * Probe npm for a newer `@kashdao/cli` release and cache the result.\n *\n * The probe is opt-in (currently `kash version --check`). It is NOT\n * called automatically on every invocation — too much traffic, too\n * much latency, too much noise for a user who never asked. When opt-in,\n * we:\n *\n * 1. Read a cached `{ checkedAt, latestVersion }` from\n * `~/.kash/version-check.json`.\n * 2. If the cache is fresher than 24h, return it.\n * 3. Otherwise fetch `https://registry.npmjs.org/@kashdao/cli/latest`\n * with a tight 5s timeout, update the cache, return.\n * 4. On any network error, return `latestVersion: null`. We never\n * throw — a flaky network shouldn't break `kash version`.\n *\n * Cache file lives in the same directory as the main config so users\n * can wipe both with `rm -rf ~/.kash`. We don't reuse the config\n * file's writer because it goes through Zod validation and would\n * round-trip the entire config on every cache write.\n */\n\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nimport { resolveConfigPathsForOverride } from './config-store.js';\n\nconst NPM_REGISTRY_URL = 'https://registry.npmjs.org/@kashdao/cli/latest';\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h\nconst FETCH_TIMEOUT_MS = 5_000;\n\nexport type VersionCheckResult = {\n /** The CLI version baked into this build (`CLI_VERSION`). */\n readonly current: string;\n /** Latest published version from npm; `null` if the probe failed. */\n readonly latestVersion: string | null;\n /** True iff `latestVersion` is strictly greater than `current`. */\n readonly isOutdated: boolean;\n /** ISO-8601 timestamp of when the latest version was last fetched. */\n readonly lastCheckedAt: string | null;\n /** True iff the result came from the on-disk cache (not a fresh fetch). */\n readonly fromCache: boolean;\n};\n\ntype CacheFile = {\n readonly checkedAt: string;\n readonly latestVersion: string;\n};\n\nfunction cachePath(): string {\n // Place the cache next to the config file so `rm -rf ~/.kash` wipes\n // both. We pull the directory from `resolveConfigPathsForOverride`\n // (NOT the bare `resolveConfigPaths`) so a `KASH_CONFIG=/tmp/foo.json`\n // environment variable redirects the cache to the same alternate\n // directory as the config it sits next to. Using the bare helper\n // would have left the cache at `~/.kash/version-check.json` even\n // when the config was redirected — a real bug for users on\n // air-gapped / read-only-home setups who set `KASH_CONFIG` to point\n // at a writable directory.\n const { file } = resolveConfigPathsForOverride(undefined);\n return join(dirname(file), 'version-check.json');\n}\n\nasync function readCache(): Promise<CacheFile | null> {\n const path = cachePath();\n if (!existsSync(path)) return null;\n try {\n const raw = await readFile(path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<CacheFile>;\n if (typeof parsed.checkedAt === 'string' && typeof parsed.latestVersion === 'string') {\n return { checkedAt: parsed.checkedAt, latestVersion: parsed.latestVersion };\n }\n return null;\n } catch {\n // Corrupted cache → ignore. The fresh fetch will overwrite it.\n return null;\n }\n}\n\nasync function writeCache(latestVersion: string): Promise<void> {\n const path = cachePath();\n try {\n await mkdir(dirname(path), { recursive: true });\n const payload: CacheFile = {\n checkedAt: new Date().toISOString(),\n latestVersion,\n };\n await writeFile(path, JSON.stringify(payload, null, 2), 'utf8');\n } catch {\n // Best-effort — read-only filesystems and friends shouldn't break\n // the main flow.\n }\n}\n\n/**\n * The CLI is a published-to-npm public package that intentionally\n * has zero `@kashdao/*` runtime deps beyond `@kashdao/sdk` and\n * `@kashdao/protocol-sdk` (enforced by sync-to-public-mirror.ts).\n * Pulling in `@kashdao/http-client` would break that invariant.\n * This call is non-critical (best-effort version-update notice),\n * short-lived (caller-supplied AbortSignal), and to a single\n * well-known host (the npm registry) — all guarantees that the\n * `HttpClient` rule exists to enforce.\n */\nasync function fetchLatest(signal: AbortSignal): Promise<string | null> {\n try {\n const response = await /* eslint-disable-line @kashdao/no-bare-fetch */ fetch(\n NPM_REGISTRY_URL,\n {\n signal,\n headers: { accept: 'application/json' },\n }\n );\n if (!response.ok) return null;\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version === 'string' && body.version.length > 0) {\n return body.version;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Compare two semver-shaped strings. Returns `1` if a > b, `-1` if\n * a < b, `0` if equal. Pre-release / build metadata is ignored — for\n * the \"you're behind\" prompt we only care about the major.minor.patch\n * triple. A non-semver string returns `0` (treat as up-to-date rather\n * than nag the user with a false positive).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const re = /^(\\d+)\\.(\\d+)\\.(\\d+)/;\n const ma = re.exec(a);\n const mb = re.exec(b);\n if (!ma || !mb) return 0;\n for (let i = 1; i <= 3; i++) {\n const ai = Number.parseInt(ma[i]!, 10);\n const bi = Number.parseInt(mb[i]!, 10);\n if (ai > bi) return 1;\n if (ai < bi) return -1;\n }\n return 0;\n}\n\n/**\n * Hard opt-out for environments that can't (or don't want to) reach\n * registry.npmjs.org — corporate egress filters, air-gapped CI, users\n * who simply prefer never to see the prompt. Any truthy value of\n * `KASH_NO_UPDATE_CHECK` short-circuits with \"no idea, didn't ask\".\n *\n * The check is already opt-in (only runs on `kash version --check`),\n * so this is belt-and-braces — but it gives operators a single env\n * var to set in their shell rc to neutralise the call site without\n * grepping the source.\n */\nexport function isOptedOut(): boolean {\n const v = process.env['KASH_NO_UPDATE_CHECK'];\n if (typeof v !== 'string') return false;\n const t = v.trim().toLowerCase();\n return t === '1' || t === 'true' || t === 'yes' || t === 'on';\n}\n\nexport async function checkLatestVersion(current: string): Promise<VersionCheckResult> {\n // 0. Operator opt-out → return immediately with nothing fetched and\n // no cache touched. The caller treats `latestVersion: null` as\n // \"couldn't check\" and stays quiet.\n if (isOptedOut()) {\n return {\n current,\n latestVersion: null,\n isOutdated: false,\n lastCheckedAt: null,\n fromCache: false,\n };\n }\n\n // 1. Cache hit within TTL → return immediately.\n const cached = await readCache();\n if (cached) {\n const age = Date.now() - new Date(cached.checkedAt).getTime();\n if (Number.isFinite(age) && age >= 0 && age < CACHE_TTL_MS) {\n return {\n current,\n latestVersion: cached.latestVersion,\n isOutdated: compareVersions(cached.latestVersion, current) === 1,\n lastCheckedAt: cached.checkedAt,\n fromCache: true,\n };\n }\n }\n\n // 2. Otherwise fetch with a tight timeout. AbortController is the\n // portable way to bound `fetch` in Node 22+.\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n let latest: string | null;\n try {\n latest = await fetchLatest(controller.signal);\n } finally {\n clearTimeout(timer);\n }\n\n if (latest === null) {\n // Network error — surface a partial result rather than throwing.\n // The caller (currently `kash version --check`) decides whether to\n // warn or just stay quiet.\n return {\n current,\n latestVersion: cached?.latestVersion ?? null,\n isOutdated: cached ? compareVersions(cached.latestVersion, current) === 1 : false,\n lastCheckedAt: cached?.checkedAt ?? null,\n fromCache: cached !== null,\n };\n }\n\n await writeCache(latest);\n return {\n current,\n latestVersion: latest,\n isOutdated: compareVersions(latest, current) === 1,\n lastCheckedAt: new Date().toISOString(),\n fromCache: false,\n };\n}\n"],"mappings":";;;;;;;;AAsBA,SAAS,kBAAkB;AAC3B,SAAS,OAAO,UAAU,iBAAiB;AAC3C,SAAS,SAAS,YAAY;AAI9B,IAAM,mBAAmB;AACzB,IAAM,eAAe,KAAK,KAAK,KAAK;AACpC,IAAM,mBAAmB;AAoBzB,SAAS,YAAoB;AAU3B,QAAM,EAAE,KAAK,IAAI,8BAA8B,MAAS;AACxD,SAAO,KAAK,QAAQ,IAAI,GAAG,oBAAoB;AACjD;AAEA,eAAe,YAAuC;AACpD,QAAM,OAAO,UAAU;AACvB,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,OAAO,cAAc,YAAY,OAAO,OAAO,kBAAkB,UAAU;AACpF,aAAO,EAAE,WAAW,OAAO,WAAW,eAAe,OAAO,cAAc;AAAA,IAC5E;AACA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,WAAW,eAAsC;AAC9D,QAAM,OAAO,UAAU;AACvB,MAAI;AACF,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,UAAqB;AAAA,MACzB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,IACF;AACA,UAAM,UAAU,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,MAAM;AAAA,EAChE,QAAQ;AAAA,EAGR;AACF;AAYA,eAAe,YAAY,QAA6C;AACtE,MAAI;AACF,UAAM,WAAW;AAAA,IAAuD;AAAA,MACtE;AAAA,MACA;AAAA,QACE;AAAA,QACA,SAAS,EAAE,QAAQ,mBAAmB;AAAA,MACxC;AAAA,IACF;AACA,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,QAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,SAAS,GAAG;AAC/D,aAAO,KAAK;AAAA,IACd;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASO,SAAS,gBAAgB,GAAW,GAAuB;AAChE,QAAM,KAAK;AACX,QAAM,KAAK,GAAG,KAAK,CAAC;AACpB,QAAM,KAAK,GAAG,KAAK,CAAC;AACpB,MAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,UAAM,KAAK,OAAO,SAAS,GAAG,CAAC,GAAI,EAAE;AACrC,UAAM,KAAK,OAAO,SAAS,GAAG,CAAC,GAAI,EAAE;AACrC,QAAI,KAAK,GAAI,QAAO;AACpB,QAAI,KAAK,GAAI,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAaO,SAAS,aAAsB;AACpC,QAAM,IAAI,QAAQ,IAAI,sBAAsB;AAC5C,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,IAAI,EAAE,KAAK,EAAE,YAAY;AAC/B,SAAO,MAAM,OAAO,MAAM,UAAU,MAAM,SAAS,MAAM;AAC3D;AAEA,eAAsB,mBAAmB,SAA8C;AAIrF,MAAI,WAAW,GAAG;AAChB,WAAO;AAAA,MACL;AAAA,MACA,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,WAAW;AAAA,IACb;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,UAAU;AAC/B,MAAI,QAAQ;AACV,UAAM,MAAM,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ;AAC5D,QAAI,OAAO,SAAS,GAAG,KAAK,OAAO,KAAK,MAAM,cAAc;AAC1D,aAAO;AAAA,QACL;AAAA,QACA,eAAe,OAAO;AAAA,QACtB,YAAY,gBAAgB,OAAO,eAAe,OAAO,MAAM;AAAA,QAC/D,eAAe,OAAO;AAAA,QACtB,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAIA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,gBAAgB;AACnE,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,YAAY,WAAW,MAAM;AAAA,EAC9C,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AAEA,MAAI,WAAW,MAAM;AAInB,WAAO;AAAA,MACL;AAAA,MACA,eAAe,QAAQ,iBAAiB;AAAA,MACxC,YAAY,SAAS,gBAAgB,OAAO,eAAe,OAAO,MAAM,IAAI;AAAA,MAC5E,eAAe,QAAQ,aAAa;AAAA,MACpC,WAAW,WAAW;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,WAAW,MAAM;AACvB,SAAO;AAAA,IACL;AAAA,IACA,eAAe;AAAA,IACf,YAAY,gBAAgB,QAAQ,OAAO,MAAM;AAAA,IACjD,gBAAe,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC,WAAW;AAAA,EACb;AACF;","names":[]}