@haven_ai/cli 0.0.0-dev.202609050932.747d815 → 0.0.0-dev.202609051106.201fc90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -350,7 +350,7 @@ function sessionExpiry(token) {
|
|
|
350
350
|
|
|
351
351
|
// src/commands.ts
|
|
352
352
|
var DEFAULT_API = "https://havenbackend-production-8a00.up.railway.app";
|
|
353
|
-
var CLI_VERSION = "0.0.0-dev.
|
|
353
|
+
var CLI_VERSION = "0.0.0-dev.202609051106.201fc90";
|
|
354
354
|
async function run(argv, deps = {}) {
|
|
355
355
|
const out = deps.out ?? ((l) => process.stdout.write(`${l}
|
|
356
356
|
`));
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/args.ts","../src/api.ts","../src/session.ts","../src/format.ts","../src/csv.ts","../src/errors.ts","../src/output.ts","../src/agent-guidance-text.ts","../src/token.ts","../src/commands.ts","../src/prompt.ts","../src/cli.ts"],"names":["resolve","homedir","join","readFile","mkdir","writeFile","chmod","rm","emitKeypressEvents"],"mappings":"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","file":"cli.cjs","sourcesContent":["export interface ParsedArgs {\n command?: string\n sub?: string\n positionals: string[]\n flags: {\n json: boolean\n help: boolean\n version: boolean\n yes: boolean\n api?: string\n email?: string\n safe?: string\n agent?: string\n limit?: number\n offset?: number\n direction?: 'in' | 'out'\n format?: string\n from?: string\n to?: string\n company?: string\n }\n}\n\nconst VALUE_FLAGS = new Set([\n '--api', '--email', '--safe', '--agent', '--limit', '--offset', '--direction',\n '--format', '--from', '--to', '--company',\n])\n\n/**\n * `haven <command> [sub] [positionals] [--flags]`. Deliberately small — no\n * dependency, no clever aliasing. Unknown flags throw so typos fail loudly.\n */\nexport function parseArgs(argv: string[]): ParsedArgs {\n const positionals: string[] = []\n const flags: ParsedArgs['flags'] = { json: false, help: false, version: false, yes: false }\n\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i]\n if (arg === '--json') flags.json = true\n else if (arg === '--help' || arg === '-h') flags.help = true\n else if (arg === '--version' || arg === '-v') flags.version = true\n else if (arg === '--yes' || arg === '-y') flags.yes = true\n else if (VALUE_FLAGS.has(arg)) {\n const value = argv[++i]\n if (value === undefined || value.startsWith('--')) {\n throw new Error(`Missing value for ${arg}`)\n }\n if (arg === '--api') flags.api = value\n else if (arg === '--email') flags.email = value\n else if (arg === '--safe') flags.safe = value\n else if (arg === '--agent') flags.agent = value\n else if (arg === '--limit') {\n const n = Number(value)\n if (!Number.isInteger(n) || n <= 0) throw new Error('--limit must be a positive integer')\n flags.limit = n\n } else if (arg === '--offset') {\n const n = Number(value)\n if (!Number.isInteger(n) || n < 0) throw new Error('--offset must be a non-negative integer')\n flags.offset = n\n } else if (arg === '--direction') {\n if (value !== 'in' && value !== 'out') throw new Error('--direction must be \"in\" or \"out\"')\n flags.direction = value\n } else if (arg === '--format') {\n if (value !== 'csv' && value !== 'sie') throw new Error('--format must be \"csv\" or \"sie\"')\n flags.format = value\n } else if (arg === '--from') flags.from = value\n else if (arg === '--to') flags.to = value\n else if (arg === '--company') flags.company = value\n } else if (arg.startsWith('--')) {\n throw new Error(`Unknown option: ${arg}`)\n } else {\n positionals.push(arg)\n }\n }\n\n const [command, sub, ...rest] = positionals\n return { command, sub, positionals: rest, flags }\n}\n\nexport function helpText(): string {\n return [\n 'haven — terminal-native companion to the Haven dashboard',\n '',\n 'Usage: haven <command> [subcommand] [options]',\n '',\n 'Auth:',\n ' login [--email <e>] Sign in (password via prompt or HAVEN_PASSWORD)',\n ' logout Clear the saved session',\n ' whoami Show the signed-in user, session expiry and API URL',\n '',\n 'For agents:',\n ' guide Print the agent onboarding runbook (same text as /for-agents.md)',\n '',\n 'Read:',\n ' wallets list List your Haven wallets',\n ' wallets balances [--safe <id|address>] Token balances for a wallet',\n ' agents list List your agents',\n ' agents show <id> Show one agent + its budget',\n ' budget show <agentId> Show an agent\\'s configured budget',\n ' activity list [--safe <id|address>] [--agent <id>] [--direction in|out] [--limit <n>] [--offset <n>]',\n ' activity export [filters] Emit CSV to stdout (--format csv, default)',\n ' activity export --format sie [--from <ISO>] [--to <ISO>] [--company <name>]',\n ' Bookkeeping-ready SIE 4I (Fortnox/Visma/Bokio)',\n ' catalog list List payable services',\n ' contacts list List your address book',\n '',\n 'Manage (backend-only — no on-chain signing):',\n ' agents pause|resume <id>',\n ' agents revoke <id> --yes Permanently revoke an agent',\n ' agents rotate-key <id> Issue a new API key (shown once)',\n ' agents rename <id> <name>',\n ' wallets rename <id> <name>',\n ' contacts add <name> <address> | contacts remove <id>',\n '',\n 'Options:',\n ' --json One JSON value on stdout, prose on stderr, on every',\n ' command including refusals: { ok: false, error: { code, message, hint? } }',\n ' --yes, -y Skip the confirmation prompt for destructive actions',\n ' --api <url> Backend URL (default: HAVEN_API_URL or http://localhost:3001)',\n ' --help, --version',\n '',\n 'Exit codes: 0 ok · 1 failed · 2 usage · 3 not authenticated · 4 refused · 5 network',\n '',\n 'On-chain actions (deploy, budgets, approvers, send) are signed in the',\n 'dashboard — this CLI reads and manages; it never holds your keys.',\n ].join('\\n')\n}\n","export class CliApiError extends Error {\n status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'CliApiError'\n this.status = status\n }\n}\n\nexport interface CliApi {\n get<T>(path: string): Promise<T>\n post<T>(path: string, body?: unknown): Promise<T>\n put<T>(path: string, body?: unknown): Promise<T>\n del<T>(path: string): Promise<T>\n /** GET a non-JSON body (e.g. an export file) as raw text. */\n getText(path: string): Promise<string>\n}\n\nexport interface CreateCliApiOptions {\n baseUrl: string\n token?: string\n fetchImpl?: typeof fetch\n}\n\n/**\n * Minimal JSON client for the Haven backend. Sends the user JWT as a Bearer\n * token when present, and surfaces backend `{ error }` messages as\n * `CliApiError` so commands can print something human.\n */\nexport function createCliApi({ baseUrl, token, fetchImpl = fetch }: CreateCliApiOptions): CliApi {\n const root = baseUrl.replace(/\\/+$/, '')\n\n async function request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = { Accept: 'application/json' }\n if (token) headers.Authorization = `Bearer ${token}`\n if (body !== undefined) headers['Content-Type'] = 'application/json'\n\n let res: Response\n try {\n res = await fetchImpl(`${root}${path}`, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n } catch (err) {\n throw new CliApiError(\n `Could not reach Haven at ${root}: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n )\n }\n\n if (res.status === 401) {\n throw new CliApiError('Not authenticated. Run `haven login` first.', 401)\n }\n\n const text = await res.text()\n const payload = text ? safeParse(text) : undefined\n\n if (!res.ok) {\n const message =\n (payload && typeof payload === 'object' && 'error' in payload && typeof payload.error === 'string'\n ? payload.error\n : null) ?? `Request failed (HTTP ${res.status}).`\n throw new CliApiError(message, res.status)\n }\n\n return payload as T\n }\n\n async function requestText(path: string): Promise<string> {\n const headers: Record<string, string> = { Accept: 'text/plain' }\n if (token) headers.Authorization = `Bearer ${token}`\n\n let res: Response\n try {\n res = await fetchImpl(`${root}${path}`, { method: 'GET', headers })\n } catch (err) {\n throw new CliApiError(\n `Could not reach Haven at ${root}: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n )\n }\n\n if (res.status === 401) {\n throw new CliApiError('Not authenticated. Run `haven login` first.', 401)\n }\n\n const text = await res.text()\n if (!res.ok) {\n const payload = text ? safeParse(text) : undefined\n const message =\n (payload && typeof payload === 'object' && 'error' in payload && typeof payload.error === 'string'\n ? payload.error\n : null) ?? `Request failed (HTTP ${res.status}).`\n throw new CliApiError(message, res.status)\n }\n return text\n }\n\n return {\n get: <T>(path: string) => request<T>('GET', path),\n post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),\n put: <T>(path: string, body?: unknown) => request<T>('PUT', path, body),\n del: <T>(path: string) => request<T>('DELETE', path),\n getText: (path: string) => requestText(path),\n }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return undefined\n }\n}\n","import { mkdir, readFile, rm, writeFile, chmod } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join, resolve } from 'node:path'\n\n/**\n * The signed-in user session. The token is a *user* JWT (same credential the\n * dashboard holds) — treat it like a secret: stored owner-only, never logged,\n * never sent anywhere but the Haven API. `apiBaseUrl` is pinned at login so\n * later commands talk to the same backend.\n */\nexport interface Session {\n token: string\n apiBaseUrl: string\n user: { id: string; email: string; name: string | null }\n}\n\nexport interface SessionStore {\n load(): Promise<Session | null>\n save(session: Session): Promise<void>\n clear(): Promise<void>\n path: string\n}\n\nfunction sessionDir(homeDir: string): string {\n return resolve(homeDir, '.haven')\n}\n\nexport function sessionPath(homeDir: string = homedir()): string {\n return join(sessionDir(homeDir), 'session.json')\n}\n\n/** File-backed session store, owner-only perms (0600 file in a 0700 dir). */\nexport function createSessionStore(homeDir: string = homedir()): SessionStore {\n const path = sessionPath(homeDir)\n return {\n path,\n async load() {\n try {\n const raw = await readFile(path, 'utf8')\n const parsed = JSON.parse(raw) as Partial<Session>\n if (!parsed.token || !parsed.apiBaseUrl || !parsed.user) return null\n return parsed as Session\n } catch {\n return null\n }\n },\n async save(session) {\n await mkdir(sessionDir(homeDir), { recursive: true, mode: 0o700 })\n await writeFile(path, `${JSON.stringify(session, null, 2)}\\n`, { mode: 0o600 })\n await chmod(path, 0o600).catch(() => undefined)\n },\n async clear() {\n await rm(path, { force: true })\n },\n }\n}\n","/** Tiny fixed-width table for human output. Scriptable callers use `--json`. */\nexport function table(headers: string[], rows: string[][]): string {\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)),\n )\n const line = (cells: string[]) =>\n cells.map((c, i) => (c ?? '').padEnd(widths[i])).join(' ').trimEnd()\n return [line(headers), line(widths.map((w) => '-'.repeat(w))), ...rows.map(line)].join('\\n')\n}\n\nexport function truncateAddress(address: string): string {\n if (!address || address.length <= 12) return address\n return `${address.slice(0, 6)}…${address.slice(-4)}`\n}\n\nconst CHAIN_NAMES: Record<number, string> = { 100: 'Gnosis', 8453: 'Base' }\n\nexport function chainName(chainId: number): string {\n return CHAIN_NAMES[chainId] ?? `chain ${chainId}`\n}\n","/**\n * CSV serialization for `haven activity export`. Mirrors the dashboard export\n * (#411): RFC 4180 quoting, CRLF line endings, and a spreadsheet\n * formula-injection guard. Kept self-contained so the CLI has no @haven_ai/*\n * runtime dependency.\n */\n\n/** Quote per RFC 4180 and neutralise leading =,+,-,@ (Excel formula injection). */\nfunction csvField(value: string): string {\n let v = value\n if (/^[=+\\-@\\t\\r]/.test(v)) v = `'${v}`\n return `\"${v.replace(/\"/g, '\"\"')}\"`\n}\n\nexport function toCsv(headers: string[], rows: string[][]): string {\n const lines = [headers.join(','), ...rows.map((r) => r.map(csvField).join(','))]\n return lines.join('\\r\\n')\n}\n","import { CliApiError } from './api.js'\n\n/**\n * Exit codes (#2525). Documented in README.md § For agents and scripts, and\n * asserted in `json-contract.test.ts` (every code, over the whole command list)\n * and `commands.test.ts` (the individual commands that produce them) — an agent\n * branches on these, so they are a contract rather than an implementation\n * detail.\n */\nexport const EXIT = {\n ok: 0,\n /** Something failed and none of the specific codes below describe it. */\n failed: 1,\n /** The command line was wrong: unknown command, missing argument, bad flag. */\n usage: 2,\n /** No stored session, or the backend rejected the one we have. Log in again. */\n notAuthenticated: 3,\n /** Authenticated, and the backend refused anyway (403, 410, other 4xx). */\n refused: 4,\n /** The backend could not be reached at all. */\n network: 5,\n} as const\n\nexport type ExitCode = (typeof EXIT)[keyof typeof EXIT]\n\n/** Machine-readable `error.code` values, one per exit code above 0. */\nexport type FailureCode = 'failed' | 'usage' | 'not_authenticated' | 'refused' | 'network'\n\n/** A wrong command line. Carries `usage` so callers do not guess the exit code. */\nexport class UsageError extends Error {\n readonly hint?: string\n constructor(message: string, hint?: string) {\n super(message)\n this.name = 'UsageError'\n this.hint = hint\n }\n}\n\nexport interface Failure {\n code: FailureCode\n exit: ExitCode\n message: string\n hint?: string\n}\n\n/**\n * One place that decides what an error means, so the JSON body and the exit\n * code cannot disagree — they are read off the same object.\n *\n * **On 401 → `not_authenticated`, not `refused`.** The issue lists 401\n * alongside 403/410 under \"refused by the backend\", and separately lists\n * \"not logged in / session expired\" — the two overlap, and a 401 is exactly\n * the second one. An agent seeing `not_authenticated` knows to re-run\n * `haven login`; `refused` tells it the opposite (the session is fine, the\n * action is not allowed). Splitting them on the wire is the whole point of\n * having two codes, so 401 resolves to the one it can act on.\n */\nexport function toFailure(err: unknown): Failure {\n if (err instanceof UsageError) {\n return { code: 'usage', exit: EXIT.usage, message: err.message, hint: err.hint }\n }\n if (err instanceof CliApiError) {\n if (err.status === 0) {\n return {\n code: 'network',\n exit: EXIT.network,\n message: err.message,\n hint: 'Check the network and `--api`, then retry.',\n }\n }\n if (err.status === 401) {\n return {\n code: 'not_authenticated',\n exit: EXIT.notAuthenticated,\n message: err.message,\n hint: 'Run `haven login` (or set HAVEN_EMAIL and HAVEN_PASSWORD).',\n }\n }\n if (err.status >= 400 && err.status < 500) {\n // 403 and 410 are the named cases; every other 4xx is the same shape of\n // answer — the backend understood and said no — so it gets the same code\n // rather than falling through to the generic one.\n return { code: 'refused', exit: EXIT.refused, message: err.message }\n }\n return { code: 'failed', exit: EXIT.failed, message: err.message }\n }\n return { code: 'failed', exit: EXIT.failed, message: err instanceof Error ? err.message : String(err) }\n}\n","import type { Failure } from './errors.js'\n\n/**\n * The `--json` contract (#2525).\n *\n * Under `--json`, **stdout carries exactly one JSON value and nothing else** —\n * every line of human prose goes to stderr instead. That is what lets an agent\n * pipe stdout straight into a parser without stripping progress chatter, and\n * it is why `note()` exists: the same call site prints a sentence for a human\n * and stays silent (on stdout) for a machine.\n *\n * Success keeps the payload shape each command already emitted — including the\n * bare arrays that `agents list` and friends return — so this change adds a\n * failure contract without breaking a script that already parses a success.\n * Failures are always the object `{ ok: false, error: { code, message, hint? } }`.\n */\nexport interface Output {\n readonly json: boolean\n /** The command's success payload. At most one per run, on stdout. */\n data(payload: unknown, human: () => string): void\n /** Raw text (an export file). Printed as-is; wrapped under `--json`. */\n text(content: string, meta: Record<string, unknown>): void\n /** Human prose. Stdout in prose mode; stderr under `--json`. */\n note(line: string): void\n /** The one failure object. Always stdout under `--json`, stderr otherwise. */\n failure(failure: Failure): void\n}\n\nexport function createOutput(\n json: boolean,\n out: (line: string) => void,\n err: (line: string) => void,\n): Output {\n return {\n json,\n data(payload, human) {\n out(json ? JSON.stringify(payload, null, 2) : human())\n },\n text(content, meta) {\n // A CSV/SIE body is the payload in prose mode. Under --json it becomes a\n // field of the single object, so the contract (\"one JSON value on\n // stdout\") holds for exports too and the content stays recoverable.\n out(json ? JSON.stringify({ ok: true, ...meta, content }, null, 2) : content)\n },\n note(line) {\n if (json) err(line)\n else out(line)\n },\n failure(failure) {\n const body = {\n ok: false as const,\n error: {\n code: failure.code,\n message: failure.message,\n ...(failure.hint ? { hint: failure.hint } : {}),\n },\n }\n if (json) out(JSON.stringify(body, null, 2))\n else err(failure.hint ? `${failure.message}\\n${failure.hint}` : failure.message)\n },\n }\n}\n","/**\n * The agent onboarding runbook — GENERATED, do not edit by hand.\n *\n * Canonical source: `packages/sdk/src/agent-guidance.ts` (#2523), served to\n * agents at `/for-agents.md`. This is a decoupled copy so `@haven_ai/cli`\n * keeps zero runtime dependencies: importing it from the SDK would put ethers,\n * viem and x402 on the `npx @haven_ai/cli` path for one Markdown string.\n * Same arrangement, and the same reason, as\n * `packages/frontend/src/lib/agent-skill-bundle.ts`.\n *\n * Regenerate: node packages/cli/scripts/sync-agent-guidance.mjs\n * The parity test in `agent-guidance-text.test.ts` fails if you forget.\n */\n\nexport const HAVEN_AGENT_RUNBOOK_MD = \"# Haven for agents — set your user up to let you pay\\n\\nYou are an AI agent whose user has no Haven account yet, or has one but has not connected you.\\n\\n> Links below are paths on this same host: resolve them against the URL you fetched this file from.\\n\\n## What Haven is, in three sentences\\n\\nYour user gives you a **budget on their own account** — not their wallet, and not a key to their funds. The budget is a delegation they sign, enforced on-chain: a payment over it, to the wrong recipient, or past its expiry is refused at execution time, not by a dashboard promise. Haven constructs and relays the payments; you get an agent credential and a signing key made on your machine, and your user can revoke the budget without you and without Haven.\\n\\n## The sequence\\n\\nFour of the six steps are your user's — each needs a human signature or a human decision. The rest is yours. If they already have a funded account, start at step 3.\\n\\n1. **HUMAN — create the account.** Name, email, password, then a passkey (Face ID / Touch ID) or a wallet. Never offer to enter any of it: you must not have their password, and the passkey is bound to their device.\\n2. **HUMAN — fund it.** USDC on Base, to the address the dashboard shows.\\n3. **HUMAN — create the agent, set its budget**, and paste you the **setup prompt** it hands back.\\n4. **YOU — run the connector command** in that prompt (below). It makes your signing key locally, registering only the public address.\\n5. **HUMAN — approve the budget** with their passkey, in the Haven tab they created the agent in: it advances to the approval step by itself once your run registers.\\n6. **YOU — verify, then pay.**\\n\\n## Hand-off scripts\\n\\nSend these as your own message, `<host>` replaced by the host you fetched this file from. Say what you cannot do, not only what they must.\\n\\n**Before signup** (step 1):\\n\\n> I can do everything except the parts that need your signature. Please open `<host>/signup?next=/agents&via=agent` — name, email, password, then a passkey (Face ID / Touch ID) or a wallet. That is your account's key: I should not have it, and I will never ask for your password. Already have one? `<host>/login?next=/agents`.\\n\\n**At the passkey step:**\\n\\n> The passkey must be made on your own device — it is what keeps the account yours, so nobody, Haven included, can move your funds without you. If this browser cannot, open `<host>/onboarding?next=/agents` on your phone and finish there.\\n\\n**At funding** (step 2):\\n\\n> Your Haven account needs USDC on Base before I can pay for anything — USDC only, no ETH: Haven sponsors the gas. The dashboard shows the address to send it to; a small amount first is fine.\\n\\n**At the budget** (step 3):\\n\\n> On `<host>/agents`, create an agent for me and set a budget — say 25 USDC per day. That is the limit I cannot exceed. It hands back a setup prompt: paste it to me and I run it here.\\n\\n**At budget approval** (step 5) — the moment your run reports that approval is required, before anything else. Send the first if your run carried `approval.url`, the second if it did not.\\n\\n> Setup is done on my side. Approve the budget here: <approval.url>. Approve it with your passkey; nothing can be spent until you do.\\n\\n> Setup is done on my side. Go back to the Haven tab where you created the agent — it should now be asking you to approve the budget. Approve it with your passkey; nothing can be spent until you do.\\n\\n## What you run\\n\\nThe setup prompt carries a **connector command** shaped like this:\\n\\n```\\nnpx -y @haven_ai/connect@<channel> --setup EXAMPLE-SETUP-TOKEN-NOT-REAL --api <api-url> --ack-local-tools\\n```\\n\\nRun the prompt's version, not this one: the token is one-time, the API URL is the backend's own, and `<channel>` is the npm tag your prompt names — never a tag you pick. The rules below come from that prompt, so \\\"me\\\" in them is your user, not Haven.\\n\\n- If you are an AI agent running this command yourself rather than a human pasting it, you should append --json: the connector then emits one machine-readable, secret-free result object on stdout with progress on stderr, and returns promptly instead of blocking while it waits for the budget approval.\\n- When a --json outcome reports approval.required: true, your first action must be to relay the approval instruction to me in your own reply — if the outcome carries approval.url, give me that link; otherwise tell me to return to Haven and approve this agent's budget — before verifying the connection, restarting anything, or any other step. Never build that link yourself: relay the one the outcome gave you or none at all. Any restart the outcome asks for is a separate instruction to give me afterwards, once the approval is done.\\n- If you ran the command without --json, the connector waits for the approval itself and prints its next steps when it finishes: relay the budget-approval instruction to me — the approval link if those steps printed one, otherwise that you need to return to Haven and approve this agent's budget — only if those printed next steps still ask for it. If they report the budget as already approved, there is nothing for me to approve.\\n- Only two changes to the command above are permitted, and no others: appending --json, and — only if the connector refuses because it could not determine the agent runtime — re-running it once with --runtime <name> added, naming the harness you are running in, using one of the values that refusal lists. Never invent a runtime name and never change anything else.\\n- Do not print private keys, API keys, credential file contents, or config secrets in chat or logs.\\n\\nIf the approval wait times out, nothing is lost — your agent is registered and the budget is still waiting to be approved. Send your user the `approval.url` your run reported, or, if it carried none, ask them to finish it in that same Haven tab. The outcome carries no setup id, so never assemble an approval link out of parts — relay the whole one it gave you or none at all.\\n\\n## How to verify\\n\\nCall `haven_get_agent`, one of the Haven MCP tools the connector wires into your runtime in step 4. It returns identity plus `spend_authority_readiness`:\\n\\n- `ready` — a budget is live; you can pay.\\n- `needs_approval` — the connector finished, nobody approved yet. Ask your user again, in their Haven tab; there is no queue to wait in.\\n- `revoked` — the credential is not active; ask your user to create a new agent.\\n\\n`ready` covers hosted identity and the budget only, not your local signer. Check that with `npx -y @haven_ai/connect@<channel> --doctor`, the same tag your prompt named — a separate command, so the two-changes rule does not bind it.\\n\\n## If you cannot open a browser\\n\\nNothing here needs you to. Steps 1-3 are links: hand your user the full `<host>/…` URL and ask them to say when it is done. Step 5 is a link only when your run reported one in `approval.url` — otherwise it is the tab they already have open, as above. Then poll `haven_get_agent` until it reads `ready`. Do not route around the sign-in wall — it makes the account theirs, not yours.\\n\\n## Vocabulary\\n\\n| Term | What it is |\\n|---|---|\\n| **setup prompt** | The text the dashboard hands your user to paste to you. Carries the command and its rules. |\\n| **connector command** | The `npx -y @haven_ai/connect@…` line you run. One-time token, one use. |\\n| **agent credential** | Your API key (`sk_agent_…`), written to `~/.haven`. It identifies you; alone it cannot move money. |\\n| **delegate key** | Your signing key, made on this machine and never sent anywhere. |\\n| **budget** | The on-chain delegation your user signed. It authorises the payment; Haven constructs and relays it. |\\n\\nNext: [your agent hit a 402](/402.md) · [everything agent-readable](/llms.txt)\\n\"\n","/**\n * Read the expiry out of the stored session JWT (#2525).\n *\n * `whoami --json` and `login --json` report when the session dies, and the\n * only place that fact exists is the token's own `exp` claim — the backend\n * signs it with `expiresIn: '7d'` (`routes/auth.ts`) and `/auth/me` does not\n * return it. So the payload segment is base64url-decoded and read.\n *\n * This deliberately does NOT verify the signature, and must never be used to\n * decide anything but what to print: the CLI has no key to verify with, and a\n * forged `exp` would only mislead the user about a token the backend will\n * reject on its own terms. It never logs, echoes or returns the token itself.\n */\nexport function sessionExpiry(token: string): string | null {\n const segment = token.split('.')[1]\n if (!segment) return null\n try {\n const json = Buffer.from(segment.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf8')\n const claims = JSON.parse(json) as { exp?: unknown }\n if (typeof claims.exp !== 'number' || !Number.isFinite(claims.exp)) return null\n return new Date(claims.exp * 1000).toISOString()\n } catch {\n // A token we cannot read is not an error worth failing a command over —\n // the expiry is informational, and every other field still resolves.\n return null\n }\n}\n","import { parseArgs, helpText, type ParsedArgs } from './args.js'\nimport { createCliApi, CliApiError, type CliApi } from './api.js'\nimport { createSessionStore, type Session, type SessionStore } from './session.js'\nimport { chainName, table, truncateAddress } from './format.js'\nimport { toCsv } from './csv.js'\nimport { EXIT, UsageError, toFailure, type ExitCode } from './errors.js'\nimport { createOutput, type Output } from './output.js'\nimport { HAVEN_AGENT_RUNBOOK_MD } from './agent-guidance-text.js'\nimport { sessionExpiry } from './token.js'\n\n// Hosted Haven backend. Override with `--api <url>` or HAVEN_API_URL (e.g. a\n// local backend at http://localhost:3001, or your own domain once self-hosted).\nconst DEFAULT_API = 'https://havenbackend-production-8a00.up.railway.app'\n// Self-reported CLI version. Owned by scripts/release-bump.mjs, which rewrites\n// the string literal below on every release — keep it a bare quoted literal.\nexport const CLI_VERSION = '0.0.0-dev.202609050932.747d815'\n\nexport interface RunDeps {\n sessionStore?: SessionStore\n /** Build an API client; injected so tests can stub the backend. */\n makeApi?: (baseUrl: string, token?: string) => CliApi\n promptPassword?: () => Promise<string>\n out?: (line: string) => void\n err?: (line: string) => void\n env?: NodeJS.ProcessEnv\n}\n\ninterface ResolvedDeps {\n sessionStore: SessionStore\n makeApi: (baseUrl: string, token?: string) => CliApi\n promptPassword: () => Promise<string>\n out: (line: string) => void\n err: (line: string) => void\n env: NodeJS.ProcessEnv\n /** Set once `--json` is known; every command writes through it. */\n o: Output\n}\n\n/**\n * Every command this CLI dispatches, as data (#2525).\n *\n * The table-driven contract test in `json-contract.test.ts` iterates THIS list\n * and asserts each command's `--json` refusal is one JSON object on stdout, so\n * a command added to `dispatch` without adding it here is not covered. Its\n * ceiling, stated plainly: the test proves the listed commands honour the\n * contract, not that the list is complete. A drift test below pins the list\n * against `dispatch`'s own switch to close that gap by execution.\n */\nexport const COMMANDS = [\n 'login', 'logout', 'whoami', 'guide',\n 'wallets list', 'wallets balances', 'wallets rename',\n 'agents list', 'agents show', 'agents pause', 'agents resume', 'agents revoke',\n 'agents rotate-key', 'agents rename',\n 'budget show',\n 'activity list', 'activity export',\n 'catalog list',\n 'contacts list', 'contacts add', 'contacts remove',\n] as const\n\n// ── Backend response shapes (subset the CLI needs) ──────────────────\ninterface Safe { id: string; safe_address: string; chain_id: number; name: string; is_default: boolean }\ninterface Allowance { token_symbol: string; allowance_amount: string; reset_period_min: number }\ninterface Agent { id: string; name: string; status: string; allowances?: Allowance[] }\ninterface Balance { symbol: string; formatted: string; balance: string }\ninterface Txn {\n hash: string; direction: 'in' | 'out'; valueFormatted: string; asset: string\n source?: string; timestamp: number; safeName?: string\n from?: string; to?: string; isError?: boolean\n tokenSymbol?: string; tokenAddress?: string; chainId?: number; safeAddress?: string\n agentName?: string; paymentFlowStatus?: string | null; activityType?: string\n}\ninterface CatalogEntry { name: string; category: string; rail: string; price_display?: string | null; status: string }\ninterface Contact { id: string; name: string; address: string }\n\n/** Entry point. Returns a process exit code; never throws for expected errors. */\nexport async function run(argv: string[], deps: RunDeps = {}): Promise<number> {\n const out = deps.out ?? ((l: string) => process.stdout.write(`${l}\\n`))\n const err = deps.err ?? ((l: string) => process.stderr.write(`${l}\\n`))\n\n // `--json` has to be known before anything can be emitted, including a parse\n // failure's own message. Scanning argv for the flag is deliberate: parseArgs\n // throws on a bad line, and a refusal that ignored --json because the parse\n // failed would break the contract exactly when a caller most needs it.\n const json = argv.includes('--json')\n const o = createOutput(json, out, err)\n\n const d: ResolvedDeps = {\n sessionStore: deps.sessionStore ?? createSessionStore(),\n makeApi: deps.makeApi ?? ((baseUrl, token) => createCliApi({ baseUrl, token })),\n promptPassword: deps.promptPassword ?? (() => Promise.reject(new Error('No password input available'))),\n out,\n err,\n env: deps.env ?? process.env,\n o,\n }\n\n let args: ParsedArgs\n try {\n args = parseArgs(argv)\n } catch (e) {\n return fail(d, new UsageError(e instanceof Error ? e.message : String(e), 'Run `haven --help`.'))\n }\n\n if (args.flags.version) {\n o.data({ version: CLI_VERSION }, () => CLI_VERSION)\n return EXIT.ok\n }\n if (args.flags.help || !args.command) {\n o.data({ help: helpText() }, () => helpText())\n return EXIT.ok\n }\n\n try {\n return await dispatch(args, d)\n } catch (e) {\n return fail(d, e)\n }\n}\n\n/** The single exit: one failure object, one exit code, read off one decision. */\nfunction fail(d: ResolvedDeps, err: unknown): ExitCode {\n const failure = toFailure(err)\n d.o.failure(failure)\n return failure.exit\n}\n\nasync function dispatch(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const key = args.sub ? `${args.command} ${args.sub}` : args.command\n switch (key) {\n case 'guide': return cmdGuide(args, d)\n case 'login': return cmdLogin(args, d)\n case 'logout': return cmdLogout(args, d)\n case 'whoami': return cmdWhoami(args, d)\n case 'wallets list': return cmdWalletsList(args, d)\n case 'wallets balances': return cmdWalletsBalances(args, d)\n case 'agents list': return cmdAgentsList(args, d)\n case 'agents show': return cmdAgentsShow(args, d)\n case 'agents pause': return cmdAgentLifecycle(args, d, 'pause')\n case 'agents resume': return cmdAgentLifecycle(args, d, 'resume')\n case 'agents revoke': return cmdAgentRevoke(args, d)\n case 'agents rotate-key': return cmdAgentRotateKey(args, d)\n case 'agents rename': return cmdAgentRename(args, d)\n case 'budget show': return cmdBudgetShow(args, d)\n case 'wallets rename': return cmdWalletRename(args, d)\n case 'activity list': return cmdActivityList(args, d)\n case 'activity export': return cmdActivityExport(args, d)\n case 'catalog list': return cmdCatalogList(args, d)\n case 'contacts list': return cmdContactsList(args, d)\n case 'contacts add': return cmdContactsAdd(args, d)\n case 'contacts remove': return cmdContactsRemove(args, d)\n default:\n throw new UsageError(`Unknown command: ${key}.`, 'Run `haven --help` for the command list.')\n }\n}\n\nfunction baseUrlFor(args: ParsedArgs, d: ResolvedDeps, session: Session | null): string {\n return args.flags.api ?? session?.apiBaseUrl ?? d.env.HAVEN_API_URL ?? DEFAULT_API\n}\n\nasync function authed(args: ParsedArgs, d: ResolvedDeps): Promise<{ session: Session; api: CliApi }> {\n const session = await d.sessionStore.load()\n // Status 401 so a missing local session and a rejected one produce the same\n // code and the same advice — from the caller's side they are one situation.\n if (!session) throw new CliApiError('Not authenticated.', 401)\n return { session, api: d.makeApi(baseUrlFor(args, d, session), session.token) }\n}\n\nfunction emit(d: ResolvedDeps, _json: boolean, data: unknown, human: () => string): void {\n d.o.data(data, human)\n}\n\n// ── Guide ───────────────────────────────────────────────────────────\n\n/**\n * Print the agent onboarding runbook — the same text served at\n * `/for-agents.md` (#2523). Offline by construction: the string is compiled in,\n * so an agent with no session and no network still gets the instructions that\n * tell it what to do about exactly that.\n */\nasync function cmdGuide(_args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n d.o.data({ ok: true, format: 'markdown', content: HAVEN_AGENT_RUNBOOK_MD }, () => HAVEN_AGENT_RUNBOOK_MD)\n return EXIT.ok\n}\n\n// ── Auth ────────────────────────────────────────────────────────────\n\nasync function cmdLogin(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const email = args.flags.email ?? d.env.HAVEN_EMAIL\n if (!email) {\n throw new UsageError('An email is required.', 'Pass --email <address>, or set HAVEN_EMAIL.')\n }\n const password = d.env.HAVEN_PASSWORD ?? (await d.promptPassword())\n if (!password) {\n throw new UsageError('A password is required.', 'Set HAVEN_PASSWORD for a non-interactive run.')\n }\n const baseUrl = baseUrlFor(args, d, null)\n const api = d.makeApi(baseUrl)\n const res = await api.post<{ token: string; user: Session['user'] }>('/auth/login', { email, password })\n await d.sessionStore.save({ token: res.token, apiBaseUrl: baseUrl, user: res.user })\n // The issue specifies { ok, email, expires_at }; `user` and `apiBaseUrl` stay\n // because they were already the shape and dropping them would break a script\n // that reads them for no gain. Neither the password nor the token is echoed —\n // `expires_at` is derived from the token, never the token itself.\n emit(\n d,\n args.flags.json,\n { ok: true, email: res.user.email, expires_at: sessionExpiry(res.token), user: res.user, apiBaseUrl: baseUrl },\n () => `Signed in as ${res.user.email}.`,\n )\n return EXIT.ok\n}\n\nasync function cmdLogout(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n await d.sessionStore.clear()\n emit(d, args.flags.json, { ok: true, signed_out: true }, () => 'Signed out.')\n return EXIT.ok\n}\n\nasync function cmdWhoami(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { session, api } = await authed(args, d)\n const user = await api.get<Session['user']>('/auth/me')\n // The four fields #2525 asks for — id, email, session expiry, api url — laid\n // over the profile the route already returned, so nothing a caller reads\n // today disappears. `expires_at` is null when the token carries no readable\n // `exp`, which is a fact worth reporting rather than an error.\n emit(\n d,\n args.flags.json,\n { ...user, id: user.id, email: user.email, expires_at: sessionExpiry(session.token), api_url: session.apiBaseUrl },\n () => `${user.email}${user.name ? ` (${user.name})` : ''}`,\n )\n return EXIT.ok\n}\n\n// ── Wallets ─────────────────────────────────────────────────────────\n\nasync function cmdWalletsList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { safes } = await api.get<{ safes: Safe[] }>('/user/safes')\n emit(d, args.flags.json, safes, () =>\n safes.length === 0\n ? 'No Haven wallets yet.'\n : table(\n ['NAME', 'NETWORK', 'ADDRESS', 'DEFAULT'],\n safes.map((s) => [s.name, chainName(s.chain_id), truncateAddress(s.safe_address), s.is_default ? '✓' : '']),\n ),\n )\n return EXIT.ok\n}\n\nasync function cmdWalletsBalances(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { safes } = await api.get<{ safes: Safe[] }>('/user/safes')\n const safe = pickSafe(safes, args.flags.safe)\n if (!safe) {\n if (args.flags.safe) throw new UsageError(`No wallet matches \"${args.flags.safe}\".`)\n throw new CliApiError('No Haven wallet found.', 404)\n }\n const { balances } = await api.get<{ balances: Balance[] }>(\n `/balances/${safe.safe_address}?chain_id=${safe.chain_id}`,\n )\n emit(d, args.flags.json, { safe: safe.name, chainId: safe.chain_id, balances }, () =>\n [\n `${safe.name} · ${chainName(safe.chain_id)} · ${truncateAddress(safe.safe_address)}`,\n balances.length === 0\n ? ' (no balances)'\n : table(['TOKEN', 'BALANCE'], balances.map((b) => [b.symbol, b.formatted])),\n ].join('\\n'),\n )\n return EXIT.ok\n}\n\nfunction pickSafe(safes: Safe[], ref?: string): Safe | undefined {\n if (!ref) return safes.find((s) => s.is_default) ?? safes[0]\n const lower = ref.toLowerCase()\n return safes.find((s) => s.id === ref || s.safe_address.toLowerCase() === lower)\n}\n\n// ── Agents & budget ─────────────────────────────────────────────────\n\nasync function cmdAgentsList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { agents } = await api.get<{ agents: Agent[] }>('/agents')\n emit(d, args.flags.json, agents, () =>\n agents.length === 0\n ? 'No agents yet.'\n : table(\n ['ID', 'NAME', 'STATUS', 'BUDGETS'],\n agents.map((a) => [a.id, a.name, a.status, budgetSummary(a.allowances)]),\n ),\n )\n return EXIT.ok\n}\n\nasync function cmdAgentsShow(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven agents show <id>')\n const { api } = await authed(args, d)\n const agent = await api.get<Agent>(`/agents/${id}`)\n emit(d, args.flags.json, agent, () =>\n [\n `${agent.name} [${agent.status}]`,\n `id: ${agent.id}`,\n `budget: ${budgetSummary(agent.allowances)}`,\n ].join('\\n'),\n )\n return EXIT.ok\n}\n\nasync function cmdBudgetShow(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven budget show <agentId>')\n const { api } = await authed(args, d)\n const agent = await api.get<Agent>(`/agents/${id}`)\n const allowances = agent.allowances ?? []\n emit(d, args.flags.json, allowances, () =>\n allowances.length === 0\n ? `${agent.name} has no configured budget.`\n : table(\n ['TOKEN', 'AMOUNT', 'RESETS'],\n allowances.map((a) => [a.token_symbol, a.allowance_amount, resetLabel(a.reset_period_min)]),\n ),\n )\n return EXIT.ok\n}\n\nfunction budgetSummary(allowances?: Allowance[]): string {\n if (!allowances || allowances.length === 0) return '—'\n return allowances.map((a) => `${a.allowance_amount} ${a.token_symbol}`).join(', ')\n}\n\nfunction resetLabel(mins: number): string {\n if (mins === 0) return 'one-time'\n if (mins === 1440) return 'daily'\n if (mins === 10080) return 'weekly'\n if (mins === 43200) return 'monthly'\n return `every ${mins}m`\n}\n\nasync function cmdAgentLifecycle(args: ParsedArgs, d: ResolvedDeps, action: 'pause' | 'resume'): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError(`Usage: haven agents ${action} <id>`)\n const { api } = await authed(args, d)\n await api.post(`/agents/${id}/${action}`)\n const status = action === 'pause' ? 'paused' : 'resumed'\n emit(d, args.flags.json, { ok: true, agent_id: id, status }, () => `Agent ${id} ${status}.`)\n return EXIT.ok\n}\n\nasync function cmdAgentRevoke(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven agents revoke <id> --yes')\n // Revoke is terminal (status can't go back to active). Require explicit --yes\n // so it can't happen by accident in a script.\n if (!args.flags.yes) {\n throw new UsageError(\n `This permanently revokes agent ${id}.`,\n 'Re-run with --yes to confirm. Revoke is terminal — the agent cannot go back to active.',\n )\n }\n const { api } = await authed(args, d)\n await api.post(`/agents/${id}/revoke`)\n emit(\n d,\n args.flags.json,\n { ok: true, agent_id: id, status: 'revoked' },\n () => `Agent ${id} revoked. To also remove its on-chain allowance, use the dashboard.`,\n )\n return EXIT.ok\n}\n\nasync function cmdAgentRotateKey(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven agents rotate-key <id>')\n const { api } = await authed(args, d)\n const res = await api.post<{ api_key: string; api_key_prefix: string }>(`/agents/${id}/rotate-key`)\n // The key is the payload, so it belongs on stdout in both modes. The\n // SENTENCE about it is prose and moves to stderr under --json, which is what\n // keeps stdout a single parseable object with a secret in exactly one field.\n d.o.note('New API key (shown once — store it now; the old key stops working):')\n emit(d, args.flags.json, res, () => res.api_key)\n return EXIT.ok\n}\n\nasync function cmdAgentRename(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const [id, ...nameParts] = args.positionals\n const name = nameParts.join(' ').trim()\n if (!id || !name) throw new UsageError('Usage: haven agents rename <id> <name>')\n const { api } = await authed(args, d)\n await api.put(`/agents/${id}`, { name })\n emit(d, args.flags.json, { ok: true, agent_id: id, name }, () => `Agent ${id} renamed to \"${name}\".`)\n return EXIT.ok\n}\n\nasync function cmdWalletRename(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const [id, ...nameParts] = args.positionals\n const name = nameParts.join(' ').trim()\n if (!id || !name) throw new UsageError('Usage: haven wallets rename <id> <name>')\n const { api } = await authed(args, d)\n await api.put(`/user/safes/${id}`, { name })\n emit(d, args.flags.json, { ok: true, safe_id: id, name }, () => `Wallet ${id} renamed to \"${name}\".`)\n return EXIT.ok\n}\n\n// ── Activity ────────────────────────────────────────────────────────\n\n/**\n * Resolve `--safe` (id or address) to a Safe id for the `/transactions` filter,\n * mirroring `wallets balances`. Throws if `--safe` was given but matches no\n * wallet, so a typo'd filter fails loudly instead of silently returning all rows.\n */\nasync function resolveSafeId(args: ParsedArgs, api: CliApi): Promise<string | undefined> {\n if (!args.flags.safe) return undefined\n const { safes } = await api.get<{ safes: Safe[] }>('/user/safes')\n const safe = pickSafe(safes, args.flags.safe)\n if (!safe) throw new UsageError(`No wallet matches \"${args.flags.safe}\".`)\n return safe.id\n}\n\nasync function cmdActivityList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const safeId = await resolveSafeId(args, api)\n const params = new URLSearchParams({\n offset: String(args.flags.offset ?? 0),\n limit: String(args.flags.limit ?? 25),\n })\n if (safeId) params.set('safeId', safeId)\n if (args.flags.agent) params.set('agentId', args.flags.agent)\n const { transactions } = await api.get<{ transactions: Txn[] }>(`/transactions?${params.toString()}`)\n const visible = args.flags.direction\n ? transactions.filter((t) => t.direction === args.flags.direction)\n : transactions\n emit(d, args.flags.json, visible, () =>\n visible.length === 0\n ? 'No activity.'\n : table(\n ['DATE', 'DIR', 'AMOUNT', 'TYPE', 'ACCOUNT'],\n visible.map((t) => [\n new Date(t.timestamp * 1000).toISOString().slice(0, 10),\n t.direction === 'in' ? 'in' : 'out',\n `${t.direction === 'in' ? '+' : '-'}${t.valueFormatted} ${t.asset}`,\n t.source ?? 'transfer',\n t.safeName ?? '',\n ]),\n ),\n )\n return EXIT.ok\n}\n\nasync function cmdActivityExport(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n if (args.flags.format === 'sie') return exportSie(args, d)\n const { api } = await authed(args, d)\n const safeId = await resolveSafeId(args, api)\n const params = new URLSearchParams({\n offset: String(args.flags.offset ?? 0),\n limit: String(args.flags.limit ?? 1000),\n })\n if (safeId) params.set('safeId', safeId)\n if (args.flags.agent) params.set('agentId', args.flags.agent)\n const { transactions } = await api.get<{ transactions: Txn[] }>(`/transactions?${params.toString()}`)\n const visible = args.flags.direction\n ? transactions.filter((t) => t.direction === args.flags.direction)\n : transactions\n\n // Same columns as the dashboard export (#411), minus counterparty_name\n // (no contacts join in the CLI yet).\n const headers = [\n 'date', 'type', 'status', 'direction', 'amount', 'token_symbol', 'token_address',\n 'counterparty_address', 'safe_address', 'agent_name', 'tx_hash', 'chain_id',\n ]\n const rows = visible.map((t) => [\n new Date(t.timestamp * 1000).toISOString(),\n exportType(t),\n exportStatus(t),\n t.direction,\n t.valueFormatted,\n t.tokenSymbol ?? t.asset ?? '',\n t.tokenAddress ?? '',\n (t.direction === 'in' ? t.from : t.to) ?? '',\n t.safeAddress ?? '',\n t.agentName ?? '',\n t.hash,\n t.chainId != null ? String(t.chainId) : '',\n ])\n d.o.text(toCsv(headers, rows), { format: 'csv', rows: rows.length })\n return EXIT.ok\n}\n\nfunction exportType(t: Txn): string {\n if (t.activityType === 'delegate_sweep') return 'allowance funding'\n if (t.source === 'x402') return 'x402'\n if (t.source === 'mpp_demo') return 'mpp'\n return t.direction === 'in' ? 'receive' : 'send'\n}\n\nfunction exportStatus(t: Txn): string {\n if (t.isError) return 'failed'\n if (t.paymentFlowStatus === 'confirming_merchant') return 'pending'\n return 'executed'\n}\n\n/** SIE 4I export: the backend builds the verifikat file (book-time SEK + BAS). */\nasync function exportSie(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const params = new URLSearchParams({ format: 'sie' })\n if (args.flags.from) params.set('from', args.flags.from)\n if (args.flags.to) params.set('to', args.flags.to)\n if (args.flags.company) params.set('company', args.flags.company)\n const content = await api.getText(`/accounting/export?${params.toString()}`)\n d.o.text(content, { format: 'sie' })\n return EXIT.ok\n}\n\n// ── Catalog ─────────────────────────────────────────────────────────\n\nasync function cmdCatalogList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { entries } = await api.get<{ entries: CatalogEntry[] }>('/catalog')\n emit(d, args.flags.json, entries, () =>\n entries.length === 0\n ? 'Catalog is empty.'\n : table(\n ['NAME', 'CATEGORY', 'RAIL', 'PRICE', 'STATUS'],\n entries.map((e) => [e.name, e.category, e.rail, e.price_display ?? '—', e.status]),\n ),\n )\n return EXIT.ok\n}\n\n// ── Contacts ────────────────────────────────────────────────────────\n\nasync function cmdContactsList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { contacts } = await api.get<{ contacts: Contact[] }>('/contacts')\n emit(d, args.flags.json, contacts, () =>\n contacts.length === 0\n ? 'No contacts yet.'\n : table(['ID', 'NAME', 'ADDRESS'], contacts.map((c) => [c.id, c.name, truncateAddress(c.address)])),\n )\n return EXIT.ok\n}\n\nasync function cmdContactsAdd(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const [address, ...nameParts] = [...args.positionals].reverse()\n // positionals are <name...> <address>; address is last, name is the rest.\n const name = nameParts.reverse().join(' ').trim()\n if (!name || !address) throw new UsageError('Usage: haven contacts add <name> <address>')\n const { api } = await authed(args, d)\n const contact = await api.post<Contact>('/contacts', { name, address })\n emit(d, args.flags.json, contact, () => `Added contact \"${contact.name}\" (${truncateAddress(contact.address)}).`)\n return EXIT.ok\n}\n\nasync function cmdContactsRemove(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven contacts remove <id>')\n const { api } = await authed(args, d)\n await api.del(`/contacts/${id}`)\n emit(d, args.flags.json, { ok: true, contact_id: id, removed: true }, () => `Contact ${id} removed.`)\n return EXIT.ok\n}\n","import { emitKeypressEvents } from 'node:readline'\n\n/** The three streams the prompt touches, injectable so a test can watch them. */\nexport interface PromptStreams {\n stdin: NodeJS.ReadStream\n stdout: NodeJS.WriteStream\n stderr: NodeJS.WriteStream\n}\n\n/**\n * Read a password from the TTY without echoing it. Falls back to a plain line\n * read when stdin isn't a TTY (so piping `HAVEN_PASSWORD` or a heredoc still\n * works, though the env var is the documented non-interactive path).\n *\n * Exported and stream-injected for one reason: which stream the prompt writes\n * to is part of the `--json` contract, and asserting it needs a seam. It is\n * `stderr` — see the comment at the write.\n */\nexport function promptPasswordWith(streams: PromptStreams): Promise<string> {\n return new Promise((resolve, reject) => {\n const { stdin, stderr } = streams\n if (!stdin.isTTY) {\n let data = ''\n stdin.setEncoding('utf8')\n stdin.on('data', (chunk) => (data += chunk))\n stdin.on('end', () => resolve(data.trim()))\n stdin.on('error', reject)\n return\n }\n // stderr, never stdout (#2525 review): under `--json` stdout carries one\n // JSON value and nothing else, and a prompt written there would land ahead\n // of it. A prompt is prose addressed to a human at a terminal, so stderr is\n // where it belongs in both modes — the TTY still shows it.\n stderr.write('Password: ')\n emitKeypressEvents(stdin)\n stdin.setRawMode(true)\n let value = ''\n const onKey = (char: string, key: { name?: string; ctrl?: boolean }) => {\n if (key.name === 'return' || key.name === 'enter') {\n cleanup()\n stderr.write('\\n')\n resolve(value)\n } else if (key.ctrl && key.name === 'c') {\n cleanup()\n stderr.write('\\n')\n reject(new Error('Cancelled'))\n } else if (key.name === 'backspace') {\n value = value.slice(0, -1)\n } else if (char && !key.ctrl) {\n value += char\n }\n }\n function cleanup() {\n stdin.setRawMode(false)\n stdin.pause()\n stdin.off('keypress', onKey)\n }\n stdin.resume()\n stdin.on('keypress', onKey)\n })\n}\n","#!/usr/bin/env node\n\nimport { run } from './commands.js'\nimport { promptPasswordWith } from './prompt.js'\n\n/**\n * The bin entry, and deliberately nothing else.\n *\n * It used to also define `promptPasswordWith`, which meant importing this file\n * to test that function EXECUTED the CLI — `run(process.argv.slice(2))` against\n * vitest's own argv, ending in `process.exit(1)`. The suite still reported 102\n * passing tests with one unhandled error beside them, which is exactly the\n * shape of failure a `grep` for \"Tests\" hides (#2525 review round 3, caught by\n * CI). An entry point that self-executes must not also be an import target, so\n * the prompt lives in `prompt.ts` and this file only wires and runs.\n */\nfunction promptPassword(): Promise<string> {\n return promptPasswordWith({ stdin: process.stdin, stdout: process.stdout, stderr: process.stderr })\n}\n\nrun(process.argv.slice(2), { promptPassword })\n .then((code) => process.exit(code))\n .catch((err) => {\n // The last resort: anything that escaped run()'s own handling. It should be\n // unreachable — run() catches around both parseArgs and dispatch — but if\n // it is ever reached under `--json`, a bare sentence on stderr with exit 1\n // would be the one refusal a machine caller cannot parse. So it emits the\n // same failure shape as everything else (#2525 review, finding 2).\n const message = err instanceof Error ? err.message : String(err)\n if (process.argv.includes('--json')) {\n process.stdout.write(`${JSON.stringify({ ok: false, error: { code: 'failed', message } }, null, 2)}\\n`)\n } else {\n process.stderr.write(`${message}\\n`)\n }\n process.exit(1)\n })\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/args.ts","../src/api.ts","../src/session.ts","../src/format.ts","../src/csv.ts","../src/errors.ts","../src/output.ts","../src/agent-guidance-text.ts","../src/token.ts","../src/commands.ts","../src/prompt.ts","../src/cli.ts"],"names":["resolve","homedir","join","readFile","mkdir","writeFile","chmod","rm","emitKeypressEvents"],"mappings":";;;;;;;;;AAuBA,IAAM,WAAA,uBAAkB,GAAA,CAAI;AAAA,EAC1B,OAAA;AAAA,EAAS,SAAA;AAAA,EAAW,QAAA;AAAA,EAAU,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,UAAA;AAAA,EAAY,aAAA;AAAA,EAChE,UAAA;AAAA,EAAY,QAAA;AAAA,EAAU,MAAA;AAAA,EAAQ;AAChC,CAAC,CAAA;AAMM,SAAS,UAAU,IAAA,EAA4B;AACpD,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,KAAA,GAA6B,EAAE,IAAA,EAAM,KAAA,EAAO,MAAM,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,GAAA,EAAK,KAAA,EAAM;AAE1F,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA,EAAG;AACvC,IAAA,MAAM,GAAA,GAAM,KAAK,CAAC,CAAA;AAClB,IAAA,IAAI,GAAA,KAAQ,QAAA,EAAU,KAAA,CAAM,IAAA,GAAO,IAAA;AAAA,SAAA,IAC1B,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,IAAA,QAAY,IAAA,GAAO,IAAA;AAAA,SAAA,IAC/C,GAAA,KAAQ,WAAA,IAAe,GAAA,KAAQ,IAAA,QAAY,OAAA,GAAU,IAAA;AAAA,SAAA,IACrD,GAAA,KAAQ,OAAA,IAAW,GAAA,KAAQ,IAAA,QAAY,GAAA,GAAM,IAAA;AAAA,SAAA,IAC7C,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA,EAAG;AAC7B,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,EAAE,CAAC,CAAA;AACtB,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,EAAG;AACjD,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,GAAG,CAAA,CAAE,CAAA;AAAA,MAC5C;AACA,MAAA,IAAI,GAAA,KAAQ,OAAA,EAAS,KAAA,CAAM,GAAA,GAAM,KAAA;AAAA,WAAA,IACxB,GAAA,KAAQ,SAAA,EAAW,KAAA,CAAM,KAAA,GAAQ,KAAA;AAAA,WAAA,IACjC,GAAA,KAAQ,QAAA,EAAU,KAAA,CAAM,IAAA,GAAO,KAAA;AAAA,WAAA,IAC/B,GAAA,KAAQ,SAAA,EAAW,KAAA,CAAM,KAAA,GAAQ,KAAA;AAAA,WAAA,IACjC,QAAQ,SAAA,EAAW;AAC1B,QAAA,MAAM,CAAA,GAAI,OAAO,KAAK,CAAA;AACtB,QAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,CAAC,CAAA,IAAK,KAAK,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,oCAAoC,CAAA;AACxF,QAAA,KAAA,CAAM,KAAA,GAAQ,CAAA;AAAA,MAChB,CAAA,MAAA,IAAW,QAAQ,UAAA,EAAY;AAC7B,QAAA,MAAM,CAAA,GAAI,OAAO,KAAK,CAAA;AACtB,QAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,CAAC,CAAA,IAAK,IAAI,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,yCAAyC,CAAA;AAC5F,QAAA,KAAA,CAAM,MAAA,GAAS,CAAA;AAAA,MACjB,CAAA,MAAA,IAAW,QAAQ,aAAA,EAAe;AAChC,QAAA,IAAI,UAAU,IAAA,IAAQ,KAAA,KAAU,OAAO,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAC1F,QAAA,KAAA,CAAM,SAAA,GAAY,KAAA;AAAA,MACpB,CAAA,MAAA,IAAW,QAAQ,UAAA,EAAY;AAC7B,QAAA,IAAI,UAAU,KAAA,IAAS,KAAA,KAAU,OAAO,MAAM,IAAI,MAAM,iCAAiC,CAAA;AACzF,QAAA,KAAA,CAAM,MAAA,GAAS,KAAA;AAAA,MACjB,CAAA,MAAA,IAAW,GAAA,KAAQ,QAAA,EAAU,KAAA,CAAM,IAAA,GAAO,KAAA;AAAA,WAAA,IACjC,GAAA,KAAQ,MAAA,EAAQ,KAAA,CAAM,EAAA,GAAK,KAAA;AAAA,WAAA,IAC3B,GAAA,KAAQ,WAAA,EAAa,KAAA,CAAM,OAAA,GAAU,KAAA;AAAA,IAChD,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,IAAI,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,GAAG,CAAA,CAAE,CAAA;AAAA,IAC1C,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,KAAK,GAAG,CAAA;AAAA,IACtB;AAAA,EACF;AAEA,EAAA,MAAM,CAAC,OAAA,EAAS,GAAA,EAAK,GAAG,IAAI,CAAA,GAAI,WAAA;AAChC,EAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,MAAM,KAAA,EAAM;AAClD;AAEO,SAAS,QAAA,GAAmB;AACjC,EAAA,OAAO;AAAA,IACL,+DAAA;AAAA,IACA,EAAA;AAAA,IACA,+CAAA;AAAA,IACA,EAAA;AAAA,IACA,OAAA;AAAA,IACA,2EAAA;AAAA,IACA,mDAAA;AAAA,IACA,+EAAA;AAAA,IACA,EAAA;AAAA,IACA,aAAA;AAAA,IACA,4FAAA;AAAA,IACA,EAAA;AAAA,IACA,OAAA;AAAA,IACA,mDAAA;AAAA,IACA,wEAAA;AAAA,IACA,4CAAA;AAAA,IACA,uDAAA;AAAA,IACA,6DAAA;AAAA,IACA,wGAAA;AAAA,IACA,0EAAA;AAAA,IACA,+EAAA;AAAA,IACA,0EAAA;AAAA,IACA,iDAAA;AAAA,IACA,kDAAA;AAAA,IACA,EAAA;AAAA,IACA,mDAAA;AAAA,IACA,4BAAA;AAAA,IACA,6DAAA;AAAA,IACA,kEAAA;AAAA,IACA,6BAAA;AAAA,IACA,8BAAA;AAAA,IACA,wDAAA;AAAA,IACA,EAAA;AAAA,IACA,UAAA;AAAA,IACA,+EAAA;AAAA,IACA,sGAAA;AAAA,IACA,gFAAA;AAAA,IACA,yFAAA;AAAA,IACA,qBAAA;AAAA,IACA,EAAA;AAAA,IACA,oGAAA;AAAA,IACA,EAAA;AAAA,IACA,uEAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;;;AC9HO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAM;AAAA,EACrC,MAAA;AAAA,EACA,WAAA,CAAY,SAAiB,MAAA,EAAgB;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF,CAAA;AAsBO,SAAS,aAAa,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,GAAY,OAAM,EAAgC;AAC/F,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAEvC,EAAA,eAAe,OAAA,CAAW,MAAA,EAAgB,IAAA,EAAc,IAAA,EAA4B;AAClF,IAAA,MAAM,OAAA,GAAkC,EAAE,MAAA,EAAQ,kBAAA,EAAmB;AACrE,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAClD,IAAA,IAAI,IAAA,KAAS,MAAA,EAAW,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAElD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,QACtC,MAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAM,IAAA,KAAS,KAAA,CAAA,GAAY,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,GAAI,KAAA;AAAA,OACnD,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAI,WAAA;AAAA,QACR,CAAA,yBAAA,EAA4B,IAAI,CAAA,EAAA,EAAK,GAAA,YAAe,QAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA,CAAA;AAAA,QACrF;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,MAAA,MAAM,IAAI,WAAA,CAAY,6CAAA,EAA+C,GAAG,CAAA;AAAA,IAC1E;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,MAAM,OAAA,GAAU,IAAA,GAAO,SAAA,CAAU,IAAI,CAAA,GAAI,MAAA;AAEzC,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,WACH,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,IAAY,WAAW,OAAA,IAAW,OAAO,OAAA,CAAQ,KAAA,KAAU,WACtF,OAAA,CAAQ,KAAA,GACR,IAAA,KAAS,CAAA,qBAAA,EAAwB,IAAI,MAAM,CAAA,EAAA,CAAA;AACjD,MAAA,MAAM,IAAI,WAAA,CAAY,OAAA,EAAS,GAAA,CAAI,MAAM,CAAA;AAAA,IAC3C;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,eAAe,YAAY,IAAA,EAA+B;AACxD,IAAA,MAAM,OAAA,GAAkC,EAAE,MAAA,EAAQ,YAAA,EAAa;AAC/D,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAElD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,IACpE,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAI,WAAA;AAAA,QACR,CAAA,yBAAA,EAA4B,IAAI,CAAA,EAAA,EAAK,GAAA,YAAe,QAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA,CAAA;AAAA,QACrF;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,MAAA,MAAM,IAAI,WAAA,CAAY,6CAAA,EAA+C,GAAG,CAAA;AAAA,IAC1E;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,OAAA,GAAU,IAAA,GAAO,SAAA,CAAU,IAAI,CAAA,GAAI,MAAA;AACzC,MAAA,MAAM,WACH,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,IAAY,WAAW,OAAA,IAAW,OAAO,OAAA,CAAQ,KAAA,KAAU,WACtF,OAAA,CAAQ,KAAA,GACR,IAAA,KAAS,CAAA,qBAAA,EAAwB,IAAI,MAAM,CAAA,EAAA,CAAA;AACjD,MAAA,MAAM,IAAI,WAAA,CAAY,OAAA,EAAS,GAAA,CAAI,MAAM,CAAA;AAAA,IAC3C;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,CAAI,IAAA,KAAiB,OAAA,CAAW,OAAO,IAAI,CAAA;AAAA,IAChD,MAAM,CAAI,IAAA,EAAc,SAAmB,OAAA,CAAW,MAAA,EAAQ,MAAM,IAAI,CAAA;AAAA,IACxE,KAAK,CAAI,IAAA,EAAc,SAAmB,OAAA,CAAW,KAAA,EAAO,MAAM,IAAI,CAAA;AAAA,IACtE,GAAA,EAAK,CAAI,IAAA,KAAiB,OAAA,CAAW,UAAU,IAAI,CAAA;AAAA,IACnD,OAAA,EAAS,CAAC,IAAA,KAAiB,WAAA,CAAY,IAAI;AAAA,GAC7C;AACF;AAEA,SAAS,UAAU,IAAA,EAAuB;AACxC,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AC3FA,SAAS,WAAW,OAAA,EAAyB;AAC3C,EAAA,OAAOA,YAAA,CAAQ,SAAS,QAAQ,CAAA;AAClC;AAEO,SAAS,WAAA,CAAY,OAAA,GAAkBC,UAAA,EAAQ,EAAW;AAC/D,EAAA,OAAOC,SAAA,CAAK,UAAA,CAAW,OAAO,CAAA,EAAG,cAAc,CAAA;AACjD;AAGO,SAAS,kBAAA,CAAmB,OAAA,GAAkBD,UAAA,EAAQ,EAAiB;AAC5E,EAAA,MAAM,IAAA,GAAO,YAAY,OAAO,CAAA;AAChC,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,MAAM,IAAA,GAAO;AACX,MAAA,IAAI;AACF,QAAA,MAAM,GAAA,GAAM,MAAME,iBAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AACvC,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,QAAA,IAAI,CAAC,OAAO,KAAA,IAAS,CAAC,OAAO,UAAA,IAAc,CAAC,MAAA,CAAO,IAAA,EAAM,OAAO,IAAA;AAChE,QAAA,OAAO,MAAA;AAAA,MACT,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IACA,MAAM,KAAK,OAAA,EAAS;AAClB,MAAA,MAAMC,cAAA,CAAM,WAAW,OAAO,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,GAAA,EAAO,CAAA;AACjE,MAAA,MAAMC,kBAAA,CAAU,MAAM,CAAA,EAAG,IAAA,CAAK,UAAU,OAAA,EAAS,IAAA,EAAM,CAAC,CAAC;AAAA,CAAA,EAAM,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC9E,MAAA,MAAMC,eAAM,IAAA,EAAM,GAAK,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,IAChD,CAAA;AAAA,IACA,MAAM,KAAA,GAAQ;AACZ,MAAA,MAAMC,WAAA,CAAG,IAAA,EAAM,EAAE,KAAA,EAAO,MAAM,CAAA;AAAA,IAChC;AAAA,GACF;AACF;;;ACtDO,SAAS,KAAA,CAAM,SAAmB,IAAA,EAA0B;AACjE,EAAA,MAAM,SAAS,OAAA,CAAQ,GAAA;AAAA,IAAI,CAAC,CAAA,EAAG,CAAA,KAC7B,IAAA,CAAK,GAAA,CAAI,EAAE,MAAA,EAAQ,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAA,CAAO,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA,EAAI,MAAM,CAAC;AAAA,GAC5D;AACA,EAAA,MAAM,OAAO,CAAC,KAAA,KACZ,MAAM,GAAA,CAAI,CAAC,GAAG,CAAA,KAAA,CAAO,CAAA,IAAK,IAAI,MAAA,CAAO,MAAA,CAAO,CAAC,CAAC,CAAC,EAAE,IAAA,CAAK,IAAI,EAAE,OAAA,EAAQ;AACtE,EAAA,OAAO,CAAC,KAAK,OAAO,CAAA,EAAG,KAAK,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,MAAA,CAAO,CAAC,CAAC,CAAC,GAAG,GAAG,IAAA,CAAK,IAAI,IAAI,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC7F;AAEO,SAAS,gBAAgB,OAAA,EAAyB;AACvD,EAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,IAAU,IAAI,OAAO,OAAA;AAC7C,EAAA,OAAO,CAAA,EAAG,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,MAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,EAAE,CAAC,CAAA,CAAA;AACpD;AAEA,IAAM,WAAA,GAAsC,EAAE,GAAA,EAAK,QAAA,EAAU,MAAM,MAAA,EAAO;AAEnE,SAAS,UAAU,OAAA,EAAyB;AACjD,EAAA,OAAO,WAAA,CAAY,OAAO,CAAA,IAAK,CAAA,MAAA,EAAS,OAAO,CAAA,CAAA;AACjD;;;ACXA,SAAS,SAAS,KAAA,EAAuB;AACvC,EAAA,IAAI,CAAA,GAAI,KAAA;AACR,EAAA,IAAI,eAAe,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,GAAI,IAAI,CAAC,CAAA,CAAA;AACrC,EAAA,OAAO,CAAA,CAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAC,CAAA,CAAA,CAAA;AAClC;AAEO,SAAS,KAAA,CAAM,SAAmB,IAAA,EAA0B;AACjE,EAAA,MAAM,QAAQ,CAAC,OAAA,CAAQ,KAAK,GAAG,CAAA,EAAG,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAA,CAAI,QAAQ,EAAE,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAC/E,EAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAC1B;;;ACRO,IAAM,IAAA,GAAO;AAAA,EAClB,EAAA,EAAI,CAAA;AAAA;AAAA,EAEJ,MAAA,EAAQ,CAAA;AAAA;AAAA,EAER,KAAA,EAAO,CAAA;AAAA;AAAA,EAEP,gBAAA,EAAkB,CAAA;AAAA;AAAA,EAElB,OAAA,EAAS,CAAA;AAAA;AAAA,EAET,OAAA,EAAS;AACX,CAAA;AAQO,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EAC3B,IAAA;AAAA,EACT,WAAA,CAAY,SAAiB,IAAA,EAAe;AAC1C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF,CAAA;AAqBO,SAAS,UAAU,GAAA,EAAuB;AAC/C,EAAA,IAAI,eAAe,UAAA,EAAY;AAC7B,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,IAAA,CAAK,KAAA,EAAO,OAAA,EAAS,GAAA,CAAI,OAAA,EAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAK;AAAA,EACjF;AACA,EAAA,IAAI,eAAe,WAAA,EAAa;AAC9B,IAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,SAAA;AAAA,QACN,MAAM,IAAA,CAAK,OAAA;AAAA,QACX,SAAS,GAAA,CAAI,OAAA;AAAA,QACb,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AACA,IAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,mBAAA;AAAA,QACN,MAAM,IAAA,CAAK,gBAAA;AAAA,QACX,SAAS,GAAA,CAAI,OAAA;AAAA,QACb,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AACA,IAAA,IAAI,GAAA,CAAI,MAAA,IAAU,GAAA,IAAO,GAAA,CAAI,SAAS,GAAA,EAAK;AAIzC,MAAA,OAAO,EAAE,MAAM,SAAA,EAAW,IAAA,EAAM,KAAK,OAAA,EAAS,OAAA,EAAS,IAAI,OAAA,EAAQ;AAAA,IACrE;AACA,IAAA,OAAO,EAAE,MAAM,QAAA,EAAU,IAAA,EAAM,KAAK,MAAA,EAAQ,OAAA,EAAS,IAAI,OAAA,EAAQ;AAAA,EACnE;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAA,EAAE;AACxG;;;AC3DO,SAAS,YAAA,CACd,IAAA,EACA,GAAA,EACA,GAAA,EACQ;AACR,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,IAAA,CAAK,SAAS,KAAA,EAAO;AACnB,MAAA,GAAA,CAAI,IAAA,GAAO,KAAK,SAAA,CAAU,OAAA,EAAS,MAAM,CAAC,CAAA,GAAI,OAAO,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,IAAA,CAAK,SAAS,IAAA,EAAM;AAIlB,MAAA,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,EAAE,EAAA,EAAI,IAAA,EAAM,GAAG,IAAA,EAAM,OAAA,EAAQ,EAAG,IAAA,EAAM,CAAC,IAAI,OAAO,CAAA;AAAA,IAC9E,CAAA;AAAA,IACA,KAAK,IAAA,EAAM;AACT,MAAA,IAAI,IAAA,MAAU,IAAI,CAAA;AAAA,eACT,IAAI,CAAA;AAAA,IACf,CAAA;AAAA,IACA,QAAQ,OAAA,EAAS;AACf,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,EAAA,EAAI,KAAA;AAAA,QACJ,KAAA,EAAO;AAAA,UACL,MAAM,OAAA,CAAQ,IAAA;AAAA,UACd,SAAS,OAAA,CAAQ,OAAA;AAAA,UACjB,GAAI,QAAQ,IAAA,GAAO,EAAE,MAAM,OAAA,CAAQ,IAAA,KAAS;AAAC;AAC/C,OACF;AACA,MAAA,IAAI,MAAM,GAAA,CAAI,IAAA,CAAK,UAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,WACtC,GAAA,CAAI,OAAA,CAAQ,IAAA,GAAO,CAAA,EAAG,QAAQ,OAAO;AAAA,EAAK,OAAA,CAAQ,IAAI,CAAA,CAAA,GAAK,OAAA,CAAQ,OAAO,CAAA;AAAA,IACjF;AAAA,GACF;AACF;;;AC/CO,IAAM,sBAAA,GAAyB,wyPAAA;;;ACD/B,SAAS,cAAc,KAAA,EAA8B;AAC1D,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAClC,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,EAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA,EAAG,QAAQ,CAAA,CAAE,SAAS,MAAM,CAAA;AACjG,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC9B,IAAA,IAAI,OAAO,MAAA,CAAO,GAAA,KAAQ,QAAA,IAAY,CAAC,OAAO,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,EAAG,OAAO,IAAA;AAC3E,IAAA,OAAO,IAAI,IAAA,CAAK,MAAA,CAAO,GAAA,GAAM,GAAI,EAAE,WAAA,EAAY;AAAA,EACjD,CAAA,CAAA,MAAQ;AAGN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;ACdA,IAAM,WAAA,GAAc,qDAAA;AAGb,IAAM,WAAA,GAAc,gCAAA;AA4D3B,eAAsB,GAAA,CAAI,IAAA,EAAgB,IAAA,GAAgB,EAAC,EAAoB;AAC7E,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,KAAQ,CAAC,MAAc,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAC;AAAA,CAAI,CAAA,CAAA;AACrE,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,KAAQ,CAAC,MAAc,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAC;AAAA,CAAI,CAAA,CAAA;AAMrE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA;AACnC,EAAA,MAAM,CAAA,GAAI,YAAA,CAAa,IAAA,EAAM,GAAA,EAAK,GAAG,CAAA;AAErC,EAAA,MAAM,CAAA,GAAkB;AAAA,IACtB,YAAA,EAAc,IAAA,CAAK,YAAA,IAAgB,kBAAA,EAAmB;AAAA,IACtD,OAAA,EAAS,IAAA,CAAK,OAAA,KAAY,CAAC,OAAA,EAAS,UAAU,YAAA,CAAa,EAAE,OAAA,EAAS,KAAA,EAAO,CAAA,CAAA;AAAA,IAC7E,cAAA,EAAgB,KAAK,cAAA,KAAmB,MAAM,QAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,6BAA6B,CAAC,CAAA,CAAA;AAAA,IACrG,GAAA;AAAA,IACA,GAAA;AAAA,IACA,GAAA,EAAK,IAAA,CAAK,GAAA,IAAO,OAAA,CAAQ,GAAA;AAAA,IACzB;AAAA,GACF;AAEA,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,UAAU,IAAI,CAAA;AAAA,EACvB,SAAS,CAAA,EAAG;AACV,IAAA,OAAO,IAAA,CAAK,CAAA,EAAG,IAAI,UAAA,CAAW,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAA,EAAG,qBAAqB,CAAC,CAAA;AAAA,EAClG;AAEA,EAAA,IAAI,IAAA,CAAK,MAAM,OAAA,EAAS;AACtB,IAAA,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,WAAA,EAAY,EAAG,MAAM,WAAW,CAAA;AAClD,IAAA,OAAO,IAAA,CAAK,EAAA;AAAA,EACd;AACA,EAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,IAAQ,CAAC,KAAK,OAAA,EAAS;AACpC,IAAA,CAAA,CAAE,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,IAAW,EAAG,MAAM,UAAU,CAAA;AAC7C,IAAA,OAAO,IAAA,CAAK,EAAA;AAAA,EACd;AAEA,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,QAAA,CAAS,IAAA,EAAM,CAAC,CAAA;AAAA,EAC/B,SAAS,CAAA,EAAG;AACV,IAAA,OAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EAClB;AACF;AAGA,SAAS,IAAA,CAAK,GAAiB,GAAA,EAAwB;AACrD,EAAA,MAAM,OAAA,GAAU,UAAU,GAAG,CAAA;AAC7B,EAAA,CAAA,CAAE,CAAA,CAAE,QAAQ,OAAO,CAAA;AACnB,EAAA,OAAO,OAAA,CAAQ,IAAA;AACjB;AAEA,eAAe,QAAA,CAAS,MAAkB,CAAA,EAAkC;AAC1E,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,CAAA,EAAI,IAAA,CAAK,GAAG,CAAA,CAAA,GAAK,IAAA,CAAK,OAAA;AAC5D,EAAA,QAAQ,GAAA;AAAK,IACX,KAAK,OAAA;AAAS,MAAA,OAAO,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IACrC,KAAK,OAAA;AAAS,MAAA,OAAO,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IACrC,KAAK,QAAA;AAAU,MAAA,OAAO,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,IACvC,KAAK,QAAA;AAAU,MAAA,OAAO,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,IACvC,KAAK,cAAA;AAAgB,MAAA,OAAO,cAAA,CAAe,MAAM,CAAC,CAAA;AAAA,IAClD,KAAK,kBAAA;AAAoB,MAAA,OAAO,kBAAA,CAAmB,MAAM,CAAC,CAAA;AAAA,IAC1D,KAAK,aAAA;AAAe,MAAA,OAAO,aAAA,CAAc,MAAM,CAAC,CAAA;AAAA,IAChD,KAAK,aAAA;AAAe,MAAA,OAAO,aAAA,CAAc,MAAM,CAAC,CAAA;AAAA,IAChD,KAAK,cAAA;AAAgB,MAAA,OAAO,iBAAA,CAAkB,IAAA,EAAM,CAAA,EAAG,OAAO,CAAA;AAAA,IAC9D,KAAK,eAAA;AAAiB,MAAA,OAAO,iBAAA,CAAkB,IAAA,EAAM,CAAA,EAAG,QAAQ,CAAA;AAAA,IAChE,KAAK,eAAA;AAAiB,MAAA,OAAO,cAAA,CAAe,MAAM,CAAC,CAAA;AAAA,IACnD,KAAK,mBAAA;AAAqB,MAAA,OAAO,iBAAA,CAAkB,MAAM,CAAC,CAAA;AAAA,IAC1D,KAAK,eAAA;AAAiB,MAAA,OAAO,cAAA,CAAe,MAAM,CAAC,CAAA;AAAA,IACnD,KAAK,aAAA;AAAe,MAAA,OAAO,aAAA,CAAc,MAAM,CAAC,CAAA;AAAA,IAChD,KAAK,gBAAA;AAAkB,MAAA,OAAO,eAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,IACrD,KAAK,eAAA;AAAiB,MAAA,OAAO,eAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,IACpD,KAAK,iBAAA;AAAmB,MAAA,OAAO,iBAAA,CAAkB,MAAM,CAAC,CAAA;AAAA,IACxD,KAAK,cAAA;AAAgB,MAAA,OAAO,cAAA,CAAe,MAAM,CAAC,CAAA;AAAA,IAClD,KAAK,eAAA;AAAiB,MAAA,OAAO,eAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,IACpD,KAAK,cAAA;AAAgB,MAAA,OAAO,cAAA,CAAe,MAAM,CAAC,CAAA;AAAA,IAClD,KAAK,iBAAA;AAAmB,MAAA,OAAO,iBAAA,CAAkB,MAAM,CAAC,CAAA;AAAA,IACxD;AACE,MAAA,MAAM,IAAI,UAAA,CAAW,CAAA,iBAAA,EAAoB,GAAG,KAAK,0CAA0C,CAAA;AAAA;AAEjG;AAEA,SAAS,UAAA,CAAW,IAAA,EAAkB,CAAA,EAAiB,OAAA,EAAiC;AACtF,EAAA,OAAO,KAAK,KAAA,CAAM,GAAA,IAAO,SAAS,UAAA,IAAc,CAAA,CAAE,IAAI,aAAA,IAAiB,WAAA;AACzE;AAEA,eAAe,MAAA,CAAO,MAAkB,CAAA,EAA6D;AACnG,EAAA,MAAM,OAAA,GAAU,MAAM,CAAA,CAAE,YAAA,CAAa,IAAA,EAAK;AAG1C,EAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,WAAA,CAAY,sBAAsB,GAAG,CAAA;AAC7D,EAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,CAAA,CAAE,OAAA,CAAQ,UAAA,CAAW,IAAA,EAAM,CAAA,EAAG,OAAO,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA,EAAE;AAChF;AAEA,SAAS,IAAA,CAAK,CAAA,EAAiB,KAAA,EAAgB,IAAA,EAAe,KAAA,EAA2B;AACvF,EAAA,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAA,EAAM,KAAK,CAAA;AACtB;AAUA,eAAe,QAAA,CAAS,OAAmB,CAAA,EAAkC;AAC3E,EAAA,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,OAAA,EAAS,sBAAA,EAAuB,EAAG,MAAM,sBAAsB,CAAA;AACxG,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAIA,eAAe,QAAA,CAAS,MAAkB,CAAA,EAAkC;AAC1E,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,KAAA,IAAS,EAAE,GAAA,CAAI,WAAA;AACxC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,UAAA,CAAW,uBAAA,EAAyB,6CAA6C,CAAA;AAAA,EAC7F;AACA,EAAA,MAAM,WAAW,CAAA,CAAE,GAAA,CAAI,cAAA,IAAmB,MAAM,EAAE,cAAA,EAAe;AACjE,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,UAAA,CAAW,yBAAA,EAA2B,+CAA+C,CAAA;AAAA,EACjG;AACA,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA;AACxC,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,OAAO,CAAA;AAC7B,EAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,IAAA,CAA+C,eAAe,EAAE,KAAA,EAAO,UAAU,CAAA;AACvG,EAAA,MAAM,CAAA,CAAE,YAAA,CAAa,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,CAAI,KAAA,EAAO,UAAA,EAAY,OAAA,EAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,CAAA;AAKnF,EAAA,IAAA;AAAA,IACE,CAAA;AAAA,IACA,KAAK,KAAA,CAAM,IAAA;AAAA,IACX,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,GAAA,CAAI,KAAK,KAAA,EAAO,UAAA,EAAY,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,EAAG,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,YAAY,OAAA,EAAQ;AAAA,IAC7G,MAAM,CAAA,aAAA,EAAgB,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,GACtC;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,SAAA,CAAU,MAAkB,CAAA,EAAkC;AAC3E,EAAA,MAAM,CAAA,CAAE,aAAa,KAAA,EAAM;AAC3B,EAAA,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,EAAA,EAAI,IAAA,EAAM,UAAA,EAAY,IAAA,EAAK,EAAG,MAAM,aAAa,CAAA;AAC5E,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,SAAA,CAAU,MAAkB,CAAA,EAAkC;AAC3E,EAAA,MAAM,EAAE,OAAA,EAAS,GAAA,KAAQ,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AAC7C,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAqB,UAAU,CAAA;AAKtD,EAAA,IAAA;AAAA,IACE,CAAA;AAAA,IACA,KAAK,KAAA,CAAM,IAAA;AAAA,IACX,EAAE,GAAG,IAAA,EAAM,EAAA,EAAI,IAAA,CAAK,IAAI,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,UAAA,EAAY,cAAc,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAA,EAAS,QAAQ,UAAA,EAAW;AAAA,IACjH,MAAM,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,EAAG,IAAA,CAAK,IAAA,GAAO,CAAA,EAAA,EAAK,IAAA,CAAK,IAAI,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA;AAAA,GAC1D;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAIA,eAAe,cAAA,CAAe,MAAkB,CAAA,EAAkC;AAChF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,GAAA,CAAI,IAAuB,aAAa,CAAA;AAChE,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,KAAA;AAAA,IAAO,MAC9B,KAAA,CAAM,MAAA,KAAW,CAAA,GACb,uBAAA,GACA,KAAA;AAAA,MACE,CAAC,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAW,SAAS,CAAA;AAAA,MACxC,MAAM,GAAA,CAAI,CAAC,MAAM,CAAC,CAAA,CAAE,MAAM,SAAA,CAAU,CAAA,CAAE,QAAQ,CAAA,EAAG,eAAA,CAAgB,EAAE,YAAY,CAAA,EAAG,EAAE,UAAA,GAAa,QAAA,GAAM,EAAE,CAAC;AAAA;AAC5G,GACN;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,kBAAA,CAAmB,MAAkB,CAAA,EAAkC;AACpF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,GAAA,CAAI,IAAuB,aAAa,CAAA;AAChE,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,KAAA,EAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAC5C,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,WAAW,CAAA,mBAAA,EAAsB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAA,CAAI,CAAA;AACnF,IAAA,MAAM,IAAI,WAAA,CAAY,wBAAA,EAA0B,GAAG,CAAA;AAAA,EACrD;AACA,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,GAAA,CAAI,GAAA;AAAA,IAC7B,CAAA,UAAA,EAAa,IAAA,CAAK,YAAY,CAAA,UAAA,EAAa,KAAK,QAAQ,CAAA;AAAA,GAC1D;AACA,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,EAAE,IAAA,EAAM,IAAA,CAAK,MAAM,OAAA,EAAS,IAAA,CAAK,UAAU,QAAA,EAAS;AAAA,IAAG,MAC9E;AAAA,MACE,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,MAAA,EAAM,SAAA,CAAU,IAAA,CAAK,QAAQ,CAAC,CAAA,MAAA,EAAM,eAAA,CAAgB,IAAA,CAAK,YAAY,CAAC,CAAA,CAAA;AAAA,MAClF,SAAS,MAAA,KAAW,CAAA,GAChB,oBACA,KAAA,CAAM,CAAC,SAAS,SAAS,CAAA,EAAG,SAAS,GAAA,CAAI,CAAC,MAAM,CAAC,CAAA,CAAE,QAAQ,CAAA,CAAE,SAAS,CAAC,CAAC;AAAA,KAC9E,CAAE,KAAK,IAAI;AAAA,GACb;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,SAAS,QAAA,CAAS,OAAe,GAAA,EAAgC;AAC/D,EAAA,IAAI,CAAC,GAAA,EAAK,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA;AAC3D,EAAA,MAAM,KAAA,GAAQ,IAAI,WAAA,EAAY;AAC9B,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,GAAA,IAAO,CAAA,CAAE,YAAA,CAAa,WAAA,EAAY,KAAM,KAAK,CAAA;AACjF;AAIA,eAAe,aAAA,CAAc,MAAkB,CAAA,EAAkC;AAC/E,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,GAAA,CAAI,IAAyB,SAAS,CAAA;AAC/D,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,MAAA;AAAA,IAAQ,MAC/B,MAAA,CAAO,MAAA,KAAW,CAAA,GACd,gBAAA,GACA,KAAA;AAAA,MACE,CAAC,IAAA,EAAM,MAAA,EAAQ,QAAA,EAAU,SAAS,CAAA;AAAA,MAClC,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,CAAA,CAAE,IAAA,EAAM,EAAE,MAAA,EAAQ,aAAA,CAAc,CAAA,CAAE,UAAU,CAAC,CAAC;AAAA;AACzE,GACN;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,aAAA,CAAc,MAAkB,CAAA,EAAkC;AAC/E,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,WAAW,+BAA+B,CAAA;AAC7D,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,QAAQ,MAAM,GAAA,CAAI,GAAA,CAAW,CAAA,QAAA,EAAW,EAAE,CAAA,CAAE,CAAA;AAClD,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,KAAA;AAAA,IAAO,MAC9B;AAAA,MACE,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,GAAA,EAAM,MAAM,MAAM,CAAA,CAAA,CAAA;AAAA,MAC/B,CAAA,IAAA,EAAO,MAAM,EAAE,CAAA,CAAA;AAAA,MACf,CAAA,QAAA,EAAW,aAAA,CAAc,KAAA,CAAM,UAAU,CAAC,CAAA;AAAA,KAC5C,CAAE,KAAK,IAAI;AAAA,GACb;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,aAAA,CAAc,MAAkB,CAAA,EAAkC;AAC/E,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,WAAW,oCAAoC,CAAA;AAClE,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,QAAQ,MAAM,GAAA,CAAI,GAAA,CAAW,CAAA,QAAA,EAAW,EAAE,CAAA,CAAE,CAAA;AAClD,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,UAAA,IAAc,EAAC;AACxC,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,UAAA;AAAA,IAAY,MACnC,UAAA,CAAW,MAAA,KAAW,IAClB,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,0BAAA,CAAA,GACb,KAAA;AAAA,MACE,CAAC,OAAA,EAAS,QAAA,EAAU,QAAQ,CAAA;AAAA,MAC5B,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,YAAA,EAAc,CAAA,CAAE,gBAAA,EAAkB,UAAA,CAAW,CAAA,CAAE,gBAAgB,CAAC,CAAC;AAAA;AAC5F,GACN;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,SAAS,cAAc,UAAA,EAAkC;AACvD,EAAA,IAAI,CAAC,UAAA,IAAc,UAAA,CAAW,MAAA,KAAW,GAAG,OAAO,QAAA;AACnD,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,gBAAgB,CAAA,CAAA,EAAI,CAAA,CAAE,YAAY,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AACnF;AAEA,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,IAAI,IAAA,KAAS,GAAG,OAAO,UAAA;AACvB,EAAA,IAAI,IAAA,KAAS,MAAM,OAAO,OAAA;AAC1B,EAAA,IAAI,IAAA,KAAS,OAAO,OAAO,QAAA;AAC3B,EAAA,IAAI,IAAA,KAAS,OAAO,OAAO,SAAA;AAC3B,EAAA,OAAO,SAAS,IAAI,CAAA,CAAA,CAAA;AACtB;AAEA,eAAe,iBAAA,CAAkB,IAAA,EAAkB,CAAA,EAAiB,MAAA,EAA6C;AAC/G,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,UAAA,CAAW,CAAA,oBAAA,EAAuB,MAAM,CAAA,KAAA,CAAO,CAAA;AAClE,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,IAAI,IAAA,CAAK,CAAA,QAAA,EAAW,EAAE,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,MAAA,KAAW,OAAA,GAAU,QAAA,GAAW,SAAA;AAC/C,EAAA,IAAA,CAAK,GAAG,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,IAAI,IAAA,EAAM,QAAA,EAAU,EAAA,EAAI,MAAA,IAAU,MAAM,CAAA,MAAA,EAAS,EAAE,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAC3F,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,cAAA,CAAe,MAAkB,CAAA,EAAkC;AAChF,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,WAAW,uCAAuC,CAAA;AAGrE,EAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,GAAA,EAAK;AACnB,IAAA,MAAM,IAAI,UAAA;AAAA,MACR,kCAAkC,EAAE,CAAA,CAAA,CAAA;AAAA,MACpC;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,GAAA,CAAI,IAAA,CAAK,CAAA,QAAA,EAAW,EAAE,CAAA,OAAA,CAAS,CAAA;AACrC,EAAA,IAAA;AAAA,IACE,CAAA;AAAA,IACA,KAAK,KAAA,CAAM,IAAA;AAAA,IACX,EAAE,EAAA,EAAI,IAAA,EAAM,QAAA,EAAU,EAAA,EAAI,QAAQ,SAAA,EAAU;AAAA,IAC5C,MAAM,SAAS,EAAE,CAAA,mEAAA;AAAA,GACnB;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,iBAAA,CAAkB,MAAkB,CAAA,EAAkC;AACnF,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,WAAW,qCAAqC,CAAA;AACnE,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,MAAM,MAAM,GAAA,CAAI,IAAA,CAAkD,CAAA,QAAA,EAAW,EAAE,CAAA,WAAA,CAAa,CAAA;AAIlG,EAAA,CAAA,CAAE,CAAA,CAAE,KAAK,0EAAqE,CAAA;AAC9E,EAAA,IAAA,CAAK,GAAG,IAAA,CAAK,KAAA,CAAM,MAAM,GAAA,EAAK,MAAM,IAAI,OAAO,CAAA;AAC/C,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,cAAA,CAAe,MAAkB,CAAA,EAAkC;AAChF,EAAA,MAAM,CAAC,EAAA,EAAI,GAAG,SAAS,IAAI,IAAA,CAAK,WAAA;AAChC,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACtC,EAAA,IAAI,CAAC,EAAA,IAAM,CAAC,MAAM,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAC/E,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,IAAI,GAAA,CAAI,CAAA,QAAA,EAAW,EAAE,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA;AACvC,EAAA,IAAA,CAAK,GAAG,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,IAAI,IAAA,EAAM,QAAA,EAAU,EAAA,EAAI,IAAA,IAAQ,MAAM,CAAA,MAAA,EAAS,EAAE,CAAA,aAAA,EAAgB,IAAI,CAAA,EAAA,CAAI,CAAA;AACpG,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,eAAA,CAAgB,MAAkB,CAAA,EAAkC;AACjF,EAAA,MAAM,CAAC,EAAA,EAAI,GAAG,SAAS,IAAI,IAAA,CAAK,WAAA;AAChC,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACtC,EAAA,IAAI,CAAC,EAAA,IAAM,CAAC,MAAM,MAAM,IAAI,WAAW,yCAAyC,CAAA;AAChF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,IAAI,GAAA,CAAI,CAAA,YAAA,EAAe,EAAE,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA;AAC3C,EAAA,IAAA,CAAK,GAAG,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,IAAI,IAAA,EAAM,OAAA,EAAS,EAAA,EAAI,IAAA,IAAQ,MAAM,CAAA,OAAA,EAAU,EAAE,CAAA,aAAA,EAAgB,IAAI,CAAA,EAAA,CAAI,CAAA;AACpG,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AASA,eAAe,aAAA,CAAc,MAAkB,GAAA,EAA0C;AACvF,EAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,OAAO,MAAA;AAC7B,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,GAAA,CAAI,IAAuB,aAAa,CAAA;AAChE,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,KAAA,EAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAC5C,EAAA,IAAI,CAAC,MAAM,MAAM,IAAI,WAAW,CAAA,mBAAA,EAAsB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAA,CAAI,CAAA;AACzE,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,eAAA,CAAgB,MAAkB,CAAA,EAAkC;AACjF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,IAAA,EAAM,GAAG,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB;AAAA,IACjC,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,UAAU,CAAC,CAAA;AAAA,IACrC,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,SAAS,EAAE;AAAA,GACrC,CAAA;AACD,EAAA,IAAI,MAAA,EAAQ,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,MAAM,CAAA;AACvC,EAAA,IAAI,IAAA,CAAK,MAAM,KAAA,EAAO,MAAA,CAAO,IAAI,SAAA,EAAW,IAAA,CAAK,MAAM,KAAK,CAAA;AAC5D,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,MAAM,GAAA,CAAI,IAA6B,CAAA,cAAA,EAAiB,MAAA,CAAO,QAAA,EAAU,CAAA,CAAE,CAAA;AACpG,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,SAAA,GACvB,YAAA,CAAa,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAA,KAAc,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,GAC/D,YAAA;AACJ,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,OAAA;AAAA,IAAS,MAChC,OAAA,CAAQ,MAAA,KAAW,CAAA,GACf,cAAA,GACA,KAAA;AAAA,MACE,CAAC,MAAA,EAAQ,KAAA,EAAO,QAAA,EAAU,QAAQ,SAAS,CAAA;AAAA,MAC3C,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAAA,QACjB,IAAI,IAAA,CAAK,CAAA,CAAE,SAAA,GAAY,GAAI,EAAE,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,QACtD,CAAA,CAAE,SAAA,KAAc,IAAA,GAAO,IAAA,GAAO,KAAA;AAAA,QAC9B,CAAA,EAAG,CAAA,CAAE,SAAA,KAAc,IAAA,GAAO,GAAA,GAAM,GAAG,CAAA,EAAG,CAAA,CAAE,cAAc,CAAA,CAAA,EAAI,CAAA,CAAE,KAAK,CAAA,CAAA;AAAA,QACjE,EAAE,MAAA,IAAU,UAAA;AAAA,QACZ,EAAE,QAAA,IAAY;AAAA,OACf;AAAA;AACH,GACN;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,iBAAA,CAAkB,MAAkB,CAAA,EAAkC;AACnF,EAAA,IAAI,KAAK,KAAA,CAAM,MAAA,KAAW,OAAO,OAAO,SAAA,CAAU,MAAM,CAAC,CAAA;AACzD,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,IAAA,EAAM,GAAG,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB;AAAA,IACjC,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,UAAU,CAAC,CAAA;AAAA,IACrC,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,SAAS,GAAI;AAAA,GACvC,CAAA;AACD,EAAA,IAAI,MAAA,EAAQ,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,MAAM,CAAA;AACvC,EAAA,IAAI,IAAA,CAAK,MAAM,KAAA,EAAO,MAAA,CAAO,IAAI,SAAA,EAAW,IAAA,CAAK,MAAM,KAAK,CAAA;AAC5D,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,MAAM,GAAA,CAAI,IAA6B,CAAA,cAAA,EAAiB,MAAA,CAAO,QAAA,EAAU,CAAA,CAAE,CAAA;AACpG,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,SAAA,GACvB,YAAA,CAAa,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAA,KAAc,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,GAC/D,YAAA;AAIJ,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,MAAA;AAAA,IAAQ,MAAA;AAAA,IAAQ,QAAA;AAAA,IAAU,WAAA;AAAA,IAAa,QAAA;AAAA,IAAU,cAAA;AAAA,IAAgB,eAAA;AAAA,IACjE,sBAAA;AAAA,IAAwB,cAAA;AAAA,IAAgB,YAAA;AAAA,IAAc,SAAA;AAAA,IAAW;AAAA,GACnE;AACA,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAAA,IAC9B,IAAI,IAAA,CAAK,CAAA,CAAE,SAAA,GAAY,GAAI,EAAE,WAAA,EAAY;AAAA,IACzC,WAAW,CAAC,CAAA;AAAA,IACZ,aAAa,CAAC,CAAA;AAAA,IACd,CAAA,CAAE,SAAA;AAAA,IACF,CAAA,CAAE,cAAA;AAAA,IACF,CAAA,CAAE,WAAA,IAAe,CAAA,CAAE,KAAA,IAAS,EAAA;AAAA,IAC5B,EAAE,YAAA,IAAgB,EAAA;AAAA,IAAA,CACjB,EAAE,SAAA,KAAc,IAAA,GAAO,CAAA,CAAE,IAAA,GAAO,EAAE,EAAA,KAAO,EAAA;AAAA,IAC1C,EAAE,WAAA,IAAe,EAAA;AAAA,IACjB,EAAE,SAAA,IAAa,EAAA;AAAA,IACf,CAAA,CAAE,IAAA;AAAA,IACF,EAAE,OAAA,IAAW,IAAA,GAAO,MAAA,CAAO,CAAA,CAAE,OAAO,CAAA,GAAI;AAAA,GACzC,CAAA;AACD,EAAA,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,OAAA,EAAS,IAAI,CAAA,EAAG,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,CAAA;AACnE,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,SAAS,WAAW,CAAA,EAAgB;AAClC,EAAA,IAAI,CAAA,CAAE,YAAA,KAAiB,gBAAA,EAAkB,OAAO,mBAAA;AAChD,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,MAAA,EAAQ,OAAO,MAAA;AAChC,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,UAAA,EAAY,OAAO,KAAA;AACpC,EAAA,OAAO,CAAA,CAAE,SAAA,KAAc,IAAA,GAAO,SAAA,GAAY,MAAA;AAC5C;AAEA,SAAS,aAAa,CAAA,EAAgB;AACpC,EAAA,IAAI,CAAA,CAAE,SAAS,OAAO,QAAA;AACtB,EAAA,IAAI,CAAA,CAAE,iBAAA,KAAsB,qBAAA,EAAuB,OAAO,SAAA;AAC1D,EAAA,OAAO,UAAA;AACT;AAGA,eAAe,SAAA,CAAU,MAAkB,CAAA,EAAkC;AAC3E,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,SAAS,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,OAAO,CAAA;AACpD,EAAA,IAAI,IAAA,CAAK,MAAM,IAAA,EAAM,MAAA,CAAO,IAAI,MAAA,EAAQ,IAAA,CAAK,MAAM,IAAI,CAAA;AACvD,EAAA,IAAI,IAAA,CAAK,MAAM,EAAA,EAAI,MAAA,CAAO,IAAI,IAAA,EAAM,IAAA,CAAK,MAAM,EAAE,CAAA;AACjD,EAAA,IAAI,IAAA,CAAK,MAAM,OAAA,EAAS,MAAA,CAAO,IAAI,SAAA,EAAW,IAAA,CAAK,MAAM,OAAO,CAAA;AAChE,EAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,OAAA,CAAQ,sBAAsB,MAAA,CAAO,QAAA,EAAU,CAAA,CAAE,CAAA;AAC3E,EAAA,CAAA,CAAE,EAAE,IAAA,CAAK,OAAA,EAAS,EAAE,MAAA,EAAQ,OAAO,CAAA;AACnC,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAIA,eAAe,cAAA,CAAe,MAAkB,CAAA,EAAkC;AAChF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAM,GAAA,CAAI,IAAiC,UAAU,CAAA;AACzE,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,OAAA;AAAA,IAAS,MAChC,OAAA,CAAQ,MAAA,KAAW,CAAA,GACf,mBAAA,GACA,KAAA;AAAA,MACE,CAAC,MAAA,EAAQ,UAAA,EAAY,MAAA,EAAQ,SAAS,QAAQ,CAAA;AAAA,MAC9C,QAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,EAAE,IAAA,EAAM,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,MAAM,CAAA,CAAE,aAAA,IAAiB,QAAA,EAAK,CAAA,CAAE,MAAM,CAAC;AAAA;AACnF,GACN;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAIA,eAAe,eAAA,CAAgB,MAAkB,CAAA,EAAkC;AACjF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,GAAA,CAAI,IAA6B,WAAW,CAAA;AACvE,EAAA,IAAA;AAAA,IAAK,CAAA;AAAA,IAAG,KAAK,KAAA,CAAM,IAAA;AAAA,IAAM,QAAA;AAAA,IAAU,MACjC,QAAA,CAAS,MAAA,KAAW,CAAA,GAChB,kBAAA,GACA,MAAM,CAAC,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAA,EAAG,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,CAAA,CAAE,IAAA,EAAM,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAC,CAAC;AAAA,GACtG;AACA,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,cAAA,CAAe,MAAkB,CAAA,EAAkC;AAChF,EAAA,MAAM,CAAC,OAAA,EAAS,GAAG,SAAS,CAAA,GAAI,CAAC,GAAG,IAAA,CAAK,WAAW,CAAA,CAAE,OAAA,EAAQ;AAE9D,EAAA,MAAM,OAAO,SAAA,CAAU,OAAA,GAAU,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AAChD,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,SAAS,MAAM,IAAI,WAAW,4CAA4C,CAAA;AACxF,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,IAAA,CAAc,aAAa,EAAE,IAAA,EAAM,SAAS,CAAA;AACtE,EAAA,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,SAAS,MAAM,CAAA,eAAA,EAAkB,OAAA,CAAQ,IAAI,CAAA,GAAA,EAAM,eAAA,CAAgB,OAAA,CAAQ,OAAO,CAAC,CAAA,EAAA,CAAI,CAAA;AAChH,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AAEA,eAAe,iBAAA,CAAkB,MAAkB,CAAA,EAAkC;AACnF,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,WAAW,mCAAmC,CAAA;AACjE,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpC,EAAA,MAAM,GAAA,CAAI,GAAA,CAAI,CAAA,UAAA,EAAa,EAAE,CAAA,CAAE,CAAA;AAC/B,EAAA,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,EAAA,EAAI,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,SAAS,IAAA,EAAK,EAAG,MAAM,CAAA,QAAA,EAAW,EAAE,CAAA,SAAA,CAAW,CAAA;AACpG,EAAA,OAAO,IAAA,CAAK,EAAA;AACd;AC9hBO,SAAS,mBAAmB,OAAA,EAAyC;AAC1E,EAAA,OAAO,IAAI,OAAA,CAAQ,CAACP,QAAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,OAAA;AAC1B,IAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,MAAA,IAAI,IAAA,GAAO,EAAA;AACX,MAAA,KAAA,CAAM,YAAY,MAAM,CAAA;AACxB,MAAA,KAAA,CAAM,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAW,QAAQ,KAAM,CAAA;AAC3C,MAAA,KAAA,CAAM,GAAG,KAAA,EAAO,MAAMA,SAAQ,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA;AAC1C,MAAA,KAAA,CAAM,EAAA,CAAG,SAAS,MAAM,CAAA;AACxB,MAAA;AAAA,IACF;AAKA,IAAA,MAAA,CAAO,MAAM,YAAY,CAAA;AACzB,IAAAQ,2BAAA,CAAmB,KAAK,CAAA;AACxB,IAAA,KAAA,CAAM,WAAW,IAAI,CAAA;AACrB,IAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,IAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAc,GAAA,KAA2C;AACtE,MAAA,IAAI,GAAA,CAAI,IAAA,KAAS,QAAA,IAAY,GAAA,CAAI,SAAS,OAAA,EAAS;AACjD,QAAA,OAAA,EAAQ;AACR,QAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AACjB,QAAAR,SAAQ,KAAK,CAAA;AAAA,MACf,CAAA,MAAA,IAAW,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,SAAS,GAAA,EAAK;AACvC,QAAA,OAAA,EAAQ;AACR,QAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AACjB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,WAAW,CAAC,CAAA;AAAA,MAC/B,CAAA,MAAA,IAAW,GAAA,CAAI,IAAA,KAAS,WAAA,EAAa;AACnC,QAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,MAC3B,CAAA,MAAA,IAAW,IAAA,IAAQ,CAAC,GAAA,CAAI,IAAA,EAAM;AAC5B,QAAA,KAAA,IAAS,IAAA;AAAA,MACX;AAAA,IACF,CAAA;AACA,IAAA,SAAS,OAAA,GAAU;AACjB,MAAA,KAAA,CAAM,WAAW,KAAK,CAAA;AACtB,MAAA,KAAA,CAAM,KAAA,EAAM;AACZ,MAAA,KAAA,CAAM,GAAA,CAAI,YAAY,KAAK,CAAA;AAAA,IAC7B;AACA,IAAA,KAAA,CAAM,MAAA,EAAO;AACb,IAAA,KAAA,CAAM,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA,EAC5B,CAAC,CAAA;AACH;;;AC5CA,SAAS,cAAA,GAAkC;AACzC,EAAA,OAAO,kBAAA,CAAmB,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,CAAA;AACpG;AAEA,GAAA,CAAI,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,EAAE,gBAAgB,CAAA,CAC1C,KAAK,CAAC,IAAA,KAAS,QAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CACjC,KAAA,CAAM,CAAC,GAAA,KAAQ;AAMd,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAG;AACnC,IAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,EAAE,MAAM,QAAA,EAAU,OAAA,IAAU,EAAG,IAAA,EAAM,CAAC,CAAC;AAAA,CAAI,CAAA;AAAA,EACxG,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,OAAO;AAAA,CAAI,CAAA;AAAA,EACrC;AACA,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA","file":"cli.cjs","sourcesContent":["export interface ParsedArgs {\n command?: string\n sub?: string\n positionals: string[]\n flags: {\n json: boolean\n help: boolean\n version: boolean\n yes: boolean\n api?: string\n email?: string\n safe?: string\n agent?: string\n limit?: number\n offset?: number\n direction?: 'in' | 'out'\n format?: string\n from?: string\n to?: string\n company?: string\n }\n}\n\nconst VALUE_FLAGS = new Set([\n '--api', '--email', '--safe', '--agent', '--limit', '--offset', '--direction',\n '--format', '--from', '--to', '--company',\n])\n\n/**\n * `haven <command> [sub] [positionals] [--flags]`. Deliberately small — no\n * dependency, no clever aliasing. Unknown flags throw so typos fail loudly.\n */\nexport function parseArgs(argv: string[]): ParsedArgs {\n const positionals: string[] = []\n const flags: ParsedArgs['flags'] = { json: false, help: false, version: false, yes: false }\n\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i]\n if (arg === '--json') flags.json = true\n else if (arg === '--help' || arg === '-h') flags.help = true\n else if (arg === '--version' || arg === '-v') flags.version = true\n else if (arg === '--yes' || arg === '-y') flags.yes = true\n else if (VALUE_FLAGS.has(arg)) {\n const value = argv[++i]\n if (value === undefined || value.startsWith('--')) {\n throw new Error(`Missing value for ${arg}`)\n }\n if (arg === '--api') flags.api = value\n else if (arg === '--email') flags.email = value\n else if (arg === '--safe') flags.safe = value\n else if (arg === '--agent') flags.agent = value\n else if (arg === '--limit') {\n const n = Number(value)\n if (!Number.isInteger(n) || n <= 0) throw new Error('--limit must be a positive integer')\n flags.limit = n\n } else if (arg === '--offset') {\n const n = Number(value)\n if (!Number.isInteger(n) || n < 0) throw new Error('--offset must be a non-negative integer')\n flags.offset = n\n } else if (arg === '--direction') {\n if (value !== 'in' && value !== 'out') throw new Error('--direction must be \"in\" or \"out\"')\n flags.direction = value\n } else if (arg === '--format') {\n if (value !== 'csv' && value !== 'sie') throw new Error('--format must be \"csv\" or \"sie\"')\n flags.format = value\n } else if (arg === '--from') flags.from = value\n else if (arg === '--to') flags.to = value\n else if (arg === '--company') flags.company = value\n } else if (arg.startsWith('--')) {\n throw new Error(`Unknown option: ${arg}`)\n } else {\n positionals.push(arg)\n }\n }\n\n const [command, sub, ...rest] = positionals\n return { command, sub, positionals: rest, flags }\n}\n\nexport function helpText(): string {\n return [\n 'haven — terminal-native companion to the Haven dashboard',\n '',\n 'Usage: haven <command> [subcommand] [options]',\n '',\n 'Auth:',\n ' login [--email <e>] Sign in (password via prompt or HAVEN_PASSWORD)',\n ' logout Clear the saved session',\n ' whoami Show the signed-in user, session expiry and API URL',\n '',\n 'For agents:',\n ' guide Print the agent onboarding runbook (same text as /for-agents.md)',\n '',\n 'Read:',\n ' wallets list List your Haven wallets',\n ' wallets balances [--safe <id|address>] Token balances for a wallet',\n ' agents list List your agents',\n ' agents show <id> Show one agent + its budget',\n ' budget show <agentId> Show an agent\\'s configured budget',\n ' activity list [--safe <id|address>] [--agent <id>] [--direction in|out] [--limit <n>] [--offset <n>]',\n ' activity export [filters] Emit CSV to stdout (--format csv, default)',\n ' activity export --format sie [--from <ISO>] [--to <ISO>] [--company <name>]',\n ' Bookkeeping-ready SIE 4I (Fortnox/Visma/Bokio)',\n ' catalog list List payable services',\n ' contacts list List your address book',\n '',\n 'Manage (backend-only — no on-chain signing):',\n ' agents pause|resume <id>',\n ' agents revoke <id> --yes Permanently revoke an agent',\n ' agents rotate-key <id> Issue a new API key (shown once)',\n ' agents rename <id> <name>',\n ' wallets rename <id> <name>',\n ' contacts add <name> <address> | contacts remove <id>',\n '',\n 'Options:',\n ' --json One JSON value on stdout, prose on stderr, on every',\n ' command including refusals: { ok: false, error: { code, message, hint? } }',\n ' --yes, -y Skip the confirmation prompt for destructive actions',\n ' --api <url> Backend URL (default: HAVEN_API_URL or http://localhost:3001)',\n ' --help, --version',\n '',\n 'Exit codes: 0 ok · 1 failed · 2 usage · 3 not authenticated · 4 refused · 5 network',\n '',\n 'On-chain actions (deploy, budgets, approvers, send) are signed in the',\n 'dashboard — this CLI reads and manages; it never holds your keys.',\n ].join('\\n')\n}\n","export class CliApiError extends Error {\n status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'CliApiError'\n this.status = status\n }\n}\n\nexport interface CliApi {\n get<T>(path: string): Promise<T>\n post<T>(path: string, body?: unknown): Promise<T>\n put<T>(path: string, body?: unknown): Promise<T>\n del<T>(path: string): Promise<T>\n /** GET a non-JSON body (e.g. an export file) as raw text. */\n getText(path: string): Promise<string>\n}\n\nexport interface CreateCliApiOptions {\n baseUrl: string\n token?: string\n fetchImpl?: typeof fetch\n}\n\n/**\n * Minimal JSON client for the Haven backend. Sends the user JWT as a Bearer\n * token when present, and surfaces backend `{ error }` messages as\n * `CliApiError` so commands can print something human.\n */\nexport function createCliApi({ baseUrl, token, fetchImpl = fetch }: CreateCliApiOptions): CliApi {\n const root = baseUrl.replace(/\\/+$/, '')\n\n async function request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = { Accept: 'application/json' }\n if (token) headers.Authorization = `Bearer ${token}`\n if (body !== undefined) headers['Content-Type'] = 'application/json'\n\n let res: Response\n try {\n res = await fetchImpl(`${root}${path}`, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n } catch (err) {\n throw new CliApiError(\n `Could not reach Haven at ${root}: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n )\n }\n\n if (res.status === 401) {\n throw new CliApiError('Not authenticated. Run `haven login` first.', 401)\n }\n\n const text = await res.text()\n const payload = text ? safeParse(text) : undefined\n\n if (!res.ok) {\n const message =\n (payload && typeof payload === 'object' && 'error' in payload && typeof payload.error === 'string'\n ? payload.error\n : null) ?? `Request failed (HTTP ${res.status}).`\n throw new CliApiError(message, res.status)\n }\n\n return payload as T\n }\n\n async function requestText(path: string): Promise<string> {\n const headers: Record<string, string> = { Accept: 'text/plain' }\n if (token) headers.Authorization = `Bearer ${token}`\n\n let res: Response\n try {\n res = await fetchImpl(`${root}${path}`, { method: 'GET', headers })\n } catch (err) {\n throw new CliApiError(\n `Could not reach Haven at ${root}: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n )\n }\n\n if (res.status === 401) {\n throw new CliApiError('Not authenticated. Run `haven login` first.', 401)\n }\n\n const text = await res.text()\n if (!res.ok) {\n const payload = text ? safeParse(text) : undefined\n const message =\n (payload && typeof payload === 'object' && 'error' in payload && typeof payload.error === 'string'\n ? payload.error\n : null) ?? `Request failed (HTTP ${res.status}).`\n throw new CliApiError(message, res.status)\n }\n return text\n }\n\n return {\n get: <T>(path: string) => request<T>('GET', path),\n post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),\n put: <T>(path: string, body?: unknown) => request<T>('PUT', path, body),\n del: <T>(path: string) => request<T>('DELETE', path),\n getText: (path: string) => requestText(path),\n }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return undefined\n }\n}\n","import { mkdir, readFile, rm, writeFile, chmod } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join, resolve } from 'node:path'\n\n/**\n * The signed-in user session. The token is a *user* JWT (same credential the\n * dashboard holds) — treat it like a secret: stored owner-only, never logged,\n * never sent anywhere but the Haven API. `apiBaseUrl` is pinned at login so\n * later commands talk to the same backend.\n */\nexport interface Session {\n token: string\n apiBaseUrl: string\n user: { id: string; email: string; name: string | null }\n}\n\nexport interface SessionStore {\n load(): Promise<Session | null>\n save(session: Session): Promise<void>\n clear(): Promise<void>\n path: string\n}\n\nfunction sessionDir(homeDir: string): string {\n return resolve(homeDir, '.haven')\n}\n\nexport function sessionPath(homeDir: string = homedir()): string {\n return join(sessionDir(homeDir), 'session.json')\n}\n\n/** File-backed session store, owner-only perms (0600 file in a 0700 dir). */\nexport function createSessionStore(homeDir: string = homedir()): SessionStore {\n const path = sessionPath(homeDir)\n return {\n path,\n async load() {\n try {\n const raw = await readFile(path, 'utf8')\n const parsed = JSON.parse(raw) as Partial<Session>\n if (!parsed.token || !parsed.apiBaseUrl || !parsed.user) return null\n return parsed as Session\n } catch {\n return null\n }\n },\n async save(session) {\n await mkdir(sessionDir(homeDir), { recursive: true, mode: 0o700 })\n await writeFile(path, `${JSON.stringify(session, null, 2)}\\n`, { mode: 0o600 })\n await chmod(path, 0o600).catch(() => undefined)\n },\n async clear() {\n await rm(path, { force: true })\n },\n }\n}\n","/** Tiny fixed-width table for human output. Scriptable callers use `--json`. */\nexport function table(headers: string[], rows: string[][]): string {\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)),\n )\n const line = (cells: string[]) =>\n cells.map((c, i) => (c ?? '').padEnd(widths[i])).join(' ').trimEnd()\n return [line(headers), line(widths.map((w) => '-'.repeat(w))), ...rows.map(line)].join('\\n')\n}\n\nexport function truncateAddress(address: string): string {\n if (!address || address.length <= 12) return address\n return `${address.slice(0, 6)}…${address.slice(-4)}`\n}\n\nconst CHAIN_NAMES: Record<number, string> = { 100: 'Gnosis', 8453: 'Base' }\n\nexport function chainName(chainId: number): string {\n return CHAIN_NAMES[chainId] ?? `chain ${chainId}`\n}\n","/**\n * CSV serialization for `haven activity export`. Mirrors the dashboard export\n * (#411): RFC 4180 quoting, CRLF line endings, and a spreadsheet\n * formula-injection guard. Kept self-contained so the CLI has no @haven_ai/*\n * runtime dependency.\n */\n\n/** Quote per RFC 4180 and neutralise leading =,+,-,@ (Excel formula injection). */\nfunction csvField(value: string): string {\n let v = value\n if (/^[=+\\-@\\t\\r]/.test(v)) v = `'${v}`\n return `\"${v.replace(/\"/g, '\"\"')}\"`\n}\n\nexport function toCsv(headers: string[], rows: string[][]): string {\n const lines = [headers.join(','), ...rows.map((r) => r.map(csvField).join(','))]\n return lines.join('\\r\\n')\n}\n","import { CliApiError } from './api.js'\n\n/**\n * Exit codes (#2525). Documented in README.md § For agents and scripts, and\n * asserted in `json-contract.test.ts` (every code, over the whole command list)\n * and `commands.test.ts` (the individual commands that produce them) — an agent\n * branches on these, so they are a contract rather than an implementation\n * detail.\n */\nexport const EXIT = {\n ok: 0,\n /** Something failed and none of the specific codes below describe it. */\n failed: 1,\n /** The command line was wrong: unknown command, missing argument, bad flag. */\n usage: 2,\n /** No stored session, or the backend rejected the one we have. Log in again. */\n notAuthenticated: 3,\n /** Authenticated, and the backend refused anyway (403, 410, other 4xx). */\n refused: 4,\n /** The backend could not be reached at all. */\n network: 5,\n} as const\n\nexport type ExitCode = (typeof EXIT)[keyof typeof EXIT]\n\n/** Machine-readable `error.code` values, one per exit code above 0. */\nexport type FailureCode = 'failed' | 'usage' | 'not_authenticated' | 'refused' | 'network'\n\n/** A wrong command line. Carries `usage` so callers do not guess the exit code. */\nexport class UsageError extends Error {\n readonly hint?: string\n constructor(message: string, hint?: string) {\n super(message)\n this.name = 'UsageError'\n this.hint = hint\n }\n}\n\nexport interface Failure {\n code: FailureCode\n exit: ExitCode\n message: string\n hint?: string\n}\n\n/**\n * One place that decides what an error means, so the JSON body and the exit\n * code cannot disagree — they are read off the same object.\n *\n * **On 401 → `not_authenticated`, not `refused`.** The issue lists 401\n * alongside 403/410 under \"refused by the backend\", and separately lists\n * \"not logged in / session expired\" — the two overlap, and a 401 is exactly\n * the second one. An agent seeing `not_authenticated` knows to re-run\n * `haven login`; `refused` tells it the opposite (the session is fine, the\n * action is not allowed). Splitting them on the wire is the whole point of\n * having two codes, so 401 resolves to the one it can act on.\n */\nexport function toFailure(err: unknown): Failure {\n if (err instanceof UsageError) {\n return { code: 'usage', exit: EXIT.usage, message: err.message, hint: err.hint }\n }\n if (err instanceof CliApiError) {\n if (err.status === 0) {\n return {\n code: 'network',\n exit: EXIT.network,\n message: err.message,\n hint: 'Check the network and `--api`, then retry.',\n }\n }\n if (err.status === 401) {\n return {\n code: 'not_authenticated',\n exit: EXIT.notAuthenticated,\n message: err.message,\n hint: 'Run `haven login` (or set HAVEN_EMAIL and HAVEN_PASSWORD).',\n }\n }\n if (err.status >= 400 && err.status < 500) {\n // 403 and 410 are the named cases; every other 4xx is the same shape of\n // answer — the backend understood and said no — so it gets the same code\n // rather than falling through to the generic one.\n return { code: 'refused', exit: EXIT.refused, message: err.message }\n }\n return { code: 'failed', exit: EXIT.failed, message: err.message }\n }\n return { code: 'failed', exit: EXIT.failed, message: err instanceof Error ? err.message : String(err) }\n}\n","import type { Failure } from './errors.js'\n\n/**\n * The `--json` contract (#2525).\n *\n * Under `--json`, **stdout carries exactly one JSON value and nothing else** —\n * every line of human prose goes to stderr instead. That is what lets an agent\n * pipe stdout straight into a parser without stripping progress chatter, and\n * it is why `note()` exists: the same call site prints a sentence for a human\n * and stays silent (on stdout) for a machine.\n *\n * Success keeps the payload shape each command already emitted — including the\n * bare arrays that `agents list` and friends return — so this change adds a\n * failure contract without breaking a script that already parses a success.\n * Failures are always the object `{ ok: false, error: { code, message, hint? } }`.\n */\nexport interface Output {\n readonly json: boolean\n /** The command's success payload. At most one per run, on stdout. */\n data(payload: unknown, human: () => string): void\n /** Raw text (an export file). Printed as-is; wrapped under `--json`. */\n text(content: string, meta: Record<string, unknown>): void\n /** Human prose. Stdout in prose mode; stderr under `--json`. */\n note(line: string): void\n /** The one failure object. Always stdout under `--json`, stderr otherwise. */\n failure(failure: Failure): void\n}\n\nexport function createOutput(\n json: boolean,\n out: (line: string) => void,\n err: (line: string) => void,\n): Output {\n return {\n json,\n data(payload, human) {\n out(json ? JSON.stringify(payload, null, 2) : human())\n },\n text(content, meta) {\n // A CSV/SIE body is the payload in prose mode. Under --json it becomes a\n // field of the single object, so the contract (\"one JSON value on\n // stdout\") holds for exports too and the content stays recoverable.\n out(json ? JSON.stringify({ ok: true, ...meta, content }, null, 2) : content)\n },\n note(line) {\n if (json) err(line)\n else out(line)\n },\n failure(failure) {\n const body = {\n ok: false as const,\n error: {\n code: failure.code,\n message: failure.message,\n ...(failure.hint ? { hint: failure.hint } : {}),\n },\n }\n if (json) out(JSON.stringify(body, null, 2))\n else err(failure.hint ? `${failure.message}\\n${failure.hint}` : failure.message)\n },\n }\n}\n","/**\n * The agent onboarding runbook — GENERATED, do not edit by hand.\n *\n * Canonical source: `packages/sdk/src/agent-guidance.ts` (#2523), served to\n * agents at `/for-agents.md`. This is a decoupled copy so `@haven_ai/cli`\n * keeps zero runtime dependencies: importing it from the SDK would put ethers,\n * viem and x402 on the `npx @haven_ai/cli` path for one Markdown string.\n * Same arrangement, and the same reason, as\n * `packages/frontend/src/lib/agent-skill-bundle.ts`.\n *\n * Regenerate: node packages/cli/scripts/sync-agent-guidance.mjs\n * The parity test in `agent-guidance-text.test.ts` fails if you forget.\n */\n\nexport const HAVEN_AGENT_RUNBOOK_MD = \"# Haven for agents — set your user up to let you pay\\n\\nYou are an AI agent whose user has no Haven account yet, or has one but has not connected you.\\n\\n> Links below are paths on this same host: resolve them against the URL you fetched this file from.\\n\\n## What Haven is, in three sentences\\n\\nYour user gives you a **budget on their own account** — not their wallet, and not a key to their funds. The budget is a delegation they sign, enforced on-chain: a payment over it, to the wrong recipient, or past its expiry is refused at execution time, not by a dashboard promise. Haven constructs and relays the payments; you get an agent credential and a signing key made on your machine, and your user can revoke the budget without you and without Haven.\\n\\n## The sequence\\n\\nFour of the six steps are your user's — each needs a human signature or a human decision. The rest is yours. If they already have a funded account, start at step 3.\\n\\n1. **HUMAN — create the account.** Name, email, password, then a passkey (Face ID / Touch ID) or a wallet. Never offer to enter any of it: you must not have their password, and the passkey is bound to their device.\\n2. **HUMAN — fund it.** USDC on Base, to the address the dashboard shows.\\n3. **HUMAN — create the agent, set its budget**, and paste you the **setup prompt** it hands back.\\n4. **YOU — run the connector command** in that prompt (below). It makes your signing key locally, registering only the public address.\\n5. **HUMAN — approve the budget** with their passkey, in the Haven tab they created the agent in: it advances to the approval step by itself once your run registers.\\n6. **YOU — verify, then pay.**\\n\\n## Hand-off scripts\\n\\nSend these as your own message, `<host>` replaced by the host you fetched this file from. Say what you cannot do, not only what they must.\\n\\n**Before signup** (step 1):\\n\\n> I can do everything except the parts that need your signature. Please open `<host>/signup?next=/agents&via=agent` — name, email, password, then a passkey (Face ID / Touch ID) or a wallet. That is your account's key: I should not have it, and I will never ask for your password. Already have one? `<host>/login?next=/agents`.\\n\\n**At the passkey step:**\\n\\n> The passkey must be made on your own device — it is what keeps the account yours, so nobody, Haven included, can move your funds without you. If this browser cannot, open `<host>/onboarding?next=/agents` on your phone and finish there.\\n\\n**At funding** (step 2):\\n\\n> Your Haven account needs USDC on Base before I can pay for anything — USDC only, no ETH: Haven sponsors the gas. The dashboard shows the address to send it to; a small amount first is fine.\\n\\n**At the budget** (step 3):\\n\\n> On `<host>/agents`, create an agent for me and set a budget — say 25 USDC per day. That is the limit I cannot exceed. It hands back a setup prompt: paste it to me and I run it here.\\n\\n**At budget approval** (step 5) — the moment your run reports that approval is required, before anything else. Send the first if your run carried `approval.url`, the second if it did not.\\n\\n> Setup is done on my side. Approve the budget here: <approval.url>. Approve it with your passkey; nothing can be spent until you do.\\n\\n> Setup is done on my side. Go back to the Haven tab where you created the agent — it should now be asking you to approve the budget. Approve it with your passkey; nothing can be spent until you do.\\n\\n## What you run\\n\\nThe setup prompt carries a **connector command** shaped like this:\\n\\n```\\nnpx -y @haven_ai/connect@<channel> --setup EXAMPLE-SETUP-TOKEN-NOT-REAL --api <api-url> --ack-local-tools\\n```\\n\\nRun the prompt's version, not this one: the token is one-time, the API URL is the backend's own, and `<channel>` is the npm tag your prompt names — never a tag you pick. The rules below come from that prompt, so \\\"me\\\" in them is your user, not Haven.\\n\\n- If you are an AI agent running this command yourself rather than a human pasting it, you should append --json: the connector then emits one machine-readable, secret-free result object on stdout with progress on stderr, and returns promptly instead of blocking while it waits for the budget approval.\\n- When a --json outcome reports approval.required: true, your first action must be to relay the approval instruction to me in your own reply — if the outcome carries approval.url, give me that link; otherwise tell me to return to Haven and approve this agent's budget — before verifying the connection, restarting anything, or any other step. Never build that link yourself: relay the one the outcome gave you or none at all. Any restart the outcome asks for is a separate instruction to give me afterwards, once the approval is done.\\n- If you ran the command without --json, the connector waits for the approval itself and prints its next steps when it finishes: relay the budget-approval instruction to me — the approval link if those steps printed one, otherwise that you need to return to Haven and approve this agent's budget — only if those printed next steps still ask for it. If they report the budget as already approved, there is nothing for me to approve.\\n- Only two changes to the command above are permitted, and no others: appending --json, and — only if the connector refuses because it could not determine the agent runtime — re-running it once with --runtime <name> added, naming the harness you are running in, using one of the values that refusal lists. Never invent a runtime name and never change anything else.\\n- Do not print private keys, API keys, credential file contents, or config secrets in chat or logs.\\n\\nIf the approval wait times out, nothing is lost — your agent is registered and the budget is still waiting to be approved. Send your user the `approval.url` your run reported, or, if it carried none, ask them to finish it in that same Haven tab. The outcome carries no setup id, so never assemble an approval link out of parts — relay the whole one it gave you or none at all.\\n\\n## How to verify\\n\\nCall `haven_get_agent`, one of the Haven MCP tools the connector wires into your runtime in step 4. It returns identity plus `spend_authority_readiness`:\\n\\n- `ready` — a budget is live; you can pay.\\n- `needs_approval` — the connector finished, nobody approved yet. Ask your user again, in their Haven tab; there is no queue to wait in.\\n- `revoked` — the credential is not active; ask your user to create a new agent.\\n\\n`ready` covers hosted identity and the budget only, not your local signer. Check that with `npx -y @haven_ai/connect@<channel> --doctor`, the same tag your prompt named — a separate command, so the two-changes rule does not bind it.\\n\\n## If you cannot open a browser\\n\\nNothing here needs you to. Steps 1-3 are links: hand your user the full `<host>/…` URL and ask them to say when it is done. Step 5 is a link only when your run reported one in `approval.url` — otherwise it is the tab they already have open, as above. Then poll `haven_get_agent` until it reads `ready`. Do not route around the sign-in wall — it makes the account theirs, not yours.\\n\\n## Vocabulary\\n\\n| Term | What it is |\\n|---|---|\\n| **setup prompt** | The text the dashboard hands your user to paste to you. Carries the command and its rules. |\\n| **connector command** | The `npx -y @haven_ai/connect@…` line you run. One-time token, one use. |\\n| **agent credential** | Your API key (`sk_agent_…`), written to `~/.haven`. It identifies you; alone it cannot move money. |\\n| **delegate key** | Your signing key, made on this machine and never sent anywhere. |\\n| **budget** | The on-chain delegation your user signed. It authorises the payment; Haven constructs and relays it. |\\n\\nNext: [your agent hit a 402](/402.md) · [everything agent-readable](/llms.txt)\\n\"\n","/**\n * Read the expiry out of the stored session JWT (#2525).\n *\n * `whoami --json` and `login --json` report when the session dies, and the\n * only place that fact exists is the token's own `exp` claim — the backend\n * signs it with `expiresIn: '7d'` (`routes/auth.ts`) and `/auth/me` does not\n * return it. So the payload segment is base64url-decoded and read.\n *\n * This deliberately does NOT verify the signature, and must never be used to\n * decide anything but what to print: the CLI has no key to verify with, and a\n * forged `exp` would only mislead the user about a token the backend will\n * reject on its own terms. It never logs, echoes or returns the token itself.\n */\nexport function sessionExpiry(token: string): string | null {\n const segment = token.split('.')[1]\n if (!segment) return null\n try {\n const json = Buffer.from(segment.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf8')\n const claims = JSON.parse(json) as { exp?: unknown }\n if (typeof claims.exp !== 'number' || !Number.isFinite(claims.exp)) return null\n return new Date(claims.exp * 1000).toISOString()\n } catch {\n // A token we cannot read is not an error worth failing a command over —\n // the expiry is informational, and every other field still resolves.\n return null\n }\n}\n","import { parseArgs, helpText, type ParsedArgs } from './args.js'\nimport { createCliApi, CliApiError, type CliApi } from './api.js'\nimport { createSessionStore, type Session, type SessionStore } from './session.js'\nimport { chainName, table, truncateAddress } from './format.js'\nimport { toCsv } from './csv.js'\nimport { EXIT, UsageError, toFailure, type ExitCode } from './errors.js'\nimport { createOutput, type Output } from './output.js'\nimport { HAVEN_AGENT_RUNBOOK_MD } from './agent-guidance-text.js'\nimport { sessionExpiry } from './token.js'\n\n// Hosted Haven backend. Override with `--api <url>` or HAVEN_API_URL (e.g. a\n// local backend at http://localhost:3001, or your own domain once self-hosted).\nconst DEFAULT_API = 'https://havenbackend-production-8a00.up.railway.app'\n// Self-reported CLI version. Owned by scripts/release-bump.mjs, which rewrites\n// the string literal below on every release — keep it a bare quoted literal.\nexport const CLI_VERSION = '0.0.0-dev.202609051106.201fc90'\n\nexport interface RunDeps {\n sessionStore?: SessionStore\n /** Build an API client; injected so tests can stub the backend. */\n makeApi?: (baseUrl: string, token?: string) => CliApi\n promptPassword?: () => Promise<string>\n out?: (line: string) => void\n err?: (line: string) => void\n env?: NodeJS.ProcessEnv\n}\n\ninterface ResolvedDeps {\n sessionStore: SessionStore\n makeApi: (baseUrl: string, token?: string) => CliApi\n promptPassword: () => Promise<string>\n out: (line: string) => void\n err: (line: string) => void\n env: NodeJS.ProcessEnv\n /** Set once `--json` is known; every command writes through it. */\n o: Output\n}\n\n/**\n * Every command this CLI dispatches, as data (#2525).\n *\n * The table-driven contract test in `json-contract.test.ts` iterates THIS list\n * and asserts each command's `--json` refusal is one JSON object on stdout, so\n * a command added to `dispatch` without adding it here is not covered. Its\n * ceiling, stated plainly: the test proves the listed commands honour the\n * contract, not that the list is complete. A drift test below pins the list\n * against `dispatch`'s own switch to close that gap by execution.\n */\nexport const COMMANDS = [\n 'login', 'logout', 'whoami', 'guide',\n 'wallets list', 'wallets balances', 'wallets rename',\n 'agents list', 'agents show', 'agents pause', 'agents resume', 'agents revoke',\n 'agents rotate-key', 'agents rename',\n 'budget show',\n 'activity list', 'activity export',\n 'catalog list',\n 'contacts list', 'contacts add', 'contacts remove',\n] as const\n\n// ── Backend response shapes (subset the CLI needs) ──────────────────\ninterface Safe { id: string; safe_address: string; chain_id: number; name: string; is_default: boolean }\ninterface Allowance { token_symbol: string; allowance_amount: string; reset_period_min: number }\ninterface Agent { id: string; name: string; status: string; allowances?: Allowance[] }\ninterface Balance { symbol: string; formatted: string; balance: string }\ninterface Txn {\n hash: string; direction: 'in' | 'out'; valueFormatted: string; asset: string\n source?: string; timestamp: number; safeName?: string\n from?: string; to?: string; isError?: boolean\n tokenSymbol?: string; tokenAddress?: string; chainId?: number; safeAddress?: string\n agentName?: string; paymentFlowStatus?: string | null; activityType?: string\n}\ninterface CatalogEntry { name: string; category: string; rail: string; price_display?: string | null; status: string }\ninterface Contact { id: string; name: string; address: string }\n\n/** Entry point. Returns a process exit code; never throws for expected errors. */\nexport async function run(argv: string[], deps: RunDeps = {}): Promise<number> {\n const out = deps.out ?? ((l: string) => process.stdout.write(`${l}\\n`))\n const err = deps.err ?? ((l: string) => process.stderr.write(`${l}\\n`))\n\n // `--json` has to be known before anything can be emitted, including a parse\n // failure's own message. Scanning argv for the flag is deliberate: parseArgs\n // throws on a bad line, and a refusal that ignored --json because the parse\n // failed would break the contract exactly when a caller most needs it.\n const json = argv.includes('--json')\n const o = createOutput(json, out, err)\n\n const d: ResolvedDeps = {\n sessionStore: deps.sessionStore ?? createSessionStore(),\n makeApi: deps.makeApi ?? ((baseUrl, token) => createCliApi({ baseUrl, token })),\n promptPassword: deps.promptPassword ?? (() => Promise.reject(new Error('No password input available'))),\n out,\n err,\n env: deps.env ?? process.env,\n o,\n }\n\n let args: ParsedArgs\n try {\n args = parseArgs(argv)\n } catch (e) {\n return fail(d, new UsageError(e instanceof Error ? e.message : String(e), 'Run `haven --help`.'))\n }\n\n if (args.flags.version) {\n o.data({ version: CLI_VERSION }, () => CLI_VERSION)\n return EXIT.ok\n }\n if (args.flags.help || !args.command) {\n o.data({ help: helpText() }, () => helpText())\n return EXIT.ok\n }\n\n try {\n return await dispatch(args, d)\n } catch (e) {\n return fail(d, e)\n }\n}\n\n/** The single exit: one failure object, one exit code, read off one decision. */\nfunction fail(d: ResolvedDeps, err: unknown): ExitCode {\n const failure = toFailure(err)\n d.o.failure(failure)\n return failure.exit\n}\n\nasync function dispatch(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const key = args.sub ? `${args.command} ${args.sub}` : args.command\n switch (key) {\n case 'guide': return cmdGuide(args, d)\n case 'login': return cmdLogin(args, d)\n case 'logout': return cmdLogout(args, d)\n case 'whoami': return cmdWhoami(args, d)\n case 'wallets list': return cmdWalletsList(args, d)\n case 'wallets balances': return cmdWalletsBalances(args, d)\n case 'agents list': return cmdAgentsList(args, d)\n case 'agents show': return cmdAgentsShow(args, d)\n case 'agents pause': return cmdAgentLifecycle(args, d, 'pause')\n case 'agents resume': return cmdAgentLifecycle(args, d, 'resume')\n case 'agents revoke': return cmdAgentRevoke(args, d)\n case 'agents rotate-key': return cmdAgentRotateKey(args, d)\n case 'agents rename': return cmdAgentRename(args, d)\n case 'budget show': return cmdBudgetShow(args, d)\n case 'wallets rename': return cmdWalletRename(args, d)\n case 'activity list': return cmdActivityList(args, d)\n case 'activity export': return cmdActivityExport(args, d)\n case 'catalog list': return cmdCatalogList(args, d)\n case 'contacts list': return cmdContactsList(args, d)\n case 'contacts add': return cmdContactsAdd(args, d)\n case 'contacts remove': return cmdContactsRemove(args, d)\n default:\n throw new UsageError(`Unknown command: ${key}.`, 'Run `haven --help` for the command list.')\n }\n}\n\nfunction baseUrlFor(args: ParsedArgs, d: ResolvedDeps, session: Session | null): string {\n return args.flags.api ?? session?.apiBaseUrl ?? d.env.HAVEN_API_URL ?? DEFAULT_API\n}\n\nasync function authed(args: ParsedArgs, d: ResolvedDeps): Promise<{ session: Session; api: CliApi }> {\n const session = await d.sessionStore.load()\n // Status 401 so a missing local session and a rejected one produce the same\n // code and the same advice — from the caller's side they are one situation.\n if (!session) throw new CliApiError('Not authenticated.', 401)\n return { session, api: d.makeApi(baseUrlFor(args, d, session), session.token) }\n}\n\nfunction emit(d: ResolvedDeps, _json: boolean, data: unknown, human: () => string): void {\n d.o.data(data, human)\n}\n\n// ── Guide ───────────────────────────────────────────────────────────\n\n/**\n * Print the agent onboarding runbook — the same text served at\n * `/for-agents.md` (#2523). Offline by construction: the string is compiled in,\n * so an agent with no session and no network still gets the instructions that\n * tell it what to do about exactly that.\n */\nasync function cmdGuide(_args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n d.o.data({ ok: true, format: 'markdown', content: HAVEN_AGENT_RUNBOOK_MD }, () => HAVEN_AGENT_RUNBOOK_MD)\n return EXIT.ok\n}\n\n// ── Auth ────────────────────────────────────────────────────────────\n\nasync function cmdLogin(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const email = args.flags.email ?? d.env.HAVEN_EMAIL\n if (!email) {\n throw new UsageError('An email is required.', 'Pass --email <address>, or set HAVEN_EMAIL.')\n }\n const password = d.env.HAVEN_PASSWORD ?? (await d.promptPassword())\n if (!password) {\n throw new UsageError('A password is required.', 'Set HAVEN_PASSWORD for a non-interactive run.')\n }\n const baseUrl = baseUrlFor(args, d, null)\n const api = d.makeApi(baseUrl)\n const res = await api.post<{ token: string; user: Session['user'] }>('/auth/login', { email, password })\n await d.sessionStore.save({ token: res.token, apiBaseUrl: baseUrl, user: res.user })\n // The issue specifies { ok, email, expires_at }; `user` and `apiBaseUrl` stay\n // because they were already the shape and dropping them would break a script\n // that reads them for no gain. Neither the password nor the token is echoed —\n // `expires_at` is derived from the token, never the token itself.\n emit(\n d,\n args.flags.json,\n { ok: true, email: res.user.email, expires_at: sessionExpiry(res.token), user: res.user, apiBaseUrl: baseUrl },\n () => `Signed in as ${res.user.email}.`,\n )\n return EXIT.ok\n}\n\nasync function cmdLogout(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n await d.sessionStore.clear()\n emit(d, args.flags.json, { ok: true, signed_out: true }, () => 'Signed out.')\n return EXIT.ok\n}\n\nasync function cmdWhoami(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { session, api } = await authed(args, d)\n const user = await api.get<Session['user']>('/auth/me')\n // The four fields #2525 asks for — id, email, session expiry, api url — laid\n // over the profile the route already returned, so nothing a caller reads\n // today disappears. `expires_at` is null when the token carries no readable\n // `exp`, which is a fact worth reporting rather than an error.\n emit(\n d,\n args.flags.json,\n { ...user, id: user.id, email: user.email, expires_at: sessionExpiry(session.token), api_url: session.apiBaseUrl },\n () => `${user.email}${user.name ? ` (${user.name})` : ''}`,\n )\n return EXIT.ok\n}\n\n// ── Wallets ─────────────────────────────────────────────────────────\n\nasync function cmdWalletsList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { safes } = await api.get<{ safes: Safe[] }>('/user/safes')\n emit(d, args.flags.json, safes, () =>\n safes.length === 0\n ? 'No Haven wallets yet.'\n : table(\n ['NAME', 'NETWORK', 'ADDRESS', 'DEFAULT'],\n safes.map((s) => [s.name, chainName(s.chain_id), truncateAddress(s.safe_address), s.is_default ? '✓' : '']),\n ),\n )\n return EXIT.ok\n}\n\nasync function cmdWalletsBalances(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { safes } = await api.get<{ safes: Safe[] }>('/user/safes')\n const safe = pickSafe(safes, args.flags.safe)\n if (!safe) {\n if (args.flags.safe) throw new UsageError(`No wallet matches \"${args.flags.safe}\".`)\n throw new CliApiError('No Haven wallet found.', 404)\n }\n const { balances } = await api.get<{ balances: Balance[] }>(\n `/balances/${safe.safe_address}?chain_id=${safe.chain_id}`,\n )\n emit(d, args.flags.json, { safe: safe.name, chainId: safe.chain_id, balances }, () =>\n [\n `${safe.name} · ${chainName(safe.chain_id)} · ${truncateAddress(safe.safe_address)}`,\n balances.length === 0\n ? ' (no balances)'\n : table(['TOKEN', 'BALANCE'], balances.map((b) => [b.symbol, b.formatted])),\n ].join('\\n'),\n )\n return EXIT.ok\n}\n\nfunction pickSafe(safes: Safe[], ref?: string): Safe | undefined {\n if (!ref) return safes.find((s) => s.is_default) ?? safes[0]\n const lower = ref.toLowerCase()\n return safes.find((s) => s.id === ref || s.safe_address.toLowerCase() === lower)\n}\n\n// ── Agents & budget ─────────────────────────────────────────────────\n\nasync function cmdAgentsList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { agents } = await api.get<{ agents: Agent[] }>('/agents')\n emit(d, args.flags.json, agents, () =>\n agents.length === 0\n ? 'No agents yet.'\n : table(\n ['ID', 'NAME', 'STATUS', 'BUDGETS'],\n agents.map((a) => [a.id, a.name, a.status, budgetSummary(a.allowances)]),\n ),\n )\n return EXIT.ok\n}\n\nasync function cmdAgentsShow(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven agents show <id>')\n const { api } = await authed(args, d)\n const agent = await api.get<Agent>(`/agents/${id}`)\n emit(d, args.flags.json, agent, () =>\n [\n `${agent.name} [${agent.status}]`,\n `id: ${agent.id}`,\n `budget: ${budgetSummary(agent.allowances)}`,\n ].join('\\n'),\n )\n return EXIT.ok\n}\n\nasync function cmdBudgetShow(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven budget show <agentId>')\n const { api } = await authed(args, d)\n const agent = await api.get<Agent>(`/agents/${id}`)\n const allowances = agent.allowances ?? []\n emit(d, args.flags.json, allowances, () =>\n allowances.length === 0\n ? `${agent.name} has no configured budget.`\n : table(\n ['TOKEN', 'AMOUNT', 'RESETS'],\n allowances.map((a) => [a.token_symbol, a.allowance_amount, resetLabel(a.reset_period_min)]),\n ),\n )\n return EXIT.ok\n}\n\nfunction budgetSummary(allowances?: Allowance[]): string {\n if (!allowances || allowances.length === 0) return '—'\n return allowances.map((a) => `${a.allowance_amount} ${a.token_symbol}`).join(', ')\n}\n\nfunction resetLabel(mins: number): string {\n if (mins === 0) return 'one-time'\n if (mins === 1440) return 'daily'\n if (mins === 10080) return 'weekly'\n if (mins === 43200) return 'monthly'\n return `every ${mins}m`\n}\n\nasync function cmdAgentLifecycle(args: ParsedArgs, d: ResolvedDeps, action: 'pause' | 'resume'): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError(`Usage: haven agents ${action} <id>`)\n const { api } = await authed(args, d)\n await api.post(`/agents/${id}/${action}`)\n const status = action === 'pause' ? 'paused' : 'resumed'\n emit(d, args.flags.json, { ok: true, agent_id: id, status }, () => `Agent ${id} ${status}.`)\n return EXIT.ok\n}\n\nasync function cmdAgentRevoke(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven agents revoke <id> --yes')\n // Revoke is terminal (status can't go back to active). Require explicit --yes\n // so it can't happen by accident in a script.\n if (!args.flags.yes) {\n throw new UsageError(\n `This permanently revokes agent ${id}.`,\n 'Re-run with --yes to confirm. Revoke is terminal — the agent cannot go back to active.',\n )\n }\n const { api } = await authed(args, d)\n await api.post(`/agents/${id}/revoke`)\n emit(\n d,\n args.flags.json,\n { ok: true, agent_id: id, status: 'revoked' },\n () => `Agent ${id} revoked. To also remove its on-chain allowance, use the dashboard.`,\n )\n return EXIT.ok\n}\n\nasync function cmdAgentRotateKey(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven agents rotate-key <id>')\n const { api } = await authed(args, d)\n const res = await api.post<{ api_key: string; api_key_prefix: string }>(`/agents/${id}/rotate-key`)\n // The key is the payload, so it belongs on stdout in both modes. The\n // SENTENCE about it is prose and moves to stderr under --json, which is what\n // keeps stdout a single parseable object with a secret in exactly one field.\n d.o.note('New API key (shown once — store it now; the old key stops working):')\n emit(d, args.flags.json, res, () => res.api_key)\n return EXIT.ok\n}\n\nasync function cmdAgentRename(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const [id, ...nameParts] = args.positionals\n const name = nameParts.join(' ').trim()\n if (!id || !name) throw new UsageError('Usage: haven agents rename <id> <name>')\n const { api } = await authed(args, d)\n await api.put(`/agents/${id}`, { name })\n emit(d, args.flags.json, { ok: true, agent_id: id, name }, () => `Agent ${id} renamed to \"${name}\".`)\n return EXIT.ok\n}\n\nasync function cmdWalletRename(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const [id, ...nameParts] = args.positionals\n const name = nameParts.join(' ').trim()\n if (!id || !name) throw new UsageError('Usage: haven wallets rename <id> <name>')\n const { api } = await authed(args, d)\n await api.put(`/user/safes/${id}`, { name })\n emit(d, args.flags.json, { ok: true, safe_id: id, name }, () => `Wallet ${id} renamed to \"${name}\".`)\n return EXIT.ok\n}\n\n// ── Activity ────────────────────────────────────────────────────────\n\n/**\n * Resolve `--safe` (id or address) to a Safe id for the `/transactions` filter,\n * mirroring `wallets balances`. Throws if `--safe` was given but matches no\n * wallet, so a typo'd filter fails loudly instead of silently returning all rows.\n */\nasync function resolveSafeId(args: ParsedArgs, api: CliApi): Promise<string | undefined> {\n if (!args.flags.safe) return undefined\n const { safes } = await api.get<{ safes: Safe[] }>('/user/safes')\n const safe = pickSafe(safes, args.flags.safe)\n if (!safe) throw new UsageError(`No wallet matches \"${args.flags.safe}\".`)\n return safe.id\n}\n\nasync function cmdActivityList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const safeId = await resolveSafeId(args, api)\n const params = new URLSearchParams({\n offset: String(args.flags.offset ?? 0),\n limit: String(args.flags.limit ?? 25),\n })\n if (safeId) params.set('safeId', safeId)\n if (args.flags.agent) params.set('agentId', args.flags.agent)\n const { transactions } = await api.get<{ transactions: Txn[] }>(`/transactions?${params.toString()}`)\n const visible = args.flags.direction\n ? transactions.filter((t) => t.direction === args.flags.direction)\n : transactions\n emit(d, args.flags.json, visible, () =>\n visible.length === 0\n ? 'No activity.'\n : table(\n ['DATE', 'DIR', 'AMOUNT', 'TYPE', 'ACCOUNT'],\n visible.map((t) => [\n new Date(t.timestamp * 1000).toISOString().slice(0, 10),\n t.direction === 'in' ? 'in' : 'out',\n `${t.direction === 'in' ? '+' : '-'}${t.valueFormatted} ${t.asset}`,\n t.source ?? 'transfer',\n t.safeName ?? '',\n ]),\n ),\n )\n return EXIT.ok\n}\n\nasync function cmdActivityExport(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n if (args.flags.format === 'sie') return exportSie(args, d)\n const { api } = await authed(args, d)\n const safeId = await resolveSafeId(args, api)\n const params = new URLSearchParams({\n offset: String(args.flags.offset ?? 0),\n limit: String(args.flags.limit ?? 1000),\n })\n if (safeId) params.set('safeId', safeId)\n if (args.flags.agent) params.set('agentId', args.flags.agent)\n const { transactions } = await api.get<{ transactions: Txn[] }>(`/transactions?${params.toString()}`)\n const visible = args.flags.direction\n ? transactions.filter((t) => t.direction === args.flags.direction)\n : transactions\n\n // Same columns as the dashboard export (#411), minus counterparty_name\n // (no contacts join in the CLI yet).\n const headers = [\n 'date', 'type', 'status', 'direction', 'amount', 'token_symbol', 'token_address',\n 'counterparty_address', 'safe_address', 'agent_name', 'tx_hash', 'chain_id',\n ]\n const rows = visible.map((t) => [\n new Date(t.timestamp * 1000).toISOString(),\n exportType(t),\n exportStatus(t),\n t.direction,\n t.valueFormatted,\n t.tokenSymbol ?? t.asset ?? '',\n t.tokenAddress ?? '',\n (t.direction === 'in' ? t.from : t.to) ?? '',\n t.safeAddress ?? '',\n t.agentName ?? '',\n t.hash,\n t.chainId != null ? String(t.chainId) : '',\n ])\n d.o.text(toCsv(headers, rows), { format: 'csv', rows: rows.length })\n return EXIT.ok\n}\n\nfunction exportType(t: Txn): string {\n if (t.activityType === 'delegate_sweep') return 'allowance funding'\n if (t.source === 'x402') return 'x402'\n if (t.source === 'mpp_demo') return 'mpp'\n return t.direction === 'in' ? 'receive' : 'send'\n}\n\nfunction exportStatus(t: Txn): string {\n if (t.isError) return 'failed'\n if (t.paymentFlowStatus === 'confirming_merchant') return 'pending'\n return 'executed'\n}\n\n/** SIE 4I export: the backend builds the verifikat file (book-time SEK + BAS). */\nasync function exportSie(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const params = new URLSearchParams({ format: 'sie' })\n if (args.flags.from) params.set('from', args.flags.from)\n if (args.flags.to) params.set('to', args.flags.to)\n if (args.flags.company) params.set('company', args.flags.company)\n const content = await api.getText(`/accounting/export?${params.toString()}`)\n d.o.text(content, { format: 'sie' })\n return EXIT.ok\n}\n\n// ── Catalog ─────────────────────────────────────────────────────────\n\nasync function cmdCatalogList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { entries } = await api.get<{ entries: CatalogEntry[] }>('/catalog')\n emit(d, args.flags.json, entries, () =>\n entries.length === 0\n ? 'Catalog is empty.'\n : table(\n ['NAME', 'CATEGORY', 'RAIL', 'PRICE', 'STATUS'],\n entries.map((e) => [e.name, e.category, e.rail, e.price_display ?? '—', e.status]),\n ),\n )\n return EXIT.ok\n}\n\n// ── Contacts ────────────────────────────────────────────────────────\n\nasync function cmdContactsList(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const { api } = await authed(args, d)\n const { contacts } = await api.get<{ contacts: Contact[] }>('/contacts')\n emit(d, args.flags.json, contacts, () =>\n contacts.length === 0\n ? 'No contacts yet.'\n : table(['ID', 'NAME', 'ADDRESS'], contacts.map((c) => [c.id, c.name, truncateAddress(c.address)])),\n )\n return EXIT.ok\n}\n\nasync function cmdContactsAdd(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const [address, ...nameParts] = [...args.positionals].reverse()\n // positionals are <name...> <address>; address is last, name is the rest.\n const name = nameParts.reverse().join(' ').trim()\n if (!name || !address) throw new UsageError('Usage: haven contacts add <name> <address>')\n const { api } = await authed(args, d)\n const contact = await api.post<Contact>('/contacts', { name, address })\n emit(d, args.flags.json, contact, () => `Added contact \"${contact.name}\" (${truncateAddress(contact.address)}).`)\n return EXIT.ok\n}\n\nasync function cmdContactsRemove(args: ParsedArgs, d: ResolvedDeps): Promise<number> {\n const id = args.positionals[0]\n if (!id) throw new UsageError('Usage: haven contacts remove <id>')\n const { api } = await authed(args, d)\n await api.del(`/contacts/${id}`)\n emit(d, args.flags.json, { ok: true, contact_id: id, removed: true }, () => `Contact ${id} removed.`)\n return EXIT.ok\n}\n","import { emitKeypressEvents } from 'node:readline'\n\n/** The three streams the prompt touches, injectable so a test can watch them. */\nexport interface PromptStreams {\n stdin: NodeJS.ReadStream\n stdout: NodeJS.WriteStream\n stderr: NodeJS.WriteStream\n}\n\n/**\n * Read a password from the TTY without echoing it. Falls back to a plain line\n * read when stdin isn't a TTY (so piping `HAVEN_PASSWORD` or a heredoc still\n * works, though the env var is the documented non-interactive path).\n *\n * Exported and stream-injected for one reason: which stream the prompt writes\n * to is part of the `--json` contract, and asserting it needs a seam. It is\n * `stderr` — see the comment at the write.\n */\nexport function promptPasswordWith(streams: PromptStreams): Promise<string> {\n return new Promise((resolve, reject) => {\n const { stdin, stderr } = streams\n if (!stdin.isTTY) {\n let data = ''\n stdin.setEncoding('utf8')\n stdin.on('data', (chunk) => (data += chunk))\n stdin.on('end', () => resolve(data.trim()))\n stdin.on('error', reject)\n return\n }\n // stderr, never stdout (#2525 review): under `--json` stdout carries one\n // JSON value and nothing else, and a prompt written there would land ahead\n // of it. A prompt is prose addressed to a human at a terminal, so stderr is\n // where it belongs in both modes — the TTY still shows it.\n stderr.write('Password: ')\n emitKeypressEvents(stdin)\n stdin.setRawMode(true)\n let value = ''\n const onKey = (char: string, key: { name?: string; ctrl?: boolean }) => {\n if (key.name === 'return' || key.name === 'enter') {\n cleanup()\n stderr.write('\\n')\n resolve(value)\n } else if (key.ctrl && key.name === 'c') {\n cleanup()\n stderr.write('\\n')\n reject(new Error('Cancelled'))\n } else if (key.name === 'backspace') {\n value = value.slice(0, -1)\n } else if (char && !key.ctrl) {\n value += char\n }\n }\n function cleanup() {\n stdin.setRawMode(false)\n stdin.pause()\n stdin.off('keypress', onKey)\n }\n stdin.resume()\n stdin.on('keypress', onKey)\n })\n}\n","#!/usr/bin/env node\n\nimport { run } from './commands.js'\nimport { promptPasswordWith } from './prompt.js'\n\n/**\n * The bin entry, and deliberately nothing else.\n *\n * It used to also define `promptPasswordWith`, which meant importing this file\n * to test that function EXECUTED the CLI — `run(process.argv.slice(2))` against\n * vitest's own argv, ending in `process.exit(1)`. The suite still reported 102\n * passing tests with one unhandled error beside them, which is exactly the\n * shape of failure a `grep` for \"Tests\" hides (#2525 review round 3, caught by\n * CI). An entry point that self-executes must not also be an import target, so\n * the prompt lives in `prompt.ts` and this file only wires and runs.\n */\nfunction promptPassword(): Promise<string> {\n return promptPasswordWith({ stdin: process.stdin, stdout: process.stdout, stderr: process.stderr })\n}\n\nrun(process.argv.slice(2), { promptPassword })\n .then((code) => process.exit(code))\n .catch((err) => {\n // The last resort: anything that escaped run()'s own handling. It should be\n // unreachable — run() catches around both parseArgs and dispatch — but if\n // it is ever reached under `--json`, a bare sentence on stderr with exit 1\n // would be the one refusal a machine caller cannot parse. So it emits the\n // same failure shape as everything else (#2525 review, finding 2).\n const message = err instanceof Error ? err.message : String(err)\n if (process.argv.includes('--json')) {\n process.stdout.write(`${JSON.stringify({ ok: false, error: { code: 'failed', message } }, null, 2)}\\n`)\n } else {\n process.stderr.write(`${message}\\n`)\n }\n process.exit(1)\n })\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -348,7 +348,7 @@ function sessionExpiry(token) {
|
|
|
348
348
|
|
|
349
349
|
// src/commands.ts
|
|
350
350
|
var DEFAULT_API = "https://havenbackend-production-8a00.up.railway.app";
|
|
351
|
-
var CLI_VERSION = "0.0.0-dev.
|
|
351
|
+
var CLI_VERSION = "0.0.0-dev.202609051106.201fc90";
|
|
352
352
|
async function run(argv, deps = {}) {
|
|
353
353
|
const out = deps.out ?? ((l) => process.stdout.write(`${l}
|
|
354
354
|
`));
|