@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/config/index.ts","../src/commands/config/export.ts","../src/commands/config/import.ts","../src/commands/config/profiles.ts","../src/commands/config/remove.ts","../src/commands/config/reset.ts","../src/commands/config/set.ts","../src/commands/config/show.ts","../src/commands/config/use.ts"],"sourcesContent":["/**\n * `kash config` — inspect and edit the local CLI configuration.\n */\n\nimport { Command } from 'commander';\n\nimport { exportConfigCommand } from './export.js';\nimport { importConfigCommand } from './import.js';\nimport { profilesCommand } from './profiles.js';\nimport { removeProfileCommand } from './remove.js';\nimport { resetConfigCommand } from './reset.js';\nimport { setConfigCommand } from './set.js';\nimport { showConfigCommand } from './show.js';\nimport { useProfileCommand } from './use.js';\n\nexport const configCommand = new Command('config')\n .description('Inspect and edit ~/.kash/config.json (multi-profile).')\n .addCommand(showConfigCommand)\n .addCommand(setConfigCommand)\n .addCommand(profilesCommand)\n .addCommand(useProfileCommand)\n .addCommand(removeProfileCommand)\n .addCommand(resetConfigCommand)\n .addCommand(exportConfigCommand)\n .addCommand(importConfigCommand);\n","/**\n * `kash config export` — dump the entire multi-profile config to\n * stdout (or a file via `--out`).\n *\n * **Default redaction.** API keys are replaced with the literal string\n * `<redacted>` so the dump is safe to commit to a shared bucket or\n * paste into a support ticket. Pass `--include-secrets` to opt into\n * round-trippable export (e.g. moving a profile to a new machine).\n *\n * **Round-trip pairing.** Output of this command is the canonical\n * input for `kash config import`. The file format mirrors the\n * on-disk shape: `{ version: 1, currentProfile, profiles: {...} }`.\n */\n\nimport { writeFile } from 'node:fs/promises';\n\nimport { Command } from 'commander';\n\nimport { CliError, toCliError } from '../../errors.js';\nimport { readWholeFile, type CliFile, type CliConfig } from '../../utils/config-store.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, print, printJson } from '../../utils/output.js';\n\nconst REDACTED = '<redacted>';\n\ntype ExportOptions = {\n out?: string;\n includeSecrets?: boolean;\n};\n\nexport const exportConfigCommand = new Command('export')\n .description('Dump the entire multi-profile config (API keys redacted by default).')\n .option('-o, --out <path>', 'write to a file instead of stdout (mode 0600)')\n .option('--include-secrets', 'include raw API keys in the export (round-trippable)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config export # safe-by-default; redacted JSON to stdout\n $ kash config export --out kash-config.json # write to a file (mode 0600)\n $ kash config export --include-secrets --out kash.json # round-trippable (DO NOT commit)\n\nNotes:\n - Without --include-secrets, every \\`apiKey\\` is replaced with \\`${REDACTED}\\` —\n safe to commit and share for debugging without leaking credentials.\n - The output is the canonical input for \\`kash config import\\`. Imports\n refuse to apply a profile whose apiKey is still \\`${REDACTED}\\`.\n - Use --out to route to a file the CLI can write at mode 0600. Stdout\n inherits whatever umask the parent shell has.\n`\n )\n .action(async (options: ExportOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n try {\n const file = await readWholeFile({\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n\n // Walk every profile and redact apiKey unless the caller asked\n // to include secrets. Other direct-mode fields (rpcUrl,\n // smartAccount, bundlerUrl, signerKeyRef) are kept as-is —\n // they're configuration, not secrets. Raw private keys never\n // live in the config (signerKeyRef is a `file:`/`env:` pointer).\n const sanitized: CliFile = {\n ...file,\n profiles: Object.fromEntries(\n Object.entries(file.profiles).map(([name, profile]) => [\n name,\n sanitizeProfile(profile, options.includeSecrets ?? false),\n ])\n ),\n };\n\n const payload = JSON.stringify(sanitized, null, 2);\n\n if (options.out) {\n try {\n await writeFile(options.out, `${payload}\\n`, { encoding: 'utf8', mode: 0o600 });\n if (!globals.json) {\n log.success(`Wrote ${options.out} (mode 0600).`);\n if (!options.includeSecrets) {\n log.info(\n `Secrets redacted. Pass --include-secrets to produce a round-trippable export.`\n );\n }\n }\n } catch (cause) {\n throw new CliError(`Failed to write ${options.out}.`, {\n code: 'CONFIGURATION',\n recoverable: true,\n suggestion: 'Verify the path is writable and the parent directory exists.',\n cause,\n });\n }\n return;\n }\n\n // No --out: dump JSON to stdout. Honor --json by emitting the\n // file shape (same payload, but routed through printJson so\n // pretty/compact respects --quiet). Without --json we still emit\n // JSON because that's the only sensible export format — but skip\n // the human-mode banner.\n if (globals.json) {\n printJson(sanitized);\n } else {\n // Plain stdout. Append a header to stderr (so it doesn't\n // pollute the JSON pipe) noting the redaction policy.\n if (!options.includeSecrets) {\n log.info(`API keys redacted. Pass --include-secrets for round-trippable export.`);\n }\n print(payload);\n }\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\nfunction sanitizeProfile(profile: CliConfig, includeSecrets: boolean): CliConfig {\n if (includeSecrets) return profile;\n if (profile.apiKey === undefined) return profile;\n // Use a marker the importer can detect; real keys never collide\n // because they all start with `kash_`.\n return { ...profile, apiKey: REDACTED };\n}\n\nexport { REDACTED as REDACTED_API_KEY_MARKER };\n","/**\n * `kash config import` — merge a config bundle (produced by\n * `kash config export`) into the local config file.\n *\n * **Source.** Reads from `<file>` argument, or stdin when no argument\n * is given. The input must match the v1 file shape; anything else is\n * rejected as INVALID_INPUT.\n *\n * **Merge policy.** Profiles in the imported file are merged into the\n * existing profiles map. By default, existing profiles with the same\n * name are OVERWRITTEN. Pass `--no-overwrite` to skip those — useful\n * when restoring a backup against a partial config.\n *\n * **Redaction guard.** Profiles whose `apiKey` is still the literal\n * marker (`<redacted>` from `config export` without\n * `--include-secrets`) are refused with a clear error. We don't want\n * to silently overwrite a working key with a placeholder string.\n *\n * **currentProfile.** If the imported file specifies a\n * `currentProfile`, we use it — but only if that profile actually\n * lands in the merged file. Otherwise we keep the existing\n * `currentProfile` unchanged.\n */\n\nimport { readFile } from 'node:fs/promises';\n\nimport { Command } from 'commander';\n\nimport { CliError, toCliError } from '../../errors.js';\nimport {\n cliFileSchema,\n readWholeFile,\n writeWholeFile,\n type CliFile,\n type CliConfig,\n} from '../../utils/config-store.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, print, printJson, style } from '../../utils/output.js';\n\nimport { REDACTED_API_KEY_MARKER } from './export.js';\n\ntype ImportOptions = {\n // Commander stores `--no-overwrite` as `{ overwrite: false }` —\n // the default for a `--no-X` boolean option is `true`, so the\n // explicit `false` means the user passed `--no-overwrite`.\n overwrite?: boolean;\n dryRun?: boolean;\n};\n\nexport const importConfigCommand = new Command('import')\n .description('Merge a `kash config export` bundle into the local config (mode 0600).')\n .argument('[file]', 'path to a JSON bundle (omit to read from stdin)')\n .option('--no-overwrite', 'skip profiles whose name already exists locally')\n .option('--dry-run', 'preview the merge without writing to disk')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config import kash.json\n $ kash config export --include-secrets | ssh prod-host kash config import\n $ kash config import kash.json --no-overwrite # never replace existing profiles\n $ kash config import kash.json --dry-run --json # preview the merged result\n\nNotes:\n - The input format is exactly what \\`kash config export\\` produces.\n - Profiles whose apiKey is still \\`${REDACTED_API_KEY_MARKER}\\` are refused — re-export\n with --include-secrets to get a round-trippable bundle.\n - --dry-run emits the merged file shape without persisting it. Useful\n for diffing against the on-disk file before committing to a write.\n`\n )\n .action(async (file: string | undefined, options: ImportOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n try {\n const raw = await readSource(file);\n // Redaction check runs first on the raw JSON so users get the\n // \"you exported without --include-secrets\" message rather than\n // a generic schema-validation error (because `<redacted>`\n // doesn't match the `kash_` prefix the schema enforces).\n validateRedactionRaw(raw);\n const parsed = parseAndValidate(raw);\n\n const existing = await readWholeFile({\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n const merged = mergeFiles(existing, parsed, options.overwrite === false);\n\n if (options.dryRun === true) {\n if (globals.json) {\n printJson({ merged, written: false });\n } else {\n log.info('Dry run — no changes written.');\n print(JSON.stringify(merged, null, 2));\n }\n return;\n }\n\n await writeWholeFile(merged, {\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n\n if (globals.json) {\n printJson({\n merged,\n written: true,\n profiles: Object.keys(merged.profiles).sort(),\n currentProfile: merged.currentProfile ?? null,\n });\n return;\n }\n\n const importedNames = Object.keys(parsed.profiles);\n const merged_n = Object.keys(merged.profiles).length;\n log.success(\n `Imported ${String(importedNames.length)} profile(s); local config now has ${String(merged_n)} profile(s).`\n );\n if (merged.currentProfile) {\n log.info(`Active profile: ${style.bold(merged.currentProfile)}`);\n }\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\nasync function readSource(file: string | undefined): Promise<string> {\n if (file !== undefined) {\n try {\n return await readFile(file, 'utf8');\n } catch (cause) {\n throw new CliError(`Failed to read ${file}.`, {\n code: 'CONFIGURATION',\n recoverable: true,\n suggestion: 'Verify the path exists and is readable.',\n cause,\n });\n }\n }\n // No file: read from stdin. process.stdin is async iterable in Node 22+.\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n // process.stdin emits Buffer in binary streams and string in\n // text mode; coerce both into Buffer so concat is well-typed.\n if (typeof chunk === 'string') {\n chunks.push(Buffer.from(chunk));\n } else if (chunk instanceof Buffer) {\n chunks.push(chunk);\n } else {\n chunks.push(Buffer.from(chunk as Uint8Array));\n }\n }\n if (chunks.length === 0) {\n throw new CliError('No input received on stdin.', {\n code: 'INVALID_INPUT',\n recoverable: true,\n suggestion: 'Pass a path argument or pipe a `kash config export` bundle into stdin.',\n });\n }\n // Strip a leading UTF-8 BOM. Notepad / VSCode-with-utf8bom and many\n // Windows tools prepend U+FEFF to UTF-8 files; without the strip,\n // `JSON.parse` chokes on the leading non-whitespace character.\n const { stripBom } = await import('../../utils/stdin.js');\n return stripBom(Buffer.concat(chunks).toString('utf8'));\n}\n\nfunction parseAndValidate(raw: string): CliFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n throw new CliError('Input is not valid JSON.', {\n code: 'INVALID_INPUT',\n recoverable: true,\n suggestion:\n 'The bundle must match the output of `kash config export`. Re-run that command and pipe the result.',\n cause,\n });\n }\n const result = cliFileSchema.safeParse(parsed);\n if (!result.success) {\n const first = result.error.issues[0];\n throw new CliError(\n `Input does not match the config file shape${\n first ? `: ${first.path.join('.')}: ${first.message}` : '.'\n }`,\n {\n code: 'INVALID_INPUT',\n recoverable: true,\n suggestion: 'Re-export from a known-good machine via `kash config export`.',\n }\n );\n }\n return result.data;\n}\n\n/**\n * Cheap raw-text scan for the redaction marker before strict schema\n * validation runs. The marker is a literal sentinel that real API\n * keys can't collide with (real keys start with `kash_`), so a\n * substring check is safe.\n */\nfunction validateRedactionRaw(raw: string): void {\n if (raw.includes(`\"apiKey\": \"${REDACTED_API_KEY_MARKER}\"`)) {\n throw new CliError('Bundle contains redacted API keys — cannot import.', {\n code: 'INVALID_INPUT',\n recoverable: true,\n suggestion:\n 'Re-run `kash config export --include-secrets` on the source machine to produce a round-trippable bundle.',\n });\n }\n}\n\nfunction mergeFiles(existing: CliFile, incoming: CliFile, noOverwrite: boolean): CliFile {\n const profiles: Record<string, CliConfig> = { ...existing.profiles };\n for (const [name, profile] of Object.entries(incoming.profiles)) {\n if (noOverwrite && name in profiles) continue;\n profiles[name] = profile;\n }\n\n // Decide currentProfile: incoming wins only if it points at a real\n // profile post-merge. Otherwise keep the existing setting.\n let currentProfile = existing.currentProfile;\n if (incoming.currentProfile && incoming.currentProfile in profiles) {\n currentProfile = incoming.currentProfile;\n }\n\n return {\n version: 1,\n ...(currentProfile === undefined ? {} : { currentProfile }),\n profiles,\n };\n}\n","/**\n * `kash config profiles` — list every profile in the config file.\n */\n\nimport { Command } from 'commander';\n\nimport { toCliError } from '../../errors.js';\nimport { listProfiles } from '../../utils/config-store.js';\nimport { createTable } from '../../utils/formatting.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, print, printJson, style } from '../../utils/output.js';\n\nexport const profilesCommand = new Command('profiles')\n .description('List configured profiles in the config file.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config profiles\n $ kash config profiles --json --quiet | jq -r '.profiles[]'\n`\n )\n .action(async (_opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n let result;\n try {\n result = await listProfiles({\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson(result);\n return;\n }\n\n if (result.profiles.length === 0) {\n log.info('No profiles configured.');\n log.detail('Hint', \"Run 'kash auth set-key <key>' to create the default profile.\");\n return;\n }\n\n const table = createTable(['Active', 'Profile']);\n for (const name of result.profiles) {\n table.push([name === result.current ? style.success('•') : ' ', name]);\n }\n print(table.toString());\n });\n","/**\n * `kash config remove <profile>` — delete a named profile from the\n * config file. Refuses to delete the active profile (consistent with\n * `kash auth logout` which only clears the apiKey).\n *\n * Symmetric with `kash config use` and `kash config profiles`: every\n * write surface a multi-profile setup needs is now a first-class\n * command.\n */\n\nimport { Command } from 'commander';\n\nimport { toCliError } from '../../errors.js';\nimport { deleteProfile } from '../../utils/config-store.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, printJson } from '../../utils/output.js';\n\nexport const removeProfileCommand = new Command('remove')\n .description('Delete a named profile from the config file.')\n .argument('<profile>', 'profile name to remove')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config remove staging\n $ kash config remove old-profile --json --quiet\n`\n )\n .action(async (profile: string, _opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n let updated;\n try {\n updated = await deleteProfile(profile, {\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson({\n ok: true,\n removed: profile,\n profiles: Object.keys(updated.profiles).sort(),\n });\n return;\n }\n log.success(`Profile \"${profile}\" removed.`);\n });\n","/**\n * `kash config reset` — delete the on-disk config file.\n *\n * Asks for confirmation when stdin is a TTY (the common interactive\n * case). In `--json` or `--quiet` mode, runs unconditionally so\n * scripts don't hang waiting for input.\n */\n\nimport readline from 'node:readline/promises';\n\nimport { Command } from 'commander';\n\nimport { toCliError } from '../../errors.js';\nimport { deleteConfig, resolveConfigPathsForOverride } from '../../utils/config-store.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, printJson } from '../../utils/output.js';\n\ntype ResetOptions = {\n yes?: boolean;\n};\n\nexport const resetConfigCommand = new Command('reset')\n .description('Delete ~/.kash/config.json.')\n .option('-y, --yes', 'skip the interactive confirmation')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config reset\n $ kash config reset --yes --json --quiet\n`\n )\n .action(async (options: ResetOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n const paths = resolveConfigPathsForOverride(globals.configPath);\n\n const interactive = process.stdin.isTTY && !globals.quiet && !globals.json;\n const confirmed = options.yes || !interactive ? true : await confirm(paths.file);\n if (!confirmed) {\n log.info('Aborted.');\n return;\n }\n\n try {\n await deleteConfig({\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson({ ok: true, deleted: paths.file });\n return;\n }\n log.success(`Deleted ${paths.file}.`);\n });\n\nasync function confirm(path: string): Promise<boolean> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n try {\n const answer = await rl.question(`Delete ${path}? [y/N] `);\n return answer.trim().toLowerCase().startsWith('y');\n } finally {\n rl.close();\n }\n}\n","/**\n * `kash config set <key> <value>` — write a single config field.\n *\n * The value is parsed and validated by the same Zod schema used to\n * read the file, so corruption is impossible without bypassing the\n * CLI.\n *\n * Three field families:\n *\n * - **Kash-orchestrated** (API-backed): `apiKey`, `baseUrl`, `defaultChainId`.\n * - **Direct mode** (`kash protocol …`): `rpcUrl`, `smartAccount`,\n * `bundlerUrl`, `bundlerProvider`, `signerKeyRef`.\n * - **Custom chain** (Anvil / forks / sidechains, dot-path syntax):\n * `customChain.name`, `customChain.factoryAddress`, etc. Including\n * `customChain.smartAccount.factoryAddress`/`implementationAddress`/\n * `entryPointAddress` for SA mode on chains the protocol-sdk\n * registry doesn't cover.\n */\n\nimport { Command } from 'commander';\n\nimport { CliValidationError, toCliError } from '../../errors.js';\nimport {\n cliConfigSchema,\n readConfig,\n updateConfig,\n type CliConfig,\n type UpdateConfigResult,\n} from '../../utils/config-store.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, printJson } from '../../utils/output.js';\n\nconst TOP_LEVEL_KEYS = [\n // Kash-orchestrated\n 'apiKey',\n 'baseUrl',\n 'defaultChainId',\n // Direct mode\n 'rpcUrl',\n 'smartAccount',\n 'bundlerUrl',\n 'bundlerProvider',\n 'signerKeyRef',\n] as const;\ntype TopLevelKey = (typeof TOP_LEVEL_KEYS)[number];\n\nconst CUSTOM_CHAIN_LEAVES = [\n 'name',\n 'factoryAddress',\n 'usdcAddress',\n 'oracleAddress',\n 'vaultAddress',\n 'tokens1155Address',\n 'paramRegistryAddress',\n] as const;\ntype CustomChainLeaf = (typeof CUSTOM_CHAIN_LEAVES)[number];\n\nconst CUSTOM_CHAIN_SA_LEAVES = [\n 'factoryAddress',\n 'implementationAddress',\n 'entryPointAddress',\n] as const;\ntype CustomChainSaLeaf = (typeof CUSTOM_CHAIN_SA_LEAVES)[number];\n\nconst ALL_KEYS_FOR_HELP = [\n ...TOP_LEVEL_KEYS,\n ...CUSTOM_CHAIN_LEAVES.map((l) => `customChain.${l}`),\n ...CUSTOM_CHAIN_SA_LEAVES.map((l) => `customChain.smartAccount.${l}`),\n];\n\nexport const setConfigCommand = new Command('set')\n .description('Set a single config field.')\n .argument(\n '<key>',\n 'top-level key OR `customChain.<leaf>` / `customChain.smartAccount.<leaf>` dot-path'\n )\n .argument('<value>', 'value to set')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config set baseUrl https://api-staging.kash.bot/v1 --profile staging\n $ kash config set defaultChainId 84532 --profile staging\n\nDirect-mode (kash protocol …):\n $ kash config set rpcUrl https://base-mainnet.g.alchemy.com/v2/... --profile mm\n $ kash config set smartAccount 0xabc... --profile mm\n $ kash config set signerKeyRef file:~/.kash/keys/mm-owner.key --profile mm\n $ kash config set bundlerProvider flashbots --profile mm\n\nCustom chain (local Anvil / forks / sidechains, bypasses static registry):\n $ kash config set defaultChainId 31337 --profile anvil\n $ kash config set rpcUrl http://localhost:8545 --profile anvil\n $ kash config set customChain.name \"Anvil local\" --profile anvil\n $ kash config set customChain.factoryAddress 0xCf7Ed... --profile anvil\n $ kash config set customChain.usdcAddress 0x5FbDB... --profile anvil\n $ kash config set customChain.smartAccount.factoryAddress 0x3Aa5e... --profile anvil\n`\n )\n .action(async (key: string, value: string, _opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n let patch: Partial<CliConfig>;\n try {\n patch = await buildPatchForKey(key, value, {\n ...(globals.profile === undefined ? {} : { profile: globals.profile }),\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n } catch (cause) {\n throw toCliError(cause);\n }\n\n let result: UpdateConfigResult;\n try {\n result = await updateConfig(patch, {\n ...(globals.profile === undefined ? {} : { profile: globals.profile }),\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n // The resolved profile (from updateConfig) is the truth — when\n // the user runs `kash config set foo bar` with no flag, the\n // value lands in whatever profile the file's `currentProfile`\n // points at, NOT in the unconditional 'default'.\n const top = key.split('.', 1)[0] as keyof CliConfig;\n printJson({\n ok: true,\n key,\n value: result.stored[top] ?? null,\n profile: result.profile,\n });\n return;\n }\n log.success(`Set ${key} on profile \"${result.profile}\".`);\n });\n\nfunction isTopLevelKey(value: string): value is TopLevelKey {\n return (TOP_LEVEL_KEYS as readonly string[]).includes(value);\n}\n\nfunction isCustomChainLeaf(value: string): value is CustomChainLeaf {\n return (CUSTOM_CHAIN_LEAVES as readonly string[]).includes(value);\n}\n\nfunction isCustomChainSaLeaf(value: string): value is CustomChainSaLeaf {\n return (CUSTOM_CHAIN_SA_LEAVES as readonly string[]).includes(value);\n}\n\n/**\n * Resolve a (possibly dot-pathed) key to a partial-config patch. For\n * `customChain.*` paths we read-modify-write the existing object so\n * the user can set leaves one at a time without losing prior fields.\n */\nasync function buildPatchForKey(\n key: string,\n value: string,\n readOpts: { readonly profile?: string; readonly configPath?: string }\n): Promise<Partial<CliConfig>> {\n if (isTopLevelKey(key)) {\n return buildTopLevelPatch(key, value);\n }\n\n // customChain.<leaf> or customChain.smartAccount.<leaf> — read the\n // existing customChain object so partial sets compose, then validate\n // the merged shape against the full schema.\n if (key.startsWith('customChain.')) {\n const existing = await readConfig(readOpts);\n const existingChain = existing.customChain ?? {};\n const merged = mergeCustomChainLeaf(existingChain, key, value);\n const candidate: Partial<CliConfig> = { customChain: merged };\n // Validate the merged customChain against the schema. If the\n // user has only set a name + factoryAddress so far this will\n // fail the required usdcAddress check — that's the correct\n // behaviour: customChain on disk is always a complete object.\n cliConfigSchema.parse(candidate);\n return candidate;\n }\n\n throw new CliValidationError(\n `Unknown config key \"${key}\".`,\n `Allowed keys: ${ALL_KEYS_FOR_HELP.join(', ')}.`\n );\n}\n\nfunction buildTopLevelPatch(key: TopLevelKey, value: string): Partial<CliConfig> {\n switch (key) {\n case 'apiKey':\n case 'baseUrl':\n case 'rpcUrl':\n case 'smartAccount':\n case 'bundlerUrl':\n case 'bundlerProvider':\n case 'signerKeyRef': {\n const candidate: Partial<CliConfig> = { [key]: value };\n cliConfigSchema.parse(candidate);\n return candidate;\n }\n case 'defaultChainId': {\n const n = Number.parseInt(value, 10);\n if (!Number.isFinite(n) || n <= 0) {\n throw new CliValidationError(\n 'defaultChainId must be a positive integer.',\n undefined,\n 'defaultChainId'\n );\n }\n const candidate: Partial<CliConfig> = { defaultChainId: n };\n cliConfigSchema.parse(candidate);\n return candidate;\n }\n }\n}\n\n/**\n * Merge a single dot-pathed leaf into the existing `customChain`\n * object. Handles both flat leaves (`customChain.factoryAddress`) and\n * the one nested level (`customChain.smartAccount.factoryAddress`).\n *\n * The returned object is then re-validated against the full\n * `customChainSchema` by the caller — leaves that violate the leaf\n * regex (e.g. malformed hex) surface their schema error there, and\n * the required-field check (factoryAddress + usdcAddress) ensures we\n * never persist a half-built customChain.\n */\nfunction mergeCustomChainLeaf(\n existing: NonNullable<CliConfig['customChain']> | Record<string, unknown>,\n key: string,\n value: string\n): NonNullable<CliConfig['customChain']> {\n const path = key.slice('customChain.'.length);\n\n if (path.startsWith('smartAccount.')) {\n const leaf = path.slice('smartAccount.'.length);\n if (!isCustomChainSaLeaf(leaf)) {\n throw new CliValidationError(\n `Unknown customChain.smartAccount leaf \"${leaf}\".`,\n `Allowed: ${CUSTOM_CHAIN_SA_LEAVES.map((l) => `customChain.smartAccount.${l}`).join(', ')}.`\n );\n }\n const sa = (existing as { smartAccount?: Record<string, unknown> }).smartAccount ?? {};\n return {\n ...(existing as NonNullable<CliConfig['customChain']>),\n smartAccount: { ...sa, [leaf]: value } as NonNullable<\n NonNullable<CliConfig['customChain']>['smartAccount']\n >,\n };\n }\n\n if (!isCustomChainLeaf(path)) {\n throw new CliValidationError(\n `Unknown customChain leaf \"${path}\".`,\n `Allowed: ${CUSTOM_CHAIN_LEAVES.map((l) => `customChain.${l}`).join(', ')}, customChain.smartAccount.<leaf>.`\n );\n }\n return {\n ...(existing as NonNullable<CliConfig['customChain']>),\n [path]: value,\n };\n}\n","/**\n * `kash config show` — print the resolved configuration.\n *\n * Sources are surfaced (env vs file vs default) so users can debug\n * \"why is my key not picking up?\" without reading the source.\n */\n\nimport { Command } from 'commander';\n\nimport { readConfig } from '../../utils/config-store.js';\nimport { redact } from '../../utils/formatting.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { print, printJson, style } from '../../utils/output.js';\n\nexport const showConfigCommand = new Command('show')\n .description('Print the resolved CLI configuration.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config show\n $ kash config show --profile staging\n $ kash config show --json --quiet | jq -r '.baseUrl'\n`\n )\n .action(async (_opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n const config = await readConfig({\n ...(globals.profile === undefined ? {} : { profile: globals.profile }),\n ...(globals.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n\n if (globals.json) {\n // Shape pinned by `CliConfigEnvelopeSchema` in `cli-schemas.ts`.\n // Includes `authenticated` so it agrees with `auth status` —\n // agents that bind one shape can consume the other. Direct-mode\n // fields are always emitted (`null` when unset) so operators\n // can introspect the full profile via JSON.\n printJson({\n profile: config.profile,\n authenticated: Boolean(config.apiKey),\n apiKey: config.apiKey ? redact(config.apiKey) : null,\n baseUrl: config.baseUrl,\n defaultChainId: config.defaultChainId,\n rpcUrl: config.rpcUrl ?? null,\n smartAccount: config.smartAccount ?? null,\n bundlerUrl: config.bundlerUrl ?? null,\n bundlerProvider: config.bundlerProvider ?? null,\n signerKeyRef: config.signerKeyRef ?? null,\n customChain: config.customChain ?? null,\n sources: config.sources,\n });\n return;\n }\n\n print('');\n print(` ${style.dim('Profile ')} ${config.profile} (${config.sources.profile})`);\n print(\n ` ${style.dim('API key ')} ${config.apiKey ? redact(config.apiKey) : '(unset)'} (${config.sources.apiKey})`\n );\n print(` ${style.dim('Base URL ')} ${config.baseUrl} (${config.sources.baseUrl})`);\n print(\n ` ${style.dim('Default chain ')} ${String(config.defaultChainId)} (${config.sources.defaultChainId})`\n );\n // Surface direct-mode fields when any are set. Skip the section\n // entirely on a Kash-orchestrated-only profile so human output\n // stays terse.\n const hasDirectMode =\n config.rpcUrl !== undefined ||\n config.smartAccount !== undefined ||\n config.bundlerUrl !== undefined ||\n config.bundlerProvider !== undefined ||\n config.signerKeyRef !== undefined;\n if (hasDirectMode) {\n print('');\n print(` ${style.dim('Direct mode ')}`);\n print(\n ` ${style.dim(' RPC URL ')} ${config.rpcUrl ?? '(unset)'} (${config.sources.rpcUrl})`\n );\n print(\n ` ${style.dim(' Smart account')} ${config.smartAccount ?? '(unset)'} (${config.sources.smartAccount})`\n );\n print(\n ` ${style.dim(' Bundler URL ')} ${config.bundlerUrl ?? '(unset)'} (${config.sources.bundlerUrl})`\n );\n print(\n ` ${style.dim(' Bundler kind ')} ${config.bundlerProvider ?? '(unset)'} (${config.sources.bundlerProvider})`\n );\n print(\n ` ${style.dim(' Signer ref ')} ${config.signerKeyRef ?? '(unset)'} (${config.sources.signerKeyRef})`\n );\n }\n\n // Custom-chain section — surfaces when the profile bypasses the\n // protocol-sdk's static chain registry (Anvil / forks / sidechains).\n if (config.customChain !== undefined) {\n const cc = config.customChain;\n print('');\n print(` ${style.dim('Custom chain ')} (${config.sources.customChain})`);\n print(` ${style.dim(' Name ')} ${cc.name}`);\n print(` ${style.dim(' Factory ')} ${cc.factoryAddress}`);\n print(` ${style.dim(' USDC ')} ${cc.usdcAddress}`);\n if (cc.oracleAddress) print(` ${style.dim(' Oracle ')} ${cc.oracleAddress}`);\n if (cc.vaultAddress) print(` ${style.dim(' Vault ')} ${cc.vaultAddress}`);\n if (cc.tokens1155Address) print(` ${style.dim(' Tokens1155 ')} ${cc.tokens1155Address}`);\n if (cc.paramRegistryAddress)\n print(` ${style.dim(' ParamRegistry')} ${cc.paramRegistryAddress}`);\n if (cc.smartAccount) {\n print(` ${style.dim(' Smart account')}`);\n print(` ${style.dim(' Factory ')} ${cc.smartAccount.factoryAddress}`);\n print(` ${style.dim(' Implement. ')} ${cc.smartAccount.implementationAddress}`);\n print(` ${style.dim(' EntryPoint ')} ${cc.smartAccount.entryPointAddress}`);\n }\n }\n });\n","/**\n * `kash config use <profile>` — switch the active profile by writing\n * the file's `currentProfile` field.\n *\n * **Existence check.** By default we refuse to switch to a profile\n * that doesn't already exist — `kash config use staing` (typo) used\n * to silently succeed and the next command would fail with a\n * confusing `AUTH_REQUIRED`. Now we surface the typo with a list of\n * known profile names. The \"set up a fresh profile\" flow opts in via\n * `--allow-new`: `kash config use newprofile --allow-new` followed by\n * `kash auth set-key --profile newprofile <key>`.\n */\n\nimport { Command } from 'commander';\n\nimport { CliValidationError, toCliError } from '../../errors.js';\nimport { readWholeFile, setCurrentProfile } from '../../utils/config-store.js';\nimport { readGlobals } from '../../utils/global-options.js';\nimport { log, printJson } from '../../utils/output.js';\n\ntype UseProfileOptions = {\n allowNew?: boolean;\n};\n\nexport const useProfileCommand = new Command('use')\n .description('Switch the active profile (writes currentProfile to the config file).')\n .argument('<profile>', 'profile name')\n .option(\n '--allow-new',\n 'permit switching to a profile that does not yet exist (you must populate it via `kash auth set-key --profile <name>` afterwards)'\n )\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash config use staging\n $ kash config use prod --json --quiet\n $ kash config use newprofile --allow-new # explicitly create a fresh profile\n\nNotes:\n - By default \\`kash config use\\` refuses unknown profile names and\n lists the known ones — a typo of an existing profile name would\n otherwise surface later as a confusing AUTH_REQUIRED.\n - Use \\`--allow-new\\` for the bootstrapping flow when you genuinely\n want to switch to a not-yet-populated profile.\n`\n )\n .action(async (profile: string, options: UseProfileOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n const configPathOpt =\n globals.configPath === undefined ? {} : { configPath: globals.configPath };\n\n // Existence check: load the file once to see which profiles\n // exist, then either surface a structured \"did you mean\" error or\n // proceed with the write.\n let knownProfiles: readonly string[];\n try {\n const file = await readWholeFile(configPathOpt);\n knownProfiles = Object.keys(file.profiles).sort();\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (!knownProfiles.includes(profile) && options.allowNew !== true) {\n const known = knownProfiles.length === 0 ? '(none yet)' : knownProfiles.join(', ');\n throw new CliValidationError(\n `Profile \"${profile}\" does not exist.`,\n `Known profiles: ${known}. Pass --allow-new to create + switch to a fresh profile (you'll then need to populate it with \\`kash auth set-key --profile ${profile}\\`).`,\n 'profile'\n );\n }\n\n let updated;\n try {\n updated = await setCurrentProfile(profile, configPathOpt);\n } catch (cause) {\n throw toCliError(cause);\n }\n\n if (globals.json) {\n printJson({\n ok: true,\n currentProfile: updated.currentProfile,\n profiles: Object.keys(updated.profiles).sort(),\n // Surface whether this was a new-profile switch — agents can\n // pipe to `kash auth set-key --profile <p>` automatically when\n // `created` is true.\n created: !knownProfiles.includes(profile),\n });\n return;\n }\n log.success(`Active profile is now \"${profile}\".`);\n if (!knownProfiles.includes(profile)) {\n log.info(`Profile is empty. Populate it with: kash auth set-key --profile ${profile} <key>`);\n }\n });\n"],"mappings":"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","names":["Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DEFAULTS,
4
+ DEFAULT_PROFILE,
5
+ PRODUCTION_BASE_URL,
6
+ STAGING_BASE_URL,
7
+ clearConfigField,
8
+ cliConfigSchema,
9
+ cliFileSchema,
10
+ deleteConfig,
11
+ deleteProfile,
12
+ inferBaseUrlFromApiKey,
13
+ listProfiles,
14
+ readConfig,
15
+ readWholeFile,
16
+ resolveConfigPaths,
17
+ resolveConfigPathsForOverride,
18
+ setCurrentProfile,
19
+ updateConfig,
20
+ writeWholeFile
21
+ } from "./chunk-KMBMQIZ7.js";
22
+ import "./chunk-YHCG2SUC.js";
23
+ import "./chunk-UZNSYATZ.js";
24
+ export {
25
+ DEFAULTS,
26
+ DEFAULT_PROFILE,
27
+ PRODUCTION_BASE_URL,
28
+ STAGING_BASE_URL,
29
+ clearConfigField,
30
+ cliConfigSchema,
31
+ cliFileSchema,
32
+ deleteConfig,
33
+ deleteProfile,
34
+ inferBaseUrlFromApiKey,
35
+ listProfiles,
36
+ readConfig,
37
+ readWholeFile,
38
+ resolveConfigPaths,
39
+ resolveConfigPathsForOverride,
40
+ setCurrentProfile,
41
+ updateConfig,
42
+ writeWholeFile
43
+ };
44
+ //# sourceMappingURL=config-store-3ZSYGXMQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ readGlobals
4
+ } from "./chunk-LBIRQHX5.js";
5
+ import {
6
+ print,
7
+ printJson,
8
+ style
9
+ } from "./chunk-VIADBYFY.js";
10
+ import "./chunk-MIXOZU2S.js";
11
+ import "./chunk-UZNSYATZ.js";
12
+
13
+ // src/commands/docs.ts
14
+ import { Command } from "commander";
15
+ function describeCommand(cmd, parents = []) {
16
+ const name = cmd.name();
17
+ const fullName = [...parents, name].join(" ");
18
+ return {
19
+ name,
20
+ fullName,
21
+ description: cmd.description(),
22
+ aliases: cmd.aliases(),
23
+ arguments: cmd.registeredArguments.map(
24
+ (arg) => ({
25
+ name: arg.name(),
26
+ required: arg.required,
27
+ variadic: arg.variadic,
28
+ description: arg.description
29
+ })
30
+ ),
31
+ // `--help` and `-V/--version` are autogenerated by Commander on
32
+ // every command; they are not part of the contract any agent
33
+ // should plan calls against. Filter them so the docs tree only
34
+ // surfaces real options.
35
+ options: cmd.options.filter((opt) => opt.long !== "--help" && opt.long !== "--version").map((opt) => describeOption(opt)),
36
+ subcommands: cmd.commands.filter((c) => !isHelpCommand(c)).map((c) => describeCommand(c, [...parents, name]))
37
+ };
38
+ }
39
+ function isHelpCommand(cmd) {
40
+ const parent = cmd.parent;
41
+ if (parent?._helpCommand === cmd) return true;
42
+ return cmd.name() === "help";
43
+ }
44
+ function describeOption(opt) {
45
+ return {
46
+ flags: opt.flags,
47
+ long: opt.long ?? void 0,
48
+ short: opt.short ?? void 0,
49
+ aliases: extractAliases(opt),
50
+ description: opt.description,
51
+ required: opt.required,
52
+ optional: opt.optional,
53
+ defaultValue: opt.defaultValue ?? null,
54
+ choices: opt.argChoices ?? void 0
55
+ };
56
+ }
57
+ function extractAliases(opt) {
58
+ const seen = /* @__PURE__ */ new Set();
59
+ const known = /* @__PURE__ */ new Set();
60
+ if (opt.long) known.add(opt.long);
61
+ if (opt.short) known.add(opt.short);
62
+ for (const raw of opt.flags.split(",")) {
63
+ const piece = raw.trim().split(/\s+/)[0];
64
+ if (piece === void 0 || piece.length === 0) continue;
65
+ if (!piece.startsWith("-")) continue;
66
+ if (known.has(piece) || seen.has(piece)) continue;
67
+ seen.add(piece);
68
+ }
69
+ return [...seen];
70
+ }
71
+ function buildDocsCommand(getProgram) {
72
+ return new Command("docs").description("Emit the full command tree as JSON (or summary in human mode).").addHelpText(
73
+ "after",
74
+ `
75
+ Examples:
76
+ $ kash docs # human summary tree
77
+ $ kash docs --json # full machine-readable tree
78
+ $ kash docs --json | jq '.subcommands[].name'
79
+ `
80
+ ).action((_opts, cmd) => {
81
+ const globals = readGlobals(cmd);
82
+ const tree = describeCommand(getProgram());
83
+ if (globals.json) {
84
+ printJson(tree);
85
+ return;
86
+ }
87
+ print("");
88
+ print(style.bold(`${tree.fullName} \u2014 ${tree.description}`));
89
+ printSubtree(tree, "");
90
+ });
91
+ }
92
+ function printSubtree(node, indent) {
93
+ for (const sub of node.subcommands) {
94
+ print(`${indent} ${style.cyan(sub.name)} ${style.dim(sub.description)}`);
95
+ printSubtree(sub, `${indent} `);
96
+ }
97
+ }
98
+ export {
99
+ buildDocsCommand,
100
+ describeCommand
101
+ };
102
+ //# sourceMappingURL=docs-MDKKSJDC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/docs.ts"],"sourcesContent":["/**\n * `kash docs` — emit the entire CLI command tree as machine-readable\n * JSON.\n *\n * AI agents call this once at startup to discover every command,\n * argument, option, and example without scraping `--help` text. The\n * shape is documented as SemVer-stable: adding new fields is a minor\n * bump, removing them a major bump.\n *\n * Human mode prints a compact summary; JSON mode emits the full tree.\n */\n\nimport { Command, type Option } from 'commander';\n\nimport { readGlobals } from '../utils/global-options.js';\nimport { print, printJson, style } from '../utils/output.js';\n\nexport type CliDocsOption = {\n /** Raw flag spec as commander stores it (e.g. `--timeout-ms, --timeout <ms>`). */\n readonly flags: string;\n /** Canonical long name (e.g. `--timeout`). May be undefined for short-only flags. */\n readonly long: string | undefined;\n /** Short flag (e.g. `-l`). May be undefined for long-only flags. */\n readonly short: string | undefined;\n /**\n * Alternative flag names accepted at parse time, separate from\n * `long` and `short`. Populated when the option declares multiple\n * spellings (e.g. `--timeout-ms, --timeout`). Agents that emit\n * shell completions or generate documentation should treat every\n * entry as equivalent to `long`/`short`.\n */\n readonly aliases: readonly string[];\n readonly description: string;\n readonly required: boolean;\n readonly optional: boolean;\n readonly defaultValue: unknown;\n readonly choices: readonly string[] | undefined;\n};\n\nexport type CliDocsArgument = {\n readonly name: string;\n readonly required: boolean;\n readonly variadic: boolean;\n readonly description: string;\n};\n\nexport type CliDocsCommand = {\n readonly name: string;\n readonly fullName: string;\n readonly description: string;\n readonly aliases: readonly string[];\n readonly arguments: readonly CliDocsArgument[];\n readonly options: readonly CliDocsOption[];\n readonly subcommands: readonly CliDocsCommand[];\n};\n\n/**\n * Walk a Commander program and produce the JSON tree. Recursive over\n * sub-commands.\n */\nexport function describeCommand(cmd: Command, parents: readonly string[] = []): CliDocsCommand {\n const name = cmd.name();\n const fullName = [...parents, name].join(' ');\n\n return {\n name,\n fullName,\n description: cmd.description(),\n aliases: cmd.aliases(),\n arguments: cmd.registeredArguments.map(\n (arg): CliDocsArgument => ({\n name: arg.name(),\n required: arg.required,\n variadic: arg.variadic,\n description: arg.description,\n })\n ),\n // `--help` and `-V/--version` are autogenerated by Commander on\n // every command; they are not part of the contract any agent\n // should plan calls against. Filter them so the docs tree only\n // surfaces real options.\n options: cmd.options\n .filter((opt) => opt.long !== '--help' && opt.long !== '--version')\n .map((opt) => describeOption(opt)),\n subcommands: cmd.commands\n .filter((c) => !isHelpCommand(c))\n .map((c) => describeCommand(c, [...parents, name])),\n };\n}\n\n/**\n * Detect Commander's autogenerated `help [command]` subcommand. We\n * filter it out so `kash docs --json` only describes real commands.\n *\n * Commander stores a `_helpCommand` reference on the parent and\n * always names the autogenerated command `help` — we check both: the\n * structural `_helpCommand` reference is the primary signal (resilient\n * to Commander renaming the default), the name fallback covers\n * versions where the structural property isn't exposed.\n */\nfunction isHelpCommand(cmd: Command): boolean {\n // Commander 13's internal field carries the parent's help-command\n // reference. Cast through `unknown` so we don't depend on the\n // private surface in production types — this is a documented\n // structural escape hatch, not arbitrary `any` use.\n const parent = (cmd as unknown as { parent?: { _helpCommand?: Command } }).parent;\n if (parent?._helpCommand === cmd) return true;\n return cmd.name() === 'help';\n}\n\nfunction describeOption(opt: Option): CliDocsOption {\n return {\n flags: opt.flags,\n long: opt.long ?? undefined,\n short: opt.short ?? undefined,\n aliases: extractAliases(opt),\n description: opt.description,\n required: opt.required,\n optional: opt.optional,\n defaultValue: opt.defaultValue ?? null,\n choices: opt.argChoices ?? undefined,\n };\n}\n\n/**\n * Derive flag-name aliases from Commander's raw `flags` string.\n *\n * Commander's `Option.flags` is the verbatim spec the call site\n * passed (e.g. `--timeout-ms, --timeout <ms>`). It surfaces `long`\n * and `short` for the first two names, but if the option declares\n * three or more spellings — or two longs as in our `--timeout-ms,\n * --timeout` aliasing — the extras are silently absorbed. We parse\n * the raw spec, dedupe against `long` / `short`, and return whatever\n * else accepts the same value.\n *\n * Agents generating completions or documentation can iterate\n * `[long, short, ...aliases].filter(Boolean)` for the full set of\n * accepted spellings.\n */\nfunction extractAliases(opt: Option): readonly string[] {\n const seen = new Set<string>();\n const known = new Set<string>();\n if (opt.long) known.add(opt.long);\n if (opt.short) known.add(opt.short);\n // The flag-spec string looks like `-l, --limit <n>` or\n // `--timeout-ms, --timeout <ms>` — split on commas, then strip\n // any trailing `<value>`/`[value]` placeholder from each piece.\n for (const raw of opt.flags.split(',')) {\n const piece = raw.trim().split(/\\s+/)[0];\n if (piece === undefined || piece.length === 0) continue;\n if (!piece.startsWith('-')) continue; // not a flag (would be the value placeholder)\n if (known.has(piece) || seen.has(piece)) continue;\n seen.add(piece);\n }\n return [...seen];\n}\n\nexport function buildDocsCommand(getProgram: () => Command): Command {\n return new Command('docs')\n .description('Emit the full command tree as JSON (or summary in human mode).')\n .addHelpText(\n 'after',\n `\nExamples:\n $ kash docs # human summary tree\n $ kash docs --json # full machine-readable tree\n $ kash docs --json | jq '.subcommands[].name'\n`\n )\n .action((_opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n const tree = describeCommand(getProgram());\n\n if (globals.json) {\n printJson(tree);\n return;\n }\n\n print('');\n print(style.bold(`${tree.fullName} — ${tree.description}`));\n printSubtree(tree, '');\n });\n}\n\nfunction printSubtree(node: CliDocsCommand, indent: string): void {\n for (const sub of node.subcommands) {\n print(`${indent} ${style.cyan(sub.name)} ${style.dim(sub.description)}`);\n printSubtree(sub, `${indent} `);\n }\n}\n"],"mappings":"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","names":[]}