@toon-protocol/rig 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/rig.ts","../../src/cli/dispatch.ts","../../src/cli/balance.ts","../../src/cli/daemon-session.ts","../../src/cli/errors.ts","../../src/cli/push.ts","../../src/rig-pointer.ts","../../src/gateway-preference.ts","../../src/cli/rig-pointer-record.ts","../../src/cli/render.ts","../../src/cli/git-config.ts","../../src/cli/remote.ts","../../src/cli/chain.ts","../../src/cli/channel.ts","../../src/cli/clone.ts","../../src/cli/events.ts","../../src/cli/tracker.ts","../../src/cli/entry.ts","../../src/cli/fetch.ts","../../src/cli/fund.ts","../../src/cli/git-passthrough.ts","../../src/cli/identity-cmd.ts","../../src/cli/init.ts","../../src/cli/git-author.ts","../../src/cli/maintainers.ts","../../src/cli/name.ts","../../src/cli/site.ts","../../src/arweave-manifest.ts","../../src/cli/site-record.ts","../../src/cli/output.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * `rig` — the git-native TOON CLI shipped by `@toon-protocol/rig` (epic\n * #222; standalone-only since #248; git passthrough since #250).\n *\n * rig-owned subcommands (see ./dispatch.ts):\n * init one-shot repo setup (identity + toon.* git config)\n * remote relays as git remotes (#249): add/remove/list\n * push estimate → confirm → execute (#229)\n * issue | comment | pr single NIP-34 event publishes (#231), incl.\n * `pr status` (moved from `rig status` in #250)\n * channel payment channels (#262/#263): list, open,\n * close, settle\n * fund | balance client money lifecycle (#263): devnet faucet\n * drip; wallet + channel balances\n *\n * Everything else is `git <argv...>` verbatim: `rig status` runs git status.\n *\n * STRICT `--json` STDOUT (#265): when a rig-owned command runs with `--json`,\n * stdout carries exactly one JSON document — the process-level stdout guard\n * reroutes every other write (including dependencies' `console.log`) to\n * stderr, the io layer sends human lines to stderr, and the post-dispatch\n * backstop emits an error envelope for paths that bailed before emitting.\n * The git passthrough is exempt: it inherits stdio verbatim (./output.ts).\n * The enforcement matrix in ./strict-json.test.ts mirrors this composition.\n */\n\nimport { createInterface } from 'node:readline/promises';\nimport { dispatch } from './dispatch.js';\nimport {\n calmBootstrapNoise,\n isJsonInvocation,\n makeCliIo,\n redirectStdoutToStderr,\n type RigIo,\n} from './output.js';\n\n/** Real terminal I/O: stdout/stderr sinks + readline y/N confirm. */\nfunction makeIo(jsonMode: boolean): RigIo {\n // Reframe the embedded client's expected announce-402 stderr noise (#280)\n // — installed for every mode, before any command code can run.\n calmBootstrapNoise();\n // In --json mode, patch process.stdout FIRST — before any command (or its\n // dynamically imported dependencies) can write — and keep the only real\n // stdout writer for the machine document.\n const guard = jsonMode ? redirectStdoutToStderr() : undefined;\n return makeCliIo({\n jsonMode,\n writeStdout: guard\n ? guard.write\n : (text) => {\n process.stdout.write(text);\n },\n writeStderr: (text) => {\n process.stderr.write(text);\n },\n isInteractive: Boolean(process.stdin.isTTY && process.stdout.isTTY),\n confirm: async (question) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n try {\n const answer = (await rl.question(question)).trim().toLowerCase();\n return answer === 'y' || answer === 'yes';\n } finally {\n rl.close();\n }\n },\n });\n}\n\n/**\n * Exit as soon as stdio is flushed (#279). By the time dispatch resolves,\n * every command has finished its work and awaited its teardown — but the\n * embedded `@toon-protocol/client` can leave a keep-alive socket behind\n * that holds the Node event loop open for ~30 more seconds. That lingering\n * handle — not discovery or negotiation — was the bulk of the uniform\n * \"~32s per paid command\" tax the #279 study measured. Nothing rig can\n * reach unrefs it, so the one-shot CLI does what one-shot CLIs do: flush\n * and exit.\n */\nfunction exitWhenFlushed(code: number): void {\n process.exitCode = code;\n let pending = 2;\n const done = (): void => {\n pending -= 1;\n if (pending === 0) process.exit(code);\n };\n process.stdout.write('', done);\n process.stderr.write('', done);\n}\n\nconst argv = process.argv.slice(2);\nconst io = makeIo(isJsonInvocation(argv));\n\ndispatch(argv, {\n io,\n env: process.env,\n cwd: process.cwd(),\n}).then(\n (code) => {\n io.ensureSingleJsonDoc(code);\n exitWhenFlushed(code);\n },\n (err: unknown) => {\n process.stderr.write(\n `rig: unexpected error: ${err instanceof Error ? (err.stack ?? err.message) : String(err)}\\n`\n );\n io.ensureSingleJsonDoc(1);\n exitWhenFlushed(1);\n }\n);\n","/**\n * `rig` subcommand dispatch (#250): rig-owned verbs first, git for the rest.\n *\n * rig owns exactly: init, identity, remote, clone, fetch, push, site, issue,\n * comment, pr, maintainers, channel (+ the `channels` list shorthand), fund,\n * balance, chain, entry, name, help/-h/--help, and --version. EVERY other\n * subcommand is executed as `git <argv...>` verbatim (./git-passthrough.ts)\n * — `rig status` IS `git status`, `rig add -p`, `rig commit`, `rig rebase\n * -i`, … all land in git with rig's stdio and git's exit code. Owned verbs\n * always win: `rig push` is the paid TOON push and shadows `git push`, and\n * `rig clone`/`rig fetch` (#278) are the free TOON transports shadowing\n * their git counterparts (plain-git clone/fetch/push stay available by\n * calling git directly).\n *\n * The NIP-34 status publish that used to be `rig status` lives at\n * `rig pr status` since #250 (BREAKING) — bare `rig status` is git's.\n *\n * `--json` (#265) follows the same ownership boundary: it is a flag OF the\n * owned subcommands, never a global rig flag. `rig --json status` starts\n * with a verb rig does not own (`--json`), so the WHOLE argv passes through\n * to git verbatim — rig neither consumes the flag nor applies the strict\n * stdout contract to git's inherited stdio. The owned-verb list is pinned to\n * ./output.ts's RIG_OWNED_VERBS (strict-json.test.ts keeps them in sync).\n */\n\nimport { createRequire } from 'node:module';\nimport { runBalance } from './balance.js';\nimport { runChain } from './chain.js';\nimport { runChannel } from './channel.js';\nimport { runClone } from './clone.js';\nimport { runComment, runIssue, runPr, type EventCommandDeps } from './events.js';\nimport { runEntry } from './entry.js';\nimport { runFetch } from './fetch.js';\nimport { runFund } from './fund.js';\nimport { runGitPassthrough, type GitRunner } from './git-passthrough.js';\nimport { runIdentity } from './identity-cmd.js';\nimport { runInit } from './init.js';\nimport { runMaintainers } from './maintainers.js';\nimport { runName, type LoadArns } from './name.js';\nimport { runPush, PUSH_USAGE } from './push.js';\nimport { runRemote } from './remote.js';\nimport { runSite } from './site.js';\n\nexport const USAGE = `rig — git with a TOON remote (pay-to-write Nostr + Arweave)\n\nUsage: rig <command> [options]\n\nCommands rig owns:\n identity create generate a fresh identity (BIP-39) into the\n encrypted keystore — the phrase is shown ONCE;\n back it up. This is your first step on a new box\n identity show the active identity's source + derived pubkey\n (never the phrase)\n identity import write an EXISTING phrase (read from stdin) to the\n encrypted keystore\n init set up this repo: resolve your identity (or offer\n to generate one) and write the toon.* git config\n remote add <name> <url> add a relay as a REAL git remote (\"origin\" is\n remote remove <name> the default publish target); remove/list manage\n remote list them — \\`git remote -v\\` shows the same data\n clone <relay-url> <owner>/<repo-id> [dir]\n clone a TOON repo (free): relay state + Arweave\n objects (SHA-1 verified) → a real git repository,\n push/pull-capable out of the box\n fetch [remote] fetch remote refs + missing objects (free) and\n update refs/remotes/<remote>/*; no merge. Shadows\n git fetch (plain \\`git fetch\\` stays available)\n push [remote] [refspecs...] plan, price, confirm, and execute a paid push\n to TOON (defaults to the \"origin\" remote). rig\n push is the TOON transport and shadows git push;\n plain-git pushes remain available by running\n \\`git push\\` directly\n site publish [ref] deploy a pushed repo as a permaweb site: build the\n ar.io path manifest (paths → Arweave txids) and\n upload it as one paid store write; prints the URL\n site url [ref] print the last-published site URL for a ref (free)\n issue create file an issue (kind:1621) against a repo\n issue list | show <id> read the repo's issues + comments (free)\n pr list | show <id> read the repo's patches; show prints the full\n patch text (free)\n comment <root-event-id> comment (kind:1622) on an issue or patch\n pr create publish a patch (kind:1617) with real\n \\`git format-patch\\` content\n pr status <event-id> <state> set an issue/patch status (kind:1630-1633):\n open | applied | closed | draft\n maintainers list show the repo's declared maintainers (free); add/\n maintainers add <pubkey> remove republish the kind:30617 to change who may\n maintainers remove <pubkey> author authoritative issue/PR status (owner is\n always an implicit maintainer)\n fund drip devnet faucet funds to this identity's\n wallet (free); on other networks prints the\n address(es) to fund externally\n balance wallet balances + payment-channel holdings\n (free — chain reads and local state only)\n chain [set <c>|unset] choose which chain/USDC settles paid writes\n (evm|sol|mina); free — reads/writes local config\n entry [apex|sandbox|url] choose the network entry node (payment ingress +\n relay): apex settles evm|sol|mina, sandbox is the\n Mina-only multihop demo path; free — writes local\n config and clears the cached topology\n name buy <name> ArNS naming (#367): buy points a human name at an\n name set <name> <txId> Arweave txId, owned + paid by this identity's\n name status <name> Solana key. buy spends mARIO on Solana via the\n ar.io registry (NOT ILP); status is free. Needs\n the optional \\`@ar.io/sdk\\` dependency\n channel list show the payment channels paid commands hold\n (free — reads local state; \\`rig channels\\` is a\n shorthand for \\`rig channel list\\`)\n channel open explicitly open (or resume) the channel for a\n peer; --deposit adds collateral (on-chain)\n channel deploy-zkapp pre-deploy this identity's dedicated Mina\n PaymentChannel zkApp (on-chain; the Mina open\n path otherwise does this automatically)\n channel close <channelId> start the settlement challenge window (on-chain)\n channel settle <channelId> release collateral after the window (on-chain)\n\nAny other command is passed through to git verbatim: \\`rig status\\` runs\n\\`git status\\`, and \\`rig add -p\\`, \\`rig commit\\`, \\`rig log --oneline\\`,\n\\`rig rebase -i\\`, … behave exactly like git (same output, same exit code).\n\nRun \\`rig <command> --help\\` for a rig command's flags. \\`rig init\\`,\n\\`rig remote\\`, \\`rig clone\\`, \\`rig fetch\\`, \\`rig issue list/show\\`,\n\\`rig pr list/show\\`, \\`rig fund\\`, \\`rig balance\\`, and \\`rig channel list\\`\nare free; push/issue create/comment/pr create/pr status are paid writes —\npermanent and non-refundable —\nand channel open/close/settle are on-chain wallet transactions; each states\nwhat it will spend and asks for confirmation before doing so (--yes skips,\n--json emits machine output).\n\nWith --json, stdout carries exactly ONE JSON document (everything human-facing\ngoes to stderr), so \\`rig <command> --json | jq\\` always parses. --json is a\nper-subcommand flag on the commands rig owns, NOT a global rig flag: it does\nnot apply to the git passthrough (\\`rig status --json\\` runs\n\\`git status --json\\`), and flags placed before the subcommand\n(\\`rig --json status\\`) pass through to git untouched.\n\nSTANDALONE MODE: by default rig delegates paid commands to a running\ntoon-clientd that holds the same identity (it owns the payment channel and its\nbootstrap is warm). To bypass the daemon and always sign for yourself, set\nRIG_STANDALONE=1 in your environment (the durable, applies-to-everything\nswitch) or pass --standalone / --no-daemon to a paid command. rig then runs\nfully embedded; a per-identity lockfile still stops two rig processes from\nracing the channel. If a daemon is ALSO actively writing on this identity,\nstop it (its pid is in ~/.toon-client/daemon.pid) to avoid a claim race.`;\n\n/** Dispatch deps: the event-command deps plus an injectable git runner. */\nexport interface DispatchDeps extends EventCommandDeps {\n /** Runs the git passthrough (default: real spawned git; tests inject). */\n runGit?: GitRunner;\n /**\n * `rig name` ArNS SDK loader seam (#367): defaults to the lazy `@ar.io/sdk`\n * import; tests inject a stub so no real ar.io registry call is ever made.\n */\n loadArns?: LoadArns;\n}\n\n/**\n * Version of the @toon-protocol/rig package this CLI shipped in. Resolved at\n * runtime relative to this module, which tsup may emit either as the\n * dist/cli/rig.js entry or a dist/ chunk — hence the short upward walk.\n */\nexport function rigVersion(): string {\n const require = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = require(rel) as { name?: string; version?: string };\n if (pkg.name === '@toon-protocol/rig' && pkg.version) return pkg.version;\n } catch {\n // keep walking up\n }\n }\n return 'unknown';\n}\n\n/** Route one rig invocation (argv WITHOUT node/script); returns the exit code. */\nexport async function dispatch(\n argv: string[],\n deps: DispatchDeps\n): Promise<number> {\n const [command, ...rest] = argv;\n const { io } = deps;\n\n switch (command) {\n case 'init':\n return runInit(rest, deps);\n case 'identity':\n return runIdentity(rest, deps);\n case 'remote':\n return runRemote(rest, deps);\n // The #278 read path — FREE (relay + Arweave gateway reads, no payment).\n case 'clone':\n return runClone(rest, deps);\n case 'fetch':\n return runFetch(rest, deps);\n case 'push':\n return runPush(rest, deps);\n case 'site':\n return runSite(rest, deps);\n case 'issue':\n return runIssue(rest, deps);\n case 'comment':\n return runComment(rest, deps);\n case 'pr':\n return runPr(rest, deps);\n case 'maintainers':\n return runMaintainers(rest, deps);\n case 'channel':\n return runChannel(rest, deps);\n case 'channels':\n // Alias (#demo): bare `rig channels` (plus flags) is `rig channel list`;\n // a subcommand word still routes normally (`rig channels open` works).\n return runChannel(\n rest[0] !== undefined && !rest[0].startsWith('-')\n ? rest\n : ['list', ...rest],\n deps\n );\n case 'fund':\n return runFund(rest, deps);\n case 'balance':\n return runBalance(rest, deps);\n case 'chain':\n return runChain(rest, deps);\n case 'entry':\n return runEntry(rest, deps);\n case 'name':\n return runName(rest, deps);\n case 'help':\n case '--help':\n case '-h':\n io.out(USAGE);\n io.out('');\n io.out(PUSH_USAGE);\n return 0;\n case '--version':\n io.out(`rig ${rigVersion()}`);\n return 0;\n case undefined:\n io.err(USAGE);\n return 2;\n default:\n // Git passthrough (#250): rig does not own this verb, so the EXACT\n // argv tail goes to system git — flags, quoting, and exit code intact.\n return (deps.runGit ?? runGitPassthrough)(argv, {\n cwd: deps.cwd,\n env: deps.env,\n err: (line) => io.err(line),\n });\n }\n}\n","/**\n * `rig balance` — the combined money view for the active identity (#263):\n * on-chain wallet balances plus open payment-channel holdings.\n *\n * FREE: no payment, no nonce guard, no channel, no relay. The wallet section\n * reuses the client's full multi-chain reader (`ToonClient.getWalletBalances()`\n * on the UNSTARTED embedded client, #299): for every configured chain it shows\n * the native coin (ETH / SOL / MINA) AND USDC. The Solana/Mina addresses are\n * derived from the mnemonic on demand — the same keys `start()` registers and\n * `rig fund` prints — so all chains appear even before a start. The EVM chain\n * key is the settlement chain (it wins over the network preset's primary), so a\n * devnet identity funded on `evm:anvil:31337` shows that chain's balances, not\n * the preset chain's zero (the #260-era getBalances mismatch). Each chain reads\n * independently; an unreachable RPC degrades to a per-chain notice.\n * The channel section joins the #262 peer→channel map with the claim\n * watermark: deposited / claimed / available per recorded channel of THIS\n * identity. A write uplink is NOT required (`requireUplink: false`) — reads\n * work from a read-only config.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n channelStatus,\n ChannelMapStore,\n resolveChannelPaths,\n} from '../standalone/channel-map.js';\nimport type {\n WalletChainBalanceInfo,\n WalletTokenAmountInfo,\n} from '../standalone/money.js';\nimport { emitCliError } from './errors.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport { renderIdentityLine } from './render.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\nexport const BALANCE_USAGE = `Usage: rig balance [--json]\n\nShow the active identity's money: the full on-chain wallet view — native coin\nplus USDC on every configured chain (EVM / Solana / Mina) — and recorded\npayment-channel holdings (deposited / claimed / available). Free — reads chain\nRPCs and local state only; nothing is signed or paid. An unreachable chain RPC\ndegrades to a per-chain notice without failing the others.\n\nOptions:\n --json machine-readable envelope (base units as strings)\n -h, --help show this help`;\n\n/** What `rig balance` needs — the shared paid-command deps (loader seam). */\nexport type BalanceDeps = PushDeps;\n\n/** One recorded channel in the balance view. */\ninterface ChannelBalanceJson {\n channelId: string;\n destination: string;\n peerId: string;\n chain: string;\n status: 'open' | 'closing' | 'settleable' | 'settled';\n depositTotal: string | null;\n cumulativeClaimed: string | null;\n nonce: number | null;\n /** depositTotal − cumulativeClaimed, when both are known (floored at 0). */\n available: string | null;\n /**\n * cumulativeClaimed − depositTotal, when both are known (floored at 0).\n * Non-zero means the cumulative signed claims exceed the recorded on-chain\n * collateral: the peer accepted (and may keep accepting) claims it cannot\n * fully redeem on-chain until the deposit is topped up — the on-chain\n * TokenNetwork caps redemption at the deposit. `available 0` alone cannot\n * distinguish \"exactly spent\" from \"overdrawn\", hence this field.\n */\n overdrawn: string | null;\n}\n\n/** `--json` envelope. */\ninterface BalanceJson {\n command: 'balance';\n identity: IdentityReport;\n wallet: WalletChainBalanceInfo[];\n channels: ChannelBalanceJson[];\n}\n\n/**\n * Format a base-unit integer string as a human decimal using `decimals`.\n * No decimals known → the base-unit string verbatim. Trims trailing zeros but\n * keeps at least one fractional digit only when non-integer.\n */\nexport function formatUnits(amount: string, decimals?: number): string {\n if (decimals === undefined || decimals <= 0) return amount;\n const neg = amount.startsWith('-');\n const digits = (neg ? amount.slice(1) : amount).padStart(decimals + 1, '0');\n const whole = digits.slice(0, digits.length - decimals);\n const frac = digits.slice(digits.length - decimals).replace(/0+$/, '');\n return (neg ? '-' : '') + (frac ? `${whole}.${frac}` : whole);\n}\n\n/** `SYMBOL amount` for one asset, formatted with its decimals. */\nfunction renderAmount(a: WalletTokenAmountInfo): string {\n return `${a.symbol ?? 'token'} ${formatUnits(a.amount, a.decimals)}`;\n}\n\n/** Env override for the wallet-read timeout; `0` opts out (wait forever). */\nconst WALLET_READ_TIMEOUT_ENV = 'RIG_BALANCE_WALLET_TIMEOUT_MS';\n/** Default cap on the wallet read — generous, only trips a genuine hang. */\nconst DEFAULT_WALLET_READ_TIMEOUT_MS = 20_000;\n\n/** Resolve the wallet-read timeout (ms): valid non-negative env override, else default. */\nexport function walletReadTimeoutMs(env: NodeJS.ProcessEnv): number {\n const raw = env[WALLET_READ_TIMEOUT_ENV];\n if (raw === undefined || raw === '') return DEFAULT_WALLET_READ_TIMEOUT_MS;\n const n = Number(raw);\n return Number.isFinite(n) && n >= 0 ? n : DEFAULT_WALLET_READ_TIMEOUT_MS;\n}\n\n/**\n * The wallet read exceeded {@link walletReadTimeoutMs}. This is the guard that\n * turns the silent-exit bug into a loud, actionable failure: on the Mina\n * settlement path a wallet read can neither resolve nor keep a live handle\n * open (a hung GraphQL endpoint, a nonexistent on-chain account, o1js-adjacent\n * work), so awaiting it UNBOUNDED lets Node's event loop drain and the one-shot\n * CLI exits 0 with no output at all. The bounded read's live timer prevents\n * that drain and forces a decision instead.\n */\nexport class WalletReadTimeoutError extends Error {\n constructor(public readonly timeoutMs: number) {\n super(\n `wallet balance read timed out after ${timeoutMs}ms — the chain ` +\n 'RPC/GraphQL endpoint is unreachable or hanging. (A nonexistent Mina ' +\n 'account reads as 0, so a hang points at the endpoint, not an empty ' +\n 'balance.) Recorded channels are unaffected; retry, or set ' +\n `${WALLET_READ_TIMEOUT_ENV}=0 to wait indefinitely.`\n );\n this.name = 'WalletReadTimeoutError';\n }\n}\n\n/**\n * Read the multi-chain wallet view under a hard time bound. The `setTimeout`\n * is deliberately NOT `unref()`ed: its live handle is exactly what keeps the\n * one-shot CLI's event loop from draining to a silent exit-0 while the read\n * hangs. A late rejection from the losing promise is swallowed so it never\n * surfaces as an unhandled rejection after the race is decided.\n */\nexport async function readWalletBounded(\n read: () => Promise<WalletChainBalanceInfo[]>,\n timeoutMs: number\n): Promise<WalletChainBalanceInfo[]> {\n const settled = read();\n // A `0` (or negative) timeout opts out of the bound entirely (wait forever).\n if (timeoutMs <= 0) return settled;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const guard = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new WalletReadTimeoutError(timeoutMs)), timeoutMs);\n });\n // Don't let the loser reject into an unhandled rejection post-race.\n settled.catch(() => undefined);\n try {\n return await Promise.race([settled, guard]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\n/** Run `rig balance`; returns the process exit code. */\nexport async function runBalance(\n args: string[],\n deps: BalanceDeps\n): Promise<number> {\n const { io, env } = deps;\n let json = false;\n try {\n const { values } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(BALANCE_USAGE);\n return 0;\n }\n json = values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(BALANCE_USAGE);\n return 2;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n // Free read: works without a proxy/BTP write uplink.\n requireUplink: false,\n });\n const identity = identityReport(ctx);\n\n // ── Channels: #262 map ⋈ claim watermark, THIS identity only ────────────\n // Read FIRST: a purely local read that is always available (a corrupt map\n // is still a clear error via the outer catch), so the report can show\n // recorded channels even when the on-chain wallet read below fails.\n const store = new ChannelMapStore(resolveChannelPaths(env));\n const channels: ChannelBalanceJson[] = store\n .list()\n .filter((record) => record.identity === identity.pubkey)\n .map((record) => {\n const watermark = store.readWatermark(record.channelId);\n const deposited = record.depositTotal;\n const claimed = watermark?.cumulativeAmount;\n let available: string | null = null;\n let overdrawn: string | null = null;\n if (deposited !== undefined && claimed !== undefined) {\n const remaining = BigInt(deposited) - BigInt(claimed);\n available = (remaining > 0n ? remaining : 0n).toString();\n overdrawn = (remaining < 0n ? -remaining : 0n).toString();\n }\n return {\n channelId: record.channelId,\n destination: record.destination,\n peerId: record.peerId,\n chain: record.chain,\n status: channelStatus(watermark),\n depositTotal: deposited ?? null,\n cumulativeClaimed: claimed ?? null,\n nonce: watermark?.nonce ?? null,\n available,\n overdrawn,\n };\n });\n\n // ── Wallet: the client's full multi-chain view (#299) — native + USDC ───\n // BOUNDED. An unbounded await here is the silent-exit bug: on the Mina path\n // the read can neither resolve nor keep the event loop alive, so the CLI\n // drains and exits 0 with no output. The bound turns any such hang into a\n // loud, non-zero failure that STILL prints the identity + channels.\n let wallet: WalletChainBalanceInfo[] = [];\n let walletError: Error | undefined;\n if (ctx.money) {\n const money = ctx.money;\n try {\n wallet = await readWalletBounded(\n () => money.walletChainBalances(),\n walletReadTimeoutMs(env)\n );\n } catch (err) {\n walletError = err instanceof Error ? err : new Error(String(err));\n }\n }\n\n if (json) {\n // A wallet-read failure is a hard error in the machine contract: emit the\n // single error envelope (never a partial + a silent 0).\n if (walletError) return emitCliError(io, json, 'balance', walletError);\n io.emitJson({\n command: 'balance',\n identity,\n wallet,\n channels,\n } satisfies BalanceJson);\n return 0;\n }\n\n io.out(renderIdentityLine(identity));\n io.out('');\n io.out('Wallet (on-chain):');\n if (walletError) {\n // Loud, actionable — never a silent gap. The channels below still print.\n io.out(` wallet balances unavailable — ${walletError.message}`);\n } else if (wallet.length === 0) {\n io.out(' (no chain configured for this identity — nothing to read)');\n }\n for (const chain of wallet) {\n io.out(` ${chain.chainKey.padEnd(11)} ${chain.address}`);\n if (chain.unreadable) {\n io.out(\n ` unreadable (RPC unreachable)` +\n (chain.error ? ` — ${chain.error}` : '')\n );\n continue;\n }\n const assets = [...(chain.native ? [chain.native] : []), ...chain.tokens];\n if (assets.length === 0) {\n io.out(' (no balance readable)');\n continue;\n }\n io.out(` ${assets.map(renderAmount).join(' ')}`);\n }\n io.out('');\n io.out('Channels (recorded):');\n if (channels.length === 0) {\n io.out(\n ' none — paid commands record their channel on first use; ' +\n '`rig channel open` records one explicitly.'\n );\n }\n for (const c of channels) {\n io.out(\n ` ${c.channelId} [${c.status}] deposited ${c.depositTotal ?? '?'} ` +\n `claimed ${c.cumulativeClaimed ?? '?'} available ${c.available ?? '?'}` +\n ` (${c.chain} → ${c.destination})`\n );\n if (c.overdrawn !== null && BigInt(c.overdrawn) > 0n) {\n io.out(\n ` OVERDRAWN by ${c.overdrawn}: cumulative claims exceed the ` +\n `recorded deposit — the peer accepted claims only partially ` +\n `covered by on-chain collateral. Top up with ` +\n `\\`rig channel open --deposit <amount>\\`.`\n );\n }\n }\n // Non-zero when the wallet read failed — the report is printed, but the\n // command reports failure (never a silent success on a broken read).\n return walletError ? 1 : 0;\n } catch (err) {\n return emitCliError(io, json, 'balance', err);\n } finally {\n if (ctx) {\n try {\n await ctx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * Daemon-as-accelerator delegation for paid rig commands (#279).\n *\n * Standalone remains the DEFAULT and the guarantee: every paid command works\n * with no daemon anywhere. But standalone pays a fixed bootstrap tax (relay\n * discovery, peer negotiation, channel resume) on every invocation, while a\n * running `toon-clientd` already holds all of that state warm. When the\n * daemon holds the SAME identity, the pre-#279 nonce guard refused outright\n * (two writers would race the payment channel's cumulative-claim watermark).\n * #279 refines that: the same-identity case now DELEGATES the operation to\n * the daemon's loopback `/git/*` routes — one process (the daemon) owns the\n * watermark, which is exactly the safety property the refusal protected, and\n * the command finishes in daemon time instead of bootstrap time.\n *\n * Decision matrix ({@link resolvePaidSession}):\n *\n * daemon reachable + SAME identity → delegate (`path: 'daemon'`)\n * daemon reachable + other identity → standalone (its channels are keyed\n * to its own pubkey — no shared state)\n * daemon unreachable / not a daemon → standalone\n *\n * TRUST BOUNDARY: the daemon is trusted only because it is (a) loopback and\n * (b) proven to hold the same identity — the `GET /status` identity check\n * happens BEFORE any request body is sent. A same-identity daemon already\n * holds the mnemonic-derived keys and the channel, so delegating adds no\n * authority it does not have.\n *\n * Commands the daemon has NO route for — `rig fund`, `rig balance`,\n * `rig channel open|close|settle` — always run standalone; the on-chain\n * channel mutations among them still REFUSE under a same-identity daemon\n * (the nonce guard in ../standalone/nonce-guard.ts), because close/settle\n * must not race the daemon's live claims.\n *\n * The `DaemonGitClient` is a plain-fetch client, deliberately NOT built on\n * `@toon-protocol/client-mcp`'s ControlClient — that package depends on this\n * one (its daemon Publisher wraps our planner), so importing it back would\n * be circular. Route conventions (loopback base URL, JSON bodies, the error\n * envelope with structured 409 `non_fast_forward` / 413 `oversize_objects`\n * payloads) are mirrored here; the wire types live in `../routes.ts` for\n * client-mcp to adopt. Same duplication contract as\n * `../standalone/nonce-guard.ts` — keep in sync.\n */\n\nimport { defaultDaemonPort, standaloneForced } from '../standalone/nonce-guard.js';\nimport type {\n GitCommentRequest,\n GitErrorEnvelope,\n GitEstimateRequest,\n GitEstimateResponse,\n GitEventResponse,\n GitIssueRequest,\n GitPatchRequest,\n GitPushRequest,\n GitPushResponse,\n GitStatusRequest,\n} from '../routes.js';\nimport { resolveIdentity, type IdentitySourceKind } from './identity.js';\nimport type {\n LoadStandalone,\n StandaloneContext,\n} from './standalone-context.js';\n\n// ---------------------------------------------------------------------------\n// Daemon probe (GET /status — identity check BEFORE anything is sent)\n// ---------------------------------------------------------------------------\n\n/** Result of probing the toon-clientd loopback `/status`. */\nexport interface DaemonProbe {\n /** Control API base URL probed, e.g. `http://127.0.0.1:8787`. */\n baseUrl: string;\n /** True when `/status` answered 200 with parseable JSON. */\n reachable: boolean;\n /** `identity.nostrPubkey` from the status body (when reachable). */\n identity?: string;\n /** `ready` from the status body (channel open, publish-ready). */\n ready?: boolean;\n /** Daemon's default relay URL (`relay.url`). */\n relayUrl?: string;\n /**\n * Daemon's flat per-event publish fee (`feePerEvent`, base units, decimal\n * string) — what the single-event subcommands quote before confirming.\n */\n feePerEvent?: string;\n /**\n * Optional-route capabilities the daemon advertises (`capabilities` in the\n * `/status` body, #306). `'git'` means the `/git/*` write path exists. A\n * daemon older than the field itself omits it entirely — so an UNDEFINED or\n * absent-of-`'git'` value must be read as \"no git support\" (fail closed),\n * NOT delegated to (it would 404 mid-operation).\n */\n capabilities?: string[];\n}\n\n/**\n * True when the probed daemon advertises the `/git/*` write path (#306).\n * Fails closed: a daemon that predates the `capabilities` field reports\n * `undefined` here, which is treated as \"no git routes\" so rig raises a clear\n * upgrade error instead of delegating into a mid-operation 404.\n */\nexport function daemonSupportsGit(probe: DaemonProbe): boolean {\n return Array.isArray(probe.capabilities) && probe.capabilities.includes('git');\n}\n\n/** Injectable probe signature (tests fake this instead of the network). */\nexport type ProbeDaemon = (\n env: NodeJS.ProcessEnv,\n fetchImpl: typeof fetch\n) => Promise<DaemonProbe>;\n\n/** Loopback control API base URL (port: `TOON_CLIENT_HTTP_PORT`, else 8787). */\nexport function daemonBaseUrl(env: NodeJS.ProcessEnv): string {\n const raw = env['TOON_CLIENT_HTTP_PORT'];\n const parsed = raw ? Number(raw) : NaN;\n const port =\n Number.isFinite(parsed) && parsed > 0 ? parsed : defaultDaemonPort();\n return `http://127.0.0.1:${port}`;\n}\n\n/**\n * Probe `GET /status` on the loopback control API. Anything short of a 200\n * with JSON (no listener, timeout, some other local service) reports\n * unreachable — the caller then runs standalone.\n */\nexport async function probeDaemon(\n env: NodeJS.ProcessEnv,\n fetchImpl: typeof fetch,\n timeoutMs = 1500\n): Promise<DaemonProbe> {\n const baseUrl = daemonBaseUrl(env);\n try {\n const res = await fetchImpl(`${baseUrl}/status`, {\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return { baseUrl, reachable: false };\n const body = (await res.json()) as {\n ready?: unknown;\n identity?: { nostrPubkey?: unknown };\n relay?: { url?: unknown };\n feePerEvent?: unknown;\n capabilities?: unknown;\n };\n const probe: DaemonProbe = { baseUrl, reachable: true };\n const pubkey = body?.identity?.nostrPubkey;\n if (typeof pubkey === 'string' && pubkey !== '') probe.identity = pubkey;\n if (typeof body?.ready === 'boolean') probe.ready = body.ready;\n if (typeof body?.relay?.url === 'string' && body.relay.url !== '') {\n probe.relayUrl = body.relay.url;\n }\n if (typeof body?.feePerEvent === 'string' && body.feePerEvent !== '') {\n probe.feePerEvent = body.feePerEvent;\n }\n // Only keep string entries — an old daemon omits the field entirely, and\n // daemonSupportsGit() reads a missing/garbage value as \"no git routes\".\n if (Array.isArray(body?.capabilities)) {\n probe.capabilities = body.capabilities.filter(\n (c): c is string => typeof c === 'string'\n );\n }\n return probe;\n } catch {\n return { baseUrl, reachable: false };\n }\n}\n\n// ---------------------------------------------------------------------------\n// /git/* loopback client (plain fetch — see module doc for the no-import rule)\n// ---------------------------------------------------------------------------\n\n/** The daemon answered a `/git/*` route with a non-2xx error envelope. */\nexport class DaemonRouteError extends Error {\n constructor(\n /** HTTP status code (409 non_fast_forward, 413 oversize_objects, …). */\n public readonly status: number,\n /** The parsed error envelope (structured payloads at the top level). */\n public readonly envelope: GitErrorEnvelope\n ) {\n super(envelope.detail ?? envelope.error);\n this.name = 'DaemonRouteError';\n }\n}\n\n/**\n * A same-identity daemon holds the identity but is too old to serve the\n * `/git/*` routes (#306 — version skew: git routes added in #227, delegation\n * in #279). Raised at the capability pre-flight (no `'git'` in `/status`\n * `capabilities`), and as defense-in-depth when a git route still 404s despite\n * a positive probe. NOT auto-fell-back to standalone on purpose: a\n * same-identity daemon holding the identity makes the #228 nonce guard REFUSE\n * standalone anyway (both writers would race the channel's cumulative-claim\n * watermark) — so the only correct, non-racy resolution is upgrading or\n * stopping the daemon.\n */\nexport class DaemonTooOldForGitError extends Error {\n constructor(\n /** Control API base URL the stale daemon answered on. */\n public readonly baseUrl: string,\n /** The shared Nostr pubkey (hex), when known — shortened in the message. */\n public readonly pubkey?: string\n ) {\n const holds =\n pubkey !== undefined && pubkey !== ''\n ? ` holds this identity (${pubkey.slice(0, 8)}…)`\n : ' holds this identity';\n super(\n `toon-clientd at ${baseUrl}${holds} but is too old to handle git ` +\n 'operations (missing /git routes). Upgrade the daemon ' +\n '(npm i -g @toon-protocol/client-mcp@latest, then restart it) — or ' +\n 'stop it to let rig run standalone.'\n );\n this.name = 'DaemonTooOldForGitError';\n }\n}\n\n/** The daemon vanished between the identity probe and the operation. */\nexport class DaemonUnreachableError extends Error {\n constructor(\n public readonly baseUrl: string,\n cause: unknown\n ) {\n super(\n `toon-clientd stopped answering at ${baseUrl} after the identity ` +\n `probe — nothing was paid. Re-run: rig falls back to standalone ` +\n `automatically when no daemon responds` +\n (cause instanceof Error ? ` (${cause.message})` : '')\n );\n this.name = 'DaemonUnreachableError';\n }\n}\n\nexport class DaemonGitClient {\n constructor(\n private readonly baseUrl: string,\n private readonly fetchImpl: typeof fetch,\n /** Shared identity pubkey, for the too-old error message on a 404. */\n private readonly pubkey?: string\n ) {}\n\n gitEstimate(req: GitEstimateRequest): Promise<GitEstimateResponse> {\n return this.post<GitEstimateResponse>('/git/estimate', req);\n }\n\n gitPush(req: GitPushRequest): Promise<GitPushResponse> {\n return this.post<GitPushResponse>('/git/push', req);\n }\n\n gitIssue(req: GitIssueRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/issue', req);\n }\n\n gitComment(req: GitCommentRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/comment', req);\n }\n\n gitPatch(req: GitPatchRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/patch', req);\n }\n\n gitStatus(req: GitStatusRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/status', req);\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n let res: Response;\n try {\n res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n } catch (err) {\n throw new DaemonUnreachableError(this.baseUrl, err);\n }\n // Defense in depth (#306): a 404 on a `/git/*` route means the route is\n // not registered — a daemon too old for the git write path, despite the\n // capability pre-flight having (wrongly) passed. Surface the same\n // actionable upgrade error rather than the opaque \"HTTP 404\" envelope.\n if (res.status === 404) {\n throw new DaemonTooOldForGitError(this.baseUrl, this.pubkey);\n }\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text === '' ? {} : JSON.parse(text);\n } catch {\n throw new DaemonRouteError(res.status, {\n error: 'invalid_response',\n detail: `daemon returned non-JSON (HTTP ${res.status}): ${text.slice(0, 200)}`,\n });\n }\n if (!res.ok) {\n const envelope =\n parsed && typeof parsed === 'object' && 'error' in parsed\n ? (parsed as GitErrorEnvelope)\n : { error: 'http_error', detail: `HTTP ${res.status}` };\n throw new DaemonRouteError(res.status, envelope);\n }\n return parsed as T;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Paid-session resolution (the decision matrix)\n// ---------------------------------------------------------------------------\n\n/** Which transport a paid command ran on (stderr line + `--json` field). */\nexport type SessionPath = 'daemon' | 'standalone';\n\n/** The delegated fast path: a same-identity daemon owns the operation. */\nexport interface DaemonSession {\n path: 'daemon';\n client: DaemonGitClient;\n baseUrl: string;\n /** Locally-resolved identity (source tier + pubkey — never the phrase). */\n identity: {\n pubkey: string;\n source: IdentitySourceKind;\n sourceLabel: string;\n };\n /** Daemon's flat per-event fee (base units, decimal), when reported. */\n feePerEvent?: string;\n /** Daemon's configured relay URL, when reported (mismatch warning). */\n daemonRelayUrl?: string;\n}\n\n/** The default path: the embedded, nonce-guarded standalone context. */\nexport interface StandaloneSession {\n path: 'standalone';\n ctx: StandaloneContext;\n}\n\nexport type PaidSession = DaemonSession | StandaloneSession;\n\nexport interface ResolveSessionOptions {\n env: NodeJS.ProcessEnv;\n /** Working directory (identity `.env` walk / standalone loader). */\n cwd: string;\n /** Stderr line sink (the chosen-path line always prints here). */\n warn(line: string): void;\n /** Standalone factory (`deps.loadStandalone ?? defaultLoadStandalone`). */\n loadStandalone: LoadStandalone;\n /** Relay-origin for the standalone #264 network bootstrap, when resolved. */\n relayUrl?: string;\n /** Fetch impl for probe + delegated requests (tests). Default: global. */\n fetchImpl?: typeof fetch;\n /** Probe override (tests). Default: {@link probeDaemon}. */\n probeDaemon?: ProbeDaemon;\n}\n\n/**\n * Decide how this paid command pays (see the module-doc matrix) and return a\n * ready session. The chosen path is announced on stderr either way, BEFORE\n * the expensive work starts. Identity is confirmed against the daemon's\n * `/status` before anything else is sent to it.\n */\nexport async function resolvePaidSession(\n options: ResolveSessionOptions\n): Promise<PaidSession> {\n const fetchImpl = options.fetchImpl ?? fetch;\n\n // Force-standalone override (RIG_STANDALONE / `rig --standalone`): skip the\n // daemon probe outright and run embedded, even when a same-identity daemon\n // is up and supports the /git routes. The user has explicitly opted out of\n // delegation; createStandaloneContext skips the same-identity refusal too,\n // and the NonceLock still guards against concurrent standalone processes.\n if (standaloneForced(options.env)) {\n options.warn(\n 'rig: paid path: standalone (RIG_STANDALONE set — toon-clientd bypassed)'\n );\n const ctx = await options.loadStandalone({\n env: options.env,\n cwd: options.cwd,\n warn: options.warn,\n ...(options.relayUrl !== undefined ? { relayUrl: options.relayUrl } : {}),\n });\n return { path: 'standalone', ctx };\n }\n\n const probe = await (options.probeDaemon ?? probeDaemon)(\n options.env,\n fetchImpl\n );\n\n if (probe.reachable && probe.identity !== undefined) {\n // Local identity resolution only happens when there is a daemon to\n // compare against — the standalone loader resolves it itself otherwise.\n const identity = await resolveIdentity({\n env: options.env,\n cwd: options.cwd,\n warn: options.warn,\n });\n if (identity.pubkey === probe.identity) {\n // Capability pre-flight (#306): a same-identity daemon that predates the\n // `/git/*` routes (older client-mcp) has `/status` but 404s every git\n // route. Delegating would dead-end with an opaque 404, and blindly\n // falling back to standalone is unsafe — the #228 nonce guard REFUSES\n // standalone while a same-identity daemon is up (cumulative-claim race).\n // Fail closed with a clear upgrade/stop remediation instead.\n if (!daemonSupportsGit(probe)) {\n throw new DaemonTooOldForGitError(probe.baseUrl, identity.pubkey);\n }\n options.warn(\n `rig: paid path: daemon — toon-clientd at ${probe.baseUrl} holds ` +\n `this identity (${identity.pubkey.slice(0, 8)}…), delegating`\n );\n return {\n path: 'daemon',\n client: new DaemonGitClient(probe.baseUrl, fetchImpl, identity.pubkey),\n baseUrl: probe.baseUrl,\n identity: {\n pubkey: identity.pubkey,\n source: identity.source,\n sourceLabel: identity.sourceLabel,\n },\n ...(probe.feePerEvent !== undefined\n ? { feePerEvent: probe.feePerEvent }\n : {}),\n ...(probe.relayUrl !== undefined\n ? { daemonRelayUrl: probe.relayUrl }\n : {}),\n };\n }\n options.warn(\n `rig: paid path: standalone — the toon-clientd at ${probe.baseUrl} ` +\n `runs a different identity (${probe.identity.slice(0, 8)}…), no ` +\n 'shared channel state'\n );\n } else {\n options.warn(\n `rig: paid path: standalone (no toon-clientd at ${probe.baseUrl})`\n );\n }\n\n const ctx = await options.loadStandalone({\n env: options.env,\n cwd: options.cwd,\n warn: options.warn,\n ...(options.relayUrl !== undefined ? { relayUrl: options.relayUrl } : {}),\n });\n return { path: 'standalone', ctx };\n}\n","/**\n * Error UX for the `rig` commands: map structured planner/publisher errors\n * to actionable terminal output (and a machine-readable envelope for\n * `--json`). The CLI is standalone-only (#248), so everything here is either\n * a local planner error, an identity/config-chain error, or a tagged error\n * surfaced from the embedded publisher (matched by name — those classes live\n * behind the lazy `@toon-protocol/client` dynamic import).\n */\n\nimport { MAX_OBJECT_SIZE } from '../objects.js';\nimport {\n NonFastForwardError,\n OversizeObjectsError,\n type OversizeObject,\n type RejectedRefUpdate,\n} from '../push.js';\nimport { GitError } from '../repo-reader.js';\nimport {\n DaemonRouteError,\n DaemonTooOldForGitError,\n DaemonUnreachableError,\n} from './daemon-session.js';\nimport { MissingIdentityError } from './identity.js';\nimport type { CliIo } from './output.js';\n\n/** Normalized error description: terminal lines + `--json` envelope. */\nexport interface DescribedError {\n /** Stable machine code. */\n code: string;\n /** Human-facing lines (message first, remediation after). */\n lines: string[];\n /** Machine envelope for `--json` output (structured payload included). */\n json: Record<string, unknown>;\n}\n\n/**\n * A command could not resolve the NIP-34 repo address\n * (`30617:<ownerPubkey>:<repoId>`) from flags or the `toon.*` git config\n * keys `rig init` writes.\n */\nexport class UnconfiguredRepoAddressError extends Error {\n constructor(\n /** Which half of the address is missing. */\n public readonly missing: 'repository id' | 'repository owner'\n ) {\n super(\n `no ${missing} configured — this command addresses the repo as ` +\n '30617:<ownerPubkey>:<repoId>. Run `rig init` once inside the repo ' +\n '(it writes toon.repoid/toon.owner to the local git config), or ' +\n `pass ${missing === 'repository id' ? '--repo-id <id>' : '--owner <pubkey>'} ` +\n \"explicitly (use --owner for repos you don't own).\"\n );\n this.name = 'UnconfiguredRepoAddressError';\n }\n}\n\n/** A relay URL (flag, `rig remote add`, or a remote's stored URL) is junk. */\nexport class InvalidRelayUrlError extends Error {\n constructor(\n public readonly url: string,\n /** What was being resolved, e.g. `remote \"origin\"`. */\n context: string\n ) {\n super(\n `${context}: ${JSON.stringify(url)} is not a relay URL — relays are ` +\n 'ws://, wss://, http://, or https://'\n );\n this.name = 'InvalidRelayUrlError';\n }\n}\n\n/** A paid command addressed a git remote that is not configured. */\nexport class UnknownRemoteError extends Error {\n constructor(public readonly remote: string) {\n super(\n `no remote named ${JSON.stringify(remote)} is configured — ` +\n '`rig remote list` shows configured remotes; add it with ' +\n `\\`rig remote add ${remote} <relay-url>\\``\n );\n this.name = 'UnknownRemoteError';\n }\n}\n\n/**\n * The addressed git remote carries multiple URLs (`git remote set-url --add`\n * done by hand). rig publishes to exactly one relay per paid command, so this\n * is refused BEFORE anything is fetched, uploaded, or paid (the #243\n * single-relay guard, extended to remotes).\n */\nexport class MultiUrlRemoteError extends Error {\n constructor(\n public readonly remote: string,\n public readonly urls: string[]\n ) {\n super(\n `remote ${JSON.stringify(remote)} has ${urls.length} URLs ` +\n `(${urls.join(', ')}) — rig supports one relay URL per remote. ` +\n `Fix it with \\`git remote set-url ${remote} <relay-url>\\`. ` +\n 'Nothing was uploaded, published, or paid.'\n );\n this.name = 'MultiUrlRemoteError';\n }\n}\n\n/** No relay resolved: no --relay, no usable remote, no legacy toon.relay. */\nexport class NoOriginConfiguredError extends Error {\n constructor(\n /** URL of an existing `origin` remote that is NOT a relay, if any. */\n nonRelayOriginUrl?: string\n ) {\n super(\n 'no origin configured — run `rig remote add origin <relay-url>` ' +\n '(or pass --relay <url> for a one-off publish).' +\n (nonRelayOriginUrl !== undefined\n ? `\\nThe existing \"origin\" remote (${nonRelayOriginUrl}) is not a ` +\n 'relay URL, so rig ignores it — add the relay under another ' +\n 'name (`rig remote add toon <relay-url>`) and target it ' +\n 'explicitly (`rig push toon` / `--remote toon`).'\n : '')\n );\n this.name = 'NoOriginConfiguredError';\n }\n}\n\n/** A rig command ran outside any git repository. */\nexport class NotAGitRepositoryError extends Error {\n constructor(cwd: string) {\n super(\n `not a git repository: ${cwd}\\n` +\n 'rig can create one for you: re-run `rig init --git-init` (in a ' +\n 'terminal, plain `rig init` offers the same via a prompt). Or run ' +\n '`git init` yourself first, then re-run.'\n );\n this.name = 'NotAGitRepositoryError';\n }\n}\n\nfunction nonFastForwardLines(refs: RejectedRefUpdate[]): string[] {\n return [\n 'Push rejected: non-fast-forward update for:',\n ...refs.map(\n (r) =>\n ` ${r.refname} remote ${r.remoteSha.slice(0, 7)} is not an ancestor of local ${r.localSha.slice(0, 7)}`\n ),\n 'The remote moved since your last push. Re-run with --force to overwrite it',\n 'WARNING: --force rewrites the published ref history for every reader of this repo.',\n ];\n}\n\nfunction oversizeLines(objects: OversizeObject[]): string[] {\n return [\n `Push rejected: ${objects.length} object(s) exceed the ${MAX_OBJECT_SIZE}-byte (95KB) upload limit:`,\n ...objects.map((o) => ` ${o.path ?? o.sha} ${o.type}, ${o.size} bytes`),\n 'Objects over 95KB are a hard error in v1 — split or remove the file(s) from history to push.',\n 'Large-object support is tracked in toon-client#235.',\n ];\n}\n\n/**\n * Normalize any command-path error for rendering. `command` names the rig\n * subcommand for the generic \"rig <command> failed\" lines.\n */\nexport function describeError(err: unknown, command = 'push'): DescribedError {\n if (err instanceof UnconfiguredRepoAddressError) {\n return {\n code: 'unconfigured_repo_address',\n lines: err.message.split('\\n'),\n json: { error: 'unconfigured_repo_address', detail: err.message },\n };\n }\n if (err instanceof NotAGitRepositoryError) {\n return {\n code: 'not_a_git_repository',\n lines: err.message.split('\\n'),\n json: { error: 'not_a_git_repository', detail: err.message },\n };\n }\n if (err instanceof InvalidRelayUrlError) {\n return {\n code: 'invalid_relay_url',\n lines: err.message.split('\\n'),\n json: { error: 'invalid_relay_url', detail: err.message, url: err.url },\n };\n }\n if (err instanceof UnknownRemoteError) {\n return {\n code: 'unknown_remote',\n lines: err.message.split('\\n'),\n json: {\n error: 'unknown_remote',\n detail: err.message,\n remote: err.remote,\n },\n };\n }\n if (err instanceof MultiUrlRemoteError) {\n return {\n code: 'multi_url_remote',\n lines: err.message.split('\\n'),\n json: {\n error: 'multi_url_remote',\n detail: err.message,\n remote: err.remote,\n urls: err.urls,\n },\n };\n }\n if (err instanceof NoOriginConfiguredError) {\n return {\n code: 'no_origin_configured',\n lines: err.message.split('\\n'),\n json: { error: 'no_origin_configured', detail: err.message },\n };\n }\n if (err instanceof MissingIdentityError) {\n return {\n code: 'missing_identity',\n lines: err.message.split('\\n'),\n json: { error: 'missing_identity', detail: err.message },\n };\n }\n if (err instanceof NonFastForwardError) {\n return {\n code: 'non_fast_forward',\n lines: nonFastForwardLines(err.refs),\n json: { error: 'non_fast_forward', detail: err.message, refs: err.refs },\n };\n }\n if (err instanceof OversizeObjectsError) {\n return {\n code: 'oversize_objects',\n lines: oversizeLines(err.objects),\n json: {\n error: 'oversize_objects',\n detail: err.message,\n objects: err.objects,\n },\n };\n }\n if (err instanceof GitError) {\n return {\n code: 'git_error',\n lines: [`git failed: ${err.message}`],\n json: { error: 'git_error', detail: err.message },\n };\n }\n // `rig name` (#367): the optional `@ar.io/sdk` dependency is not installed.\n // Matched by name (the class lives in name.ts) so tsup chunk duplication can\n // never break instanceof — same rationale as the standalone-path errors below.\n if (err instanceof Error && err.name === 'ArnsSdkUnavailableError') {\n return {\n code: 'arns_sdk_unavailable',\n lines: err.message.split('\\n'),\n json: { error: 'arns_sdk_unavailable', detail: err.message },\n };\n }\n // `rig name` (#376): `@ar.io/sdk` IS installed but its API surface doesn't\n // match — kept distinct from \"not installed\" so the remediation (upgrade,\n // not install) is right. Matched by name for the same chunk-duplication\n // rationale as above.\n if (err instanceof Error && err.name === 'ArnsSdkIncompatibleError') {\n return {\n code: 'arns_sdk_incompatible',\n lines: err.message.split('\\n'),\n json: { error: 'arns_sdk_incompatible', detail: err.message },\n };\n }\n\n // Delegated-daemon path (#279): the daemon's /git/* error envelope carries\n // the same structured payloads the local planner throws — render them\n // identically so the two paths are indistinguishable to the user.\n if (err instanceof DaemonRouteError) {\n const envelope = err.envelope;\n if (\n envelope.error === 'non_fast_forward' &&\n Array.isArray(envelope['refs'])\n ) {\n return {\n code: 'non_fast_forward',\n lines: nonFastForwardLines(envelope['refs'] as RejectedRefUpdate[]),\n json: { ...envelope },\n };\n }\n if (\n envelope.error === 'oversize_objects' &&\n Array.isArray(envelope['objects'])\n ) {\n return {\n code: 'oversize_objects',\n lines: oversizeLines(envelope['objects'] as OversizeObject[]),\n json: { ...envelope },\n };\n }\n const retryHint =\n envelope.retryable === true\n ? ['The daemon reports this as retryable — re-run shortly.']\n : [];\n return {\n code: envelope.error,\n lines: [\n `daemon rejected the operation (HTTP ${err.status}): ` +\n (envelope.detail ?? envelope.error),\n ...retryHint,\n ],\n json: { ...envelope },\n };\n }\n if (err instanceof DaemonUnreachableError) {\n return {\n code: 'daemon_unreachable',\n lines: err.message.split('\\n'),\n json: { error: 'daemon_unreachable', detail: err.message },\n };\n }\n // Version skew (#306): a same-identity daemon too old for the /git/* routes.\n // The message already carries the upgrade + stop-daemon remediation.\n if (err instanceof DaemonTooOldForGitError) {\n return {\n code: 'daemon_too_old_for_git',\n lines: err.message.split('\\n'),\n json: {\n error: 'daemon_too_old_for_git',\n detail: err.message,\n baseUrl: err.baseUrl,\n ...(err.pubkey !== undefined ? { pubkey: err.pubkey } : {}),\n },\n };\n }\n\n // Standalone-path tagged errors (matched by name — the classes live behind\n // the optional dynamic import).\n const name = err instanceof Error ? err.name : '';\n const message = err instanceof Error ? err.message : String(err);\n if (name === 'DaemonIdentityConflictError') {\n return {\n code: 'daemon_identity_conflict',\n lines: [\n message,\n 'Paid writes delegate to a same-identity daemon automatically; ' +\n 'seeing this means the daemon appeared mid-run or this operation ' +\n 'has no daemon route — stop the daemon and re-run.',\n ],\n json: { error: 'daemon_identity_conflict', detail: message },\n };\n }\n if (name === 'MissingUplinkError') {\n return {\n code: 'missing_uplink',\n lines: [message],\n json: { error: 'missing_uplink', detail: message },\n };\n }\n // Peer→channel map corruption (#262) — matched by name so tsup chunk\n // duplication between the cli and standalone entries can't break instanceof.\n if (name === 'ChannelMapCorruptError') {\n return {\n code: 'channel_map_corrupt',\n lines: [message],\n json: { error: 'channel_map_corrupt', detail: message },\n };\n }\n // Settle attempted before the challenge window elapsed (#263) — the client\n // throws this retryable error BEFORE spending gas; surface when to retry.\n if (name === 'SettleTooEarlyError') {\n const settleableAt = (err as { settleableAt?: unknown }).settleableAt;\n return {\n code: 'settle_too_early',\n lines: [\n message,\n 'The settlement challenge window is still open — nothing was spent. ' +\n 'Re-run `rig channel settle` after the settleable time.',\n ],\n json: {\n error: 'settle_too_early',\n detail: message,\n ...(typeof settleableAt === 'string' ? { settleableAt } : {}),\n },\n };\n }\n\n // The #278 read path — matched by name (same tsup chunk-duplication\n // rationale as above; the classes live in clone.ts / object-fetch.ts /\n // materialize.ts).\n if (name === 'RepoNotFoundError') {\n return {\n code: 'repo_not_found',\n lines: message.split('\\n'),\n json: { error: 'repo_not_found', detail: message },\n };\n }\n if (name === 'MissingRemoteObjectsError') {\n const missing = (err as { missing?: unknown }).missing;\n return {\n code: 'missing_remote_objects',\n lines: message.split('\\n'),\n json: {\n error: 'missing_remote_objects',\n detail: message,\n ...(Array.isArray(missing) ? { missing } : {}),\n },\n };\n }\n if (name === 'ObjectIntegrityError' || name === 'ObjectWriteMismatchError') {\n return {\n code: 'object_integrity',\n lines: message.split('\\n'),\n json: { error: 'object_integrity', detail: message },\n };\n }\n\n return {\n code: 'error',\n lines: [`rig ${command} failed: ${message}`],\n json: { error: 'error', detail: message },\n };\n}\n\n/**\n * The one command-error emitter (#265): the machine envelope (tagged with\n * the command name) goes to stdout via `emitJson` when `--json` is active,\n * and the human-facing lines ALWAYS go to stderr — so JSON consumers get the\n * parseable envelope while a human tailing stderr still sees the detail.\n * Returns the exit code (always 1) so callers can `return emitCliError(…)`.\n */\nexport function emitCliError(\n io: CliIo,\n json: boolean,\n command: string,\n err: unknown\n): 1 {\n const described = describeError(err, command);\n if (json) io.emitJson({ command, ...described.json });\n for (const line of described.lines) io.err(line);\n return 1;\n}\n","/**\n * `rig push [remote] [refspecs...]` — estimate → confirm → execute (#229,\n * standalone since #248, git-like remote resolution since #249,\n * daemon-as-accelerator since #279).\n *\n * STANDALONE is the default and the guarantee: plan locally (`planPush`) and\n * execute through the embedded, nonce-guarded StandalonePublisher (loaded\n * via dynamic import so runs that fail earlier never need\n * `@toon-protocol/client`). The identity comes from the RIG_MNEMONIC\n * precedence chain (./identity.ts).\n *\n * DAEMON FAST PATH (#279, ./daemon-session.ts): when a running toon-clientd\n * holds the SAME identity, the whole estimate→push pipeline is delegated to\n * its loopback `/git/estimate` + `/git/push` routes instead of refusing —\n * the daemon already owns the channel watermark and its bootstrap is warm,\n * so the command finishes in seconds. A daemon on a different identity, or\n * no daemon, runs standalone. The chosen path prints to stderr and lands in\n * the `--json` envelope as `path`.\n *\n * Repo addressing comes from the `toon.*` git config keys `rig init` writes\n * (`--repo-id` overrides); an unconfigured repo is a hard \"run `rig init`\n * first\" error — nothing is written as a side effect of pushing.\n *\n * The relay comes from the repo's git remotes (#249): when the first\n * positional matches a configured remote name it is the push target,\n * otherwise it is a refspec and the remote defaults to `origin`. `--relay`\n * is an ad-hoc override that bypasses remotes (all positionals are then\n * refspecs); the deprecated v0.1 `git config toon.relay` still works with a\n * migration nudge. See ./remote.ts for the full resolution order.\n *\n * Money is only spent after the confirm gate: `--yes`, or an interactive\n * y/N prompt (a non-TTY session without `--yes` refuses). `--json` emits the\n * wire-shaped plan/receipts for agent consumers; without `--yes` it becomes\n * a pure estimate (plan JSON, nothing executed, exit 0).\n */\n\nimport { createHash } from 'node:crypto';\nimport { parseArgs } from 'node:util';\nimport {\n DEFAULT_RIG_WEB_BUNDLE,\n DEFAULT_RIG_WEB_GATEWAY,\n DEFAULT_RIG_WEB_URL,\n RIG_WEB_ENTRY_CSS_ENV,\n RIG_WEB_GATEWAY_ENV,\n RIG_WEB_ENTRY_JS_ENV,\n RIG_WEB_TX_ENV,\n RIG_WEB_URL_ENV,\n generateRigPointerHtml,\n} from '../rig-pointer.js';\nimport { PREFERRED_GATEWAY, mirrorGatewaysFor } from '../gateway-preference.js';\nimport { hexToNpub } from '../npub.js';\nimport { planPush, executePush } from '../push.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport {\n readRigPointerRecord,\n writeRigPointerRecord,\n} from './rig-pointer-record.js';\nimport { renderIdentityLine, renderPlan, renderResult } from './render.js';\nimport {\n serializePushPlan,\n serializePushResult,\n type GitEstimateResponse,\n type GitPushResponse,\n} from '../routes.js';\nimport { uploadChargeFor, type FeeRates } from '../publisher.js';\nimport {\n resolvePaidSession,\n type PaidSession,\n type ProbeDaemon,\n type SessionPath,\n} from './daemon-session.js';\nimport { RIG_STANDALONE_ENV } from '../standalone/nonce-guard.js';\nimport { emitCliError, UnconfiguredRepoAddressError } from './errors.js';\nimport {\n listGitRemotes,\n readToonConfig,\n resolveRepoRoot,\n} from './git-config.js';\nimport type { IdentitySourceKind } from './identity.js';\nimport { resolveRelays, singleRelayRefusal } from './remote.js';\nimport type {\n LoadStandalone,\n StandaloneContext,\n} from './standalone-context.js';\n\n// ---------------------------------------------------------------------------\n// Dependency seam (real wiring in rig.ts; tests inject fakes)\n// ---------------------------------------------------------------------------\n\n/**\n * Terminal I/O seam — lives in ./output.ts since #265 (the strict `--json`\n * stdout layer); re-exported here because every command module historically\n * imports it from push.ts.\n */\nexport type { CliIo } from './output.js';\nimport type { CliIo } from './output.js';\n\nexport interface PushDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Standalone factory; defaults to the real dynamic-import loader. */\n loadStandalone?: LoadStandalone;\n /** Fetch for the daemon probe + delegated `/git/*` requests (tests). */\n fetchImpl?: typeof fetch;\n /** Daemon `/status` probe override (tests fake the loopback daemon). */\n probeDaemon?: ProbeDaemon;\n}\n\n/**\n * Return deps with the force-standalone override switched on — the\n * `--standalone` / `--no-daemon` per-command flag, equivalent to running with\n * `RIG_STANDALONE=1` in the environment. Every paid path reads the override\n * from `env` ({@link standaloneForced}), so injecting it here makes the flag\n * bypass the daemon for both session resolution and the embedded publisher's\n * guard. Generic so the event commands keep their extra deps.\n */\nexport function withForcedStandalone<D extends PushDeps>(deps: D): D {\n return { ...deps, env: { ...deps.env, [RIG_STANDALONE_ENV]: '1' } };\n}\n\n/**\n * Resolve the paid session for a command from its deps (#279): probe for a\n * same-identity toon-clientd (→ delegate) before falling back to the\n * standalone loader. Shared by push and the single-event commands.\n */\nexport function loadPaidSession(\n deps: PushDeps,\n relayUrl: string | undefined\n): Promise<PaidSession> {\n return resolvePaidSession({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => deps.io.err(line),\n loadStandalone: deps.loadStandalone ?? defaultLoadStandalone,\n ...(relayUrl !== undefined ? { relayUrl } : {}),\n ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}),\n ...(deps.probeDaemon ? { probeDaemon: deps.probeDaemon } : {}),\n });\n}\n\n/**\n * Default standalone factory (shared by every paid command). Dynamic import:\n * `standalone-mode` (and its `@toon-protocol/client` dependency) only loads\n * once a command actually needs to sign or pay.\n */\nexport const defaultLoadStandalone: LoadStandalone = async (options) => {\n const mod = await import('./standalone-mode.js');\n return mod.createStandaloneContext(options);\n};\n\n/** Identity report shared by every paid command's `--json` envelope. */\nexport interface IdentityReport {\n /** Derived Nostr pubkey (hex) of the active identity. */\n pubkey: string;\n /** Which tier of the RIG_MNEMONIC precedence chain supplied it. */\n source: IdentitySourceKind;\n /** Human-facing source label, e.g. `RIG_MNEMONIC env` or a file path. */\n sourceLabel: string;\n}\n\n/** Build the identity report of a loaded standalone context. */\nexport function identityReport(ctx: StandaloneContext): IdentityReport {\n return {\n pubkey: ctx.ownerPubkey,\n source: ctx.identitySource,\n sourceLabel: ctx.identitySourceLabel,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\nexport const PUSH_USAGE = `Usage: rig push [remote] [refspecs...] [options]\n\nPush local git refs to TOON: uploads the object delta to Arweave (paid) and\npublishes the NIP-34 refs event (kind:30618; kind:30617 announce on first\npush). Writes are permanent and non-refundable.\n\nThe repo must be set up once with \\`rig init\\` (writes toon.repoid/toon.owner\nto the local git config); the identity comes from RIG_MNEMONIC (env or a\nproject .env), or the ~/.toon-client keystore/config.\n\nThe relay is a git remote: \\`rig push\\` publishes via \"origin\" (set up with\n\\`rig remote add origin <relay-url>\\`); \\`rig push <remote> [refspecs...]\\`\npublishes via a named remote. When the first positional matches a configured\nremote name it is the remote; otherwise it is a refspec and the remote\ndefaults to origin. Refspecs are branch/tag names or full refnames; default\nis the current branch.\n\nEvery push also keeps the repo's RIG PAGE current: a permanent Arweave\npage that RENDERS this repo in place — it boots the FULL Rig (rig-web)\nfrom its Arweave deployment with this repo pinned, everything served from\nArweave + the relay. The pointer is content-addressed, so it is paid for\nonce and reused for free until the relay or Rig deployment changes.\n--no-rig-page skips it.\n\nOptions:\n --force allow non-fast-forward ref updates (overwrites remote history)\n --all push all local branches\n --tags push all local tags\n --no-rig-page skip the Rig-page pointer upload for this push\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable plan/receipts; without --yes it is a pure\n estimate (nothing executed)\n --relay <url> ad-hoc relay override (exactly one) — bypasses the\n configured remotes; every positional is then a refspec.\n The deprecated v0.1 \\`git config toon.relay\\` still works\n as a fallback, with a migration nudge\n --repo-id <id> repository id / NIP-34 d-tag (default: git config\n toon.repoid — run \\`rig init\\` to set it)\n --standalone always run embedded, bypassing a running toon-clientd\n (alias: --no-daemon). Same as RIG_STANDALONE=1 — set that\n env var to make it the durable default\n -h, --help show this help`;\n\n// ---------------------------------------------------------------------------\n// Refspec selection\n// ---------------------------------------------------------------------------\n\n/**\n * Build the \"no such local ref\" error: name the missing ref, then point at the\n * current branch (with a `did you mean` using the real branch name) or, when\n * HEAD is detached/unborn, list the local branches. This is deliberately NOT\n * the ref-deletion guard — a branch that simply doesn't exist is the common\n * case (e.g. the docs say `main` but the repo is on `master`), and mentioning\n * \"ref deletion\" there is a confusing red herring.\n */\nfunction noSuchRefMessage(\n spec: string,\n head: string | undefined,\n refs: readonly { refname: string }[],\n remoteName: string\n): string {\n const branches = refs\n .filter((r) => r.refname.startsWith('refs/heads/'))\n .map((r) => r.refname.slice('refs/heads/'.length));\n const current =\n head && head.startsWith('refs/heads/')\n ? head.slice('refs/heads/'.length)\n : undefined;\n let msg = `no local branch or tag ${JSON.stringify(spec)}`;\n if (current) {\n msg +=\n ` — your current branch is ${JSON.stringify(current)} ` +\n `(did you mean \\`rig push ${remoteName} ${current}\\`?)`;\n } else if (branches.length > 0) {\n msg += ` — local branches: ${branches.join(', ')}`;\n } else {\n msg += ' — this repository has no branches yet (make a commit first)';\n }\n return msg;\n}\n\n/**\n * Expand positional refspecs / `--all` / `--tags` into full refnames using\n * the local ref list; default (no selection) is the current branch.\n * `remoteName` (default `origin`) only shapes the `did you mean` hint on a\n * missing ref.\n */\nexport async function selectRefspecs(\n reader: GitRepoReader,\n positionals: string[],\n all: boolean,\n tags: boolean,\n remoteName = 'origin'\n): Promise<string[]> {\n const { head, refs } = await reader.listRefs();\n const byName = new Set(refs.map((r) => r.refname));\n\n const selected: string[] = [];\n const add = (refname: string): void => {\n if (!selected.includes(refname)) selected.push(refname);\n };\n\n for (const spec of positionals) {\n if (byName.has(spec)) {\n add(spec);\n } else if (byName.has(`refs/heads/${spec}`)) {\n add(`refs/heads/${spec}`);\n } else if (byName.has(`refs/tags/${spec}`)) {\n add(`refs/tags/${spec}`);\n } else if (spec.startsWith(':')) {\n // git deletion syntax (`rig push origin :branch`) — the one case where\n // \"out of scope in v1\" genuinely applies.\n throw new Error(\n `deleting remote refs (${JSON.stringify(spec)}) is out of scope in v1`\n );\n } else {\n throw new Error(noSuchRefMessage(spec, head, refs, remoteName));\n }\n }\n if (all) {\n for (const ref of refs) {\n if (ref.refname.startsWith('refs/heads/')) add(ref.refname);\n }\n }\n if (tags) {\n for (const ref of refs) {\n if (ref.refname.startsWith('refs/tags/')) add(ref.refname);\n }\n }\n if (selected.length === 0) {\n if (!head) {\n throw new Error(\n 'HEAD is detached and no refspec was given — pass a branch/tag name, --all, or --tags'\n );\n }\n add(head);\n }\n return selected;\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\ninterface PushFlags {\n force: boolean;\n all: boolean;\n tags: boolean;\n /** Deploy/refresh the per-repo Rig page (default; --no-rig-page skips). */\n rigPage: boolean;\n yes: boolean;\n json: boolean;\n relay: string[];\n repoId?: string;\n /** Force embedded standalone, bypassing the daemon (--standalone/--no-daemon). */\n standalone: boolean;\n help: boolean;\n positionals: string[];\n}\n\nfunction parsePushArgs(args: string[]): PushFlags {\n const { values, positionals } = parseArgs({\n args,\n options: {\n force: { type: 'boolean', default: false },\n all: { type: 'boolean', default: false },\n tags: { type: 'boolean', default: false },\n 'no-rig-page': { type: 'boolean', default: false },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n relay: { type: 'string', multiple: true },\n 'repo-id': { type: 'string' },\n standalone: { type: 'boolean', default: false },\n 'no-daemon': { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n const flags: PushFlags = {\n force: values.force ?? false,\n all: values.all ?? false,\n tags: values.tags ?? false,\n rigPage: !(values['no-rig-page'] ?? false),\n yes: values.yes ?? false,\n json: values.json ?? false,\n relay: values.relay ?? [],\n standalone: (values.standalone ?? false) || (values['no-daemon'] ?? false),\n help: values.help ?? false,\n positionals,\n };\n const repoId = values['repo-id'];\n if (repoId !== undefined) flags.repoId = repoId;\n return flags;\n}\n\n// ---------------------------------------------------------------------------\n// Rig pointer (per-repo Rig page — see ../rig-pointer.ts)\n// ---------------------------------------------------------------------------\n\n/** The Rig-pointer step resolved for THIS push, before the confirm gate. */\ninterface RigPointerPlan {\n /** 'upload' pays for a (new/changed) pointer; 'unchanged' reuses for free. */\n action: 'upload' | 'unchanged';\n html: string;\n contentHash: string;\n bytes: number;\n /** Fee for the upload action, base units (0n when unchanged). */\n fee: bigint;\n /** Recorded txId (unchanged action only). */\n recordedTxId?: string;\n}\n\n/** Rig-page report in receipts / the `--json` envelope. */\nexport interface RigPageReport {\n /** What happened: fresh upload, free reuse, or skipped (flag/daemon path). */\n status: 'published' | 'unchanged' | 'skipped';\n txId?: string;\n /** Permanent pointer URL on the preferred ar.io gateway. */\n url?: string;\n feePaid?: string;\n detail?: string;\n}\n\n/**\n * Gateway for printed Rig-page URLs: the shared list's first MAINNET gateway\n * ({@link PREFERRED_GATEWAY} — never ar.io's testnet), `RIG_ARWEAVE_GATEWAY`\n * overriding, same as `rig site`. Distinct from the BUNDLE gateway embedded in\n * the pointer HTML ({@link DEFAULT_RIG_WEB_GATEWAY}), which tracks where the\n * rig-web deploy lives.\n */\nfunction pointerGateway(env: NodeJS.ProcessEnv): string {\n return (env['RIG_ARWEAVE_GATEWAY'] ?? PREFERRED_GATEWAY).replace(/\\/+$/, '');\n}\n\n/**\n * Every OTHER gateway from the shared list, printed under the primary.\n *\n * All of them, not just one: a gateway can be flat DOWN, not merely behind.\n * Observed 2026-08-15 — `ar-io.dev` answered `503` on its own root while the\n * page was live and byte-identical on both other gateways, and a single\n * printed alternate is one outage away from leaving the reader with no\n * working link and the impression their push failed.\n */\nfunction mirrorGateways(primary: string): string[] {\n return mirrorGatewaysFor(primary);\n}\n\n/** Build the Rig-pointer plan: deterministic pointer + content-addressed skip. */\nfunction planRigPointer(args: {\n env: NodeJS.ProcessEnv;\n ownerPubkey: string;\n repoId: string;\n relay: string;\n /** The store route's terms; the pointer's upload is priced by its size. */\n feeRates: FeeRates;\n}): RigPointerPlan {\n const html = generateRigPointerHtml({\n bundle: {\n manifestTx: args.env[RIG_WEB_TX_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.manifestTx,\n entryJs: args.env[RIG_WEB_ENTRY_JS_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.entryJs,\n entryCss:\n args.env[RIG_WEB_ENTRY_CSS_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.entryCss,\n },\n gateway: (args.env[RIG_WEB_GATEWAY_ENV] ?? DEFAULT_RIG_WEB_GATEWAY).replace(\n /\\/+$/,\n ''\n ),\n rigWebUrl: args.env[RIG_WEB_URL_ENV] ?? DEFAULT_RIG_WEB_URL,\n relay: args.relay,\n ownerNpub: hexToNpub(args.ownerPubkey),\n repoId: args.repoId,\n });\n const contentHash = createHash('sha256').update(html).digest('hex');\n const bytes = Buffer.byteLength(html);\n const record = readRigPointerRecord(args.env, args.repoId);\n if (\n record &&\n record.contentHash === contentHash &&\n record.owner === args.ownerPubkey\n ) {\n return {\n action: 'unchanged',\n html,\n contentHash,\n bytes,\n fee: 0n,\n recordedTxId: record.pointerTxId,\n };\n }\n return {\n action: 'upload',\n html,\n contentHash,\n bytes,\n fee: uploadChargeFor(args.feeRates, bytes),\n };\n}\n\n/** JSON envelope emitted by `--json` runs (agents consume this). */\ninterface PushJsonOutput {\n command: 'push';\n repoId: string;\n /** Which transport paid: delegated daemon or embedded standalone (#279). */\n path: SessionPath;\n /** Active identity: source tier + derived pubkey (never the phrase). */\n identity: IdentityReport;\n /** True when the paid execute step ran. */\n executed: boolean;\n /** True when every selected ref already matched the remote (no-op). */\n upToDate: boolean;\n plan: GitEstimateResponse;\n result?: GitPushResponse;\n /** Per-repo Rig-page outcome (absent on estimates / early exits). */\n rigPage?: RigPageReport;\n hint?: string;\n}\n\n/** Run `rig push`; returns the process exit code. */\nexport async function runPush(args: string[], deps: PushDeps): Promise<number> {\n const { io } = deps;\n\n let flags: PushFlags;\n try {\n flags = parsePushArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PUSH_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(PUSH_USAGE);\n return 0;\n }\n // --standalone/--no-daemon: force embedded, bypassing any running daemon\n // (same as RIG_STANDALONE=1 for this one invocation).\n if (flags.standalone) deps = withForcedStandalone(deps);\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n // ── Repo + config resolution (rig init writes these) ────────────────────\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const reader = new GitRepoReader(repoRoot);\n\n // ── Remote-vs-refspec resolution (git-like: `rig push [remote] [refspecs…]`)\n // The first positional is the remote when it names a configured git\n // remote; with --relay the remotes are bypassed and every positional is\n // a refspec.\n let remoteName: string | undefined;\n let refspecArgs = flags.positionals;\n if (flags.relay.length === 0 && refspecArgs.length > 0) {\n const first = refspecArgs[0] as string;\n const remoteNames = new Set(\n (await listGitRemotes(repoRoot)).map((r) => r.name)\n );\n if (remoteNames.has(first)) {\n remoteName = first;\n refspecArgs = refspecArgs.slice(1);\n } else {\n // Not a remote, so it must be a refspec — distinguish a typo'd /\n // unconfigured remote from a bad refspec with one combined error.\n const { refs } = await reader.listRefs();\n const known = new Set(refs.map((r) => r.refname));\n if (\n !known.has(first) &&\n !known.has(`refs/heads/${first}`) &&\n !known.has(`refs/tags/${first}`)\n ) {\n throw new Error(\n `${JSON.stringify(first)} is neither a configured remote nor a ` +\n 'local branch/tag — add the relay remote ' +\n `(\\`rig remote add ${first} <relay-url>\\`; \\`rig remote list\\` ` +\n 'shows configured remotes) or fix the refspec'\n );\n }\n }\n }\n const refspecs = await selectRefspecs(\n reader,\n refspecArgs,\n flags.all,\n flags.tags,\n remoteName ?? 'origin'\n );\n\n // ── Relay resolution (#249: --relay > named remote > origin > toon.relay)\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) io.err(resolved.nudge);\n const relaysUsed = resolved.relays;\n // StandalonePublisher publishes to exactly one relay (its publishEvent\n // throws on >1). Multiple relays can arrive here without explicit intent\n // (repeated --relay flags, an old multi-valued git config `toon.relay`).\n // Refuse up front, before anything is fetched, uploaded, or paid.\n if (relaysUsed.length > 1) {\n io.err(singleRelayRefusal(resolved, 'Nothing was uploaded or paid.'));\n return 1;\n }\n\n // ── Paid session (#279): same-identity daemon → delegate; else the\n // standalone context (identity chain + nonce guard).\n const session = await loadPaidSession(deps, relaysUsed[0]);\n const path = session.path;\n let identity: IdentityReport;\n if (session.path === 'standalone') {\n standaloneCtx = session.ctx;\n identity = identityReport(standaloneCtx);\n } else {\n identity = session.identity;\n }\n\n if (toonConfig.owner && toonConfig.owner !== identity.pubkey) {\n io.err(\n `warning: git config toon.owner (${toonConfig.owner.slice(0, 8)}…) differs from ` +\n `the active identity (${identity.pubkey.slice(0, 8)}…) — this push publishes ` +\n \"under the ACTIVE identity's repo namespace, not the configured owner's. \" +\n 'Re-run `rig init` to adopt the active identity.'\n );\n }\n\n // ── Estimate ────────────────────────────────────────────────────────────\n // Standalone plans locally; the daemon path delegates the plan to\n // `POST /git/estimate` (same wire shape — ../routes.ts).\n let plan: GitEstimateResponse;\n let execute: () => Promise<GitPushResponse>;\n let pointerPlan: RigPointerPlan | undefined;\n let rigPageSkipDetail: string | undefined;\n if (session.path === 'standalone') {\n const ctx = session.ctx;\n const remoteState = await ctx.fetchRemote({\n ownerPubkey: ctx.ownerPubkey,\n repoId,\n relayUrls: relaysUsed,\n });\n const feeRates = await ctx.publisher.getFeeRates();\n const pushPlan = await planPush({\n repoReader: reader,\n remoteState,\n feeRates,\n repoId,\n refs: refspecs,\n force: flags.force,\n });\n plan = serializePushPlan(pushPlan);\n execute = async () =>\n serializePushResult(\n pushPlan,\n await executePush({\n plan: pushPlan,\n publisher: ctx.publisher,\n remoteState,\n repoReader: reader,\n relayUrls: relaysUsed,\n })\n );\n // ── Rig page (the repo's rig-web page) — planned BEFORE the\n // confirm gate so its fee is part of what the user approves.\n if (!flags.rigPage) {\n rigPageSkipDetail = 'skipped (--no-rig-page)';\n } else if (relaysUsed[0] === undefined) {\n rigPageSkipDetail = 'skipped (no relay resolved for the pointer)';\n } else if (!ctx.publisher.uploadBlob) {\n rigPageSkipDetail =\n 'skipped (the active publisher cannot upload raw blobs)';\n } else {\n pointerPlan = planRigPointer({\n env: deps.env,\n ownerPubkey: ctx.ownerPubkey,\n repoId,\n relay: relaysUsed[0],\n feeRates,\n });\n }\n } else {\n const client = session.client;\n plan = await client.gitEstimate({\n repoPath: repoRoot,\n repoId,\n refspecs,\n force: flags.force,\n relayUrls: relaysUsed,\n });\n execute = () =>\n client.gitPush({\n repoPath: repoRoot,\n repoId,\n refspecs,\n force: flags.force,\n relayUrls: relaysUsed,\n confirm: true,\n });\n // The delegated daemon owns the paid pipeline but exposes no raw-blob\n // upload route yet — the pointer refreshes on the next standalone push.\n rigPageSkipDetail =\n 'skipped on the daemon path (refreshes on the next standalone push)';\n }\n\n // ── Rig-page pointer publish (shared by the normal path and the\n // up-to-date refresh below; never fails a succeeded push) ────────────────\n const gateway = pointerGateway(deps.env);\n const publishPointer = async (\n pointer: RigPointerPlan\n ): Promise<RigPageReport> => {\n try {\n // Guarded at plan time: a plan only exists when uploadBlob is available.\n const ctx = standaloneCtx as StandaloneContext;\n const receipt = await (\n ctx.publisher.uploadBlob as NonNullable<\n typeof ctx.publisher.uploadBlob\n >\n )({\n body: Buffer.from(pointer.html, 'utf8'),\n contentType: 'text/html',\n repoId,\n });\n writeRigPointerRecord(deps.env, {\n repoId,\n owner: identity.pubkey,\n pointerTxId: receipt.txId,\n contentHash: pointer.contentHash,\n updatedAt: Date.now(),\n });\n return {\n status: 'published',\n txId: receipt.txId,\n url: `${gateway}/${receipt.txId}`,\n feePaid: receipt.feePaid.toString(),\n };\n } catch (err) {\n // The record was not updated, so the next push retries the upload.\n return {\n status: 'skipped',\n detail: `pointer upload failed (push itself succeeded; the next push retries): ${\n err instanceof Error ? err.message : String(err)\n }`,\n };\n }\n };\n const printRigPage = (rigPage: RigPageReport): void => {\n if (rigPage.url) {\n io.out(\n `Rig page: ${rigPage.url}` +\n (rigPage.status === 'published'\n ? ` paid ${rigPage.feePaid}`\n : '') +\n ' (renders this repo from Arweave)'\n );\n const mirrors = rigPage.txId ? mirrorGateways(gateway) : [];\n if (mirrors.length > 0 && rigPage.txId) {\n const txId = rigPage.txId;\n io.out(\n ' also: (same page — try these if the address above does ' +\n 'not load; gateways index fresh uploads at different speeds, ' +\n 'and any one of them can be down)'\n );\n for (const mirror of mirrors) {\n io.out(` ${mirror}/${txId}`);\n }\n }\n } else if (rigPage.detail) {\n io.err(`rig page: ${rigPage.detail}`);\n }\n };\n\n // ── Up-to-date short-circuit (never publish a no-op refs event) ─────────\n // A STALE Rig page still refreshes here: the pointer changes when the Rig\n // build / relay / gateway changes, not the refs — requiring a dummy\n // commit to roll it forward would be absurd.\n const upToDate = plan.refUpdates.every((u) => u.kind === 'up-to-date');\n if (upToDate) {\n if (pointerPlan?.action !== 'upload') {\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: true,\n plan,\n } satisfies PushJsonOutput);\n } else {\n io.out('Everything up-to-date — nothing to push (and nothing paid).');\n }\n return 0;\n }\n\n if (!flags.json) {\n io.out(\n 'Everything up-to-date — refs unchanged, but the Rig page is stale ' +\n '(new Rig build, relay, or gateway):'\n );\n io.out(` rig page ${pointerPlan.bytes} bytes ${pointerPlan.fee}`);\n io.out(renderIdentityLine(identity));\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: true,\n plan,\n hint: 'refs up-to-date; the Rig page is stale — re-run with --yes to refresh it (or --no-rig-page to skip)',\n } satisfies PushJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or --no-rig-page to skip the refresh)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Refresh the Rig page (total ${pointerPlan.fee} base units)? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was uploaded or published.');\n return 1;\n }\n }\n const rigPage = await publishPointer(pointerPlan);\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: true,\n plan,\n rigPage,\n } satisfies PushJsonOutput);\n } else {\n printRigPage(rigPage);\n }\n return 0;\n }\n\n // ── Confirm gate ────────────────────────────────────────────────────────\n // The confirmed total covers the push plan PLUS a (new/changed) Rig\n // pointer; an unchanged pointer is free and printed as such.\n const confirmTotal =\n BigInt(plan.estimate.totalFee) + (pointerPlan?.fee ?? 0n);\n if (!flags.json) {\n for (const line of renderPlan(plan)) io.out(line);\n if (pointerPlan?.action === 'upload') {\n io.out(\n ` rig page ${pointerPlan.bytes} bytes ${pointerPlan.fee}` +\n ` (repo page — paid once, reused until relay/rig-web changes)`\n );\n io.out(` total with rig page ${confirmTotal}`);\n }\n io.out(renderIdentityLine(identity));\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: false,\n plan,\n hint: 'estimate only — re-run with --yes to upload and publish (permanent, non-refundable)',\n } satisfies PushJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid push (total ${confirmTotal} base units)? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was uploaded or published.');\n return 1;\n }\n }\n\n // ── Execute ─────────────────────────────────────────────────────────────\n const result = await execute();\n\n // ── Rig-page pointer (after the push succeeded; never fails it) ─────────\n let rigPage: RigPageReport;\n if (!pointerPlan) {\n rigPage = {\n status: 'skipped',\n ...(rigPageSkipDetail ? { detail: rigPageSkipDetail } : {}),\n };\n } else if (pointerPlan.action === 'unchanged') {\n rigPage = {\n status: 'unchanged',\n txId: pointerPlan.recordedTxId as string,\n url: `${gateway}/${pointerPlan.recordedTxId}`,\n };\n } else {\n rigPage = await publishPointer(pointerPlan);\n }\n\n // ── Receipts ────────────────────────────────────────────────────────────\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: true,\n upToDate: false,\n plan,\n result,\n rigPage,\n } satisfies PushJsonOutput);\n } else {\n for (const line of renderResult(result)) io.out(line);\n printRigPage(rigPage);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'push', err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * Per-repo Rig pointer — the permanent Arweave page that RENDERS a pushed\n * repo in place, deployed by `rig push` the way GitHub Pages tracks a repo.\n * User-facing name: the repo's \"Rig page\".\n *\n * The pointer boots the FULL React Rig from its Arweave deployment: it pins\n * `window.__RIG_CONFIG__ = {relay, owner, repo}`, presets the HashRouter\n * route in its own URL fragment, and loads rig-web's entry css/js from the\n * deployment's path manifest (`rig-web/scripts/deploy-arweave.mjs` — every\n * build output uploaded GZIPPED under ArDrive Turbo's free tier with a\n * `Content-Encoding` tag the gateways serve as a header, so the whole app\n * fits without a funded wallet). Module-relative imports resolve against the\n * MODULE's URL, so the entire chunk graph loads from the manifest while the\n * address bar stays on the pointer.\n *\n * A `<noscript>`/delayed fallback links to the Pages deployment\n * ({@link DEFAULT_RIG_WEB_URL}). The earlier single-file rig-lite build\n * (`rig-web/lite/rig-lite.js`) remains in-tree as the ultra-light option.\n *\n * The generated HTML is DETERMINISTIC for a given (bundle, gateway,\n * rigWebUrl, relay, owner, repoId) so `rig push` can content-address it:\n * the pointer uploads once and every later push skips the fee until one of\n * those inputs changes (../cli/rig-pointer-record.ts).\n */\n\n/** One released Arweave deployment of rig-web (manifest + entry assets). */\nexport interface RigWebBundle {\n /** The ar.io path-manifest txId (`https://<gateway>/<tx>/` serves the app). */\n manifestTx: string;\n /** Entry module path inside the manifest (hashed per build). */\n entryJs: string;\n /** Entry stylesheet path inside the manifest (hashed per build). */\n entryCss: string;\n}\n\n/**\n * The current rig-web deployment on Arweave (deployed 2026-07-17 via\n * `deploy-arweave.mjs`, 122 files, free tier). Override per-field with\n * `RIG_WEB_TX` / `RIG_WEB_ENTRY_JS` / `RIG_WEB_ENTRY_CSS`.\n */\nexport const DEFAULT_RIG_WEB_BUNDLE: RigWebBundle = {\n manifestTx: 'Iy8sHYVnoevSpwDC2lqUoIg8BWdes9NmMbgmPd81UpU',\n entryJs: 'assets/index-BuKzYubR.js',\n entryCss: 'assets/index-H5D6cmfa.css',\n};\n\n/** Env vars overriding the bundle (e.g. a newer deploy before release). */\nexport const RIG_WEB_TX_ENV = 'RIG_WEB_TX';\nexport const RIG_WEB_ENTRY_JS_ENV = 'RIG_WEB_ENTRY_JS';\nexport const RIG_WEB_ENTRY_CSS_ENV = 'RIG_WEB_ENTRY_CSS';\n\n/**\n * Gateway the pointer loads the rig-web BUNDLE from. Tied to where the\n * bundle deploy lives (mainnet, via Turbo), NOT to where `rig push`\n * uploads repo data: the assets are stored GZIPPED with a\n * `Content-Encoding` tag that `arweave.net` serves as a real header —\n * `ar-io.dev` drops it and ships raw gzip bytes, which the browser then\n * fails to parse (\"Invalid or unexpected token\", blank page). Override\n * with `RIG_WEB_GATEWAY` alongside a bundle override.\n */\nexport const DEFAULT_RIG_WEB_GATEWAY = 'https://arweave.net';\n\n/** Env var overriding the bundle gateway. */\nexport const RIG_WEB_GATEWAY_ENV = 'RIG_WEB_GATEWAY';\n\n/** Pages deployment for the no-JS / delayed fallback link (tracks main). */\nexport const DEFAULT_RIG_WEB_URL = 'https://toon-protocol.github.io/rig';\n\n/** Env var overriding the fallback URL. */\nexport const RIG_WEB_URL_ENV = 'RIG_WEB_URL';\n\nexport interface RigPointerOptions {\n /** The Arweave rig-web deployment the pointer boots. */\n bundle: RigWebBundle;\n /** Gateway base the app loads from (no trailing /). */\n gateway: string;\n /** Fallback rig-web deployment for the no-JS link (no trailing /). */\n rigWebUrl: string;\n /** Relay the Rig should read the repo from (`wss://…`). */\n relay: string;\n /** Repo owner as npub (rig-web routes are `#/<npub>/<repo>`). */\n ownerNpub: string;\n /** Repository id (NIP-34 d-tag). */\n repoId: string;\n}\n\n/** The repo's HashRouter fragment, with the relay threaded through. */\nexport function repoHashRoute(\n options: Pick<RigPointerOptions, 'relay' | 'ownerNpub' | 'repoId'>\n): string {\n const { relay, ownerNpub, repoId } = options;\n // Route + query INSIDE the fragment — rig-web's relay resolution reads\n // `[?&]relay=` from the fragment (rig-web/README.md \"Relay resolution\n // order\"), so this works on any static host with no rewrites.\n return `#/${encodeURIComponent(ownerNpub)}/${encodeURIComponent(repoId)}?relay=${encodeURIComponent(relay)}`;\n}\n\n/** The full-Rig fallback URL for a repo (Pages deployment). */\nexport function rigWebRoute(\n options: Pick<RigPointerOptions, 'rigWebUrl' | 'relay' | 'ownerNpub' | 'repoId'>\n): string {\n return `${options.rigWebUrl.replace(/\\/+$/, '')}/${repoHashRoute(options)}`;\n}\n\n/** Escape a string for safe embedding in an HTML attribute/text position. */\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/**\n * Generate the pointer HTML: the full-Rig boot-in-place shell. Loads only\n * the immutable Arweave deployment it exists to boot; degrades to a\n * fallback link with JS disabled.\n */\nexport function generateRigPointerHtml(options: RigPointerOptions): string {\n const gateway = options.gateway.replace(/\\/+$/, '');\n const base = `${gateway}/${options.bundle.manifestTx}`;\n const cssHref = `${base}/${options.bundle.entryCss}`;\n const jsSrc = `${base}/${options.bundle.entryJs}`;\n const fallback = rigWebRoute(options);\n const safeFallback = escapeHtml(fallback);\n const title = escapeHtml(`${options.repoId} — Rig`);\n\n // Escape `<` so hostile config values can never break out of the script.\n const config = JSON.stringify({\n relay: options.relay,\n owner: options.ownerNpub,\n repo: options.repoId,\n }).replace(/</g, '\\\\u003c');\n const hashRoute = JSON.stringify(repoHashRoute(options)).replace(\n /</g,\n '\\\\u003c'\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\"><head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n <meta name=\"description\" content=\"Decentralized Git on Nostr &amp; TOON Protocol\">\n <title>${title}</title>\n <link rel=\"icon\" href=\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>&#x2692;</text></svg>\">\n <script>window.__RIG_CONFIG__=${config};if(!location.hash||location.hash===\"#\")location.replace(${hashRoute})</script>\n <link rel=\"stylesheet\" href=\"${escapeHtml(cssHref)}\">\n <script type=\"module\" crossorigin src=\"${escapeHtml(jsSrc)}\"></script>\n</head><body>\n <div id=\"app\"></div>\n <noscript><p>JavaScript is off — open <a href=\"${safeFallback}\">${title}</a> in the hosted Rig.</p></noscript>\n <p hidden data-fallback>If nothing loads, open <a href=\"${safeFallback}\">${title}</a> in the hosted Rig.</p>\n <script>setTimeout(function(){var p=document.querySelector(\"[data-fallback]\");var app=document.getElementById(\"app\");if(p&&(!app||!app.childElementCount))p.hidden=false},8000)</script>\n</body></html>\n`;\n}\n","/**\n * Which Arweave gateway rig PRINTS.\n *\n * Fetches try every gateway in `@toon-protocol/arweave`'s shared list, so the\n * order there only matters for redundancy. A printed URL is different: it is\n * the one link a reader clicks. `ar-io.dev` heads the shared list but is\n * ar.io's TESTNET gateway — its ArNS resolver runs against the Solana devnet\n * contracts and it serves testnet-bundler uploads that never reach Arweave —\n * so a mainnet upload printed there is a guaranteed 404 (toon-client#577\n * reorders the shared list). Until then rig prefers the first MAINNET gateway\n * of that list and never prints the testnet one as the primary.\n */\n\nimport { ARWEAVE_GATEWAYS } from '@toon-protocol/arweave';\n\nconst TESTNET_GATEWAY = /(^|\\.)ar-io\\.dev$/i;\n\n/** Every gateway that is not ar.io's testnet. Malformed URLs are not gateways. */\nexport function isMainnetGateway(url: string): boolean {\n try {\n return !TESTNET_GATEWAY.test(new URL(url).hostname);\n } catch {\n return false;\n }\n}\n\n/** The gateway a printed URL defaults to: the shared list's first mainnet one. */\nexport const PREFERRED_GATEWAY: string =\n ARWEAVE_GATEWAYS.find(isMainnetGateway) ?? 'https://arweave.net';\n\n/** The shared list minus one gateway, for \"also at\" mirrors under a primary. */\nexport function mirrorGatewaysFor(primary: string): string[] {\n const p = primary.replace(/\\/+$/, '');\n return ARWEAVE_GATEWAYS.filter((g) => g.replace(/\\/+$/, '') !== p);\n}\n","/**\n * Local record of the last-published Rig pointer per repo — what lets\n * `rig push` keep the per-repo Rig page (../rig-pointer.ts) current like\n * GitHub Pages WITHOUT re-paying on every push.\n *\n * The pointer HTML is deterministic for (rigWebUrl, relay, owner, repoId),\n * so its sha-256 is recorded alongside the uploaded txId: while the hash\n * matches, later pushes reuse the recorded URL for free; when any input\n * changes (relay moved, rig-web base flipped to the Arweave bundle), the\n * next push uploads a fresh pointer and the record rolls forward.\n *\n * Same storage conventions as ./site-record.ts: a JSON file under\n * `TOON_CLIENT_HOME` (default `~/.toon-client`), keyed by repoId (local,\n * single-user scope); corrupt/missing files are treated as empty for reads\n * and overwritten on write.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const RIG_POINTER_FILENAME = 'rig-pointers.json';\n\n/** One recorded Rig-pointer publish. */\nexport interface RigPointerRecord {\n repoId: string;\n /** Owner pubkey (hex) the pointer was published under. */\n owner: string;\n /** The pointer transaction id (43-char base64url). */\n pointerTxId: string;\n /** sha-256 (hex) of the pointer HTML that was uploaded. */\n contentHash: string;\n /** Unix milliseconds of the publish. */\n updatedAt: number;\n}\n\ntype RigPointerFile = Record<string, RigPointerRecord>;\n\nfunction storeDir(env: NodeJS.ProcessEnv): string {\n return env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n}\n\nfunction storePath(env: NodeJS.ProcessEnv): string {\n return join(storeDir(env), RIG_POINTER_FILENAME);\n}\n\nfunction readAll(env: NodeJS.ProcessEnv): RigPointerFile {\n try {\n const parsed = JSON.parse(readFileSync(storePath(env), 'utf8')) as unknown;\n if (parsed && typeof parsed === 'object') return parsed as RigPointerFile;\n return {};\n } catch {\n // Missing or corrupt → empty (never fatal to a push).\n return {};\n }\n}\n\n/** The recorded pointer for a repo, if any. */\nexport function readRigPointerRecord(\n env: NodeJS.ProcessEnv,\n repoId: string\n): RigPointerRecord | undefined {\n return readAll(env)[repoId];\n}\n\n/** Record a pointer publish (overwrites the repo's previous record). */\nexport function writeRigPointerRecord(\n env: NodeJS.ProcessEnv,\n record: RigPointerRecord\n): void {\n const all = readAll(env);\n all[record.repoId] = record;\n mkdirSync(storeDir(env), { recursive: true });\n writeFileSync(storePath(env), `${JSON.stringify(all, null, 2)}\\n`);\n}\n","/**\n * Human-facing rendering for `rig push`: the pre-push confirm table and the\n * post-push receipts. Machine consumers use `--json` instead (the raw wire\n * shapes from ../routes.ts) — nothing here is meant to be parsed.\n */\n\nimport type {\n GitEstimateResponse,\n GitEventResponse,\n GitPushResponse,\n GitRefUpdate,\n GitRepoAddr,\n} from '../routes.js';\n\n/** Group thousands for readability: 1234567 → '1,234,567'. */\nexport function formatNumber(value: number | string | bigint): string {\n return String(value).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction shortSha(sha: string | null): string {\n return sha ? sha.slice(0, 7) : '(none)';\n}\n\nfunction refLine(update: GitRefUpdate): string {\n const arrow = `${shortSha(update.remoteSha)} → ${shortSha(update.localSha)}`;\n return ` ${update.refname} ${arrow} (${update.kind})`;\n}\n\n/**\n * One-line identity report: derived pubkey + which chain tier supplied the\n * mnemonic (never the phrase itself).\n */\nexport function renderIdentityLine(identity: {\n pubkey: string;\n sourceLabel: string;\n}): string {\n return `Identity: ${identity.pubkey} (from ${identity.sourceLabel})`;\n}\n\n/** The pre-push confirm table (refs, objects, itemized fees, warning). */\nexport function renderPlan(plan: GitEstimateResponse): string[] {\n const lines: string[] = [];\n lines.push(\n `Push plan for repo \"${plan.repoId}\"` +\n (plan.announceNeeded ? ' — first push, will announce (kind:30617)' : '')\n );\n lines.push('Refs:');\n for (const update of plan.refUpdates) lines.push(refLine(update));\n\n const est = plan.estimate;\n const skipped = Object.keys(plan.knownShaToTxId).length;\n const emptySkipped = est.skippedEmptyCount ?? 0;\n lines.push(\n `Objects: ${est.objectCount} to upload` +\n ` (${formatNumber(est.totalObjectBytes)} bytes)` +\n (skipped > 0 ? `; ${skipped} already on Arweave (free)` : '') +\n (emptySkipped > 0\n ? `; ${emptySkipped} empty blob${emptySkipped === 1 ? '' : 's'} skipped ` +\n '(reconstructed on clone)'\n : '')\n );\n lines.push('Fees (base units):');\n lines.push(\n ` upload ${est.objectCount} object(s), ${formatNumber(est.totalObjectBytes)} bytes` +\n ` ${formatNumber(est.uploadFee)}`\n );\n lines.push(` events ${est.eventCount} event(s) ${formatNumber(est.eventFees)}`);\n lines.push(` total ${formatNumber(est.totalFee)}`);\n lines.push('Writes are permanent and non-refundable.');\n return lines;\n}\n\n/** Human label for a per-event fee that may be unknown (older daemons). */\nexport function feeLabel(fee: string | undefined): string {\n return fee !== undefined\n ? `${formatNumber(fee)} base units`\n : \"the publisher's configured per-event fee\";\n}\n\n/**\n * Pre-publish summary for the single-event subcommands\n * (issue/comment/pr/status): what is published, against which repo address,\n * at what fee — the confirm gate follows these lines.\n */\nexport function renderEventPlan(opts: {\n /** e.g. `issue \"Fix the flux\" (kind:1621)`. */\n action: string;\n addr: GitRepoAddr;\n /** Active identity (source + derived pubkey). */\n identity: { pubkey: string; sourceLabel: string };\n /** Per-event fee (base units, decimal string), when known. */\n fee?: string;\n}): string[] {\n return [\n `Publish ${opts.action}`,\n `Repo: 30617:${opts.addr.ownerPubkey}:${opts.addr.repoId}`,\n renderIdentityLine(opts.identity),\n `Fee: ${feeLabel(opts.fee)}. Writes are permanent and non-refundable.`,\n ];\n}\n\n/** Receipt line for one published single-event git write. */\nexport function renderEventReceipt(\n action: string,\n result: GitEventResponse\n): string[] {\n const lines = [\n `Published ${action}: ${result.eventId} paid ${formatNumber(result.feePaid)} base units`,\n ];\n if (result.channelBalanceAfter !== undefined) {\n lines.push(\n `Channel balance after: ${formatNumber(result.channelBalanceAfter)} base units`\n );\n }\n return lines;\n}\n\n/** Post-push receipts: per-object skipped/paid, event ids, paid-vs-estimate. */\nexport function renderResult(result: GitPushResponse): string[] {\n const lines: string[] = [];\n lines.push(`Pushed \"${result.repoId}\":`);\n const paid = result.uploads.filter((u) => !u.skipped);\n const skipped = result.uploads.filter((u) => u.skipped);\n for (const upload of result.uploads) {\n lines.push(\n ` object ${upload.sha.slice(0, 12)} ${upload.skipped ? 'skipped (already stored)' : `paid ${formatNumber(upload.feePaid)}`}` +\n ` ar:${upload.txId}`\n );\n }\n lines.push(\n `Uploads: ${paid.length} paid, ${skipped.length} skipped (content-addressed).`\n );\n const emptySkipped = result.estimate.skippedEmptyCount ?? 0;\n if (emptySkipped > 0) {\n lines.push(\n `Empty blobs: ${emptySkipped} skipped (zero-byte, not uploaded — ` +\n 'reconstructed on clone).'\n );\n }\n if (result.announceReceipt) {\n lines.push(\n `Announcement (kind:30617): ${result.announceReceipt.eventId}` +\n ` paid ${formatNumber(result.announceReceipt.feePaid)}`\n );\n }\n lines.push(\n `Refs event (kind:30618): ${result.refsReceipt.eventId}` +\n ` paid ${formatNumber(result.refsReceipt.feePaid)}`\n );\n lines.push(\n `Total paid: ${formatNumber(result.totalFeePaid)} base units` +\n ` (estimate was ${formatNumber(result.estimate.totalFee)})`\n );\n return lines;\n}\n","/**\n * Repo-local `rig` configuration, persisted in git's own storage:\n *\n * toon.repoid NIP-34 repository identifier (`d` tag)\n * toon.owner repository owner's Nostr pubkey (hex) — the identity that\n * signs kind:30617/30618 (`a`-tag `30617:<owner>:<repoId>`)\n * toon.relay relay URL(s), multi-valued — DEPRECATED since #249 (relays\n * live in real git remotes now; the key stays readable as a\n * fallback and is removed in v0.3)\n *\n * plus the REAL git remotes (`remote.<name>.url`) that #249 maps relays onto:\n * `rig remote add origin <relay-url>` is `git remote add`, so `git remote -v`\n * shows rig's relays and plain git tooling round-trips them.\n *\n * All access goes through `execFile git` with argument arrays (same\n * injection posture as GitRepoReader — never a shell).\n */\n\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\n/** The rig-relevant git config keys of one repository. */\nexport interface ToonRepoConfig {\n repoId?: string;\n owner?: string;\n relays: string[];\n}\n\nasync function git(\n repoPath: string,\n args: string[],\n allowExitCodes: number[] = []\n): Promise<{ stdout: string; exitCode: number }> {\n try {\n const { stdout } = await execFileAsync('git', args, {\n cwd: repoPath,\n encoding: 'utf-8',\n });\n return { stdout, exitCode: 0 };\n } catch (err) {\n const e = err as NodeJS.ErrnoException & {\n code?: number | string;\n stdout?: string;\n stderr?: string;\n };\n const exitCode = typeof e.code === 'number' ? e.code : undefined;\n if (exitCode !== undefined && allowExitCodes.includes(exitCode)) {\n return { stdout: e.stdout ?? '', exitCode };\n }\n throw new Error(\n `git ${args.join(' ')} failed${exitCode !== undefined ? ` (exit ${exitCode})` : ''}: ` +\n `${(e.stderr ?? e.message ?? '').trim()}`\n );\n }\n}\n\n/**\n * Resolve the repository worktree root for `cwd` via\n * `git rev-parse --show-toplevel`. Throws a clear error when `cwd` is not\n * inside a git repository.\n */\nexport async function resolveRepoRoot(cwd: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['rev-parse', '--show-toplevel'],\n { cwd, encoding: 'utf-8' }\n );\n const root = stdout.trim();\n if (!root) throw new Error('empty rev-parse output');\n return root;\n } catch (err) {\n const e = err as { stderr?: string; message?: string };\n throw new Error(\n `not a git repository (run rig inside a repo): ${(e.stderr ?? e.message ?? '').trim()}`\n );\n }\n}\n\n/**\n * `git init` in `dir` — create a fresh repository there (never a shell). Runs\n * ONLY in `dir` itself, never a parent, and is idempotent (git init on an\n * existing repo is a no-op). Used by `rig init` when it offers to create the\n * repo for the user (consent-gated), mirroring how it offers to mint an\n * identity on a cold start.\n *\n * The initial branch is forced to `main`, deterministically — a stock git\n * without `init.defaultBranch=main` would otherwise create `master`, and every\n * rig doc/quickstart says `main` (so `rig push origin main` / `rig checkout\n * main` would then fail against a repo whose only branch is `master`). git\n * ≥ 2.28 takes `--initial-branch=main`; older git falls back to pointing the\n * unborn HEAD at `refs/heads/main` (no commits yet, so this just renames the\n * pending branch).\n */\nexport async function initGitRepository(dir: string): Promise<void> {\n try {\n await git(dir, ['init', '--initial-branch=main']);\n } catch {\n await git(dir, ['init']);\n await git(dir, ['symbolic-ref', 'HEAD', 'refs/heads/main']);\n }\n}\n\n/** Read the `toon.*` git config keys of the repository at `repoPath`. */\nexport async function readToonConfig(repoPath: string): Promise<ToonRepoConfig> {\n // exit 1 = key unset (git config --get convention) — tolerated everywhere.\n const [repoId, owner, relays] = await Promise.all([\n git(repoPath, ['config', '--get', 'toon.repoid'], [1]),\n git(repoPath, ['config', '--get', 'toon.owner'], [1]),\n git(repoPath, ['config', '--get-all', 'toon.relay'], [1]),\n ]);\n const config: ToonRepoConfig = {\n relays: relays.stdout\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean),\n };\n const id = repoId.stdout.trim();\n if (repoId.exitCode === 0 && id) config.repoId = id;\n const own = owner.stdout.trim();\n if (owner.exitCode === 0 && own) config.owner = own;\n return config;\n}\n\n/** One configured git remote: its name + (possibly multiple) fetch URLs. */\nexport interface GitRemoteInfo {\n name: string;\n urls: string[];\n}\n\n/**\n * URLs of the git remote `name` (`remote.<name>.url`, multi-valued when\n * `git remote set-url --add` was used). `[]` when the remote does not exist.\n */\nexport async function getGitRemoteUrls(\n repoPath: string,\n name: string\n): Promise<string[]> {\n // exit 1 = key unset / invalid key — either way, no such remote.\n const { stdout } = await git(\n repoPath,\n ['config', '--get-all', `remote.${name}.url`],\n [1]\n );\n return stdout\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n}\n\n/** All configured git remotes with their URLs (`git remote -v` data). */\nexport async function listGitRemotes(\n repoPath: string\n): Promise<GitRemoteInfo[]> {\n const { stdout } = await git(repoPath, ['remote']);\n const names = stdout\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n const remotes: GitRemoteInfo[] = [];\n for (const name of names) {\n remotes.push({ name, urls: await getGitRemoteUrls(repoPath, name) });\n }\n return remotes;\n}\n\n/** The repo-local git author identity (`user.name` + `user.email`). */\nexport interface GitAuthorConfig {\n name?: string;\n email?: string;\n}\n\n/**\n * Read the repository's LOCAL `user.name` / `user.email` (never `--global`).\n * A `--local --get` miss is exit 1 (tolerated) and yields `undefined` — so\n * this reports only what THIS repo overrides, not any inherited global value.\n */\nexport async function readGitAuthor(\n repoPath: string\n): Promise<GitAuthorConfig> {\n const [name, email] = await Promise.all([\n git(repoPath, ['config', '--local', '--get', 'user.name'], [1]),\n git(repoPath, ['config', '--local', '--get', 'user.email'], [1]),\n ]);\n const config: GitAuthorConfig = {};\n const n = name.stdout.trim();\n if (name.exitCode === 0 && n) config.name = n;\n const e = email.stdout.trim();\n if (email.exitCode === 0 && e) config.email = e;\n return config;\n}\n\n/**\n * Set the repository's LOCAL git author identity — `git config --local`, so it\n * overrides any global `user.name`/`user.email` FOR THIS REPO ONLY and never\n * touches `~/.gitconfig`. On a rig repo the nostr key is the identity, so the\n * commit author == push signer == nostr identity (a coherent authorship chain\n * baked into the git objects on Arweave).\n */\nexport async function setGitAuthor(\n repoPath: string,\n author: { name: string; email: string }\n): Promise<void> {\n await git(repoPath, ['config', '--local', 'user.name', author.name]);\n await git(repoPath, ['config', '--local', 'user.email', author.email]);\n}\n\n/** `git remote add <name> <url>` — real git remote storage, never a shell. */\nexport async function addGitRemote(\n repoPath: string,\n name: string,\n url: string\n): Promise<void> {\n await git(repoPath, ['remote', 'add', name, url]);\n}\n\n/** `git remote remove <name>`. */\nexport async function removeGitRemote(\n repoPath: string,\n name: string\n): Promise<void> {\n await git(repoPath, ['remote', 'remove', name]);\n}\n\n/**\n * Persist the `toon.*` keys (repo-local config). Only supplied fields are\n * written; `relays` replaces the whole multi-valued list.\n */\nexport async function writeToonConfig(\n repoPath: string,\n config: { repoId?: string; owner?: string; relays?: string[] }\n): Promise<void> {\n if (config.repoId !== undefined) {\n await git(repoPath, ['config', 'toon.repoid', config.repoId]);\n }\n if (config.owner !== undefined) {\n await git(repoPath, ['config', 'toon.owner', config.owner]);\n }\n if (config.relays !== undefined && config.relays.length > 0) {\n // Replace the whole list: unset-all (exit 5 = key did not exist) + re-add.\n await git(repoPath, ['config', '--unset-all', 'toon.relay'], [5]);\n for (const relay of config.relays) {\n await git(repoPath, ['config', '--add', 'toon.relay', relay]);\n }\n }\n}\n","/**\n * Relays as origins (#249): the `rig remote` subcommand and the relay\n * resolution every paid command shares.\n *\n * Remotes are stored as REAL git remotes (`git remote add/remove` under the\n * hood), so `git remote -v` shows them and plain git tooling round-trips the\n * config — no parallel store. Paid commands resolve their relay as:\n *\n * 1. `--relay <url>` ad-hoc override, bypasses remotes\n * 2. a named remote `rig push <remote>` / `--remote <name>`\n * 3. the `origin` remote the default target\n * 4. git config `toon.relay` DEPRECATED v0.1 fallback (one-line nudge;\n * the key is removed in v0.3)\n * 5. error \"no origin configured — run `rig remote\n * add origin <relay-url>`\"\n *\n * A remote with multiple URLs (`git remote set-url --add` done by hand) is\n * refused BEFORE anything is fetched, uploaded, or paid: rig publishes to\n * exactly one relay per paid command (the #243 single-relay guard). One\n * carve-out: a default `origin` whose URLs are ALL non-relay is a plain git\n * remote — it is skipped like any single non-relay origin, never refused.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n emitCliError,\n InvalidRelayUrlError,\n MultiUrlRemoteError,\n NoOriginConfiguredError,\n NotAGitRepositoryError,\n UnknownRemoteError,\n} from './errors.js';\nimport {\n addGitRemote,\n getGitRemoteUrls,\n listGitRemotes,\n readToonConfig,\n removeGitRemote,\n resolveRepoRoot,\n} from './git-config.js';\nimport type { CliIo } from './push.js';\n\n// ---------------------------------------------------------------------------\n// Relay URL validation\n// ---------------------------------------------------------------------------\n\nconst RELAY_PROTOCOLS = new Set(['ws:', 'wss:', 'http:', 'https:']);\n\n/** True when `url` parses and uses a relay scheme (ws/wss/http/https). */\nexport function isRelayUrl(url: string): boolean {\n try {\n return RELAY_PROTOCOLS.has(new URL(url).protocol);\n } catch {\n return false;\n }\n}\n\n/** Throw {@link InvalidRelayUrlError} unless `url` is a relay URL. */\nexport function assertRelayUrl(url: string, context: string): void {\n if (!isRelayUrl(url)) throw new InvalidRelayUrlError(url, context);\n}\n\n// ---------------------------------------------------------------------------\n// Relay resolution (shared by push + the event commands)\n// ---------------------------------------------------------------------------\n\n/** Where the resolved relay came from. */\nexport type RelaySource = 'relay-flag' | 'remote' | 'toon.relay';\n\nexport interface ResolvedRelays {\n /** Relay URLs to publish to (paid commands still enforce exactly one). */\n relays: string[];\n source: RelaySource;\n /** The git remote that supplied the URL (source === 'remote'). */\n remoteName?: string;\n /** One-line stderr note (toon.relay deprecation), when applicable. */\n nudge?: string;\n}\n\nexport interface ResolveRelaysOptions {\n /** `--relay` flag values (may be >1 — the command-level guard refuses). */\n relayFlags: string[];\n /** Explicitly requested remote (`rig push <remote>` / `--remote <name>`). */\n remoteName?: string | undefined;\n /** Repo worktree root; undefined when not inside a git repository. */\n repoRoot?: string | undefined;\n /** Deprecated `git config toon.relay` values (v0.1 fallback). */\n toonRelays: string[];\n}\n\n/**\n * Resolve the relay(s) for a paid command. Throws (before any payment):\n * {@link UnknownRemoteError}, {@link MultiUrlRemoteError},\n * {@link InvalidRelayUrlError}, {@link NoOriginConfiguredError}.\n */\nexport async function resolveRelays(\n opts: ResolveRelaysOptions\n): Promise<ResolvedRelays> {\n // 1. Ad-hoc --relay override: bypasses the configured remotes entirely.\n if (opts.relayFlags.length > 0) {\n return { relays: opts.relayFlags, source: 'relay-flag' };\n }\n\n // 2. Explicitly named remote: must exist, carry ONE URL, and be a relay.\n if (opts.remoteName !== undefined) {\n const urls =\n opts.repoRoot !== undefined\n ? await getGitRemoteUrls(opts.repoRoot, opts.remoteName)\n : [];\n if (urls.length === 0) throw new UnknownRemoteError(opts.remoteName);\n if (urls.length > 1) throw new MultiUrlRemoteError(opts.remoteName, urls);\n const url = urls[0] as string;\n assertRelayUrl(url, `remote ${JSON.stringify(opts.remoteName)}`);\n return { relays: urls, source: 'remote', remoteName: opts.remoteName };\n }\n\n // 3. Default remote: origin — when it looks like a relay. A PURELY\n // non-relay origin (e.g. a GitHub clone URL, even one with several\n // mirror push URLs) is skipped, not an error: rig shares git's remote\n // namespace, so pre-existing git origins must not break paid commands\n // that can still resolve via toon.relay. But the moment ANY of a\n // multi-URL origin's URLs is relay-shaped, the publish target is\n // ambiguous — refuse before anything is fetched, uploaded, or paid\n // (the #243 single-relay guard).\n let nonRelayOriginUrl: string | undefined;\n if (opts.repoRoot !== undefined) {\n const urls = await getGitRemoteUrls(opts.repoRoot, 'origin');\n if (urls.length === 1 && isRelayUrl(urls[0] as string)) {\n return { relays: urls, source: 'remote', remoteName: 'origin' };\n }\n if (urls.length > 1 && urls.some(isRelayUrl)) {\n throw new MultiUrlRemoteError('origin', urls);\n }\n // Reachable only when every remaining URL is non-relay (single relay URL\n // returned above; multi-URL with any relay URL threw above), so urls[0]\n // is guaranteed non-relay — NoOriginConfiguredError's message relies on\n // that (\"the existing origin is not a relay URL\").\n if (urls.length > 0) nonRelayOriginUrl = urls[0] as string;\n }\n\n // 4. Deprecated v0.1 fallback: git config toon.relay (nudges to migrate).\n if (opts.toonRelays.length > 0) {\n return {\n relays: opts.toonRelays,\n source: 'toon.relay',\n nudge:\n 'note: git config toon.relay is deprecated (removed in v0.3) — ' +\n `migrate: rig remote add origin ${opts.toonRelays[0]}`,\n };\n }\n\n // 5. Nothing resolved.\n throw new NoOriginConfiguredError(nonRelayOriginUrl);\n}\n\n/**\n * Refusal line for >1 resolved relays: the StandalonePublisher publishes to\n * exactly one relay per paid command, and multiple can arrive without\n * explicit intent (repeated --relay flags, a multi-valued toon.relay).\n * `nothingHappened` names what was NOT done, e.g. 'Nothing was uploaded or\n * paid.'\n */\nexport function singleRelayRefusal(\n resolved: ResolvedRelays,\n nothingHappened: string\n): string {\n const fix =\n resolved.source === 'relay-flag'\n ? 'pass exactly one --relay <url>'\n : 'trim git config toon.relay to one URL (better: migrate — ' +\n '`rig remote add origin <relay-url>`)';\n return (\n `rig publishes to a single relay, but ${resolved.relays.length} are ` +\n `configured (${resolved.relays.join(', ')}) — ${fix}. ${nothingHappened}`\n );\n}\n\n// ---------------------------------------------------------------------------\n// rig remote <add|remove|list>\n// ---------------------------------------------------------------------------\n\nexport const REMOTE_USAGE = `Usage: rig remote <add|remove|list> [args] [options]\n\nManage the relays this repo publishes to. Remotes are stored as REAL git\nremotes (\\`git remote -v\\` shows them; plain git tooling round-trips). Paid\ncommands publish via the \"origin\" remote by default; \\`rig push <remote>\\`\nand \\`--remote <name>\\` target another one. Free — nothing is published or\npaid.\n\nCommands:\n add <name> <relay-url> add a remote pointing at a relay (the URL must be\n ws://, wss://, http://, or https://)\n remove <name> remove a remote\n list list remote names + URLs (the default subcommand)\n\nOptions:\n --json machine-readable envelope (all subcommands)\n -h, --help show this help`;\n\n/** Deps subset `rig remote` needs (free — no publisher, no identity). */\nexport interface RemoteDeps {\n io: CliIo;\n cwd: string;\n}\n\n/** Run `rig remote …`; returns the process exit code. */\nexport async function runRemote(\n args: string[],\n deps: RemoteDeps\n): Promise<number> {\n const { io } = deps;\n\n let sub: string | undefined;\n let rest: string[];\n let json: boolean;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) {\n io.out(REMOTE_USAGE);\n return 0;\n }\n json = values.json ?? false;\n [sub, ...rest] = positionals;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(REMOTE_USAGE);\n return 2;\n }\n\n // Argument-shape validation (exit 2) before touching the repository.\n switch (sub) {\n case undefined:\n case 'list':\n if (rest.length > 0) {\n io.err(`rig remote list takes no arguments (got ${rest.join(' ')})`);\n io.err(REMOTE_USAGE);\n return 2;\n }\n break;\n case 'add': {\n if (rest.length !== 2) {\n io.err('usage: rig remote add <name> <relay-url>');\n io.err(REMOTE_USAGE);\n return 2;\n }\n const url = rest[1] as string;\n if (!isRelayUrl(url)) {\n io.err(\n `cannot add remote: ${JSON.stringify(url)} is not a relay URL — ` +\n 'relays are ws://, wss://, http://, or https://'\n );\n return 2;\n }\n break;\n }\n case 'remove':\n if (rest.length !== 1) {\n io.err('usage: rig remote remove <name>');\n io.err(REMOTE_USAGE);\n return 2;\n }\n break;\n default:\n io.err(`unknown rig remote subcommand: ${sub}`);\n io.err(REMOTE_USAGE);\n return 2;\n }\n\n try {\n let repoRoot: string;\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n } catch {\n throw new NotAGitRepositoryError(deps.cwd);\n }\n\n switch (sub) {\n case undefined:\n case 'list': {\n const remotes = await listGitRemotes(repoRoot);\n if (json) {\n io.emitJson({ command: 'remote', remotes });\n return 0;\n }\n if (remotes.length === 0) {\n io.out(\n 'no remotes configured — add one: rig remote add origin <relay-url>'\n );\n return 0;\n }\n for (const remote of remotes) {\n for (const url of remote.urls) {\n io.out(\n `${remote.name}\\t${url}` +\n (isRelayUrl(url) ? '' : '\\t(not a relay URL — ignored by rig)')\n );\n }\n if (remote.urls.length > 1) {\n io.err(\n `warning: remote \"${remote.name}\" has ${remote.urls.length} ` +\n 'URLs — rig supports one relay URL per remote (fix with ' +\n `\\`git remote set-url ${remote.name} <relay-url>\\`)`\n );\n }\n }\n return 0;\n }\n\n case 'add': {\n const [name, url] = rest as [string, string];\n const existing = await getGitRemoteUrls(repoRoot, name);\n if (existing.length > 0) {\n const detail =\n `remote ${JSON.stringify(name)} already exists ` +\n `(${existing.join(', ')}) — nothing changed. Point it ` +\n `somewhere else with \\`git remote set-url ${name} <relay-url>\\`, ` +\n `or \\`rig remote remove ${name}\\` first.`;\n if (json) {\n io.emitJson({\n command: 'remote',\n error: 'remote_exists',\n detail,\n remote: name,\n urls: existing,\n });\n }\n io.err(detail);\n return 1;\n }\n await addGitRemote(repoRoot, name, url);\n if (!json) io.out(`Added remote ${name} → ${url}`);\n if (name === 'origin') {\n if (!json) {\n io.out(\n '`rig push` and the event commands now publish here by default.'\n );\n }\n const toonConfig = await readToonConfig(repoRoot);\n if (toonConfig.relays.length > 0) {\n io.err(\n `note: git config toon.relay (${toonConfig.relays.join(', ')}) ` +\n 'is deprecated and now shadowed by the origin remote — drop ' +\n 'it with `git config --unset-all toon.relay` (the key is ' +\n 'removed in v0.3).'\n );\n }\n }\n if (json) {\n io.emitJson({ command: 'remote', action: 'add', name, url });\n }\n return 0;\n }\n\n case 'remove': {\n const name = rest[0] as string;\n const existing = await getGitRemoteUrls(repoRoot, name);\n if (existing.length === 0) {\n const detail =\n `no remote named ${JSON.stringify(name)} — ` +\n '`rig remote list` shows configured remotes.';\n if (json) {\n io.emitJson({\n command: 'remote',\n error: 'unknown_remote',\n detail,\n remote: name,\n });\n }\n io.err(detail);\n return 1;\n }\n await removeGitRemote(repoRoot, name);\n if (json) {\n io.emitJson({ command: 'remote', action: 'remove', name });\n } else {\n io.out(`Removed remote ${name}`);\n }\n return 0;\n }\n\n /* v8 ignore next 2 -- unreachable: validated above */\n default:\n return 2;\n }\n } catch (err) {\n return emitCliError(io, json, 'remote', err);\n }\n}\n","/**\n * `rig chain` — choose which chain (and therefore which USDC token) settles\n * paid `rig` writes.\n *\n * Each supported chain has its own USDC: EVM (Base Sepolia), Solana devnet, and\n * Mina devnet. \"Which USDC is spent\" == \"which settlement chain rig picks\", and\n * that is a session/config-level choice — there is no per-`rig push` flag. This\n * command persists the choice to the shared client config's `chain` field\n * (`~/.toon-client/config.json`) — the exact knob `resolveNetworkTopology`\n * reads (env `TOON_CLIENT_CHAIN` ?? config `chain`), so the next paid command\n * settles on the named chain.\n *\n * rig chain show the current preference (and what USDC it maps to)\n * rig chain set <chain> pin the settlement chain: evm | sol | mina (or a\n * full id like evm:base:84532)\n * rig chain unset clear the pin — revert to automatic selection\n *\n * A FREE command: it only reads/writes the local config file, never the relay\n * or a chain. When nothing is pinned, rig auto-selects (most-recent open\n * channel → first announced chain your wallet holds USDC on → first announced\n * EVM chain); `rig chain` reports that state.\n *\n * Precedence caveats surfaced to the user: the `TOON_CLIENT_CHAIN` env var\n * overrides the config field, and a `supportedChains` array (if set) takes\n * precedence over `chain` — writing `chain` while either is set warns that the\n * pin may not take effect until they are cleared/changed.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport type { CliIo } from './output.js';\n\n/** Canonical settlement families and the USDC each one spends. */\nconst FAMILY_USDC: Record<string, string> = {\n evm: 'EVM USDC (Base Sepolia on devnet)',\n solana: 'Solana USDC',\n mina: 'Mina USDC',\n};\n\n/**\n * Accepted `set` values → the canonical string written to config. Short aliases\n * mirror `rig fund` (`sol`, `eth`). A full chain id (with a `:`) is stored\n * verbatim; a bare family is stored as the canonical family, which the resolver\n * matches against the first announced chain of that family.\n */\nconst FAMILY_ALIASES: Record<string, string> = {\n evm: 'evm',\n eth: 'evm',\n sol: 'solana',\n solana: 'solana',\n mina: 'mina',\n};\n\n/** Human list of accepted `set` arguments (for usage/errors). */\nconst CHAIN_ARG_LIST = 'evm | sol | solana | mina (or a full id like evm:base:84532)';\n\nexport const CHAIN_USAGE = `Usage: rig chain [set <chain> | unset]\n\nChoose which chain — and therefore which USDC token — settles paid \\`rig\\`\nwrites. The choice is saved to the client config's \\`chain\\` field and applies to\nevery subsequent paid command (there is no per-command chain flag). Free: only\nthe local config file is touched.\n\n rig chain show the current settlement-chain preference\n rig chain set <chain> pin the settlement chain / USDC:\n evm → EVM USDC (Base Sepolia on devnet)\n sol → Solana USDC\n mina → Mina USDC\n (a full id like evm:base:84532 or solana:devnet also\n works; \\`solana\\` is accepted for \\`sol\\`, \\`eth\\` for \\`evm\\`)\n rig chain unset clear the pin — revert to automatic selection\n\nWhen nothing is pinned, rig auto-selects: your most-recently-used open channel's\nchain, else the first announced chain your wallet holds USDC on, else the first\nannounced EVM chain.\n\nOptions:\n --json machine-readable envelope\n -h, --help show this help`;\n\n/** What `rig chain` needs from the command environment. */\nexport interface ChainDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n}\n\n/** The slice of the shared client config `rig chain` reads/writes. */\ninterface ChainConfigFile {\n chain?: string;\n supportedChains?: string[];\n [key: string]: unknown;\n}\n\n/** `--json` envelope. */\ninterface ChainJson {\n command: 'chain';\n /** The effective settlement-chain preference, or null when unset (auto). */\n chain: string | null;\n /** Where the effective value came from. */\n source: 'env' | 'config' | 'supportedChains' | 'auto';\n /** The USDC token family the effective chain spends (null when auto). */\n usdc: string | null;\n /** The value written to the config `chain` field (set/unset only). */\n wrote?: string | null;\n configPath: string;\n /** Precedence warnings that may keep the pin from taking effect. */\n warnings?: string[];\n}\n\n/** Resolve the client config directory + path (mirrors readFundConfig). */\nfunction configPathFor(env: NodeJS.ProcessEnv): string {\n const dir = env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n return join(dir, 'config.json');\n}\n\nfunction readChainConfig(configPath: string): ChainConfigFile {\n try {\n return JSON.parse(readFileSync(configPath, 'utf8')) as ChainConfigFile;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw new Error(\n `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** Read-merge-write: preserve every other field, only touch `chain`. */\nfunction writeChainConfig(configPath: string, file: ChainConfigFile): void {\n mkdirSync(dirname(configPath), { recursive: true });\n writeFileSync(configPath, `${JSON.stringify(file, null, 2)}\\n`, 'utf8');\n}\n\n/**\n * Normalize a `set` argument to the string stored in config. A value with a\n * `:` is a full chain id (family must be evm/solana/mina); otherwise it is a\n * family alias. Throws a usage error on anything else.\n */\nfunction normalizeChain(raw: string): string {\n if (raw.includes(':')) {\n const family = raw.split(':')[0]?.toLowerCase() ?? '';\n if (!(family in FAMILY_USDC)) {\n throw new Error(\n `unknown chain family in ${JSON.stringify(raw)} — must start with evm:, solana:, or mina:`\n );\n }\n return raw;\n }\n const canonical = FAMILY_ALIASES[raw.toLowerCase()];\n if (!canonical) {\n throw new Error(`chain must be one of ${CHAIN_ARG_LIST}, got ${JSON.stringify(raw)}`);\n }\n return canonical;\n}\n\n/** The USDC family label for a stored chain value (family or full id). */\nfunction usdcFor(chain: string): string {\n const family = (chain.includes(':') ? (chain.split(':')[0] ?? chain) : chain).toLowerCase();\n return FAMILY_USDC[family] ?? `${family} USDC`;\n}\n\n/** Run `rig chain`; returns the process exit code. */\nexport async function runChain(args: string[], deps: ChainDeps): Promise<number> {\n const { io, env } = deps;\n\n let positionals: string[];\n let json = false;\n try {\n const parsed = parseArgs({\n args,\n allowPositionals: true,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (parsed.values.help) {\n io.out(CHAIN_USAGE);\n return 0;\n }\n positionals = parsed.positionals;\n json = parsed.values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHAIN_USAGE);\n return 2;\n }\n\n const [sub, ...subRest] = positionals;\n if (sub !== undefined && sub !== 'set' && sub !== 'unset') {\n io.err(`unknown subcommand ${JSON.stringify(sub)} — expected \\`set\\`, \\`unset\\`, or no argument`);\n io.err(CHAIN_USAGE);\n return 2;\n }\n if (sub === 'set' && subRest.length !== 1) {\n io.err(\n subRest.length === 0\n ? `rig chain set needs a chain: ${CHAIN_ARG_LIST}`\n : `rig chain set takes exactly one chain, got ${subRest.length}: ${subRest.join(' ')}`\n );\n io.err(CHAIN_USAGE);\n return 2;\n }\n if (sub === 'unset' && subRest.length !== 0) {\n io.err(`rig chain unset takes no arguments, got: ${subRest.join(' ')}`);\n io.err(CHAIN_USAGE);\n return 2;\n }\n // Normalize the `set` value here (not inside the emitCliError-wrapped block)\n // so an unknown chain is a USAGE error (exit 2), not a runtime error.\n let setValue: string | undefined;\n if (sub === 'set') {\n try {\n setValue = normalizeChain(subRest[0] as string);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHAIN_USAGE);\n return 2;\n }\n }\n\n try {\n const configPath = configPathFor(env);\n const file = readChainConfig(configPath);\n const envChain = env['TOON_CLIENT_CHAIN'];\n const supported0 = file.supportedChains?.[0];\n\n // Precedence warnings shared by set/unset: env overrides config, and a\n // supportedChains array overrides the plain `chain` field.\n const precedenceWarnings = (targetField: 'chain' | null): string[] => {\n const w: string[] = [];\n if (envChain !== undefined) {\n w.push(\n `TOON_CLIENT_CHAIN=${envChain} is set in the environment and overrides the config ` +\n `${targetField === 'chain' ? 'value you just wrote' : 'file'} — unset it for the config to take effect.`\n );\n }\n if (supported0 !== undefined) {\n w.push(\n `config \\`supportedChains\\` is set (first entry ${JSON.stringify(supported0)}) and takes ` +\n 'precedence over `chain` — clear or reorder it for this pin to take effect.'\n );\n }\n return w;\n };\n\n // ── set ────────────────────────────────────────────────────────────────\n if (sub === 'set') {\n const value = setValue as string;\n file.chain = value;\n writeChainConfig(configPath, file);\n const warnings = precedenceWarnings('chain');\n if (json) {\n io.emitJson({\n command: 'chain',\n chain: envChain ?? value,\n source: envChain !== undefined ? 'env' : 'config',\n usdc: usdcFor(envChain ?? value),\n wrote: value,\n configPath,\n ...(warnings.length ? { warnings } : {}),\n } satisfies ChainJson);\n return 0;\n }\n io.out(`Settlement chain set to ${value} → spends ${usdcFor(value)}.`);\n io.out(`Saved to ${configPath}. Applies to the next paid command (e.g. \\`rig push\\`).`);\n for (const w of warnings) io.err(`warning: ${w}`);\n return 0;\n }\n\n // ── unset ──────────────────────────────────────────────────────────────\n if (sub === 'unset') {\n const had = file.chain;\n delete file.chain;\n writeChainConfig(configPath, file);\n // After unset, what still pins the chain (env / supportedChains), if any.\n const stillPinned = envChain ?? supported0;\n if (json) {\n io.emitJson({\n command: 'chain',\n chain: stillPinned ?? null,\n source: envChain !== undefined ? 'env' : supported0 !== undefined ? 'supportedChains' : 'auto',\n usdc: stillPinned ? usdcFor(stillPinned) : null,\n wrote: null,\n configPath,\n ...(precedenceWarnings(null).length ? { warnings: precedenceWarnings(null) } : {}),\n } satisfies ChainJson);\n return 0;\n }\n io.out(\n had !== undefined\n ? `Cleared the settlement-chain pin (was ${had}).`\n : 'No settlement-chain pin was set.'\n );\n if (stillPinned !== undefined) {\n io.out(`Still pinned to ${stillPinned} by ${envChain !== undefined ? 'TOON_CLIENT_CHAIN' : 'config supportedChains'} → ${usdcFor(stillPinned)}.`);\n } else {\n io.out('Reverted to automatic selection (most-recent channel → first funded announced chain → first EVM).');\n }\n return 0;\n }\n\n // ── show (no subcommand) ────────────────────────────────────────────────\n const effective = envChain ?? file.chain ?? supported0;\n const source: ChainJson['source'] =\n envChain !== undefined\n ? 'env'\n : file.chain !== undefined\n ? 'config'\n : supported0 !== undefined\n ? 'supportedChains'\n : 'auto';\n if (json) {\n io.emitJson({\n command: 'chain',\n chain: effective ?? null,\n source,\n usdc: effective ? usdcFor(effective) : null,\n configPath,\n } satisfies ChainJson);\n return 0;\n }\n if (effective !== undefined) {\n const via =\n source === 'env'\n ? 'TOON_CLIENT_CHAIN env'\n : source === 'config'\n ? `config \\`chain\\` (${configPath})`\n : `config \\`supportedChains[0]\\``;\n io.out(`Settlement chain: ${effective} → spends ${usdcFor(effective)} (from ${via}).`);\n io.out('Change it with `rig chain set <evm|sol|mina>`, or `rig chain unset` for auto.');\n } else {\n io.out('Settlement chain: (auto) — no pin set.');\n io.out('rig picks your most-recent open channel, else the first announced chain your');\n io.out('wallet holds USDC on, else the first announced EVM chain.');\n io.out('Pin one with `rig chain set <evm|sol|mina>`.');\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'chain', err);\n }\n}\n","/**\n * `rig channel` — the payment channels paid rig commands hold (#262), plus\n * the explicit money lifecycle (#263): open / close / settle.\n *\n * Paid commands open a channel lazily on first use and RECORD it in the\n * peer→channel map under `TOON_CLIENT_HOME` (default `~/.toon-client`,\n * `rig-channels.json`), so later invocations resume the same channel instead\n * of opening (and funding) a new one per run. `rig channel list` reads that\n * map plus the client's nonce-watermark store (`channels.json`) and shows\n * current holdings — a FREE command: local files only, no client start, no\n * network, no payment (and therefore no `@toon-protocol/client` import).\n *\n * The lifecycle subcommands are ON-CHAIN wallet operations (gas + collateral\n * movement, not relay claims), so they follow the push confirm idiom: print\n * what will happen, then require `--yes` (mandatory in a non-TTY session) or\n * an interactive y/N confirm; `--json` without `--yes` is a pure plan.\n *\n * open the SAME resume-or-open path lazy paid writes use (factored, not\n * forked): resumes the recorded channel when one is live, else\n * opens + records a fresh one; `--deposit` adds collateral on top.\n * close starts the settlement challenge window for a recorded channel —\n * the channel stops paying immediately; collateral is released by\n * `settle` once the window elapses.\n * settle releases the remaining collateral after the challenge window\n * (the client refuses a too-early settle BEFORE spending gas).\n *\n * close/settle recover deposits stranded by pre-#262 one-channel-per-run\n * behaviour: any channel present in the map can be driven to settled.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n channelStatus,\n ChannelMapStore,\n resolveChannelPaths,\n type ChannelMapRecord,\n type WatermarkEntry,\n} from '../standalone/channel-map.js';\nimport { emitCliError } from './errors.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type CliIo,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport { renderIdentityLine } from './render.js';\nimport type { StandaloneContext } from './standalone-context.js';\nimport type { StandaloneMoneyOps } from '../standalone/money.js';\n\nexport const CHANNEL_USAGE = `Usage: rig channel <subcommand>\n\nManage the payment channels paid rig commands hold with relay/store peers.\nPaid commands open a channel lazily on first use and record it under\nTOON_CLIENT_HOME (default ~/.toon-client, rig-channels.json), so later\ninvocations resume the same channel instead of opening a new one per run.\n\nSubcommands:\n list [--json] show recorded channels — peer, chain, channel id, deposit,\n cumulative claimed, status. Free: reads local state only.\n\n open [--peer <ilp-destination>] [--deposit <base-units>]\n explicitly open the payment channel for a peer — the SAME\n path paid commands use lazily: resumes the recorded live\n channel if one exists (no on-chain spend), else opens and\n records a fresh one (locks the peer-negotiated initial\n deposit on-chain). --peer is the ILP destination to anchor\n to (default: the configured destination, e.g. the devnet\n apex); --deposit adds that much extra collateral after the\n open/resume. On-chain: asks for confirmation (--yes skips).\n\n close <channelId>\n close a recorded channel — an on-chain tx that starts the\n settlement challenge window (the peer's settlementTimeout).\n The channel stops paying immediately; the remaining\n collateral stays locked until \\`rig channel settle\\` after\n the window elapses. Asks for confirmation (--yes skips).\n\n settle <channelId>\n settle a closed channel once its challenge window elapsed —\n an on-chain tx that releases the remaining collateral back\n to your wallet. Refused (without spending gas) while the\n window is still open. Asks for confirmation (--yes skips).\n\nCommon options: --json (machine-readable envelopes; without --yes lifecycle\ncommands emit a pure plan and execute nothing), --yes, -h/--help.`;\n\n/**\n * What `rig channel` needs from the command environment — the shared paid\n * command deps (io/env/cwd + injectable standalone loader): `list` uses only\n * io/env, the lifecycle subcommands load the standalone context.\n */\nexport type ChannelDeps = PushDeps;\n\n/** One channel in the `--json` envelope (unknowns are null, bigints strings). */\ninterface ChannelJson {\n channelId: string;\n peerId: string;\n identity: string;\n destination: string;\n chain: string;\n tokenNetwork: string;\n depositTotal: string | null;\n cumulativeClaimed: string | null;\n nonce: number | null;\n status: 'open' | 'closing' | 'settleable' | 'settled';\n openedAt: string;\n lastUsedAt: string;\n}\n\n/** Route one `rig channel …` invocation; returns the exit code. */\nexport async function runChannel(\n args: string[],\n deps: ChannelDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'list':\n return runChannelList(rest, deps);\n case 'open':\n return runChannelOpen(rest, deps);\n case 'close':\n return runChannelWithdrawStep(rest, deps, 'close');\n case 'settle':\n return runChannelWithdrawStep(rest, deps, 'settle');\n case 'help':\n case '--help':\n case '-h':\n io.out(CHANNEL_USAGE);\n return 0;\n case undefined:\n io.err(CHANNEL_USAGE);\n return 2;\n default:\n io.err(`rig channel: unknown subcommand ${JSON.stringify(sub)}`);\n io.err(CHANNEL_USAGE);\n return 2;\n }\n}\n\n// ---------------------------------------------------------------------------\n// list (#262)\n// ---------------------------------------------------------------------------\n\nfunction runChannelList(args: string[], deps: ChannelDeps): number {\n const { io, env } = deps;\n let json = false;\n try {\n const { values } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(CHANNEL_USAGE);\n return 0;\n }\n json = values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHANNEL_USAGE);\n return 2;\n }\n\n try {\n const paths = resolveChannelPaths(env);\n const store = new ChannelMapStore(paths);\n const records = store.list();\n const rows = records.map((record) => describeChannel(record, store));\n\n if (json) {\n io.emitJson({ command: 'channel list', channels: rows });\n return 0;\n }\n if (rows.length === 0) {\n io.out(\n 'No payment channels recorded — paid rig commands (push, issue, ' +\n 'comment, pr) record the channel they open on first use, and ' +\n '`rig channel open` records an explicit one.'\n );\n return 0;\n }\n io.out(\n `${rows.length} payment channel${rows.length === 1 ? '' : 's'} ` +\n `recorded in ${paths.mapPath}:`\n );\n for (const row of rows) {\n io.out('');\n for (const line of renderChannel(row)) io.out(line);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'channel list', err);\n }\n}\n\n/** Join one map record with its watermark state. */\nfunction describeChannel(\n record: ChannelMapRecord,\n store: ChannelMapStore\n): ChannelJson {\n const watermark: WatermarkEntry | undefined = store.readWatermark(\n record.channelId\n );\n return {\n channelId: record.channelId,\n peerId: record.peerId,\n identity: record.identity,\n destination: record.destination,\n chain: record.chain,\n tokenNetwork: record.tokenNetwork,\n depositTotal: record.depositTotal ?? null,\n cumulativeClaimed: watermark?.cumulativeAmount ?? null,\n nonce: watermark?.nonce ?? null,\n status: channelStatus(watermark),\n openedAt: record.openedAt,\n lastUsedAt: record.lastUsedAt,\n };\n}\n\nfunction renderChannel(row: ChannelJson): string[] {\n const claimed =\n row.cumulativeClaimed === null\n ? 'unknown (no local claim state)'\n : `${row.cumulativeClaimed} base units (nonce ${row.nonce})`;\n return [\n `channel ${row.channelId} [${row.status}]`,\n ` peer ${row.destination} (${row.peerId})`,\n ` identity ${row.identity.slice(0, 8)}…`,\n ` chain ${row.chain}` +\n (row.tokenNetwork ? ` token-network ${row.tokenNetwork}` : ''),\n ` deposited ${row.depositTotal ?? 'unrecorded'}` +\n (row.depositTotal ? ' base units' : ''),\n ` claimed ${claimed}`,\n ` opened ${row.openedAt} (last used ${row.lastUsedAt})`,\n ];\n}\n\n// ---------------------------------------------------------------------------\n// Shared money-command plumbing (#263)\n// ---------------------------------------------------------------------------\n\n/** Load the standalone context and require its money-ops surface. */\nasync function loadMoneyContext(\n deps: ChannelDeps,\n options?: { channelDestination?: string }\n): Promise<{ ctx: StandaloneContext; money: StandaloneMoneyOps }> {\n const ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => deps.io.err(line),\n ...(options?.channelDestination\n ? { channelDestination: options.channelDestination }\n : {}),\n });\n const money = ctx.money;\n if (!money) {\n await ctx.stop().catch(() => undefined);\n throw new Error(\n 'this standalone loader does not expose money operations — ' +\n 'channel open/close/settle need a loader with the money lifecycle'\n );\n }\n return { ctx, money };\n}\n\n/**\n * The push-idiom confirm gate for an ON-CHAIN money operation. Returns the\n * exit code to bail out with, or undefined to proceed. In `--json` mode\n * without `--yes` the caller emits its plan envelope (exit 0) — this gate\n * signals that with `'json-plan'`.\n */\nasync function confirmOnChain(\n io: CliIo,\n flags: { yes: boolean; json: boolean },\n question: string\n): Promise<'proceed' | 'json-plan' | number> {\n if (flags.yes) return 'proceed';\n if (flags.json) return 'json-plan';\n if (!io.isInteractive) {\n io.err(\n 'refusing to move on-chain funds without confirmation in a ' +\n 'non-interactive session — re-run with --yes (or use --json for a plan)'\n );\n return 1;\n }\n const proceed = await io.confirm(question);\n if (proceed) return 'proceed';\n io.err('aborted — no on-chain transaction was sent.');\n return 1;\n}\n\n/** Format a string-encoded unix-seconds timestamp for humans. */\nfunction formatUnixSeconds(value: string): string {\n const ms = Number(value) * 1000;\n return Number.isFinite(ms) ? new Date(ms).toISOString() : `t=${value}s`;\n}\n\n/** Whole seconds from now until a string-encoded unix-seconds timestamp. */\nfunction secondsUntil(value: string, nowSec: number): number {\n return Number(value) - nowSec;\n}\n\n// ---------------------------------------------------------------------------\n// open\n// ---------------------------------------------------------------------------\n\ninterface ChannelOpenJson {\n command: 'channel open';\n identity: IdentityReport;\n executed: boolean;\n plan: { destination: string | null; deposit: string | null };\n result?: {\n channelId: string;\n resumed: boolean;\n destination: string;\n chain: string | null;\n peerId: string | null;\n depositTotal: string | null;\n depositAdded: string | null;\n depositTxHash: string | null;\n };\n hint?: string;\n}\n\nasync function runChannelOpen(\n args: string[],\n deps: ChannelDeps\n): Promise<number> {\n const { io } = deps;\n let peer: string | undefined;\n let deposit: bigint | undefined;\n let yes = false;\n let json = false;\n try {\n const { values } = parseArgs({\n args,\n options: {\n peer: { type: 'string' },\n deposit: { type: 'string' },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(CHANNEL_USAGE);\n return 0;\n }\n peer = values.peer;\n yes = values.yes ?? false;\n json = values.json ?? false;\n if (values.deposit !== undefined) {\n if (!/^\\d+$/.test(values.deposit) || BigInt(values.deposit) <= 0n) {\n throw new Error(\n `--deposit must be a positive base-unit integer, got ${JSON.stringify(values.deposit)}`\n );\n }\n deposit = BigInt(values.deposit);\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHANNEL_USAGE);\n return 2;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n const loaded = await loadMoneyContext(deps, {\n ...(peer ? { channelDestination: peer } : {}),\n });\n ctx = loaded.ctx;\n const identity = identityReport(ctx);\n const plan = {\n destination: peer ?? null,\n deposit: deposit?.toString() ?? null,\n };\n\n if (!json) {\n io.out('Channel open plan:');\n io.out(` peer (ILP) ${peer ?? '(configured default destination)'}`);\n io.out(\n ` deposit ${deposit !== undefined ? `+${deposit} base units of extra collateral after the open/resume` : 'none beyond the peer-negotiated initial deposit'}`\n );\n io.out(renderIdentityLine(identity));\n io.out(\n 'If a live channel is already recorded for this peer it is RESUMED ' +\n '(no on-chain spend); otherwise an on-chain channel open locks the ' +\n 'peer-negotiated initial deposit from your wallet (plus gas).'\n );\n }\n\n const gate = await confirmOnChain(\n io,\n { yes, json },\n 'Proceed with on-chain channel open? [y/N] '\n );\n if (gate === 'json-plan') {\n io.emitJson({\n command: 'channel open',\n identity,\n executed: false,\n plan,\n hint: 'plan only — re-run with --yes to open (on-chain: locks collateral and spends gas)',\n } satisfies ChannelOpenJson);\n return 0;\n }\n if (gate !== 'proceed') return gate;\n\n const outcome = await loaded.money.openChannel(\n deposit !== undefined ? { deposit } : undefined\n );\n\n if (json) {\n io.emitJson({\n command: 'channel open',\n identity,\n executed: true,\n plan,\n result: {\n channelId: outcome.channelId,\n resumed: outcome.resumed,\n destination: outcome.destination,\n chain: outcome.chain ?? null,\n peerId: outcome.peerId ?? null,\n depositTotal: outcome.depositTotal ?? null,\n depositAdded: outcome.depositAdded ?? null,\n depositTxHash: outcome.depositTxHash ?? null,\n },\n } satisfies ChannelOpenJson);\n return 0;\n }\n io.out(\n outcome.resumed\n ? `Resumed recorded channel ${outcome.channelId} — no on-chain open was needed.`\n : `Opened channel ${outcome.channelId}${outcome.chain ? ` on ${outcome.chain}` : ''} and recorded it for reuse.`\n );\n io.out(` peer ${outcome.destination}${outcome.peerId ? ` (${outcome.peerId})` : ''}`);\n if (outcome.depositAdded) {\n io.out(\n ` deposited +${outcome.depositAdded} base units` +\n (outcome.depositTxHash ? ` (tx ${outcome.depositTxHash})` : '')\n );\n }\n if (outcome.depositTotal) {\n io.out(` collateral ${outcome.depositTotal} base units total on-chain`);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'channel open', err);\n } finally {\n await stopQuietly(ctx);\n }\n}\n\n// ---------------------------------------------------------------------------\n// close / settle (the two halves of withdraw)\n// ---------------------------------------------------------------------------\n\ninterface WithdrawJson {\n command: 'channel close' | 'channel settle';\n identity: IdentityReport;\n executed: boolean;\n channelId: string;\n result?: {\n txHash: string | null;\n closedAt?: string;\n settleableAt?: string;\n };\n hint?: string;\n}\n\n/**\n * Fail-fast local pre-checks from the recorded watermark timers — before any\n * identity resolution or client start (chain state stays authoritative: the\n * client re-checks before spending gas).\n */\nfunction withdrawPrecheck(\n step: 'close' | 'settle',\n channelId: string,\n watermark: WatermarkEntry | undefined,\n nowSec: number\n): string | undefined {\n const status = channelStatus(watermark, nowSec);\n if (status === 'settled') {\n return `channel ${channelId} is already settled — nothing left to ${step}.`;\n }\n if (step === 'close') {\n if (status === 'closing' || status === 'settleable') {\n const at = watermark?.settleableAt;\n return (\n `channel ${channelId} is already closing — ` +\n (status === 'settleable'\n ? 'its challenge window has elapsed; run `rig channel settle` to release the collateral.'\n : `settleable at ${at ? formatUnixSeconds(at) : 'the end of its challenge window'} (run \\`rig channel settle\\` then).`)\n );\n }\n return undefined;\n }\n // settle\n if (status === 'open') {\n return (\n `channel ${channelId} is not closed — run \\`rig channel close ${channelId}\\` ` +\n 'first (settle only releases collateral after the challenge window of a closed channel).'\n );\n }\n if (status === 'closing' && watermark?.settleableAt !== undefined) {\n const remain = secondsUntil(watermark.settleableAt, nowSec);\n return (\n `channel ${channelId} is not settleable yet — the challenge window is ` +\n `still open (${remain}s remain, settleable at ${formatUnixSeconds(watermark.settleableAt)}). ` +\n 'Nothing was spent; re-run after that time.'\n );\n }\n return undefined;\n}\n\nasync function runChannelWithdrawStep(\n args: string[],\n deps: ChannelDeps,\n step: 'close' | 'settle'\n): Promise<number> {\n const { io, env } = deps;\n const command = `channel ${step}` as WithdrawJson['command'];\n let channelId: string | undefined;\n let yes = false;\n let json = false;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) {\n io.out(CHANNEL_USAGE);\n return 0;\n }\n yes = values.yes ?? false;\n json = values.json ?? false;\n if (positionals.length !== 1) {\n throw new Error(\n `rig channel ${step} takes exactly one <channelId> (got ${positionals.length}) — \\`rig channel list\\` shows recorded channels`\n );\n }\n channelId = positionals[0] as string;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHANNEL_USAGE);\n return 2;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n // ── Local state: the recorded channel + its watermark (free, fail-fast) ──\n const store = new ChannelMapStore(resolveChannelPaths(env));\n const record = store.list().find((r) => r.channelId === channelId);\n if (!record) {\n throw new Error(\n `no recorded channel ${JSON.stringify(channelId)} — \\`rig channel list\\` shows the channels this identity holds`\n );\n }\n const watermark = store.readWatermark(channelId);\n const nowSec = Math.floor(Date.now() / 1000);\n const refusal = withdrawPrecheck(step, channelId, watermark, nowSec);\n if (refusal) throw new Error(refusal);\n\n // ── Identity (must match the channel's opener — its claims/keys) ────────\n const loaded = await loadMoneyContext(deps);\n ctx = loaded.ctx;\n const identity = identityReport(ctx);\n if (record.identity !== identity.pubkey) {\n throw new Error(\n `channel ${channelId} was opened by identity ${record.identity.slice(0, 8)}… ` +\n `but the active identity is ${identity.pubkey.slice(0, 8)}… ` +\n `(from ${identity.sourceLabel}) — on-chain ${step} must be signed by ` +\n \"the opener's wallet key. Switch RIG_MNEMONIC (or the keystore) to that identity.\"\n );\n }\n\n // ── Plan + confirm gate ──────────────────────────────────────────────────\n if (!json) {\n const claimed = watermark?.cumulativeAmount;\n io.out(`Channel ${step} plan:`);\n io.out(` channel ${channelId} [${channelStatus(watermark, nowSec)}]`);\n io.out(` peer ${record.destination} (${record.peerId})`);\n io.out(` chain ${record.chain}`);\n io.out(\n ` deposited ${record.depositTotal ?? 'unrecorded'}` +\n (claimed !== undefined ? ` claimed ${claimed} base units` : '')\n );\n io.out(renderIdentityLine(identity));\n if (step === 'close') {\n io.out(\n 'Closing is an ON-CHAIN transaction (gas) that starts the settlement ' +\n 'challenge window: the channel stops paying immediately, and the ' +\n 'remaining collateral stays locked until `rig channel settle` ' +\n 'succeeds after the window elapses.'\n );\n } else {\n io.out(\n 'Settling is an ON-CHAIN transaction (gas) that releases the ' +\n \"remaining collateral back to your wallet. The chain's challenge \" +\n 'window is authoritative — a too-early settle is refused before ' +\n 'any gas is spent.'\n );\n }\n }\n const gate = await confirmOnChain(\n io,\n { yes, json },\n `Proceed with on-chain channel ${step}? [y/N] `\n );\n if (gate === 'json-plan') {\n io.emitJson({\n command,\n identity,\n executed: false,\n channelId,\n hint: `plan only — re-run with --yes to ${step} (on-chain transaction)`,\n } satisfies WithdrawJson);\n return 0;\n }\n if (gate !== 'proceed') return gate;\n\n // ── Execute ──────────────────────────────────────────────────────────────\n if (step === 'close') {\n const result = await loaded.money.closeChannel(record);\n if (json) {\n io.emitJson({\n command,\n identity,\n executed: true,\n channelId,\n result: {\n txHash: result.txHash ?? null,\n closedAt: result.closedAt,\n settleableAt: result.settleableAt,\n },\n } satisfies WithdrawJson);\n return 0;\n }\n io.out(\n `Channel ${channelId} is closing` +\n (result.txHash ? ` (tx ${result.txHash})` : '') +\n '.'\n );\n io.out(\n ` challenge window: settleable at ${formatUnixSeconds(result.settleableAt)} ` +\n `(~${Math.max(0, secondsUntil(result.settleableAt, nowSec))}s from now)`\n );\n io.out(\n ` run \\`rig channel settle ${channelId}\\` after that time to release the collateral.`\n );\n return 0;\n }\n\n const result = await loaded.money.settleChannel(record);\n if (json) {\n io.emitJson({\n command,\n identity,\n executed: true,\n channelId,\n result: { txHash: result.txHash ?? null },\n } satisfies WithdrawJson);\n return 0;\n }\n io.out(\n `Channel ${channelId} settled` +\n (result.txHash ? ` (tx ${result.txHash})` : '') +\n ' — the remaining collateral was released to your wallet.'\n );\n return 0;\n } catch (err) {\n return emitCliError(io, json, command, err);\n } finally {\n await stopQuietly(ctx);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Small shared helpers\n// ---------------------------------------------------------------------------\n\nasync function stopQuietly(ctx: StandaloneContext | undefined): Promise<void> {\n if (!ctx) return;\n try {\n await ctx.stop();\n } catch {\n // best-effort teardown\n }\n}\n","/**\n * `rig clone` (#278) — bootstrap a repository from TOON, no payments anywhere:\n *\n * rig clone <relay-url> <owner-npub-or-hex>/<repo-id> [dir]\n *\n * Pipeline: fetch kind:30617/30618 from the relay (../remote-state.ts) →\n * download every object the refs need from Arweave gateways with SHA-1\n * verification (../read-pipeline.ts) → materialize a REAL git repository via\n * git plumbing (../materialize.ts): `git hash-object -w --stdin -t <type>`\n * per object (written SHA re-checked), `git update-ref` per ref, HEAD from\n * the 30618 symref, worktree checkout. The clone is immediately push/pull\n * capable: toon.repoid/toon.owner are configured and the relay is added as\n * the `origin` remote.\n *\n * ATOMICITY: everything lands in a temp dir next to the destination and is\n * renamed into place only on full success — a failed clone never leaves a\n * partial/corrupt repository. Missing objects (Arweave propagation lag) are\n * an honest error listing the SHAs; corrupt objects are an integrity error.\n */\n\nimport { mkdtemp, mkdir, readdir, rename, rm, rmdir } from 'node:fs/promises';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport {\n setHeadSymref,\n isSafeRefname,\n runGit,\n updateRef,\n writeGitObjects,\n} from '../materialize.js';\nimport { npubToHex, ownerToHex } from '../npub.js';\nimport {\n collectRepoObjects,\n missingObjectsMessage,\n type MissingObject,\n} from '../read-pipeline.js';\nimport { fetchRemoteState, type RemoteState } from '../remote-state.js';\nimport { emitCliError } from './errors.js';\nimport type { ReadCommandDeps } from './read-seams.js';\n\nexport const CLONE_USAGE = `Usage: rig clone <relay-url> <owner>/<repo-id> [dir] [options]\n\nClone a TOON repository — FREE (relay reads + Arweave gateway downloads; no\npayments, no channel, no identity needed). <relay-url> is a ws:// or wss://\nNIP-01 relay; <owner> is the repo owner's pubkey as npub1… or 64-char hex;\n[dir] defaults to <repo-id>.\n\nFetches the kind:30617/30618 repository state, downloads every git object\nthe refs need from Arweave gateways (SHA-1 verified — corrupt content is\nrejected), and materializes a real git repository: objects via git plumbing,\nrefs, HEAD, checked-out worktree, toon.* config, and the relay preconfigured\nas the \"origin\" remote — so \\`rig fetch\\`, \\`rig push\\`, and the issue/pr\ncommands work immediately.\n\nNote: recently pushed objects can take 10-20 minutes to become fetchable\nfrom Arweave gateways. A clone right after a push may report missing\nobjects — retry after propagation.\n\nOptions:\n --concurrency <n> parallel gateway downloads (default 8)\n --json machine-readable result envelope\n -h, --help show this help`;\n\n/** Repo has no announcement AND no state on the relay. */\nexport class RepoNotFoundError extends Error {\n constructor(relay: string, owner: string, repoId: string) {\n super(\n `repository 30617:${owner}:${repoId} not found on ${relay} — ` +\n 'no kind:30617 announcement or kind:30618 state event exists there. ' +\n 'Check the relay URL, the owner pubkey (npub or hex), and the repo id.'\n );\n this.name = 'RepoNotFoundError';\n }\n}\n\n/** Reachable objects could not be downloaded (Arweave propagation lag). */\nexport class MissingRemoteObjectsError extends Error {\n constructor(\n public readonly missing: MissingObject[],\n context: string\n ) {\n super(missingObjectsMessage(missing, context));\n this.name = 'MissingRemoteObjectsError';\n }\n}\n\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\ninterface CloneArgs {\n relayUrl: string;\n owner: string;\n repoId: string;\n dir: string | undefined;\n concurrency: number | undefined;\n json: boolean;\n}\n\nfunction parseCloneArgs(args: string[]): CloneArgs | { help: true } {\n const { values, positionals } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n concurrency: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) return { help: true };\n if (positionals.length < 2 || positionals.length > 3) {\n throw new Error('expected: rig clone <relay-url> <owner>/<repo-id> [dir]');\n }\n const [relayUrl, addr, dir] = positionals as [string, string, string?];\n if (!WS_URL_RE.test(relayUrl)) {\n throw new Error(\n `<relay-url> must be ws:// or wss:// (got ${JSON.stringify(relayUrl)})`\n );\n }\n const slash = addr.indexOf('/');\n if (slash <= 0 || slash === addr.length - 1) {\n throw new Error(\n `expected <owner>/<repo-id> (npub or 64-char hex owner), got ${JSON.stringify(addr)}`\n );\n }\n const owner = ownerToHex(addr.slice(0, slash));\n const repoId = addr.slice(slash + 1);\n let concurrency: number | undefined;\n if (values.concurrency !== undefined) {\n concurrency = Number.parseInt(values.concurrency, 10);\n if (!Number.isSafeInteger(concurrency) || concurrency < 1) {\n throw new Error(`--concurrency must be a positive integer`);\n }\n }\n return {\n relayUrl,\n owner,\n repoId,\n dir,\n concurrency,\n json: values.json === true,\n };\n}\n\n/** True when `dir` does not exist or is an empty directory. */\nasync function isUsableDestination(dir: string): Promise<boolean> {\n try {\n const entries = await readdir(dir);\n return entries.length === 0;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'ENOENT';\n }\n}\n\n/** Pick the branch `git init --initial-branch` should use. */\nfunction initialBranch(headSymref: string | null): string {\n if (headSymref?.startsWith('refs/heads/')) {\n const name = headSymref.slice('refs/heads/'.length);\n if (name && isSafeRefname(headSymref)) return name;\n }\n return 'main';\n}\n\n/** Run `rig clone …`; returns the process exit code. */\nexport async function runClone(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let parsed: CloneArgs;\n try {\n const result = parseCloneArgs(args);\n if ('help' in result) {\n io.out(CLONE_USAGE);\n return 0;\n }\n parsed = result;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CLONE_USAGE);\n return 2;\n }\n\n const { relayUrl, owner, repoId, json } = parsed;\n const dest = resolve(deps.cwd, parsed.dir ?? repoId);\n let tempDir: string | undefined;\n\n try {\n if (!(await isUsableDestination(dest))) {\n throw new Error(\n `destination path ${JSON.stringify(dest)} already exists and is not an empty directory`\n );\n }\n\n if (!json) io.out(`Cloning into '${basename(dest)}'...`);\n\n // ── Remote state (kind:30617 + 30618) ───────────────────────────────────\n const remoteState: RemoteState = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: owner,\n repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n ...(deps.resolveSha ? { resolveSha: deps.resolveSha } : {}),\n });\n if (!remoteState.announced && remoteState.refsEvent === null) {\n throw new RepoNotFoundError(relayUrl, owner, repoId);\n }\n\n // Refs from the 30618, filtered through the hostile-relay refname gate.\n const refs = new Map<string, string>();\n for (const [refname, sha] of remoteState.refs) {\n if (!isSafeRefname(refname)) {\n io.err(\n `warning: skipping unsafe ref name from relay: ${JSON.stringify(refname)}`\n );\n continue;\n }\n refs.set(refname, sha);\n }\n if (refs.size === 0) {\n io.err(\n 'warning: the repository has no refs yet (announced but never pushed) — ' +\n 'cloning an empty repository'\n );\n }\n\n // ── Download + verify the object closure (FREE) ─────────────────────────\n const tips = [...new Set(refs.values())];\n const collected = await collectRepoObjects({\n tips,\n shaToTxId: remoteState.shaToTxId,\n resolveMissing: (shas) => remoteState.resolveMissing(shas),\n ...(deps.fetchFn ? { fetchFn: deps.fetchFn } : {}),\n ...(parsed.concurrency !== undefined\n ? { concurrency: parsed.concurrency }\n : {}),\n });\n if (collected.missing.length > 0) {\n throw new MissingRemoteObjectsError(\n collected.missing,\n `cannot clone ${owner.slice(0, 8)}…/${repoId}`\n );\n }\n for (const { sha, txId } of collected.skippedUnavailable) {\n io.err(\n `warning: unreachable object ${sha} (tx ${txId}) could not be downloaded — ` +\n 'not needed by any ref, continuing'\n );\n }\n\n // ── Materialize into a temp dir, move into place on success ────────────\n const parent = dirname(dest);\n await mkdir(parent, { recursive: true });\n tempDir = await mkdtemp(join(parent, `.${basename(dest)}.rig-clone-`));\n\n await runGit(tempDir, [\n 'init',\n '--quiet',\n `--initial-branch=${initialBranch(remoteState.headSymref)}`,\n ]);\n const written = await writeGitObjects(tempDir, collected.objects.values());\n for (const [refname, sha] of refs) {\n await updateRef(tempDir, refname, sha);\n // Remote-tracking refs, exactly like `git clone` — so `rig fetch`\n // reports honest deltas and `rig merge origin/<branch>` works.\n if (refname.startsWith('refs/heads/')) {\n const branch = refname.slice('refs/heads/'.length);\n await updateRef(tempDir, `refs/remotes/origin/${branch}`, sha);\n }\n }\n const head =\n remoteState.headSymref !== null &&\n isSafeRefname(remoteState.headSymref) &&\n refs.has(remoteState.headSymref)\n ? remoteState.headSymref\n : ([...refs.keys()].find((r) => r.startsWith('refs/heads/')) ?? null);\n if (head !== null) {\n await setHeadSymref(tempDir, head);\n await runGit(tempDir, ['reset', '--hard', '--quiet']);\n }\n\n // toon.* config + origin remote: immediately push/pull-capable.\n await runGit(tempDir, ['config', 'toon.repoid', repoId]);\n await runGit(tempDir, ['config', 'toon.owner', owner]);\n await runGit(tempDir, ['remote', 'add', 'origin', relayUrl]);\n if (head !== null) {\n // Upstream config for the checked-out branch, like `git clone`.\n const branch = head.slice('refs/heads/'.length);\n await runGit(tempDir, ['config', `branch.${branch}.remote`, 'origin']);\n await runGit(tempDir, ['config', `branch.${branch}.merge`, head]);\n }\n\n // Atomic move into place (destination may exist as an empty directory).\n try {\n await rmdir(dest);\n } catch {\n // ENOENT — the destination does not exist yet; rename creates it.\n }\n await rename(tempDir, dest);\n tempDir = undefined;\n\n // ── Report ──────────────────────────────────────────────────────────────\n if (json) {\n io.emitJson({\n command: 'clone',\n repoAddr: { ownerPubkey: owner, repoId },\n relay: relayUrl,\n directory: dest,\n head,\n refs: Object.fromEntries(refs),\n name: remoteState.name,\n objectsDownloaded: written,\n executed: true,\n });\n } else {\n io.out(`Downloaded ${written} object(s) from Arweave (SHA-1 verified).`);\n for (const [refname, sha] of refs) {\n io.out(` ${sha.slice(0, 7)} ${refname}`);\n }\n if (head !== null) io.out(`HEAD is now at ${head}`);\n io.out(\n `Configured toon.repoid=${repoId}, toon.owner=${owner.slice(0, 8)}…, ` +\n `origin → ${relayUrl}`\n );\n io.out('Done.');\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'clone', err);\n } finally {\n if (tempDir !== undefined) {\n await rm(tempDir, { recursive: true, force: true }).catch(\n () => undefined\n );\n }\n }\n}\n\n// Re-exported for the acceptance flow + tests (owner column rendering).\nexport { npubToHex };\n","/**\n * The single-event `rig` subcommands (#231): issue / comment / pr, where\n * `pr` nests `create` and `status` (#250 moved the NIP-34 status publish\n * from top-level `rig status` to `rig pr status` — bare `rig status` now\n * passes through to `git status`).\n *\n * One shared pipeline behind four thin arg-parsers, mirroring `rig push`\n * (./push.ts) exactly: repo addressing from the `toon.*` git config keys\n * `rig init` writes (`--repo-id`/`--owner` override; actionable \"run\n * `rig init`\" error when unconfigured), a fee-quoting confirm gate (`--yes`\n * skips; a non-TTY session without it refuses; `--json` without `--yes` is a\n * pure estimate), and two transports (#279, ./daemon-session.ts):\n *\n * standalone (default + guarantee) — build the NIP-34 event locally\n * (../nip34-events.ts — the same builders the toon-clientd daemon uses)\n * and pay-to-publish through the embedded, nonce-guarded\n * StandalonePublisher;\n * daemon (automatic fast path) — when a running toon-clientd holds the\n * SAME identity, delegate to its loopback POST\n * /git/issue|comment|patch|status route instead: the daemon builds,\n * signs, and pays from its warm bootstrap, and it owns the channel\n * watermark (the safety goal the old refusal protected). NOTE: the\n * single-event daemon routes publish via the daemon's own configured\n * relay route — a resolved relay that differs from it draws a warning.\n *\n * The relay resolves like `rig push` (#249): `--remote <name>`\n * (default: the `origin` git remote), `--relay <url>` as an ad-hoc override\n * that bypasses remotes, deprecated `git config toon.relay` as a nudged\n * fallback. Publishes go to a SINGLE relay; multiple configured relays and\n * multi-URL remotes are refused before anything is paid (same guard as push).\n *\n * `rig pr create --range` runs REAL `git format-patch --stdout <range>` in\n * the local repository and publishes its output as the kind:1617 content —\n * one event for the whole series (cover-letter threading is out of scope in\n * v1; see the usage text).\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { parseArgs } from 'node:util';\nimport {\n REPOSITORY_ANNOUNCEMENT_KIND,\n STATUS_APPLIED_KIND,\n STATUS_CLOSED_KIND,\n STATUS_DRAFT_KIND,\n STATUS_OPEN_KIND,\n} from '@toon-protocol/core/nip34';\nimport {\n authorizedStatusAuthors,\n buildComment,\n buildIssue,\n buildPatch,\n buildStatus,\n type StatusKind,\n type UnsignedEvent,\n} from '../nip34-events.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport {\n serializeEventReceipt,\n type GitEventResponse,\n type GitRepoAddr,\n type GitStatusValue,\n} from '../routes.js';\nimport {\n type DaemonGitClient,\n type SessionPath,\n} from './daemon-session.js';\nimport { emitCliError, UnconfiguredRepoAddressError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot, type ToonRepoConfig } from './git-config.js';\nimport {\n identityReport,\n loadPaidSession,\n withForcedStandalone,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport type { ReadSeams } from './read-seams.js';\nimport { resolveRelays, singleRelayRefusal } from './remote.js';\nimport { feeLabel, renderEventPlan, renderEventReceipt } from './render.js';\nimport type { StandaloneContext } from './standalone-context.js';\nimport {\n ISSUE_LIST_USAGE,\n ISSUE_SHOW_USAGE,\n PR_LIST_USAGE,\n PR_SHOW_USAGE,\n runIssueList,\n runIssueShow,\n runPrList,\n runPrShow,\n} from './tracker.js';\n\n// ---------------------------------------------------------------------------\n// Deps\n// ---------------------------------------------------------------------------\n\n/**\n * Push deps plus a stdin reader (issue-body fallback) and the #278 read-path\n * seams (relay WebSocket / gateway fetch / SHA resolver — used by the FREE\n * `issue list|show` and `pr list|show` subcommands); tests inject all.\n */\nexport interface EventCommandDeps extends PushDeps, ReadSeams {\n /** Read all of stdin as UTF-8 (default: the real process stdin). */\n readStdin?: () => Promise<string>;\n}\n\nconst defaultReadStdin = async (): Promise<string> => {\n // Never block waiting for keyboard input (e.g. stdout piped but stdin a\n // TTY): an interactive stdin yields no body, which surfaces as the clear\n // \"body is empty\" error instead of a hang.\n if (process.stdin.isTTY) return '';\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf-8');\n};\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\n/** Flags every single-event subcommand shares (mirrors `rig push`). */\nconst COMMON_FLAGS_USAGE = ` --repo-id <id> repository id / NIP-34 d-tag (default: git config\n toon.repoid — run \\`rig init\\` to set it)\n --owner <pubkey> repository owner pubkey, 64-char hex (default: git config\n toon.owner, then the active identity)\n --remote <name> publish via this configured git remote (default: the\n \"origin\" remote — \\`rig remote add origin <relay-url>\\`)\n --relay <url> ad-hoc relay override (exactly one) — bypasses the\n configured remotes. The deprecated v0.1 \\`git config\n toon.relay\\` still works as a fallback, with a nudge\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable receipt; without --yes it is a pure\n estimate (nothing published, exit 0)\n --standalone always run embedded, bypassing a running toon-clientd\n (alias: --no-daemon; same as RIG_STANDALONE=1)\n -h, --help show this help`;\n\nexport const ISSUE_USAGE = `Usage: rig issue create --title <title> [options]\n\nFile an issue (kind:1621) against a TOON repo — a paid publish; writes are\npermanent and non-refundable. The repo address (30617:<owner>:<repoId>) comes\nfrom the toon.* git config keys \\`rig init\\` writes.\n\nBody source (exactly one): --body, --body-file, or piped stdin.\n\nOptions:\n --title <title> issue title (subject tag) [required]\n --body <text> issue body (Markdown)\n --body-file <path> read the issue body from a file\n --label <label> label (t tag); repeatable\n${COMMON_FLAGS_USAGE}\n\nRelated (FREE reads — no payment):\n rig issue list [--state open|closed|all] list the repo's issues\n rig issue show <event-id> one issue + its comments`;\n\nexport const COMMENT_USAGE = `Usage: rig comment <root-event-id> --body <text> [options]\n\nComment (kind:1622) on an issue or patch — a paid publish; writes are\npermanent and non-refundable. <root-event-id> is the 64-char hex id of the\nkind:1621 issue / kind:1617 patch being commented on.\n\nOptions:\n --body <text> comment body (Markdown) [required]\n --parent-author <pubkey> pubkey of the TARGET event's author (p threading\n tag; default: the repo owner)\n --marker <root|reply> e-tag marker (default: root — commenting directly\n on the issue/patch)\n${COMMON_FLAGS_USAGE}`;\n\nexport const PR_CREATE_USAGE = `Usage: rig pr create --title <title> (--range <range> | --patch-file <path>) [options]\n\nPublish a patch (kind:1617) whose content is REAL \\`git format-patch\\` output —\na paid publish; writes are permanent and non-refundable. --range runs\n\\`git format-patch --stdout <range>\\` in the local repository and derives the\ncommit/parent-commit tags; --patch-file publishes a pre-generated patch\nverbatim. A multi-commit range publishes ONE kind:1617 event carrying the\nfull series text — cover-letter threading (one event per commit) is out of\nscope in v1.\n\nThe PR body (--body/--body-file) is carried in a dedicated \\`description\\`\ntag, not in the event content — the content stays pure format-patch output so\n\\`rig pr show … | git am\\` keeps working.\n\nOptions:\n --title <title> patch/PR title (subject tag) [required]\n --range <range> revision range for format-patch: <rev>, <rev>..<rev>,\n or <rev>...<rev> (mutually exclusive with --patch-file)\n --patch-file <path> literal patch text to publish\n --body <text> PR description (Markdown; description tag)\n --body-file <path> read the PR description from a file\n --branch <name> branch name (t tag)\n${COMMON_FLAGS_USAGE}`;\n\nexport const PR_STATUS_USAGE = `Usage: rig pr status <target-event-id> <open|applied|closed|draft> [options]\n\nSet the status of an issue or patch — a paid publish; writes are permanent\nand non-refundable. Publishes kind:1630 (open), 1631 (applied), 1632\n(closed), or 1633 (draft) against the 64-char hex id of the target event,\nwith the repo a-tag attached so readers can scope a status stream to the\nrepository. (This command was \\`rig status\\` before v2 — bare \\`rig status\\`\nnow passes through to \\`git status\\`.)\n\nOptions:\n${COMMON_FLAGS_USAGE}`;\n\nexport const PR_USAGE = `${PR_CREATE_USAGE}\n\n${PR_STATUS_USAGE}\n\n${PR_LIST_USAGE}\n\n${PR_SHOW_USAGE}`;\n\n// ---------------------------------------------------------------------------\n// Shared flag parsing\n// ---------------------------------------------------------------------------\n\nconst HEX64_RE = /^[0-9a-f]{64}$/;\n\nfunction assertHex64(value: string, what: string): void {\n if (!HEX64_RE.test(value)) {\n throw new Error(\n `${what} must be a 64-char lowercase hex id (got ${JSON.stringify(value)})`\n );\n }\n}\n\n/** parseArgs options every subcommand accepts (mirrors `rig push`). */\nconst COMMON_OPTIONS = {\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n relay: { type: 'string', multiple: true },\n remote: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n standalone: { type: 'boolean', default: false },\n 'no-daemon': { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n} as const;\n\ninterface CommonFlags {\n yes: boolean;\n json: boolean;\n relay: string[];\n remote?: string;\n repoId?: string;\n owner?: string;\n /** Force embedded standalone, bypassing the daemon (--standalone/--no-daemon). */\n standalone: boolean;\n help: boolean;\n}\n\nfunction pickCommon(values: Record<string, unknown>): CommonFlags {\n const flags: CommonFlags = {\n yes: values['yes'] === true,\n json: values['json'] === true,\n relay: Array.isArray(values['relay']) ? (values['relay'] as string[]) : [],\n standalone: values['standalone'] === true || values['no-daemon'] === true,\n help: values['help'] === true,\n };\n const remote = values['remote'];\n if (typeof remote === 'string') flags.remote = remote;\n const repoId = values['repo-id'];\n if (typeof repoId === 'string') flags.repoId = repoId;\n const owner = values['owner'];\n if (typeof owner === 'string') {\n assertHex64(owner, '--owner');\n flags.owner = owner;\n }\n return flags;\n}\n\n// ---------------------------------------------------------------------------\n// Shared publish pipeline\n// ---------------------------------------------------------------------------\n\ntype EventCommand = 'issue' | 'comment' | 'pr' | 'pr status';\n\ninterface RunEventOptions {\n command: EventCommand;\n flags: CommonFlags;\n deps: EventCommandDeps;\n /** Human action label WITHOUT the kind, e.g. `issue \"Fix the flux\"`. */\n actionLabel: string;\n /**\n * Build the unsigned NIP-34 event for the resolved repo address — the\n * publish payload, and the source of truth for the kind. May do real work\n * (pr runs format-patch here), so failures land in the normal error path.\n * ALWAYS called (both paths) — the kind drives rendering, and the daemon\n * path reuses locally-derived values (e.g. the format-patch output).\n */\n buildEvent: (addr: GitRepoAddr) => Promise<UnsignedEvent>;\n /**\n * Drive the matching daemon `/git/*` route (#279 delegated fast path).\n * Called only after the same-identity check and the confirm gate.\n */\n sendDaemon: (\n client: DaemonGitClient,\n addr: GitRepoAddr\n ) => Promise<GitEventResponse>;\n /**\n * Optional pre-confirm hook (#287): runs AFTER the identity + repo address\n * are resolved and the event is built, but BEFORE the plan is rendered and\n * the confirm gate. Used by `pr status` to WARN when the active identity is\n * not an authorized maintainer of the target repo (the write is still\n * allowed — the relay is permissionless — but clients honoring repo\n * authority will ignore it). Failures here must be non-fatal: emit a soft\n * note and proceed. The warning prints to stderr so the existing confirm\n * gate (or --yes) still governs whether money moves.\n */\n preConfirm?: (args: {\n identity: IdentityReport;\n addr: GitRepoAddr;\n relayUrl: string | undefined;\n }) => Promise<void>;\n}\n\n/** JSON envelope emitted by `--json` runs (agents consume this). */\ninterface EventJsonOutput {\n command: EventCommand;\n repoAddr: GitRepoAddr;\n /** Which transport paid: delegated daemon or embedded standalone (#279). */\n path: SessionPath;\n /** Active identity: source tier + derived pubkey (never the phrase). */\n identity: IdentityReport;\n /** NIP-34 kind this command publishes. */\n kind: number;\n /** True when the paid publish ran. */\n executed: boolean;\n /** Per-event fee (base units, decimal string). */\n feeEstimate: string | null;\n result?: GitEventResponse;\n hint?: string;\n}\n\n/**\n * The estimate → confirm → execute flow shared by all four subcommands.\n * Money moves only after the confirm gate and the single-relay guard.\n */\nasync function runEvent(opts: RunEventOptions): Promise<number> {\n const { command, flags, actionLabel } = opts;\n // --standalone/--no-daemon: force embedded for this invocation (same as\n // RIG_STANDALONE=1). Every paid path reads the override from `env`.\n const deps = flags.standalone\n ? withForcedStandalone(opts.deps)\n : opts.deps;\n const { io } = deps;\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n // ── Repo addressing (best-effort git config; flags can stand alone) ─────\n let repoRoot: string | undefined;\n let toonConfig: ToonRepoConfig = { relays: [] };\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n toonConfig = await readToonConfig(repoRoot);\n } catch {\n // Not inside a git repository — --repo-id/--owner must carry the address.\n }\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n\n // ── Relay resolution (#249: --relay > --remote > origin > toon.relay) ───\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: flags.remote,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) io.err(resolved.nudge);\n const relaysUsed = resolved.relays;\n // Same pre-pay guard as push: StandalonePublisher publishes to exactly\n // one relay, and multiple can arrive without explicit intent (repeated\n // --relay flags, an old multi-valued git config `toon.relay`). Refuse\n // before anything is paid.\n if (relaysUsed.length > 1) {\n io.err(singleRelayRefusal(resolved, 'Nothing was published or paid.'));\n return 1;\n }\n\n // ── Paid session (#279): same-identity daemon → delegate; else the\n // standalone context (identity chain + nonce guard) + per-event fee.\n const session = await loadPaidSession(deps, relaysUsed[0]);\n const path = session.path;\n let identity: IdentityReport;\n let fee: string | undefined;\n if (session.path === 'standalone') {\n standaloneCtx = session.ctx;\n identity = identityReport(standaloneCtx);\n fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();\n } else {\n identity = session.identity;\n fee = session.feePerEvent;\n // The single-event /git/* routes publish via the daemon's own\n // configured relay route (no relayUrls field on the wire) — surface a\n // mismatch instead of silently ignoring the resolved relay.\n const resolvedRelay = relaysUsed[0];\n if (\n resolvedRelay !== undefined &&\n session.daemonRelayUrl !== undefined &&\n session.daemonRelayUrl !== resolvedRelay\n ) {\n io.err(\n `rig: the daemon publishes via its configured relay ` +\n `(${session.daemonRelayUrl}), not the resolved relay ` +\n `(${resolvedRelay}) — stop the daemon to force the standalone ` +\n 'path if that matters'\n );\n }\n }\n\n const owner = flags.owner ?? toonConfig.owner ?? identity.pubkey;\n const addr: GitRepoAddr = { ownerPubkey: owner, repoId };\n\n // Built once: the publish payload AND the kind for rendering.\n const event = await opts.buildEvent(addr);\n const action = `kind:${event.kind} ${actionLabel}`;\n\n // ── Authority pre-check (#287) — warn (do not block) before the gate ────\n if (opts.preConfirm) {\n await opts.preConfirm({ identity, addr, relayUrl: relaysUsed[0] });\n }\n\n // ── Confirm gate (identical semantics to `rig push`) ────────────────────\n if (!flags.json) {\n for (const line of renderEventPlan({\n action,\n addr,\n identity,\n ...(fee !== undefined ? { fee } : {}),\n })) {\n io.out(line);\n }\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: addr,\n path,\n identity,\n kind: event.kind,\n executed: false,\n feeEstimate: fee ?? null,\n hint: 'estimate only — re-run with --yes to publish (permanent, non-refundable)',\n } satisfies EventJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid publish (${feeLabel(fee)})? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was published.');\n return 1;\n }\n }\n\n // ── Execute ─────────────────────────────────────────────────────────────\n let result: GitEventResponse;\n if (session.path === 'standalone') {\n const receipt = await session.ctx.publisher.publishEvent(\n event,\n relaysUsed\n );\n result = serializeEventReceipt(event.kind, receipt);\n } else {\n result = await opts.sendDaemon(session.client, addr);\n }\n\n // ── Receipts ────────────────────────────────────────────────────────────\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: addr,\n path,\n identity,\n kind: result.kind,\n executed: true,\n feeEstimate: fee ?? null,\n result,\n } satisfies EventJsonOutput);\n } else {\n for (const line of renderEventReceipt(action, result)) io.out(line);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, command, err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// rig issue create\n// ---------------------------------------------------------------------------\n\n/** Run `rig issue …`; returns the process exit code. */\nexport async function runIssue(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n if (sub === '--help' || sub === '-h' || sub === 'help') {\n io.out(ISSUE_USAGE);\n io.out('');\n io.out(ISSUE_LIST_USAGE);\n io.out('');\n io.out(ISSUE_SHOW_USAGE);\n return 0;\n }\n // FREE read subcommands (#278): relay queries only, no payment path.\n if (sub === 'list') return runIssueList(rest, deps);\n if (sub === 'show') return runIssueShow(rest, deps);\n if (sub !== 'create') {\n io.err(\n sub === undefined\n ? 'missing subcommand: rig issue <create|list|show>'\n : `unknown rig issue subcommand: ${sub}`\n );\n io.err(ISSUE_USAGE);\n return 2;\n }\n\n let flags: CommonFlags;\n let title: string;\n let bodyFlag: string | undefined;\n let bodyFile: string | undefined;\n let labels: string[];\n try {\n const { values } = parseArgs({\n args: rest,\n options: {\n ...COMMON_OPTIONS,\n title: { type: 'string' },\n body: { type: 'string' },\n 'body-file': { type: 'string' },\n label: { type: 'string', multiple: true },\n },\n allowPositionals: false,\n });\n flags = pickCommon(values);\n if (!flags.help && (values.title === undefined || values.title === '')) {\n throw new Error('--title is required');\n }\n if (values.body !== undefined && values['body-file'] !== undefined) {\n throw new Error('--body and --body-file are mutually exclusive');\n }\n title = values.title ?? '';\n bodyFlag = values.body;\n bodyFile = values['body-file'];\n labels = values.label ?? [];\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(ISSUE_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(ISSUE_USAGE);\n return 0;\n }\n\n // Body source: --body → --body-file → piped stdin.\n let body: string;\n if (bodyFlag !== undefined) {\n body = bodyFlag;\n } else if (bodyFile !== undefined) {\n try {\n body = await readFile(bodyFile, 'utf-8');\n } catch (err) {\n io.err(\n `cannot read --body-file ${bodyFile}: ${err instanceof Error ? err.message : String(err)}`\n );\n return 2;\n }\n } else if (!io.isInteractive) {\n body = await (deps.readStdin ?? defaultReadStdin)();\n } else {\n io.err('an issue body is required: pass --body/--body-file or pipe stdin');\n io.err(ISSUE_USAGE);\n return 2;\n }\n if (body.trim() === '') {\n io.err('the issue body is empty — nothing to publish');\n return 2;\n }\n\n return runEvent({\n command: 'issue',\n flags,\n deps,\n actionLabel: `issue ${JSON.stringify(title)}`,\n buildEvent: async (addr) =>\n buildIssue(addr.ownerPubkey, addr.repoId, title, body, labels),\n sendDaemon: (client, addr) =>\n client.gitIssue({\n repoAddr: addr,\n title,\n body,\n ...(labels.length > 0 ? { labels } : {}),\n }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// rig comment\n// ---------------------------------------------------------------------------\n\n/** Run `rig comment …`; returns the process exit code. */\nexport async function runComment(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let flags: CommonFlags;\n let rootEventId: string;\n let body: string;\n let parentAuthor: string | undefined;\n let marker: 'root' | 'reply';\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n ...COMMON_OPTIONS,\n body: { type: 'string' },\n 'parent-author': { type: 'string' },\n marker: { type: 'string' },\n },\n allowPositionals: true,\n });\n flags = pickCommon(values);\n if (flags.help) {\n io.out(COMMENT_USAGE);\n return 0;\n }\n if (positionals.length !== 1) {\n throw new Error(\n positionals.length === 0\n ? '<root-event-id> is required'\n : `expected exactly one <root-event-id>, got ${positionals.length} positionals`\n );\n }\n rootEventId = positionals[0] as string;\n assertHex64(rootEventId, '<root-event-id>');\n if (values.body === undefined || values.body === '') {\n throw new Error('--body is required');\n }\n body = values.body;\n parentAuthor = values['parent-author'];\n if (parentAuthor !== undefined) assertHex64(parentAuthor, '--parent-author');\n const rawMarker = values.marker ?? 'root';\n if (rawMarker !== 'root' && rawMarker !== 'reply') {\n throw new Error(`--marker must be root or reply (got ${JSON.stringify(rawMarker)})`);\n }\n marker = rawMarker;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(COMMENT_USAGE);\n return 2;\n }\n\n return runEvent({\n command: 'comment',\n flags,\n deps,\n actionLabel: `comment on ${rootEventId.slice(0, 8)}…`,\n buildEvent: async (addr) =>\n buildComment(\n addr.ownerPubkey,\n addr.repoId,\n rootEventId,\n parentAuthor ?? addr.ownerPubkey,\n body,\n marker\n ),\n sendDaemon: (client, addr) =>\n client.gitComment({\n repoAddr: addr,\n rootEventId,\n body,\n ...(parentAuthor !== undefined\n ? { parentAuthorPubkey: parentAuthor }\n : {}),\n marker,\n }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// rig pr create\n// ---------------------------------------------------------------------------\n\n/** `From <sha> <date>` separator lines of `git format-patch --stdout` output. */\nconst PATCH_FROM_RE = /^From ([0-9a-f]{40}) /gm;\n\n/** Commit SHAs of a format-patch series, in patch (oldest-first) order. */\nexport function extractPatchShas(patchText: string): string[] {\n return [...patchText.matchAll(PATCH_FROM_RE)].map((m) => m[1] as string);\n}\n\n/** Run `rig pr …` (nested dispatch: create | status); returns the exit code. */\nexport async function runPr(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'create':\n return runPrCreate(rest, deps);\n case 'status':\n return runPrStatus(rest, deps);\n // FREE read subcommands (#278): relay queries only, no payment path.\n case 'list':\n return runPrList(rest, deps);\n case 'show':\n return runPrShow(rest, deps);\n case '--help':\n case '-h':\n case 'help':\n io.out(PR_USAGE);\n return 0;\n default:\n io.err(\n sub === undefined\n ? 'missing subcommand: rig pr <create|status|list|show>'\n : `unknown rig pr subcommand: ${sub}`\n );\n io.err(PR_USAGE);\n return 2;\n }\n}\n\n/** `rig pr create` — kind:1617 patch publish. */\nasync function runPrCreate(\n rest: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let flags: CommonFlags;\n let title: string;\n let range: string | undefined;\n let patchFile: string | undefined;\n let branch: string | undefined;\n let bodyFlag: string | undefined;\n let bodyFile: string | undefined;\n try {\n const { values } = parseArgs({\n args: rest,\n options: {\n ...COMMON_OPTIONS,\n title: { type: 'string' },\n range: { type: 'string' },\n 'patch-file': { type: 'string' },\n body: { type: 'string' },\n 'body-file': { type: 'string' },\n branch: { type: 'string' },\n },\n allowPositionals: false,\n });\n flags = pickCommon(values);\n if (flags.help) {\n io.out(PR_CREATE_USAGE);\n return 0;\n }\n if (values.title === undefined || values.title === '') {\n throw new Error('--title is required');\n }\n if ((values.range === undefined) === (values['patch-file'] === undefined)) {\n throw new Error('exactly one of --range or --patch-file is required');\n }\n if (values.body !== undefined && values['body-file'] !== undefined) {\n throw new Error('--body and --body-file are mutually exclusive');\n }\n title = values.title;\n range = values.range;\n patchFile = values['patch-file'];\n branch = values.branch;\n bodyFlag = values.body;\n bodyFile = values['body-file'];\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PR_CREATE_USAGE);\n return 2;\n }\n\n // PR description (optional): --body → --body-file. Carried in the event's\n // `description` tag — NEVER prepended to the content, which must stay pure\n // `git format-patch` output for `git am` (leading prose hard-fails git's\n // patch-format detection).\n let body: string | undefined;\n if (bodyFlag !== undefined) {\n body = bodyFlag;\n } else if (bodyFile !== undefined) {\n try {\n body = await readFile(bodyFile, 'utf-8');\n } catch (err) {\n io.err(\n `cannot read --body-file ${bodyFile}: ${err instanceof Error ? err.message : String(err)}`\n );\n return 2;\n }\n }\n if (body !== undefined && body.trim() === '') {\n io.err('the PR body is empty — drop --body/--body-file or pass text');\n return 2;\n }\n\n // Captured by buildEvent for the daemon path: what is SHOWN locally (the\n // built kind:1617 content) is exactly what the delegated /git/patch\n // publishes — the daemon never re-derives the series.\n let builtPatchText: string | undefined;\n let builtCommits: { sha: string; parentSha: string }[] = [];\n\n return runEvent({\n command: 'pr',\n flags,\n deps,\n actionLabel: `patch ${JSON.stringify(title)}`,\n buildEvent: async (addr) => {\n let patchText: string;\n let commits: { sha: string; parentSha: string }[];\n if (range !== undefined) {\n // REAL format-patch output from the local repository (v1 publishes\n // the whole series as ONE event; see PR_USAGE).\n const reader = new GitRepoReader(await resolveRepoRoot(deps.cwd));\n patchText = await reader.formatPatch(range);\n if (patchText === '') {\n throw new Error(\n `range ${JSON.stringify(range)} selects no commits — nothing to publish`\n );\n }\n // commit/parent-commit tags for exactly the commits the series\n // carries (parsed from the patch itself, so the tags can never drift\n // from the content). Root commits have no parent and contribute no\n // tag pair.\n const shas = extractPatchShas(patchText);\n const parents = await reader.commitParents(shas);\n commits = shas.flatMap((sha) => {\n const parentSha = parents.get(sha)?.[0];\n return parentSha ? [{ sha, parentSha }] : [];\n });\n } else {\n patchText = await readFile(patchFile as string, 'utf-8');\n if (patchText.trim() === '') {\n throw new Error(`--patch-file ${patchFile} is empty — nothing to publish`);\n }\n commits = [];\n }\n builtPatchText = patchText;\n builtCommits = commits;\n return buildPatch(\n addr.ownerPubkey,\n addr.repoId,\n title,\n commits,\n branch,\n patchText,\n body\n );\n },\n sendDaemon: (client, addr) => {\n if (builtPatchText === undefined) {\n throw new Error('internal: patch text not built before delegation');\n }\n return client.gitPatch({\n repoAddr: addr,\n title,\n patchText: builtPatchText,\n ...(body !== undefined ? { description: body } : {}),\n ...(builtCommits.length > 0 ? { commits: builtCommits } : {}),\n ...(branch !== undefined ? { branch } : {}),\n });\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// rig pr status (top-level `rig status` before #250 — now git's)\n// ---------------------------------------------------------------------------\n\n/** NIP-34 status kinds by wire value (mirrors the daemon's mapping). */\nconst STATUS_KIND_BY_VALUE: Record<GitStatusValue, StatusKind> = {\n open: STATUS_OPEN_KIND,\n applied: STATUS_APPLIED_KIND,\n closed: STATUS_CLOSED_KIND,\n draft: STATUS_DRAFT_KIND,\n};\n\nfunction isStatusValue(value: string): value is GitStatusValue {\n return Object.hasOwn(STATUS_KIND_BY_VALUE, value);\n}\n\n/** `rig pr status` — kind:1630-1633 status publish. */\nasync function runPrStatus(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let flags: CommonFlags;\n let targetEventId: string;\n let status: GitStatusValue;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: COMMON_OPTIONS,\n allowPositionals: true,\n });\n flags = pickCommon(values);\n if (flags.help) {\n io.out(PR_STATUS_USAGE);\n return 0;\n }\n if (positionals.length !== 2) {\n throw new Error(\n 'expected exactly two arguments: <target-event-id> <open|applied|closed|draft>'\n );\n }\n targetEventId = positionals[0] as string;\n assertHex64(targetEventId, '<target-event-id>');\n const rawStatus = positionals[1] as string;\n if (!isStatusValue(rawStatus)) {\n throw new Error(\n `status must be one of open | applied | closed | draft (got ${JSON.stringify(rawStatus)})`\n );\n }\n status = rawStatus;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PR_STATUS_USAGE);\n return 2;\n }\n\n return runEvent({\n command: 'pr status',\n flags,\n deps,\n actionLabel: `status ${status} on ${targetEventId.slice(0, 8)}…`,\n buildEvent: async (addr) => {\n const event = buildStatus(targetEventId, STATUS_KIND_BY_VALUE[status]);\n // NIP-34 status events also carry the repo `a` tag so readers can scope\n // a status stream to the repository without resolving the target first\n // (mirrors the daemon's gitStatus).\n event.tags.push([\n 'a',\n `${REPOSITORY_ANNOUNCEMENT_KIND}:${addr.ownerPubkey}:${addr.repoId}`,\n ]);\n return event;\n },\n // Authority warning (#287): a status event only moves an issue/PR's\n // resolved state for repo-authority-honoring clients if its author is the\n // owner or a declared maintainer. Warn clearly when the active identity is\n // neither — the publish still happens (permissionless relay; the caller\n // may be acting on their own repo/fork), but the futility is made obvious.\n preConfirm: (args) => warnIfNotMaintainer(deps, args),\n sendDaemon: (client, addr) =>\n client.gitStatus({ repoAddr: addr, targetEventId, status }),\n });\n}\n\n/**\n * Read the target repo's kind:30617 and warn on stderr when the active\n * identity is NOT an authorized status author (owner ∪ declared maintainers,\n * #287). Never throws / never blocks: a relay read failure downgrades to a\n * \"could not verify\" note and the publish proceeds under the normal gate.\n */\nasync function warnIfNotMaintainer(\n deps: EventCommandDeps,\n args: {\n identity: IdentityReport;\n addr: GitRepoAddr;\n relayUrl: string | undefined;\n }\n): Promise<void> {\n const { io } = deps;\n const { identity, addr, relayUrl } = args;\n // The owner is always an implicit maintainer — no need to read the relay.\n if (identity.pubkey.toLowerCase() === addr.ownerPubkey.toLowerCase()) return;\n if (relayUrl === undefined) return;\n try {\n const remote = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: addr.ownerPubkey,\n repoId: addr.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n const authorized = authorizedStatusAuthors(\n addr.ownerPubkey,\n remote.announceEvent?.tags ?? []\n );\n if (authorized.has(identity.pubkey.toLowerCase())) return;\n io.err(\n `warning: you (${identity.pubkey.slice(0, 8)}…) are not a maintainer of ` +\n `30617:${addr.ownerPubkey.slice(0, 8)}…:${addr.repoId} — clients honoring ` +\n 'repo authority (rig, rig-web) will IGNORE this status when resolving the ' +\n \"issue/PR's state. Publishing anyway (the relay is permissionless); ask the \" +\n 'owner to `rig maintainers add` you if this should stick.'\n );\n } catch {\n io.err(\n 'warning: could not read the repo announcement to verify your maintainer ' +\n 'status — if you are not the owner or a declared maintainer, ' +\n 'authority-honoring clients will ignore this status.'\n );\n }\n}\n","/**\n * The FREE tracker views (#278): `rig issue list|show` and `rig pr list|show`.\n *\n * Pure relay reads over NIP-01 (../remote-state.ts `queryRelay` — the same\n * decoder that tolerates the devnet relay's non-canonical EVENT payload\n * encodings): kind:1621 issues / kind:1617 patches scoped to the repo by the\n * `#a` tag (`30617:<owner>:<repoId>`), kind:1630-1633 status events to derive\n * each item's state (LATEST-WINS: highest created_at, ties broken by lowest\n * id), and kind:1622 comments under `show`. No payments, no channel, no\n * identity — reads are free on TOON.\n *\n * State derivation mirrors rig-web's proven `resolvePRStatus`, upgraded to\n * latest-wins for issues too (a re-opened issue is open again).\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n ISSUE_KIND,\n PATCH_KIND,\n REPOSITORY_ANNOUNCEMENT_KIND,\n STATUS_APPLIED_KIND,\n STATUS_CLOSED_KIND,\n STATUS_DRAFT_KIND,\n STATUS_OPEN_KIND,\n} from '@toon-protocol/core/nip34';\nimport { COMMENT_KIND, authorizedStatusAuthors } from '../nip34-events.js';\nimport { ownerToHex } from '../npub.js';\nimport {\n queryRelay,\n type NostrEvent,\n type NostrFilter,\n type WebSocketFactory,\n type WebSocketLike,\n} from '../remote-state.js';\nimport {\n emitCliError,\n UnconfiguredRepoAddressError,\n InvalidRelayUrlError,\n} from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport type { ReadCommandDeps } from './read-seams.js';\nimport { resolveRelays } from './remote.js';\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\nconst READ_COMMON_FLAGS = ` --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or 64-char hex; default: git config)\n --remote <name> read via this configured git remote (default: origin)\n --relay <url> ad-hoc relay override; repeatable — reads are merged\n --json machine-readable envelope\n -h, --help show this help`;\n\nexport const ISSUE_LIST_USAGE = `Usage: rig issue list [--state open|closed|all] [options]\n\nList the repo's issues (kind:1621) with their derived state — FREE (relay\nreads only). State comes from kind:1630-1633 status events: the latest status\nwins; an issue with no status events is open.\n\nOptions:\n --state <state> open | closed | all (default: all)\n${READ_COMMON_FLAGS}`;\n\nexport const ISSUE_SHOW_USAGE = `Usage: rig issue show <event-id> [options]\n\nShow one issue (kind:1621): metadata, derived state, body, and its\nkind:1622 comments — FREE (relay reads only). <event-id> is the 64-char hex\nid \\`rig issue create\\` printed (also visible in \\`rig issue list\\`).\n\nOptions:\n${READ_COMMON_FLAGS}`;\n\nexport const PR_LIST_USAGE = `Usage: rig pr list [--state open|applied|closed|draft|all] [options]\n\nList the repo's patches/PRs (kind:1617) with their derived state — FREE\n(relay reads only). State comes from kind:1630-1633 status events: the\nlatest status wins; a patch with no status events is open.\n\nOptions:\n --state <state> open | applied | closed | draft | all (default: all)\n${READ_COMMON_FLAGS}`;\n\nexport const PR_SHOW_USAGE = `Usage: rig pr show <event-id> [options]\n\nShow one patch/PR (kind:1617): metadata, derived state, the FULL patch text\n(real \\`git format-patch\\` output — pipe it to \\`git am\\` to apply), and its\nkind:1622 comments — FREE (relay reads only).\n\nOptions:\n${READ_COMMON_FLAGS}`;\n\n// ---------------------------------------------------------------------------\n// Status derivation (latest-wins)\n// ---------------------------------------------------------------------------\n\nexport type TrackerStatus = 'open' | 'applied' | 'closed' | 'draft';\n\nconst STATUS_BY_KIND: Record<number, TrackerStatus> = {\n [STATUS_OPEN_KIND]: 'open',\n [STATUS_APPLIED_KIND]: 'applied',\n [STATUS_CLOSED_KIND]: 'closed',\n [STATUS_DRAFT_KIND]: 'draft',\n};\n\nconst STATUS_KINDS = [\n STATUS_OPEN_KIND,\n STATUS_APPLIED_KIND,\n STATUS_CLOSED_KIND,\n STATUS_DRAFT_KIND,\n];\n\nfunction tagValue(tags: string[][], name: string): string | undefined {\n return tags.find((t) => t[0] === name)?.[1];\n}\n\nfunction tagValues(tags: string[][], name: string): string[] {\n return tags.filter((t) => t[0] === name && t[1]).map((t) => t[1] as string);\n}\n\n/**\n * Derive the state of an issue/patch from its status events: consider only\n * kind:1630-1633 events whose `e` tag references the target AND whose author\n * is AUTHORIZED — the repo owner ∪ declared maintainers (#287). Among the\n * authorized events the LATEST wins (highest created_at, ties broken by lowest\n * event id — the same replaceable convention remote-state uses). Unauthorized\n * status events (any funded stranger) are IGNORED for state; they never move\n * it. No authorized status events ⇒ open.\n *\n * `authorized` is the lowercased-hex set from {@link authorizedStatusAuthors}.\n * When it is empty (the 30617 could not be resolved) NOTHING is authorized and\n * the state stays open — a safe, non-spoofable default.\n */\nexport function deriveStatus(\n targetEventId: string,\n statusEvents: Iterable<NostrEvent>,\n authorized: ReadonlySet<string>\n): TrackerStatus {\n let winner: NostrEvent | null = null;\n for (const event of statusEvents) {\n if (STATUS_BY_KIND[event.kind] === undefined) continue;\n if (!authorized.has(event.pubkey.toLowerCase())) continue;\n if (!event.tags.some((t) => t[0] === 'e' && t[1] === targetEventId))\n continue;\n if (\n winner === null ||\n event.created_at > winner.created_at ||\n (event.created_at === winner.created_at && event.id < winner.id)\n ) {\n winner = event;\n }\n }\n return winner === null\n ? 'open'\n : (STATUS_BY_KIND[winner.kind] as TrackerStatus);\n}\n\n// ---------------------------------------------------------------------------\n// Relay querying (multi-relay merge; tolerant decode via queryRelay)\n// ---------------------------------------------------------------------------\n\nconst RELAY_TIMEOUT_MS = 10000;\nconst HEX64_RE = /^[0-9a-f]{64}$/;\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\nfunction defaultWebSocketFactory(url: string): WebSocketLike {\n const ctor = (\n globalThis as { WebSocket?: new (url: string) => WebSocketLike }\n ).WebSocket;\n if (!ctor) {\n throw new Error(\n 'No global WebSocket constructor (Node >= 22 required) — pass webSocketFactory'\n );\n }\n return new ctor(url);\n}\n\n/**\n * Query every relay with every filter and merge events by id. Resolves as\n * long as at least one relay answered; throws when all fail.\n */\nasync function queryAll(\n relays: string[],\n filters: NostrFilter[],\n webSocketFactory: WebSocketFactory\n): Promise<Map<string, NostrEvent>> {\n const jobs = relays.flatMap((relay) =>\n filters.map((filter) =>\n queryRelay(relay, filter, RELAY_TIMEOUT_MS, webSocketFactory)\n )\n );\n const results = await Promise.allSettled(jobs);\n const byId = new Map<string, NostrEvent>();\n let failures = 0;\n let firstError: unknown;\n for (const result of results) {\n if (result.status === 'rejected') {\n failures += 1;\n firstError ??= result.reason;\n continue;\n }\n for (const event of result.value) {\n if (typeof event.id === 'string' && !byId.has(event.id)) {\n byId.set(event.id, event);\n }\n }\n }\n if (failures === results.length && results.length > 0) {\n throw firstError instanceof Error\n ? firstError\n : new Error(String(firstError));\n }\n return byId;\n}\n\n// ---------------------------------------------------------------------------\n// Shared context resolution (repo address + relays; NO identity, NO payment)\n// ---------------------------------------------------------------------------\n\ninterface TrackerFlags {\n json: boolean;\n help: boolean;\n state?: string;\n relay: string[];\n remote?: string;\n repoId?: string;\n owner?: string;\n}\n\nconst TRACKER_OPTIONS = {\n json: { type: 'boolean', default: false },\n state: { type: 'string' },\n relay: { type: 'string', multiple: true },\n remote: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n} as const;\n\nfunction pickTrackerFlags(values: Record<string, unknown>): TrackerFlags {\n const flags: TrackerFlags = {\n json: values['json'] === true,\n help: values['help'] === true,\n relay: Array.isArray(values['relay']) ? (values['relay'] as string[]) : [],\n };\n if (typeof values['state'] === 'string') flags.state = values['state'];\n if (typeof values['remote'] === 'string') flags.remote = values['remote'];\n if (typeof values['repo-id'] === 'string') flags.repoId = values['repo-id'];\n if (typeof values['owner'] === 'string')\n flags.owner = ownerToHex(values['owner']);\n return flags;\n}\n\ninterface TrackerContext {\n relays: string[];\n /** Set when the repo address resolved (list always has it; show may not). */\n repoAddr: { ownerPubkey: string; repoId: string } | null;\n webSocketFactory: WebSocketFactory;\n}\n\n/**\n * Resolve relays (+ repo address when `needRepoAddr`) from flags and the git\n * config, mirroring the paid commands' #249 chain — but reads may target\n * MULTIPLE relays (results are merged), and only ws/wss URLs are usable.\n */\nasync function resolveTrackerContext(\n flags: TrackerFlags,\n deps: ReadCommandDeps,\n needRepoAddr: boolean\n): Promise<TrackerContext> {\n let repoRoot: string | undefined;\n let toonConfig: { repoId?: string; owner?: string; relays: string[] } = {\n relays: [],\n };\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n toonConfig = await readToonConfig(repoRoot);\n } catch {\n // Not inside a git repo — flags must carry everything.\n }\n\n // Resolve the repo address from flags/git config. `list` REQUIRES it (throws\n // when unresolved). `show` does not, but resolves it OPPORTUNISTICALLY when\n // available so it can fall back to it for the authority set (#287) when the\n // shown item lacks a parseable `a` tag — otherwise `show` would report a\n // falsely-`open` status that `list` (which always has the address) resolves\n // correctly.\n let repoAddr: TrackerContext['repoAddr'] = null;\n const repoId = flags.repoId ?? toonConfig.repoId;\n const owner = flags.owner ?? toonConfig.owner;\n if (repoId && owner) {\n repoAddr = { ownerPubkey: owner, repoId };\n } else if (needRepoAddr) {\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n throw new UnconfiguredRepoAddressError('repository owner');\n }\n\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: flags.remote,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n const wsRelays = resolved.relays.filter((url) => WS_URL_RE.test(url));\n if (wsRelays.length === 0) {\n throw new InvalidRelayUrlError(\n resolved.relays[0] ?? '',\n 'reads need a ws:// or wss:// relay'\n );\n }\n\n return {\n relays: wsRelays,\n repoAddr,\n webSocketFactory: deps.webSocketFactory ?? defaultWebSocketFactory,\n };\n}\n\nfunction repoATag(addr: { ownerPubkey: string; repoId: string }): string {\n return `${REPOSITORY_ANNOUNCEMENT_KIND}:${addr.ownerPubkey}:${addr.repoId}`;\n}\n\n/**\n * Resolve the AUTHORIZED status authors (#287) for a repo: the owner ∪ the\n * maintainers declared on the repo's kind:30617 announcement. Reads the 30617\n * from the relay(s) — untrusted relays may over-return, so only the owner's\n * own announcement for this `d`-tag is honored. When no announcement is found\n * the set falls back to OWNER-ONLY (the owner is always an implicit\n * maintainer); this is the safe default — an unresolved 30617 can never widen\n * authority to a stranger.\n */\nasync function fetchAuthorizedAuthors(\n ctx: TrackerContext,\n ownerPubkey: string,\n repoId: string\n): Promise<Set<string>> {\n let announceTags: string[][] = [];\n try {\n const events = await queryAll(\n ctx.relays,\n [\n {\n kinds: [REPOSITORY_ANNOUNCEMENT_KIND],\n authors: [ownerPubkey],\n '#d': [repoId],\n },\n ],\n ctx.webSocketFactory\n );\n // Latest replaceable 30617 by (created_at, id) from the trusted owner.\n let latest: NostrEvent | null = null;\n for (const event of events.values()) {\n if (event.kind !== REPOSITORY_ANNOUNCEMENT_KIND) continue;\n if (event.pubkey !== ownerPubkey) continue;\n if (!event.tags.some((t) => t[0] === 'd' && t[1] === repoId)) continue;\n if (\n latest === null ||\n event.created_at > latest.created_at ||\n (event.created_at === latest.created_at && event.id < latest.id)\n ) {\n latest = event;\n }\n }\n if (latest) announceTags = latest.tags;\n } catch {\n // Relay read failed — fall back to owner-only authority.\n }\n return authorizedStatusAuthors(ownerPubkey, announceTags);\n}\n\n// ---------------------------------------------------------------------------\n// Shared list/show engines (issues and PRs differ only in kind + fields)\n// ---------------------------------------------------------------------------\n\ninterface TrackerItem {\n eventId: string;\n kind: number;\n title: string;\n status: TrackerStatus;\n authorPubkey: string;\n createdAt: number;\n labels: string[];\n content: string;\n /** kind:1617 only: `commit` tag SHAs. */\n commitShas?: string[];\n /** kind:1617 only: `branch` tag. */\n branch?: string;\n /**\n * kind:1617 only: the PR body from the `description` tag (#280). Separate\n * from `content`, which is pure `git format-patch` output for `git am`.\n */\n description?: string;\n}\n\nfunction parseTrackerItem(\n event: NostrEvent,\n status: TrackerStatus\n): TrackerItem {\n const item: TrackerItem = {\n eventId: event.id,\n kind: event.kind,\n title:\n tagValue(event.tags, 'subject') ??\n (event.content.split('\\n')[0] ?? '').slice(0, 120),\n status,\n authorPubkey: event.pubkey,\n createdAt: event.created_at,\n labels: tagValues(event.tags, 't'),\n content: event.content,\n };\n if (event.kind === PATCH_KIND) {\n item.commitShas = tagValues(event.tags, 'commit');\n const branch = tagValue(event.tags, 'branch');\n if (branch !== undefined) item.branch = branch;\n const description = tagValue(event.tags, 'description');\n if (description !== undefined) item.description = description;\n }\n return item;\n}\n\nfunction isoDate(createdAt: number): string {\n return new Date(createdAt * 1000).toISOString().slice(0, 10);\n}\n\n/** Fetch items of `kind` for the repo + their statuses; derive state. */\nasync function fetchItems(\n ctx: TrackerContext,\n kind: number\n): Promise<TrackerItem[]> {\n const addr = ctx.repoAddr as { ownerPubkey: string; repoId: string };\n const aTag = repoATag(addr);\n // Authority set (#287): owner ∪ declared maintainers from the 30617. Fetched\n // in parallel with the items — status resolution honors ONLY these authors.\n const authorizedPromise = fetchAuthorizedAuthors(\n ctx,\n addr.ownerPubkey,\n addr.repoId\n );\n const [itemEvents, aStatusEvents] = await Promise.all([\n queryAll(\n ctx.relays,\n [{ kinds: [kind], '#a': [aTag] }],\n ctx.webSocketFactory\n ),\n queryAll(\n ctx.relays,\n [{ kinds: STATUS_KINDS, '#a': [aTag] }],\n ctx.webSocketFactory\n ),\n ]);\n\n // Defense against over-returning relays: keep only the right kind + repo.\n const items = [...itemEvents.values()].filter(\n (e) => e.kind === kind && e.tags.some((t) => t[0] === 'a' && t[1] === aTag)\n );\n\n // Statuses may lack the repo `a` tag (other clients) — also query by `#e`.\n const statuses = new Map(aStatusEvents);\n if (items.length > 0) {\n const byE = await queryAll(\n ctx.relays,\n [{ kinds: STATUS_KINDS, '#e': items.map((i) => i.id) }],\n ctx.webSocketFactory\n );\n for (const [id, event] of byE)\n if (!statuses.has(id)) statuses.set(id, event);\n }\n\n const authorized = await authorizedPromise;\n return items\n .map((event) =>\n parseTrackerItem(event, deriveStatus(event.id, statuses.values(), authorized))\n )\n .sort((a, b) => b.createdAt - a.createdAt);\n}\n\ninterface ShownItem {\n item: TrackerItem;\n comments: {\n eventId: string;\n authorPubkey: string;\n createdAt: number;\n content: string;\n }[];\n repoATag: string | null;\n}\n\n/** Fetch one item by event id + its statuses and comments. */\nasync function fetchItem(\n ctx: TrackerContext,\n eventId: string,\n expectedKind: number\n): Promise<ShownItem> {\n const found = await queryAll(\n ctx.relays,\n [{ ids: [eventId] }],\n ctx.webSocketFactory\n );\n const event = found.get(eventId);\n if (!event) {\n throw new Error(`event ${eventId} not found on ${ctx.relays.join(', ')}`);\n }\n if (event.kind !== expectedKind) {\n const hint =\n event.kind === PATCH_KIND\n ? ' (it is a kind:1617 patch — use `rig pr show`)'\n : event.kind === ISSUE_KIND\n ? ' (it is a kind:1621 issue — use `rig issue show`)'\n : '';\n throw new Error(\n `event ${eventId} has kind ${event.kind}, expected ${expectedKind}${hint}`\n );\n }\n\n const [statusEvents, commentEvents] = await Promise.all([\n queryAll(\n ctx.relays,\n [{ kinds: STATUS_KINDS, '#e': [eventId] }],\n ctx.webSocketFactory\n ),\n queryAll(\n ctx.relays,\n [{ kinds: [COMMENT_KIND], '#e': [eventId] }],\n ctx.webSocketFactory\n ),\n ]);\n\n const comments = [...commentEvents.values()]\n .filter(\n (e) =>\n e.kind === COMMENT_KIND &&\n e.tags.some((t) => t[0] === 'e' && t[1] === eventId)\n )\n .sort((a, b) => a.created_at - b.created_at)\n .map((e) => ({\n eventId: e.id,\n authorPubkey: e.pubkey,\n createdAt: e.created_at,\n content: e.content,\n }));\n\n // Authority set (#287): prefer the shown item's own `a` tag\n // (30617:<owner>:<id>) and read that repo's 30617 for the maintainers. When\n // the item lacks a parseable `a` tag, fall back to the configured repo\n // address (--repo-id/--owner or git config) so `show` matches `list` instead\n // of reporting a falsely-`open` status. Only when NEITHER is available is the\n // set empty ⇒ status stays open (safe: no stranger can move it either way).\n const repoATag = tagValue(event.tags, 'a') ?? null;\n const parsedAddr = parseRepoATag(repoATag) ?? ctx.repoAddr;\n const authorized = parsedAddr\n ? await fetchAuthorizedAuthors(ctx, parsedAddr.ownerPubkey, parsedAddr.repoId)\n : new Set<string>();\n\n return {\n item: parseTrackerItem(\n event,\n deriveStatus(eventId, statusEvents.values(), authorized)\n ),\n comments,\n repoATag,\n };\n}\n\n/** Parse a NIP-34 repo `a` tag `30617:<owner-hex>:<repoId>` into its parts. */\nfunction parseRepoATag(\n aTag: string | null\n): { ownerPubkey: string; repoId: string } | null {\n if (!aTag) return null;\n const [kind, ownerPubkey, ...repoIdParts] = aTag.split(':');\n const repoId = repoIdParts.join(':');\n if (kind !== String(REPOSITORY_ANNOUNCEMENT_KIND) || !ownerPubkey || !repoId) {\n return null;\n }\n return { ownerPubkey, repoId };\n}\n\n// ---------------------------------------------------------------------------\n// list command (shared by issue/pr)\n// ---------------------------------------------------------------------------\n\ninterface ListSpec {\n command: 'issue list' | 'pr list';\n kind: number;\n usage: string;\n states: readonly TrackerStatus[];\n jsonKey: 'issues' | 'prs';\n}\n\nasync function runList(\n args: string[],\n deps: ReadCommandDeps,\n spec: ListSpec\n): Promise<number> {\n const { io } = deps;\n let flags: TrackerFlags;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: TRACKER_OPTIONS,\n allowPositionals: true,\n });\n if (positionals.length > 0) {\n throw new Error(`rig ${spec.command} takes no positional arguments`);\n }\n flags = pickTrackerFlags(values);\n if (\n flags.state !== undefined &&\n flags.state !== 'all' &&\n !spec.states.includes(flags.state as TrackerStatus)\n ) {\n throw new Error(\n `--state must be one of ${[...spec.states, 'all'].join(' | ')} (got ${JSON.stringify(flags.state)})`\n );\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(spec.usage);\n return 2;\n }\n if (flags.help) {\n io.out(spec.usage);\n return 0;\n }\n\n try {\n const ctx = await resolveTrackerContext(flags, deps, true);\n const all = await fetchItems(ctx, spec.kind);\n const state = flags.state ?? 'all';\n const items = state === 'all' ? all : all.filter((i) => i.status === state);\n\n if (flags.json) {\n io.emitJson({\n command: spec.command,\n repoAddr: ctx.repoAddr,\n relays: ctx.relays,\n state,\n count: items.length,\n [spec.jsonKey]: items,\n });\n return 0;\n }\n\n if (items.length === 0) {\n io.out(\n `no ${state === 'all' ? '' : `${state} `}${spec.jsonKey} found for ` +\n `${repoATag(ctx.repoAddr as { ownerPubkey: string; repoId: string })}`\n );\n return 0;\n }\n for (const item of items) {\n const labels =\n item.labels.length > 0 ? ` [${item.labels.join(', ')}]` : '';\n io.out(\n `${item.status.padEnd(7)} ${item.eventId.slice(0, 8)} ${item.title}` +\n ` (${item.authorPubkey.slice(0, 8)}, ${isoDate(item.createdAt)})${labels}`\n );\n }\n io.out(\n `${items.length} ${spec.jsonKey}${state === 'all' ? '' : ` (${state})`}`\n );\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, spec.command, err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// show command (shared by issue/pr)\n// ---------------------------------------------------------------------------\n\ninterface ShowSpec {\n command: 'issue show' | 'pr show';\n kind: number;\n usage: string;\n jsonKey: 'issue' | 'pr';\n /** PRs print their full patch text; issues print the body. */\n bodyLabel: string;\n}\n\nasync function runShow(\n args: string[],\n deps: ReadCommandDeps,\n spec: ShowSpec\n): Promise<number> {\n const { io } = deps;\n let flags: TrackerFlags;\n let eventId: string;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: TRACKER_OPTIONS,\n allowPositionals: true,\n });\n flags = pickTrackerFlags(values);\n if (flags.help) {\n io.out(spec.usage);\n return 0;\n }\n if (positionals.length !== 1) {\n throw new Error('expected exactly one <event-id>');\n }\n eventId = positionals[0] as string;\n if (!HEX64_RE.test(eventId)) {\n throw new Error(\n `<event-id> must be a 64-char lowercase hex id (got ${JSON.stringify(eventId)})`\n );\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(spec.usage);\n return 2;\n }\n\n try {\n const ctx = await resolveTrackerContext(flags, deps, false);\n const shown = await fetchItem(ctx, eventId, spec.kind);\n\n if (flags.json) {\n io.emitJson({\n command: spec.command,\n relays: ctx.relays,\n repoATag: shown.repoATag,\n [spec.jsonKey]: shown.item,\n comments: shown.comments,\n });\n return 0;\n }\n\n const { item } = shown;\n io.out(`${spec.jsonKey} ${item.eventId}`);\n io.out(`Title: ${item.title}`);\n io.out(`Status: ${item.status}`);\n io.out(`Author: ${item.authorPubkey}`);\n io.out(`Date: ${isoDate(item.createdAt)}`);\n if (item.labels.length > 0) io.out(`Labels: ${item.labels.join(', ')}`);\n if (item.branch !== undefined) io.out(`Branch: ${item.branch}`);\n if (item.commitShas && item.commitShas.length > 0) {\n io.out(`Commits: ${item.commitShas.join(', ')}`);\n }\n if (shown.repoATag !== null) io.out(`Repo: ${shown.repoATag}`);\n if (item.description !== undefined) {\n // The `description` tag (`rig pr create --body`): shown as its own\n // section so the patch text below stays pipeable into `git am`.\n io.out('');\n io.out('Body:');\n for (const line of item.description.split('\\n')) io.out(line);\n }\n io.out('');\n io.out(`${spec.bodyLabel}:`);\n for (const line of item.content.split('\\n')) io.out(line);\n io.out('');\n io.out(`Comments (${shown.comments.length}):`);\n for (const comment of shown.comments) {\n io.out(\n `--- ${comment.eventId.slice(0, 8)} by ${comment.authorPubkey.slice(0, 8)} ` +\n `on ${isoDate(comment.createdAt)}`\n );\n for (const line of comment.content.split('\\n')) io.out(line);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, spec.command, err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public entry points\n// ---------------------------------------------------------------------------\n\nconst ISSUE_STATES = ['open', 'closed', 'applied', 'draft'] as const;\nconst PR_STATES = ['open', 'applied', 'closed', 'draft'] as const;\n\n/** `rig issue list` */\nexport function runIssueList(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runList(args, deps, {\n command: 'issue list',\n kind: ISSUE_KIND,\n usage: ISSUE_LIST_USAGE,\n states: ISSUE_STATES,\n jsonKey: 'issues',\n });\n}\n\n/** `rig issue show <event-id>` */\nexport function runIssueShow(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runShow(args, deps, {\n command: 'issue show',\n kind: ISSUE_KIND,\n usage: ISSUE_SHOW_USAGE,\n jsonKey: 'issue',\n bodyLabel: 'Body',\n });\n}\n\n/** `rig pr list` */\nexport function runPrList(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runList(args, deps, {\n command: 'pr list',\n kind: PATCH_KIND,\n usage: PR_LIST_USAGE,\n states: PR_STATES,\n jsonKey: 'prs',\n });\n}\n\n/** `rig pr show <event-id>` */\nexport function runPrShow(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runShow(args, deps, {\n command: 'pr show',\n kind: PATCH_KIND,\n usage: PR_SHOW_USAGE,\n jsonKey: 'pr',\n bodyLabel: 'Patch',\n });\n}\n","/**\n * `rig entry` — name the TOON connector rig pays.\n *\n * One URL is the whole network configuration since 4.0: a connector describes\n * itself on `GET /ilp` (addresses, prices, chains, sealing key — connector ADR\n * 0050), so there is nothing else to point rig at. This command records that\n * URL as `connectorUrl` in the shared client config, optionally with the\n * free-read relay (`--relay`) the same node serves, and shows what is in\n * effect and where it came from. Free: only the local config file is touched.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport type { CliIo } from './output.js';\n\nexport const ENTRY_USAGE = `Usage: rig entry [<connector-url> | clear] [options]\n\nName the TOON connector rig pays. A connector describes itself on GET /ilp\n(its addresses, routes and prices, settlement chains), so its URL is the\nwhole configuration. Free: only the local config file is touched.\n\n rig entry show the effective connector + relay and their source\n rig entry <connector-url> record the node's client-edge URL (https://…);\n pass --relay <wss-url> to also record its free-read relay\n rig entry clear forget the recorded connector (and relay)\n\nExisting payment channels are per node: after switching, the next paid\ncommand opens or adopts a channel with the new node.\n\nNOTE for repos: the relay a repo publishes to is its git \\`origin\\` remote,\nwhich OVERRIDES the config relayUrl. After switching, point the repo too:\n\\`rig remote add origin <relay-url>\\` (or use a fresh repo).\n\nOptions:\n --relay <url> with <connector-url>: also record the relay URL (ws:// or wss://)\n --json machine-readable envelope\n -h, --help show this help`;\n\n/** What `rig entry` needs from the command environment. */\nexport interface EntryDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n}\n\n/** The slice of the shared client config `rig entry` reads/writes. */\ninterface EntryConfigFile {\n connectorUrl?: string;\n relayUrl?: string;\n /** @deprecated pre-4.0 spellings, migrated away on write. */\n proxyUrl?: string;\n btpUrl?: string;\n [key: string]: unknown;\n}\n\n/** Where an effective endpoint value came from. */\nexport type EndpointSource =\n 'env' | 'config' | 'legacy-env' | 'legacy-config' | null;\n\n/** `--json` envelope. */\ninterface EntryJson {\n command: 'entry';\n connectorUrl: string | null;\n connectorSource: EndpointSource;\n relayUrl: string | null;\n relaySource: EndpointSource;\n /** What was written to config (mutations only). */\n wrote?: { connectorUrl: string | null; relayUrl: string | null };\n configPath: string;\n warnings?: string[];\n}\n\n/** Resolve the client config directory + path (mirrors `rig chain`). */\nfunction configPathFor(env: NodeJS.ProcessEnv): string {\n const dir = env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n return join(dir, 'config.json');\n}\n\nfunction readEntryConfig(configPath: string): EntryConfigFile {\n try {\n return JSON.parse(readFileSync(configPath, 'utf8')) as EntryConfigFile;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw new Error(\n `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** Read-merge-write: preserve every other field. */\nfunction writeEntryConfig(configPath: string, file: EntryConfigFile): void {\n mkdirSync(dirname(configPath), { recursive: true });\n writeFileSync(configPath, `${JSON.stringify(file, null, 2)}\\n`, 'utf8');\n}\n\n/** The effective connector and relay, with the precedence the paid path uses. */\nexport function effectiveEntry(\n env: NodeJS.ProcessEnv,\n file: EntryConfigFile\n): {\n connectorUrl: string | null;\n connectorSource: EndpointSource;\n relayUrl: string | null;\n relaySource: EndpointSource;\n} {\n let connectorUrl: string | null = null;\n let connectorSource: EndpointSource = null;\n if (env['TOON_CONNECTOR']) {\n connectorUrl = env['TOON_CONNECTOR'];\n connectorSource = 'env';\n } else if (env['TOON_CLIENT_PROXY_URL']) {\n connectorUrl = env['TOON_CLIENT_PROXY_URL'];\n connectorSource = 'legacy-env';\n } else if (file.connectorUrl) {\n connectorUrl = file.connectorUrl;\n connectorSource = 'config';\n } else if (file.proxyUrl) {\n connectorUrl = file.proxyUrl;\n connectorSource = 'legacy-config';\n }\n const relayUrl = env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl ?? null;\n const relaySource: EndpointSource = env['TOON_CLIENT_RELAY_URL']\n ? 'env'\n : file.relayUrl\n ? 'config'\n : null;\n return { connectorUrl, connectorSource, relayUrl, relaySource };\n}\n\nconst HTTP_URL = /^https?:\\/\\/.+/i;\nconst WS_URL = /^wss?:\\/\\/.+/i;\n\n/** Run `rig entry`; returns the process exit code. */\nexport async function runEntry(\n args: string[],\n deps: EntryDeps\n): Promise<number> {\n const { io, env } = deps;\n\n let positionals: string[];\n let relayFlag: string | undefined;\n let json = false;\n try {\n const parsed = parseArgs({\n args,\n allowPositionals: true,\n options: {\n relay: { type: 'string' },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (parsed.values.help) {\n io.out(ENTRY_USAGE);\n return 0;\n }\n positionals = parsed.positionals;\n relayFlag = parsed.values.relay;\n json = parsed.values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(ENTRY_USAGE);\n return 2;\n }\n\n if (positionals.length > 1) {\n io.err(\n `rig entry takes at most one argument, got ${String(positionals.length)}: ${positionals.join(' ')}`\n );\n io.err(ENTRY_USAGE);\n return 2;\n }\n const target = positionals[0];\n\n // Usage-validate the target OUTSIDE the runtime-error wrapper (exit 2).\n let mutation:\n | { kind: 'clear' }\n | { kind: 'url'; connectorUrl: string; relayUrl?: string }\n | undefined;\n if (target !== undefined) {\n if (target === 'clear') {\n if (relayFlag !== undefined) {\n io.err('--relay only applies to a <connector-url> entry');\n io.err(ENTRY_USAGE);\n return 2;\n }\n mutation = { kind: 'clear' };\n } else if (HTTP_URL.test(target)) {\n if (relayFlag !== undefined && !WS_URL.test(relayFlag)) {\n io.err(`--relay must be a ws(s) URL, got ${JSON.stringify(relayFlag)}`);\n io.err(ENTRY_USAGE);\n return 2;\n }\n mutation = {\n kind: 'url',\n connectorUrl: target.replace(/\\/+$/, ''),\n ...(relayFlag !== undefined ? { relayUrl: relayFlag } : {}),\n };\n } else if (WS_URL.test(target)) {\n io.err(\n `${JSON.stringify(target)} is a WebSocket URL — the entry is the connector's http(s) URL ` +\n '(the one whose GET /ilp describes it); pass the relay with --relay'\n );\n io.err(ENTRY_USAGE);\n return 2;\n } else {\n io.err(\n `unknown entry ${JSON.stringify(target)} — expected a connector http(s):// URL or \\`clear\\``\n );\n io.err(ENTRY_USAGE);\n return 2;\n }\n }\n\n try {\n const configPath = configPathFor(env);\n const file = readEntryConfig(configPath);\n\n const label = (source: EndpointSource): string =>\n source === 'env'\n ? 'env'\n : source === 'legacy-env'\n ? 'env (TOON_CLIENT_PROXY_URL, pre-4.0 spelling — set TOON_CONNECTOR)'\n : source === 'config'\n ? `config (${configPath})`\n : source === 'legacy-config'\n ? `config proxyUrl (${configPath}, pre-4.0 spelling)`\n : 'not configured';\n\n // ── show (no argument) ─────────────────────────────────────────────────\n if (mutation === undefined) {\n const state = effectiveEntry(env, file);\n if (json) {\n io.emitJson({\n command: 'entry',\n ...state,\n configPath,\n } satisfies EntryJson);\n return 0;\n }\n io.out(\n `Connector ${state.connectorUrl ?? '(none)'} [${label(state.connectorSource)}]`\n );\n io.out(\n `Relay ${state.relayUrl ?? '(none)'} [${label(state.relaySource)}]`\n );\n if (!state.connectorUrl) {\n io.out(\n 'Set one with `rig entry <connector-url>` (or export TOON_CONNECTOR).'\n );\n }\n return 0;\n }\n\n // ── mutations ──────────────────────────────────────────────────────────\n const warnings: string[] = [];\n const next: EntryConfigFile = { ...file };\n // The pre-4.0 spellings are retired on any write: a stale `proxyUrl`\n // would otherwise keep outranking nothing, and `btpUrl` is ignored.\n if (file.proxyUrl !== undefined || file.btpUrl !== undefined) {\n delete next.proxyUrl;\n delete next.btpUrl;\n warnings.push(\n 'removed the pre-4.0 proxyUrl/btpUrl fields (the connector URL replaces both)'\n );\n }\n if (mutation.kind === 'clear') {\n delete next.connectorUrl;\n delete next.relayUrl;\n } else {\n next.connectorUrl = mutation.connectorUrl;\n if (mutation.relayUrl !== undefined) next.relayUrl = mutation.relayUrl;\n }\n if (env['TOON_CONNECTOR'] || env['TOON_CLIENT_PROXY_URL']) {\n warnings.push(\n 'TOON_CONNECTOR / TOON_CLIENT_PROXY_URL is set in this shell and outranks the config file'\n );\n }\n writeEntryConfig(configPath, next);\n const wrote = {\n connectorUrl: next.connectorUrl ?? null,\n relayUrl: next.relayUrl ?? null,\n };\n const state = effectiveEntry(env, next);\n\n if (json) {\n io.emitJson({\n command: 'entry',\n ...state,\n wrote,\n configPath,\n ...(warnings.length > 0 ? { warnings } : {}),\n } satisfies EntryJson);\n return 0;\n }\n if (mutation.kind === 'clear') {\n io.out(`Cleared the recorded connector in ${configPath}.`);\n } else {\n io.out(`Recorded connector ${mutation.connectorUrl} in ${configPath}.`);\n if (mutation.relayUrl !== undefined)\n io.out(`Recorded relay ${mutation.relayUrl}.`);\n }\n for (const w of warnings) io.out(`warning: ${w}`);\n io.out(\n `Effective connector: ${state.connectorUrl ?? '(none)'} [${label(state.connectorSource)}]`\n );\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'entry', err);\n }\n}\n","/**\n * `rig fetch` (#278) — the clone pipeline against an EXISTING repository:\n * fetch the remote refs + sha→txId map from the relay, download only the\n * objects the local repository is missing (SHA-1 verified), and update the\n * remote-tracking refs (refs/remotes/<remote>/*; tags to refs/tags/*),\n * reporting what moved like `git fetch` does. FREE — no payments anywhere.\n *\n * No merge: integrating fetched refs is `rig merge origin/main` (the git\n * passthrough), exactly like plain git. `rig fetch` shadows `git fetch` the\n * same way `rig push` shadows `git push`; plain-git fetches stay available\n * by running `git fetch` directly.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n isSafeRefname,\n runGit,\n updateRef,\n writeGitObjects,\n} from '../materialize.js';\nimport { ownerToHex } from '../npub.js';\nimport { collectRepoObjects } from '../read-pipeline.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport {\n emitCliError,\n InvalidRelayUrlError,\n MultiUrlRemoteError,\n UnconfiguredRepoAddressError,\n UnknownRemoteError,\n} from './errors.js';\nimport {\n readToonConfig,\n getGitRemoteUrls,\n resolveRepoRoot,\n} from './git-config.js';\nimport { MissingRemoteObjectsError } from './clone.js';\nimport type { ReadCommandDeps } from './read-seams.js';\n\nexport const FETCH_USAGE = `Usage: rig fetch [remote] [options]\n\nFetch from a TOON remote — FREE (relay reads + Arweave gateway downloads; no\npayments, no identity needed). Reads the kind:30618 repository state from the\nremote's relay, downloads only the git objects this repository is missing\n(SHA-1 verified), and updates the remote-tracking refs\n(refs/remotes/<remote>/*; tags land at refs/tags/*), reporting what moved.\n\nNo merge happens: integrate with the git passthrough, e.g.\n\\`rig merge origin/main\\`. \\`rig fetch\\` is the TOON transport and shadows\n\\`git fetch\\` — plain-git fetches remain available via \\`git fetch\\` directly.\n\nThe repo address (toon.repoid/toon.owner) comes from the config \\`rig init\\`\nor \\`rig clone\\` writes; --repo-id/--owner override.\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or 64-char hex; default: git config)\n --relay <url> ad-hoc relay override — bypasses the remote's URL\n --concurrency <n> parallel gateway downloads (default 8)\n --json machine-readable result envelope\n -h, --help show this help`;\n\n/** One remote-tracking ref movement, `git fetch`-style. */\nexport interface RefUpdate {\n /** Remote refname (as announced), e.g. `refs/heads/main`. */\n refname: string;\n /** Local ref that was updated, e.g. `refs/remotes/origin/main`. */\n localRef: string;\n oldSha: string | null;\n newSha: string;\n kind: 'new' | 'fast-forward' | 'forced' | 'up-to-date';\n}\n\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\n/** Map an announced refname to its local destination for `remote`. */\nfunction localRefFor(refname: string, remote: string): string | null {\n if (refname.startsWith('refs/heads/')) {\n return `refs/remotes/${remote}/${refname.slice('refs/heads/'.length)}`;\n }\n if (refname.startsWith('refs/tags/')) return refname;\n return null; // exotic namespaces are skipped\n}\n\n/** rev-parse a ref, null when it doesn't exist. */\nasync function resolveLocalRef(\n repoRoot: string,\n refname: string\n): Promise<string | null> {\n try {\n const out = await runGit(repoRoot, [\n 'rev-parse',\n '--verify',\n '--quiet',\n refname,\n ]);\n const sha = out.trim();\n return /^[0-9a-f]{40}$/.test(sha) ? sha : null;\n } catch {\n return null;\n }\n}\n\n/** Run `rig fetch …`; returns the process exit code. */\nexport async function runFetch(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let json = false;\n let remote = 'origin';\n let relayFlag: string | undefined;\n let repoIdFlag: string | undefined;\n let ownerFlag: string | undefined;\n let concurrency: number | undefined;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n relay: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n concurrency: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) {\n io.out(FETCH_USAGE);\n return 0;\n }\n json = values.json === true;\n if (positionals.length > 1) {\n throw new Error(\n `expected at most one [remote] argument, got ${positionals.length}`\n );\n }\n if (positionals[0] !== undefined) remote = positionals[0];\n relayFlag = values.relay;\n repoIdFlag = values['repo-id'];\n ownerFlag =\n values.owner !== undefined ? ownerToHex(values.owner) : undefined;\n if (values.concurrency !== undefined) {\n concurrency = Number.parseInt(values.concurrency, 10);\n if (!Number.isSafeInteger(concurrency) || concurrency < 1) {\n throw new Error('--concurrency must be a positive integer');\n }\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(FETCH_USAGE);\n return 2;\n }\n\n try {\n // ── Repo addressing + relay resolution ─────────────────────────────────\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = repoIdFlag ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const owner = ownerFlag ?? toonConfig.owner;\n if (!owner) throw new UnconfiguredRepoAddressError('repository owner');\n\n let relayUrl: string;\n if (relayFlag !== undefined) {\n relayUrl = relayFlag;\n } else {\n const urls = await getGitRemoteUrls(repoRoot, remote);\n if (urls.length === 0) throw new UnknownRemoteError(remote);\n if (urls.length > 1) throw new MultiUrlRemoteError(remote, urls);\n relayUrl = urls[0] as string;\n }\n if (!WS_URL_RE.test(relayUrl)) {\n throw new InvalidRelayUrlError(\n relayUrl,\n `remote ${JSON.stringify(remote)}`\n );\n }\n\n // ── Remote state ────────────────────────────────────────────────────────\n const remoteState = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: owner,\n repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n ...(deps.resolveSha ? { resolveSha: deps.resolveSha } : {}),\n });\n\n // Plan the tracking-ref updates (hostile-relay refname gate included).\n const planned: { refname: string; localRef: string; newSha: string }[] = [];\n for (const [refname, sha] of remoteState.refs) {\n if (!isSafeRefname(refname)) {\n io.err(\n `warning: skipping unsafe ref name from relay: ${JSON.stringify(refname)}`\n );\n continue;\n }\n const localRef = localRefFor(refname, remote);\n if (localRef === null) {\n io.err(\n `warning: skipping ref outside refs/heads and refs/tags: ${refname}`\n );\n continue;\n }\n planned.push({ refname, localRef, newSha: sha });\n }\n\n // ── Delta: download only what the local repository is missing ──────────\n const reader = new GitRepoReader(repoRoot);\n const tips = [...new Set(planned.map((p) => p.newSha))];\n const candidates = [...new Set([...remoteState.shaToTxId.keys(), ...tips])];\n const { missing: absent } = await reader.statObjects(candidates);\n const absentSet = new Set(absent);\n const presentLocally = new Set(\n candidates.filter((sha) => !absentSet.has(sha))\n );\n\n const collected = await collectRepoObjects({\n tips,\n shaToTxId: remoteState.shaToTxId,\n resolveMissing: (shas) => remoteState.resolveMissing(shas),\n presentLocally,\n ...(deps.fetchFn ? { fetchFn: deps.fetchFn } : {}),\n ...(concurrency !== undefined ? { concurrency } : {}),\n });\n if (collected.missing.length > 0) {\n throw new MissingRemoteObjectsError(\n collected.missing,\n `cannot fetch from ${relayUrl}`\n );\n }\n const written = await writeGitObjects(repoRoot, collected.objects.values());\n\n // ── Update tracking refs + report movements ─────────────────────────────\n const updates: RefUpdate[] = [];\n for (const { refname, localRef, newSha } of planned) {\n const oldSha = await resolveLocalRef(repoRoot, localRef);\n if (oldSha === newSha) {\n updates.push({ refname, localRef, oldSha, newSha, kind: 'up-to-date' });\n continue;\n }\n let kind: RefUpdate['kind'];\n if (oldSha === null) {\n kind = 'new';\n } else {\n kind = (await reader.isAncestor(oldSha, newSha))\n ? 'fast-forward'\n : 'forced';\n }\n await updateRef(repoRoot, localRef, newSha);\n updates.push({ refname, localRef, oldSha, newSha, kind });\n }\n\n // ── Report ──────────────────────────────────────────────────────────────\n const moved = updates.filter((u) => u.kind !== 'up-to-date');\n if (json) {\n io.emitJson({\n command: 'fetch',\n repoAddr: { ownerPubkey: owner, repoId },\n remote,\n relay: relayUrl,\n objectsDownloaded: written,\n updates,\n executed: true,\n });\n return 0;\n }\n if (moved.length === 0) {\n io.out('Already up to date.');\n return 0;\n }\n io.out(`From ${relayUrl}`);\n for (const u of moved) {\n const short = (refname: string): string =>\n refname\n .replace(/^refs\\/heads\\//, '')\n .replace(/^refs\\/tags\\//, '')\n .replace(/^refs\\/remotes\\//, '');\n const src = short(u.refname);\n const dst = short(u.localRef);\n if (u.kind === 'new') {\n const label = u.refname.startsWith('refs/tags/')\n ? '[new tag]'\n : '[new branch]';\n io.out(` * ${label.padEnd(17)} ${src.padEnd(14)} -> ${dst}`);\n } else if (u.kind === 'forced') {\n io.out(\n ` + ${(u.oldSha as string).slice(0, 7)}...${u.newSha.slice(0, 7)} ${src.padEnd(14)} -> ${dst} (forced update)`\n );\n } else {\n io.out(\n ` ${(u.oldSha as string).slice(0, 7)}..${u.newSha.slice(0, 7)} ${src.padEnd(14)} -> ${dst}`\n );\n }\n }\n io.out(`Downloaded ${written} object(s) (SHA-1 verified).`);\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'fetch', err);\n }\n}\n","/**\n * `rig fund` — drip devnet test funds to the active identity's wallet (#263).\n *\n * A FREE command: no relay, no client start, no nonce guard, no payment\n * channel — just the identity chain (RIG_MNEMONIC precedence, ./identity.ts)\n * to derive the chain address(es), and an HTTP POST per chain to the devnet\n * faucet (`@toon-protocol/client`'s `fundWallet`, which hits the USDC-ONLY\n * legs: `POST {faucet}/api/base-sepolia/request` for EVM,\n * `/api/solana/usdc-request`, `/api/mina/usdc-request` — body `{ address }`;\n * the faucet drips a FIXED amount, so there is no --amount). Each per-chain\n * drip funds ONLY the settlement token (USDC) and ASSUMES the wallet already\n * holds enough native gas to transact — the EVM leg still best-effort tops up\n * Base Sepolia gas, but Solana/Mina expect the address to already hold SOL/MINA.\n *\n * MULTI-CHAIN BY DEFAULT: with no chain argument, `rig fund` funds ALL supported\n * chains (evm + solana + mina) so the wallet matches the multi-chain\n * `rig balance` view (#299) in one run instead of three. A chain argument —\n * positional (`rig fund sol`) or `--chain <one>` — narrows to a single chain;\n * `all` is the explicit alias for the default. The drips run in PARALLEL — the\n * Mina faucet legitimately takes\n * ~75s, so serializing would cost ~150s for a run that overlaps to ~75s — and\n * each chain's result is INDEPENDENT: one chain's faucet failing never aborts\n * the others. Exit code is 0 only when every targeted chain funded; if any\n * chain failed the exit code is 1 and the per-chain breakdown is always shown.\n *\n * Faucet resolution mirrors the toon-clientd conventions\n * (client-mcp/src/daemon/config.ts — no import, keep in sync):\n * `TOON_CLIENT_FAUCET_URL` env → `faucetUrl` in the shared client config →\n * the deployed devnet faucet when the network IS (or is inferred as) devnet.\n * A configured `*.devnet.toonprotocol.dev` origin infers devnet even when\n * `network` still reads its `custom` default (#288) — that origin is BOTH a\n * devnet-looking relay/proxy/btp endpoint in env/config AND the git `origin`\n * remote `rig remote` configures (resolved the same way push/fetch resolve\n * their relay), so a fresh user who only ran `rig remote add origin\n * wss://relay-ws.devnet.toonprotocol.dev` gets the drip from a plain\n * `rig fund` with no env var. A truly FRESH install — no origin configured\n * anywhere (env, config, git `origin`) — falls back to core's committed\n * genesis seed, whose relay/btp origin names the live shared devnet, so\n * `npm i -g @toon-protocol/rig && rig fund` drips with zero config; any\n * configured origin (devnet or not) suppresses the seed, keeping the #288\n * \"explicit stays authoritative\" rule. On any other network there is no\n * faucet: the command prints the derived wallet address(es) to fund\n * externally instead of failing silently.\n *\n * The drips are awaited (a CLI has no background) but run concurrently: the\n * Mina faucet legitimately takes ~75s, so the per-chain timeout is generous\n * (daemon convention: 90s, mina 130s; `TOON_CLIENT_FAUCET_TIMEOUT_MS` /\n * config `faucetTimeoutMs` override) and a serial evm→solana→mina run would\n * stack those budgets — parallel drips overlap them.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport { resolveIdentity } from './identity.js';\nimport type { CliIo, IdentityReport } from './push.js';\nimport { renderIdentityLine } from './render.js';\nimport { resolveRelays } from './remote.js';\n\n/**\n * The deployed devnet faucet — the same edge the e2e suite drips from\n * (`client-mcp/src/e2e/devnet.ts`). Used only when the configured network is\n * `devnet` and no explicit faucet URL is set.\n */\nexport const DEVNET_FAUCET_URL = 'https://faucet.devnet.toonprotocol.dev';\n\n/** Supported faucet chains (client `FaucetChain`). */\nconst CHAINS = ['evm', 'solana'] as const;\ntype FundChain = (typeof CHAINS)[number];\n\n/**\n * Accepted chain arguments (positional `rig fund sol` or `--chain sol`), mapped\n * to the canonical selector. Short aliases (`sol`) are accepted alongside the\n * canonical names; `all` funds every supported chain (the default).\n */\nconst CHAIN_ALIASES: Record<string, FundChain | 'all'> = {\n evm: 'evm',\n eth: 'evm',\n sol: 'solana',\n solana: 'solana',\n all: 'all',\n};\n\n/** Human-readable list of accepted chain arguments (for usage/errors). */\nconst CHAIN_ARG_LIST = 'evm | sol | solana | all';\n\n/**\n * Resolve a raw chain argument (positional or `--chain`) to the canonical\n * selector, accepting short aliases. Throws a usage error on an unknown value.\n * Returns `undefined` when no chain was given (→ the all-chains default).\n */\nfunction resolveChainArg(raw: string | undefined): FundChain | 'all' | undefined {\n if (raw === undefined) return undefined;\n const canonical = CHAIN_ALIASES[raw.toLowerCase()];\n if (!canonical) {\n throw new Error(\n `chain must be one of ${CHAIN_ARG_LIST}, got ${JSON.stringify(raw)}`\n );\n }\n return canonical;\n}\n\nexport const FUND_USAGE = `Usage: rig fund [chain] [options]\n\nDrip devnet USDC to the active identity's wallet — free (the faucet pays). Each\ndrip funds ONLY the settlement token (USDC) and assumes the wallet already holds\nenough native gas to transact. By default funds ALL supported chains (evm +\nsolana + mina) so the wallet matches the multi-chain \\`rig balance\\` view in one\nrun; name a chain — positional (\\`rig fund sol\\`) or \\`--chain\\` — to narrow to\none. The per-chain drips run in parallel and are independent — one chain's\nfaucet failing does not abort the others (exit 0 only when every targeted chain\nfunded; exit 1 if any failed, with the per-chain breakdown always shown).\n\nThe identity comes from RIG_MNEMONIC (env or a project .env) or the\n~/.toon-client keystore/config; the faucet from TOON_CLIENT_FAUCET_URL, the\nfaucetUrl config field, or the deployed devnet faucet when the network is\ndevnet — including when a configured *.devnet.toonprotocol.dev origin infers\nit (a devnet relay/proxy/btp endpoint, or the git origin remote from\n\\`rig remote add origin <devnet relay>\\`). A completely fresh install with NO\norigin configured anywhere infers devnet from the built-in genesis seed, so a\nbare \\`rig fund\\` works with zero config. The faucet drips a FIXED amount per\nchain (there is no --amount). On a network without a faucet, prints the wallet\naddress(es) to fund externally instead.\n\nOptions:\n [chain] evm | sol | solana | mina | all — positional chain to\n fund (default: all supported chains)\n --chain <chain> same as the positional chain argument\n --address <address> fund this address instead of the identity's own\n (requires an explicit single chain)\n --json machine-readable envelope (per-chain results array)\n -h, --help show this help`;\n\n/** What `rig fund` needs from the command environment. */\nexport interface FundDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n /** Working directory (starts the project-local `.env` walk). */\n cwd: string;\n /** fetch used for the faucet call (tests inject; default global fetch). */\n fetchImpl?: typeof fetch;\n /**\n * Genesis-seed loader seam: consulted ONLY when nothing else — env, config,\n * or the git `origin` remote — names an origin at all (a truly fresh\n * install with no config). Defaults to the lazy standalone\n * network-bootstrap import (core's committed genesis peer); tests inject.\n */\n loadGenesisSeed?: () => Promise<\n { relayUrl?: string; btpEndpoint?: string } | undefined\n >;\n}\n\n/** The slice of the shared client config file `rig fund` consumes. */\nexport interface FundConfigFile {\n network?: string;\n faucetUrl?: string;\n faucetTimeoutMs?: number;\n relayUrl?: string;\n proxyUrl?: string;\n btpUrl?: string;\n}\n\n/** One chain's drip outcome — the parallel, independent unit of work. */\ninterface ChainDripResult {\n chain: FundChain;\n /** True when this chain's faucet drip succeeded. */\n funded: boolean;\n /** The address that was (or would have been) funded; null if none derived. */\n address: string | null;\n /** Raw faucet response body on success (shape is faucet-defined). */\n response?: unknown;\n /** Failure reason when `funded` is false. */\n error?: string;\n /** Wall-clock duration of this chain's drip in ms (present once attempted). */\n elapsedMs?: number;\n}\n\n/** `--json` envelope. */\ninterface FundJson {\n command: 'fund';\n identity: IdentityReport;\n /** True only when EVERY targeted chain funded (overall success). */\n funded: boolean;\n network: string | null;\n faucetUrl?: string;\n /** The per-chain drip results (one entry per targeted chain). */\n results?: ChainDripResult[];\n /**\n * Set when `network` was inferred as `devnet` from a\n * `*.devnet.toonprotocol.dev` origin (#288) rather than an explicit\n * `TOON_CLIENT_NETWORK`/config value — carries the origin that triggered\n * it. A fresh-install inference from the built-in genesis seed (no origin\n * configured anywhere) is marked with a ` (genesis seed)` suffix.\n */\n inferredDevnetFrom?: string;\n /** Non-devnet path: the derived wallet addresses to fund externally. */\n addresses?: { evm: string | null; solana: string | null };\n guidance?: string;\n}\n\n/** Hostname suffix of every shared-devnet edge (relay, proxy, faucet …). */\nconst SHARED_DEVNET_SUFFIX = '.devnet.toonprotocol.dev';\n\n/** `url` when its host is a shared-devnet edge (`*.devnet.toonprotocol.dev`). */\nfunction devnetHost(url: string | undefined): string | undefined {\n if (!url) return undefined;\n try {\n const { hostname } = new URL(url);\n if (\n hostname.endsWith(SHARED_DEVNET_SUFFIX) ||\n hostname === SHARED_DEVNET_SUFFIX.slice(1)\n ) {\n return url;\n }\n } catch {\n // junk URL — other commands surface that; fund only sniffs\n }\n return undefined;\n}\n\n/**\n * The first configured relay/uplink URL that points at the shared devnet\n * (`*.devnet.toonprotocol.dev`), if any. When the user's endpoints already\n * target the shared devnet but `network` still says `custom`, the fix for a\n * failed `rig fund` is `TOON_CLIENT_NETWORK=devnet` — NOT hunting for a\n * faucet URL (the #280 UX-study trap).\n *\n * The candidate endpoints are the env/config relay/proxy/btp URLs PLUS the\n * relay(s) resolved from the git `origin` remote (`originRelays`, resolved by\n * the same `rig remote`/git-config path push and fetch use — see\n * {@link resolveOriginRelays}). The git origin is the endpoint a fresh user\n * actually configures with `rig remote add origin <devnet relay>`; keying off\n * only env/config (#291) missed it, so plain `rig fund` still refused to drip\n * (#288 reopened). Exported for tests.\n */\nexport function sharedDevnetOrigin(\n env: NodeJS.ProcessEnv,\n file: FundConfigFile,\n originRelays: string[] = []\n): string | undefined {\n const candidates = [\n env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl,\n env['TOON_CLIENT_PROXY_URL'] ?? file.proxyUrl,\n env['TOON_CLIENT_BTP_URL'] ?? file.btpUrl,\n ...originRelays,\n ];\n for (const url of candidates) {\n const hit = devnetHost(url);\n if (hit) return hit;\n }\n return undefined;\n}\n\n/**\n * The relay URL(s) the git `origin` remote resolves to — the SAME resolution\n * `rig push`/`rig fetch` use (`resolveRelays` over the repo's real git\n * remotes + the deprecated `toon.relay` fallback). `rig fund` only sniffs the\n * host for the devnet suffix, so every failure mode is swallowed to `[]`: not\n * a git repo, no `origin`, a non-relay `origin` (a GitHub clone URL), or an\n * ambiguous multi-URL origin all mean \"no origin relay to infer from\" — never\n * an error out of a free command.\n */\n/**\n * Default {@link FundDeps.loadGenesisSeed}: core's committed genesis peer,\n * loaded lazily (same pattern as `rig init`'s offline relay fallback) so a\n * run that never needs it — any configured origin — never drags the\n * standalone bootstrap in. Failures mean \"no seed\", never an error out of a\n * free command.\n */\nasync function loadGenesisSeedDefault(): Promise<\n { relayUrl?: string; btpEndpoint?: string } | undefined\n> {\n // There is no built-in network seed since 4.0: a node is named (TOON_CONNECTOR\n // / `rig entry <url>`), never discovered. Nothing configured means no seed.\n return undefined;\n}\n\n/**\n * The devnet-or-not decision shared by `rig fund` and `rig name` (#288 + the\n * genesis-seed fresh-install fallback). Precedence:\n *\n * 1. An explicit non-`custom` `TOON_CLIENT_NETWORK`/config `network` is\n * authoritative — never coerced.\n * 2. Otherwise a configured `*.devnet.toonprotocol.dev` origin (env/config\n * relay/proxy/btp URL, or the git `origin` relay) infers devnet.\n * 3. Otherwise — NOTHING configured anywhere (a truly fresh install) —\n * core's committed genesis seed is consulted. Its URLs still go through\n * {@link devnetHost}: \"seed\" never hardcodes \"devnet\"; a future seed\n * pointing elsewhere simply stops inferring. Any configured origin,\n * devnet or not, suppresses the seed so a deliberately non-devnet setup\n * keeps refusing to drip.\n *\n * Exported for `rig name` (default `--via` DVM) and tests.\n */\nexport async function resolveEffectiveNetwork(opts: {\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Pre-read client config slice (callers that already loaded it). */\n file?: FundConfigFile;\n /** Genesis-seed loader seam (tests inject; default core's committed seed). */\n loadGenesisSeed?: FundDeps['loadGenesisSeed'];\n}): Promise<{\n /** The explicit env/config network value, if any. */\n network: string | undefined;\n /** `network` with devnet inference applied. */\n effectiveNetwork: string | undefined;\n /** The devnet-looking origin that drove (or could drive) inference. */\n devnetOrigin: string | undefined;\n /** True when the origin came from the built-in genesis seed. */\n seededOrigin: boolean;\n /** True when `effectiveNetwork` is an INFERRED devnet (not explicit). */\n inferredDevnet: boolean;\n}> {\n const { env, cwd } = opts;\n const file = opts.file ?? readFundConfig(env).file;\n const network = env['TOON_CLIENT_NETWORK'] ?? file.network;\n const canInfer = network === undefined || network === 'custom';\n const originRelays = canInfer ? await resolveOriginRelays(cwd) : [];\n let devnetOrigin = sharedDevnetOrigin(env, file, originRelays);\n let seededOrigin = false;\n if (devnetOrigin === undefined && canInfer) {\n const anyConfiguredOrigin = [\n env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl,\n env['TOON_CLIENT_PROXY_URL'] ?? file.proxyUrl,\n env['TOON_CLIENT_BTP_URL'] ?? file.btpUrl,\n ...originRelays,\n ].some((url) => url !== undefined);\n if (!anyConfiguredOrigin) {\n const seed = await (opts.loadGenesisSeed ?? loadGenesisSeedDefault)();\n devnetOrigin = devnetHost(seed?.relayUrl) ?? devnetHost(seed?.btpEndpoint);\n seededOrigin = devnetOrigin !== undefined;\n }\n }\n const inferredDevnet = devnetOrigin !== undefined && canInfer;\n return {\n network,\n effectiveNetwork: inferredDevnet ? 'devnet' : network,\n devnetOrigin,\n seededOrigin,\n inferredDevnet,\n };\n}\n\nexport async function resolveOriginRelays(cwd: string): Promise<string[]> {\n let repoRoot: string;\n try {\n repoRoot = await resolveRepoRoot(cwd);\n } catch {\n return [];\n }\n try {\n const toonConfig = await readToonConfig(repoRoot);\n const resolved = await resolveRelays({\n relayFlags: [],\n remoteName: undefined,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n return resolved.relays;\n } catch {\n return [];\n }\n}\n\n/**\n * Remediation for `rig fund` on a network without a faucet. Orders the\n * suggestions by likelihood (#280): the network preset FIRST — a fresh\n * config defaults to `custom`, and on the shared devnet the whole fix is\n * `TOON_CLIENT_NETWORK=devnet` — then the faucet-URL override for\n * self-hosted networks, then external funding. Exported for tests.\n */\nexport function noFaucetGuidance(\n network: string | undefined,\n devnetOrigin: string | undefined\n): string {\n const head = `no faucet is configured for network ${JSON.stringify(network ?? 'custom')}`;\n const external =\n 'To fund the wallet externally instead, send the settlement token plus ' +\n 'native gas to the address below for the chain your channels settle on.';\n if (devnetOrigin !== undefined) {\n return (\n `${head} — but your configured origin (${devnetOrigin}) looks like ` +\n 'the shared devnet. Set TOON_CLIENT_NETWORK=devnet (or \"network\": ' +\n '\"devnet\" in the client config) and re-run `rig fund` — no faucet ' +\n `URL is needed there. ${external}`\n );\n }\n return (\n `${head}. If you meant the shared devnet, set TOON_CLIENT_NETWORK=devnet ` +\n 'and re-run `rig fund` — no faucet URL is needed there. If this is a ' +\n 'self-hosted network with its own faucet, set TOON_CLIENT_FAUCET_URL ' +\n `(or the faucetUrl config field). ${external}`\n );\n}\n\nfunction readFundConfig(env: NodeJS.ProcessEnv): {\n file: FundConfigFile;\n configPath: string;\n} {\n const dir = env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n const configPath = join(dir, 'config.json');\n try {\n return {\n file: JSON.parse(readFileSync(configPath, 'utf8')) as FundConfigFile,\n configPath,\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return { file: {}, configPath };\n }\n throw new Error(\n `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** Run `rig fund`; returns the process exit code. */\nexport async function runFund(args: string[], deps: FundDeps): Promise<number> {\n const { io, env } = deps;\n\n let resolvedChain: FundChain | 'all' | undefined;\n let addressFlag: string | undefined;\n let json = false;\n try {\n const { values, positionals } = parseArgs({\n args,\n allowPositionals: true,\n options: {\n chain: { type: 'string' },\n address: { type: 'string' },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(FUND_USAGE);\n return 0;\n }\n // The chain can be given positionally (`rig fund sol`) OR with `--chain`,\n // but not both, and at most one positional is accepted.\n if (positionals.length > 1) {\n throw new Error(\n `rig fund takes at most one chain argument, got ${positionals.length}: ${positionals.join(' ')}`\n );\n }\n const positionalChain = positionals[0];\n if (positionalChain !== undefined && values.chain !== undefined) {\n throw new Error(\n 'give the chain as a positional argument (`rig fund sol`) OR with --chain, not both'\n );\n }\n resolvedChain = resolveChainArg(positionalChain ?? values.chain);\n addressFlag = values.address;\n json = values.json ?? false;\n // A per-chain address (`--address`) is meaningless across chains — an EVM\n // 0x address cannot fund Solana or Mina. Require an explicit single chain.\n if (addressFlag !== undefined && (resolvedChain === undefined || resolvedChain === 'all')) {\n throw new Error(\n `--address requires an explicit single chain (${CHAIN_ARG_LIST}) — ` +\n 'a single address cannot fund every chain'\n );\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(FUND_USAGE);\n return 2;\n }\n\n try {\n const { file } = readFundConfig(env);\n // MULTI-CHAIN BY DEFAULT (#299 parity): no chain argument (or `all`) funds\n // every supported chain; a specific chain narrows to one. The env/config\n // `chain` settlement preference no longer narrows `rig fund` — funding all\n // chains is a strict superset and matches `rig balance`.\n const targetChains: FundChain[] =\n resolvedChain === undefined || resolvedChain === 'all'\n ? [...CHAINS]\n : [resolvedChain];\n const network = env['TOON_CLIENT_NETWORK'] ?? file.network;\n // A configured `*.devnet.toonprotocol.dev` origin means the shared devnet\n // even when `network` still reads its `custom` default (#288): the host\n // already encodes it, so infer devnet and let the faucet \"just work\"\n // instead of making the user also export TOON_CLIENT_NETWORK=devnet. The\n // origin can be an env/config relay/proxy/btp endpoint OR the git `origin`\n // remote `rig remote add origin …` configured (resolved like push/fetch);\n // a fresh user who only ran that must still get the drip. An EXPLICIT\n // non-`custom` network stays authoritative — it is never coerced.\n //\n // Only an unset/`custom` network can be inferred to devnet; when the\n // network is explicit and non-`custom` the inference is a no-op, so skip\n // the git-origin resolution (several `git` subprocesses) entirely.\n const { devnetOrigin, seededOrigin, inferredDevnet, effectiveNetwork } =\n await resolveEffectiveNetwork({\n env,\n cwd: deps.cwd,\n file,\n ...(deps.loadGenesisSeed\n ? { loadGenesisSeed: deps.loadGenesisSeed }\n : {}),\n });\n const faucetUrl =\n env['TOON_CLIENT_FAUCET_URL'] ??\n file.faucetUrl ??\n (effectiveNetwork === 'devnet' ? DEVNET_FAUCET_URL : undefined);\n\n // ── Identity chain → wallet addresses (never the phrase) ────────────────\n const resolved = await resolveIdentity({\n env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n });\n const identity: IdentityReport = {\n pubkey: resolved.pubkey,\n source: resolved.source,\n sourceLabel: resolved.sourceLabel,\n };\n // Dynamic import: `@toon-protocol/client` is heavy; runs that fail\n // earlier (usage errors) never pay its startup cost.\n const client = await import('@toon-protocol/client');\n const derived = client.deriveFullIdentity(resolved.mnemonic, {\n accountIndex: resolved.accountIndex,\n scheme: 'legacy',\n });\n const addresses = {\n evm: derived.evm.address || null,\n solana: derived.solana.publicKey || null,\n };\n\n // ── No faucet on this network: name the ACTUAL knob first (#280) ────────\n if (!faucetUrl) {\n const guidance = noFaucetGuidance(network, devnetOrigin);\n if (json) {\n io.emitJson({\n command: 'fund',\n identity,\n funded: false,\n network: network ?? null,\n addresses,\n guidance,\n } satisfies FundJson);\n return 0;\n }\n io.out(renderIdentityLine(identity));\n io.out(guidance);\n io.out('Wallet addresses:');\n io.out(` evm ${addresses.evm ?? '(no key derived)'}`);\n io.out(` solana ${addresses.solana ?? '(no key derived)'}`);\n return 0;\n }\n\n // ── Devnet faucet drips (parallel, independent per chain) ───────────────\n // Env/config override applies uniformly to every chain's drip.\n const timeoutEnv = env['TOON_CLIENT_FAUCET_TIMEOUT_MS'];\n const timeoutFor = (): number => {\n if (timeoutEnv && Number.isFinite(Number(timeoutEnv))) return Number(timeoutEnv);\n if (file.faucetTimeoutMs !== undefined) return file.faucetTimeoutMs;\n return 90_000;\n };\n\n if (!json && inferredDevnet) {\n io.out(\n seededOrigin\n ? `Inferred network 'devnet' from the built-in genesis seed ` +\n `${devnetOrigin} (nothing configured — fresh install). ` +\n 'Set TOON_CLIENT_NETWORK explicitly to override.'\n : `Inferred network 'devnet' from the configured origin ${devnetOrigin} ` +\n `(network was ${JSON.stringify(network ?? 'custom')}). ` +\n 'Set TOON_CLIENT_NETWORK explicitly to override.'\n );\n }\n if (!json) {\n const list = targetChains.join(', ');\n io.out(\n `Requesting ${targetChains.length === 1 ? '' : 'parallel '}USDC drip${targetChains.length === 1 ? '' : 's'} ` +\n `from ${faucetUrl} for ${list} …`\n );\n }\n\n // Each chain is an INDEPENDENT unit: derive-or-fail and drip-or-fail are\n // both captured into a ChainDripResult so one chain's failure never\n // rejects the batch. Kicking every drip off before awaiting makes them\n // genuinely concurrent (the Mina ~75s overlaps evm/solana, not stacks).\n const singleChain = targetChains.length === 1;\n const drips = targetChains.map(async (chain): Promise<ChainDripResult> => {\n const address = (singleChain ? addressFlag : undefined) ?? addresses[chain];\n if (!address) {\n return {\n chain,\n funded: false,\n address: null,\n error: `no ${chain} address could be derived for this identity`,\n };\n }\n const started = Date.now();\n try {\n const { response } = await client.fundWallet(faucetUrl, address, chain, {\n timeout: timeoutFor(),\n ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}),\n });\n return {\n chain,\n funded: true,\n address,\n response,\n elapsedMs: Date.now() - started,\n };\n } catch (err) {\n return {\n chain,\n funded: false,\n address,\n error: err instanceof Error ? err.message : String(err),\n elapsedMs: Date.now() - started,\n };\n }\n });\n const results = await Promise.all(drips);\n const allFunded = results.every((r) => r.funded);\n\n if (json) {\n io.emitJson({\n command: 'fund',\n identity,\n funded: allFunded,\n network: effectiveNetwork ?? null,\n faucetUrl,\n results,\n ...(inferredDevnet\n ? {\n inferredDevnetFrom: seededOrigin\n ? `${devnetOrigin} (genesis seed)`\n : devnetOrigin,\n }\n : {}),\n } satisfies FundJson);\n return allFunded ? 0 : 1;\n }\n\n for (const r of results) {\n const label = r.chain.padEnd(6);\n // Always echo the funded (or attempted) address so a human can confirm\n // WHERE the funds went — essential when `--address` targets an arbitrary,\n // non-derived address a typo could misdirect (only shown via --json\n // otherwise).\n const addr = r.address ? ` → ${r.address}` : '';\n if (r.funded) {\n // The faucet drips USDC only (gas is assumed); annotate the token, and\n // the wall time for slow chains (mina) so a >1-minute wait reads as normal.\n const slow = r.elapsedMs !== undefined && r.elapsedMs >= 5_000;\n const time = slow ? ` (${Math.round((r.elapsedMs as number) / 1000)}s)` : '';\n io.out(` ${label} ✓ funded (USDC)${addr}${time}`);\n } else {\n io.out(` ${label} ✗${addr} — ${r.error ?? 'failed'}`);\n }\n }\n io.out(renderIdentityLine(identity));\n io.out('Re-check with `rig balance` (a drip can take a few blocks to land).');\n return allFunded ? 0 : 1;\n } catch (err) {\n return emitCliError(io, json, 'fund', err);\n }\n}\n","/**\n * Git passthrough (#250): any subcommand `rig` does not own is executed as\n * `git <argv...>` verbatim — `rig status`, `rig add -p`, `rig commit`,\n * `rig log --oneline`, `rig rebase -i`, everything.\n *\n * The child git runs with `stdio: 'inherit'` so interactive commands, pagers,\n * colors, and prompts behave exactly as if the user had typed `git` (no\n * capture, no buffering). The child's exit code is propagated verbatim; a\n * child killed by a signal maps to the shell convention 128+N. While the\n * child runs, rig ignores-and-forwards SIGINT/SIGTERM/SIGHUP so git (not\n * rig) decides the outcome of a Ctrl-C — e.g. `rebase -i` gets to clean up —\n * and rig then reports git's exit.\n */\n\nimport { spawn } from 'node:child_process';\nimport { constants as osConstants } from 'node:os';\n\nexport interface GitPassthroughOptions {\n /** Working directory for the git child (default: the rig process cwd). */\n cwd?: string;\n /** Environment for the git child (default: the rig process env). */\n env?: NodeJS.ProcessEnv;\n /** Write one line to stderr (missing-git error); default: process.stderr. */\n err?: (line: string) => void;\n}\n\n/** The passthrough seam `dispatch` uses; tests inject a fake. */\nexport type GitRunner = (\n argv: string[],\n options?: GitPassthroughOptions\n) => Promise<number>;\n\n/** Exit code when the system git binary cannot be found (shell convention). */\nexport const GIT_NOT_FOUND_EXIT = 127;\n\n/** Signals relayed to the git child while it runs. */\nconst RELAYED_SIGNALS: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGHUP'];\n\n/** Shell-convention exit code for a child terminated by `signal`. */\nfunction signalExitCode(signal: NodeJS.Signals): number {\n const num = osConstants.signals[signal];\n return num === undefined ? 1 : 128 + num;\n}\n\n/**\n * Run system `git` with the exact argv tail, inheriting rig's stdio.\n * Resolves to the exit code rig should exit with; never rejects.\n */\nexport const runGitPassthrough: GitRunner = (argv, options = {}) => {\n const err =\n options.err ?? ((line: string) => process.stderr.write(`${line}\\n`));\n\n return new Promise<number>((resolve) => {\n const child = spawn('git', argv, {\n stdio: 'inherit',\n ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n env: options.env ?? process.env,\n });\n\n // Terminal-generated signals (Ctrl-C) already reach the child through the\n // shared foreground process group; the handlers stop rig's default\n // die-on-signal so the child controls the outcome, and forward the signal\n // for the cases where only rig was targeted (`kill <rig-pid>`).\n const relay = new Map<NodeJS.Signals, () => void>();\n for (const signal of RELAYED_SIGNALS) {\n const handler = (): void => {\n child.kill(signal);\n };\n relay.set(signal, handler);\n process.on(signal, handler);\n }\n const restoreSignals = (): void => {\n for (const [signal, handler] of relay) process.removeListener(signal, handler);\n };\n\n child.on('error', (spawnErr: NodeJS.ErrnoException) => {\n restoreSignals();\n if (spawnErr.code === 'ENOENT') {\n err(\n `rig: git not found — \\`rig ${argv[0] ?? ''}\\` is not a rig command, so it is ` +\n 'passed through to the system `git`, which is not on your PATH. ' +\n 'Install git (https://git-scm.com) or fix your PATH.'\n );\n resolve(GIT_NOT_FOUND_EXIT);\n return;\n }\n err(`rig: failed to run git: ${spawnErr.message}`);\n resolve(1);\n });\n\n child.on('close', (code, signal) => {\n restoreSignals();\n resolve(signal !== null ? signalExitCode(signal) : (code ?? 1));\n });\n });\n};\n","/**\n * `rig identity` — the cold-start identity command group (#294).\n *\n * rig resolves a signing identity along a precedence chain (./identity.ts) but,\n * before this command, it never MINTED one: a brand-new user hit\n * {@link MissingIdentityError} and had to hand-mint a BIP-39 phrase out of band\n * before anything ran. `rig identity` closes that gap while keeping rig's\n * deliberate security invariants intact:\n *\n * - `rig identity create` — generate a fresh BIP-39 mnemonic (via the\n * client's existing generator — no hand-rolled bip39/crypto), display it\n * ONCE with a prominent backup warning, and persist it to the ENCRYPTED\n * keystore under `TOON_CLIENT_HOME` (reusing the client/daemon keystore\n * write path + the auto-password convention). This is the ONLY command\n * that ever surfaces a phrase, and `--json` is the ONE sanctioned path\n * that emits the phrase in machine output (a scripting/agent need).\n * - `rig identity show` — report the active identity's SOURCE + derived\n * pubkey; NEVER the phrase, in any mode.\n * - `rig identity import` — read an existing phrase from stdin/prompt (NEVER\n * argv — that leaks to shell history / `ps`) and write it to the keystore.\n *\n * The phrase is written ONLY to the encrypted keystore (or shown once / emitted\n * in the sanctioned `create --json` envelope) — never to git config, never to a\n * repo file, never to plaintext outside the keystore. Persistence is gated on\n * the command being explicitly invoked (and refuses to clobber an existing\n * identity without `--force`).\n */\n\nimport { existsSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport {\n clientConfigPath,\n clientKeystorePath,\n DEFAULT_KEYSTORE_PASSWORD,\n linkKeystoreInClientConfig,\n MissingIdentityError,\n readClientConfigFile,\n resolveAccountIndex,\n resolveIdentity,\n type ResolvedIdentity,\n} from './identity.js';\nimport type { CliIo } from './output.js';\nimport { renderIdentityLine } from './render.js';\nimport { deriveNostrKeyFromMnemonic } from '../standalone/nostr-identity.js';\n\n// ---------------------------------------------------------------------------\n// Deps + client-key seam\n// ---------------------------------------------------------------------------\n\n/** The `@toon-protocol/client` key operations `rig identity` reuses. */\nexport interface IdentityKeyOps {\n /** Generate a fresh mnemonic, encrypt it, and write the keystore to `path`. */\n generateKeystore(path: string, password: string): { mnemonic: string };\n /** Validate + encrypt an existing mnemonic and write the keystore to `path`. */\n importKeystore(path: string, mnemonic: string, password: string): unknown;\n /** Derive the Nostr pubkey (hex) for a mnemonic at a BIP-44 account index. */\n deriveNostrKeyFromMnemonic(\n mnemonic: string,\n accountIndex?: number\n ): { pubkey: string };\n}\n\n/** Default key-ops loader: the real client, dynamically imported (see below). */\nasync function loadKeyOps(): Promise<IdentityKeyOps> {\n const { generateKeystore, importKeystore } = await import(\n '@toon-protocol/client'\n );\n return { generateKeystore, importKeystore, deriveNostrKeyFromMnemonic };\n}\n\n/** Deps `rig identity` needs; the seams default to the real implementations. */\nexport interface IdentityDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Identity resolver seam (tests); defaults to the real chain. */\n resolveIdentityImpl?: typeof resolveIdentity;\n /** Client key-ops seam (tests); defaults to `@toon-protocol/client`. */\n loadKeyOps?: () => Promise<IdentityKeyOps>;\n /**\n * Read one line of secret input for `rig identity import` (tests). Defaults\n * to a stdin read (prompt on stderr when interactive). NEVER argv.\n */\n readSecretLine?: (prompt: string, isInteractive: boolean) => Promise<string>;\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/** Refused: an identity already resolves and `--force` was not given. */\nexport class IdentityExistsError extends Error {\n constructor(\n public readonly pubkey: string,\n public readonly sourceLabel: string\n ) {\n super(\n `an identity already resolves (${pubkey}, from ${sourceLabel}) — rig ` +\n 'will not overwrite it. Inspect it with `rig identity show`, or pass ' +\n '`--force` to replace the keystore with a brand-new identity (the old ' +\n 'phrase becomes unrecoverable unless you backed it up).'\n );\n this.name = 'IdentityExistsError';\n }\n}\n\n/** Refused: a keystore file already sits at the target path (unlinked). */\nexport class KeystoreFileExistsError extends Error {\n constructor(public readonly keystorePath: string) {\n super(\n `a keystore file already exists at ${keystorePath} — rig will not ` +\n 'overwrite it. Link it via the client config, or pass `--force` to ' +\n 'replace it with a new identity.'\n );\n this.name = 'KeystoreFileExistsError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core: generate / import → encrypted keystore\n// ---------------------------------------------------------------------------\n\n/** A newly minted (or imported) identity — the phrase is present ONLY here. */\nexport interface CreatedIdentity {\n /** The BIP-39 phrase. Surfaced only by `create` (once / `--json`). */\n mnemonic: string;\n pubkey: string;\n keystorePath: string;\n configPath: string;\n /** True when rig chose the default keystore password (no user password). */\n autoPassword: boolean;\n accountIndex: number;\n /**\n * Set only when a HIGHER-precedence source (env / .env) still shadows the\n * new keystore identity — possible only under `--force`.\n */\n shadowedBy?: { sourceLabel: string; pubkey: string };\n}\n\n/** Inputs shared by `create` and `import` (IO-free core). */\nexport interface MintIdentityInput {\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Overwrite an existing identity / keystore file. */\n force: boolean;\n warn(line: string): void;\n resolveIdentityImpl?: typeof resolveIdentity;\n loadKeyOps?: () => Promise<IdentityKeyOps>;\n}\n\ninterface KeystoreTarget {\n keystorePath: string;\n password: string;\n autoPassword: boolean;\n /** An identity that already resolved (guards + shadow reporting). */\n existing?: ResolvedIdentity;\n keyOps: IdentityKeyOps;\n}\n\n/** Guard against clobbering, resolve the keystore path + password. */\nasync function prepareKeystoreTarget(\n input: MintIdentityInput\n): Promise<KeystoreTarget> {\n const keyOps = await (input.loadKeyOps ?? loadKeyOps)();\n const resolveImpl = input.resolveIdentityImpl ?? resolveIdentity;\n\n let existing: ResolvedIdentity | undefined;\n try {\n existing = await resolveImpl({\n env: input.env,\n cwd: input.cwd,\n warn: input.warn,\n });\n } catch (err) {\n if (!(err instanceof MissingIdentityError)) throw err;\n }\n if (existing && !input.force) {\n throw new IdentityExistsError(existing.pubkey, existing.sourceLabel);\n }\n\n const keystorePath = clientKeystorePath(input.env);\n if (existsSync(keystorePath) && !input.force) {\n throw new KeystoreFileExistsError(keystorePath);\n }\n\n // The keystore password comes ONLY from TOON_CLIENT_KEYSTORE_PASSWORD (env),\n // never a CLI flag: a `--password` argv would leak the value that decrypts\n // the keystore to shell history / `ps` / `/proc` — the exact exposure this\n // command deliberately avoids for the seed phrase itself. No env var → the\n // default password, so the identity reloads with no configuration.\n const envPassword = input.env['TOON_CLIENT_KEYSTORE_PASSWORD']?.trim() || undefined;\n const autoPassword = envPassword === undefined;\n const password = envPassword ?? DEFAULT_KEYSTORE_PASSWORD;\n\n mkdirSync(dirname(keystorePath), { recursive: true });\n return { keystorePath, password, autoPassword, existing, keyOps };\n}\n\n/** BIP-44 account index exactly as {@link resolveIdentity} will pick it for\n * the keystore this command mints (`RIG_ACCOUNT_INDEX` env > shared config >\n * 0), so the reported pubkey matches subsequent runs. */\nfunction readAccountIndex(env: NodeJS.ProcessEnv): number {\n const file = readClientConfigFile(clientConfigPath(env));\n return resolveAccountIndex(env, 'keystore', file);\n}\n\n/** Assemble the {@link CreatedIdentity} once a phrase is on disk. */\nfunction finishMint(\n input: MintIdentityInput,\n target: KeystoreTarget,\n mnemonic: string\n): CreatedIdentity {\n const configPath = linkKeystoreInClientConfig(\n input.env,\n target.keystorePath,\n target.autoPassword\n );\n const accountIndex = readAccountIndex(input.env);\n const { pubkey } = target.keyOps.deriveNostrKeyFromMnemonic(\n mnemonic,\n accountIndex\n );\n const result: CreatedIdentity = {\n mnemonic,\n pubkey,\n keystorePath: target.keystorePath,\n configPath,\n autoPassword: target.autoPassword,\n accountIndex,\n };\n if (target.existing && target.existing.pubkey !== pubkey) {\n result.shadowedBy = {\n sourceLabel: target.existing.sourceLabel,\n pubkey: target.existing.pubkey,\n };\n }\n return result;\n}\n\n/** Generate a fresh identity into the encrypted keystore. */\nexport async function createIdentity(\n input: MintIdentityInput\n): Promise<CreatedIdentity> {\n const target = await prepareKeystoreTarget(input);\n const { mnemonic } = target.keyOps.generateKeystore(\n target.keystorePath,\n target.password\n );\n return finishMint(input, target, mnemonic);\n}\n\n/** Import an existing phrase into the encrypted keystore (validated). */\nexport async function importIdentity(\n input: MintIdentityInput & { mnemonic: string }\n): Promise<CreatedIdentity> {\n const target = await prepareKeystoreTarget(input);\n // importKeystore validates the BIP-39 phrase before writing anything.\n target.keyOps.importKeystore(\n target.keystorePath,\n input.mnemonic,\n target.password\n );\n return finishMint(input, target, input.mnemonic);\n}\n\n// ---------------------------------------------------------------------------\n// Human display (the one-time backup banner)\n// ---------------------------------------------------------------------------\n\n/** The one-time seed-phrase backup banner (human, non-`--json`). */\nexport function createdIdentityBanner(result: CreatedIdentity): string[] {\n return [\n '',\n '════════════════════════════════════════════════════════════════',\n ' rig: generated a new identity',\n '════════════════════════════════════════════════════════════════',\n ` Nostr pubkey : ${result.pubkey}`,\n '',\n ' Seed phrase — this phrase CONTROLS YOUR FUNDS. Write it down and',\n ' store it safely. It is shown ONCE and CANNOT be recovered:',\n '',\n ` ${result.mnemonic}`,\n '',\n ` Encrypted keystore: ${result.keystorePath}`,\n result.autoPassword\n ? ' Encrypted with the default password, so the identity reloads with no\\n' +\n ' env var. To use your own password: set TOON_CLIENT_KEYSTORE_PASSWORD\\n' +\n ' and re-import with `rig identity import`.'\n : ' Encrypted with your TOON_CLIENT_KEYSTORE_PASSWORD.',\n '════════════════════════════════════════════════════════════════',\n '',\n ];\n}\n\n/** The stderr note fired after a fresh mint, when a higher tier shadows it. */\nexport function shadowNote(shadowedBy: {\n sourceLabel: string;\n pubkey: string;\n}): string {\n return (\n `note: a higher-precedence identity (${shadowedBy.pubkey}, from ` +\n `${shadowedBy.sourceLabel}) still shadows the new keystore — rig keeps ` +\n 'using it until you remove that source (unset the env var / edit .env).'\n );\n}\n\n// ---------------------------------------------------------------------------\n// Command dispatch\n// ---------------------------------------------------------------------------\n\nexport const IDENTITY_USAGE = `Usage: rig identity <command> [options]\n\nManage the BIP-39 signing identity rig uses to sign and pay:\n\n create generate a fresh identity into the encrypted keystore under\n TOON_CLIENT_HOME. The seed phrase is shown ONCE — back it up.\n Refuses to overwrite an existing identity without --force.\n show report the ACTIVE identity's source + derived pubkey (never the\n phrase); errors with the resolution remediation when none exists.\n import read an EXISTING phrase from stdin (never a CLI argument) and write\n it to the encrypted keystore.\n\nOptions:\n --force (create/import) replace an existing identity/keystore\n --json machine-readable output. NOTE: \\`identity create --json\\`\n DELIBERATELY emits the seed phrase in a \\`mnemonic\\`\n field — treat that output as SECRET. \\`identity show\\`\n and \\`identity import\\` never emit the phrase.\n -h, --help show this help\n\nThe keystore is encrypted with TOON_CLIENT_KEYSTORE_PASSWORD when that env var\nis set, else a default password so the identity reloads with no configuration.\nrig deliberately does NOT accept the keystore password as a CLI flag — that\nwould leak the value that decrypts your keys to shell history and \\`ps\\`.`;\n\n/** Route `rig identity <sub>`; returns the process exit code. */\nexport async function runIdentity(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const [sub, ...rest] = args;\n switch (sub) {\n case 'create':\n return runIdentityCreate(rest, deps);\n case 'show':\n return runIdentityShow(rest, deps);\n case 'import':\n return runIdentityImport(rest, deps);\n case 'help':\n case '--help':\n case '-h':\n deps.io.out(IDENTITY_USAGE);\n return 0;\n case undefined:\n deps.io.err('rig identity needs a subcommand: create | show | import');\n deps.io.err(IDENTITY_USAGE);\n return 2;\n default:\n deps.io.err(`unknown rig identity subcommand: ${sub}`);\n deps.io.err(IDENTITY_USAGE);\n return 2;\n }\n}\n\ninterface MintFlags {\n force: boolean;\n json: boolean;\n help: boolean;\n}\n\nfunction parseMintArgs(args: string[], verb: string): MintFlags {\n // No `--password` option on purpose: an unknown `--password` therefore\n // errors out (caught → usage exit) rather than silently accepting a secret\n // on the command line. The keystore password comes from the env var only.\n const { values, positionals } = parseArgs({\n args,\n options: {\n force: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: false,\n });\n if (positionals.length > 0) {\n throw new Error(`rig identity ${verb} takes no positional arguments`);\n }\n return {\n force: values.force ?? false,\n json: values.json ?? false,\n help: values.help ?? false,\n };\n}\n\nasync function runIdentityCreate(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const { io } = deps;\n let flags: MintFlags;\n try {\n flags = parseMintArgs(args, 'create');\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(IDENTITY_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(IDENTITY_USAGE);\n return 0;\n }\n\n try {\n const result = await createIdentity({\n env: deps.env,\n cwd: deps.cwd,\n force: flags.force,\n warn: (line) => io.err(line),\n ...(deps.resolveIdentityImpl\n ? { resolveIdentityImpl: deps.resolveIdentityImpl }\n : {}),\n ...(deps.loadKeyOps ? { loadKeyOps: deps.loadKeyOps } : {}),\n });\n emitCreated(io, flags.json, 'identity create', result);\n return 0;\n } catch (err) {\n return emitMintError(io, flags.json, 'identity create', err);\n }\n}\n\nasync function runIdentityImport(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const { io } = deps;\n let flags: MintFlags;\n try {\n flags = parseMintArgs(args, 'import');\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(IDENTITY_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(IDENTITY_USAGE);\n return 0;\n }\n\n try {\n const read = deps.readSecretLine ?? defaultReadSecretLine;\n const phrase = (\n await read(\n 'Paste your BIP-39 seed phrase (read from stdin, not the terminal ' +\n 'history): ',\n io.isInteractive\n )\n ).trim();\n if (phrase === '') {\n throw new Error(\n 'no seed phrase provided on stdin — pipe it in or type it at the ' +\n 'prompt (never pass a phrase as a CLI argument; it leaks to shell ' +\n 'history and `ps`).'\n );\n }\n const result = await importIdentity({\n env: deps.env,\n cwd: deps.cwd,\n force: flags.force,\n mnemonic: phrase,\n warn: (line) => io.err(line),\n ...(deps.resolveIdentityImpl\n ? { resolveIdentityImpl: deps.resolveIdentityImpl }\n : {}),\n ...(deps.loadKeyOps ? { loadKeyOps: deps.loadKeyOps } : {}),\n });\n // Import NEVER echoes the phrase back (unlike create) — only the pubkey.\n if (flags.json) {\n io.emitJson({\n command: 'identity import',\n imported: true,\n pubkey: result.pubkey,\n keystorePath: result.keystorePath,\n autoPassword: result.autoPassword,\n ...(result.shadowedBy ? { shadowedBy: result.shadowedBy } : {}),\n });\n } else {\n io.out(`Imported identity ${result.pubkey}`);\n io.out(` Encrypted keystore: ${result.keystorePath}`);\n }\n if (result.shadowedBy) io.err(shadowNote(result.shadowedBy));\n return 0;\n } catch (err) {\n return emitMintError(io, flags.json, 'identity import', err);\n }\n}\n\nasync function runIdentityShow(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const { io } = deps;\n let json = false;\n let help = false;\n try {\n const parsed = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: false,\n });\n json = parsed.values.json ?? false;\n help = parsed.values.help ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(IDENTITY_USAGE);\n return 2;\n }\n if (help) {\n io.out(IDENTITY_USAGE);\n return 0;\n }\n\n try {\n const identity = await (deps.resolveIdentityImpl ?? resolveIdentity)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n });\n // NEVER the phrase — source + derived pubkey only.\n if (json) {\n io.emitJson({\n command: 'identity show',\n source: identity.source,\n sourceLabel: identity.sourceLabel,\n pubkey: identity.pubkey,\n accountIndex: identity.accountIndex,\n });\n } else {\n io.out(renderIdentityLine(identity));\n io.out(` source : ${identity.source} (${identity.sourceLabel})`);\n io.out(` pubkey : ${identity.pubkey}`);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'identity show', err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Shared emitters\n// ---------------------------------------------------------------------------\n\n/**\n * Emit a freshly created identity. `--json` is the ONE sanctioned path that\n * carries the phrase (the `mnemonic` field) — a scripting/agent need — as the\n * single stdout document; human mode prints the one-time backup banner.\n */\nexport function emitCreated(\n io: CliIo,\n json: boolean,\n command: string,\n result: CreatedIdentity\n): void {\n if (json) {\n io.emitJson({\n command,\n created: true,\n pubkey: result.pubkey,\n keystorePath: result.keystorePath,\n autoPassword: result.autoPassword,\n // DELIBERATE, documented exception to \"never print the phrase\": the\n // scripting/agent path needs the generated phrase to back it up.\n mnemonic: result.mnemonic,\n ...(result.shadowedBy ? { shadowedBy: result.shadowedBy } : {}),\n });\n io.err(\n 'rig: `--json` emitted your seed phrase in the `mnemonic` field — this ' +\n 'output is SECRET; store it safely and do not log or share it.'\n );\n } else {\n for (const line of createdIdentityBanner(result)) io.out(line);\n }\n if (result.shadowedBy) io.err(shadowNote(result.shadowedBy));\n}\n\n/** Map the mint-path errors to output; refusals get their own stable codes. */\nfunction emitMintError(\n io: CliIo,\n json: boolean,\n command: string,\n err: unknown\n): 1 {\n if (err instanceof IdentityExistsError) {\n if (json) {\n io.emitJson({\n command,\n error: 'identity_exists',\n pubkey: err.pubkey,\n detail: err.message,\n });\n }\n for (const line of err.message.split('\\n')) io.err(line);\n return 1;\n }\n if (err instanceof KeystoreFileExistsError) {\n if (json) {\n io.emitJson({\n command,\n error: 'keystore_exists',\n keystorePath: err.keystorePath,\n detail: err.message,\n });\n }\n for (const line of err.message.split('\\n')) io.err(line);\n return 1;\n }\n return emitCliError(io, json, command, err);\n}\n\n/**\n * Default secret reader: one line from stdin. When a human types the phrase at\n * a TTY, the terminal echo is SUPPRESSED — the phrase is the most sensitive\n * value this CLI handles (\"CONTROLS YOUR FUNDS\"), so it must never land in\n * cleartext on screen, scrollback, or a session recording. We write the prompt\n * to stderr ourselves, then mute readline's echo of the typed characters (like\n * a conventional password prompt). Piped, non-interactive input has no echo to\n * mask, so it is read verbatim with no prompt.\n */\nasync function defaultReadSecretLine(\n prompt: string,\n isInteractive: boolean\n): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n if (isInteractive) {\n process.stderr.write(prompt);\n // Suppress echo of the typed secret. readline routes every keystroke\n // through `_writeToOutput`; replacing it with a no-op masks the input\n // while still capturing the line.\n (rl as unknown as { _writeToOutput: (s: string) => void })._writeToOutput =\n () => {\n /* mask: swallow every echoed keystroke so the phrase never prints */\n };\n }\n try {\n const answer = await rl.question('');\n // The muted Enter left the cursor on the hidden prompt line; advance it.\n if (isInteractive) process.stderr.write('\\n');\n return answer;\n } finally {\n rl.close();\n }\n}\n","/**\n * `rig init` — one-shot, idempotent repo setup (#248).\n *\n * Replaces the old \"config written as a side effect of the first push\":\n *\n * 1. ensures the working directory is inside a git repository — when it is\n * not, it OFFERS to `git init` for you (a TTY `[y/N]` prompt, or the\n * non-interactive `--git-init` flag), mirroring how it offers to mint an\n * identity on a cold start; a refusal keeps the old `git init` hint;\n * 2. resolves the signing identity via the RIG_MNEMONIC precedence chain\n * (./identity.ts) and reports the SOURCE + derived pubkey (never the\n * phrase); a chain miss errors with all three remediation options;\n * 3. writes `toon.repoid` (default: repo directory basename; existing\n * value kept on re-runs; `--repo-id` overrides) and `toon.owner` (the\n * derived pubkey) to the repository's LOCAL git config — the mnemonic\n * itself is never written to git config or any repo file;\n * 4. reports the relay setup (#249): when the deprecated v0.1\n * `git config toon.relay` is set and no `origin` remote exists, it\n * MIGRATES the value to a real `origin` git remote (the old key stays\n * readable as a fallback and is removed in v0.3); when nothing is\n * configured it suggests `rig remote add origin <relay-url>` as the\n * follow-up step.\n *\n * Re-running updates and reports instead of erroring. `--json` emits a\n * machine-readable report. Free — nothing is published or paid.\n */\n\nimport { basename } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError, NotAGitRepositoryError } from './errors.js';\nimport {\n resolveGitAuthor,\n profileTimeoutFromEnv,\n type GitAuthor,\n} from './git-author.js';\nimport {\n addGitRemote,\n initGitRepository,\n listGitRemotes,\n readToonConfig,\n resolveRepoRoot,\n setGitAuthor,\n writeToonConfig,\n type GitRemoteInfo,\n} from './git-config.js';\nimport {\n createIdentity,\n createdIdentityBanner,\n shadowNote,\n type CreatedIdentity,\n} from './identity-cmd.js';\nimport {\n MissingIdentityError,\n resolveIdentity,\n type ResolvedIdentity,\n} from './identity.js';\nimport type { CliIo } from './push.js';\nimport { isRelayUrl } from './remote.js';\nimport { renderIdentityLine } from './render.js';\n\nexport const INIT_USAGE = `Usage: rig init [options]\n\nSet up the current git repository for rig (one-shot, idempotent, free):\nresolves your identity (RIG_MNEMONIC env → project .env → ~/.toon-client\nkeystore/config), then writes toon.repoid and toon.owner to the repo's\nLOCAL git config. Re-running updates and reports; it never errors on an\nalready-initialized repo. The seed phrase is never written anywhere.\n\nIt also sets the repo's LOCAL git commit-author from your nostr identity\n(never --global) so \\`rig commit\\`/\\`git commit\\` work out of the box and every\ncommit is attributed to the signer: user.email = <npub>@nostr, user.name =\nyour kind:0 profile display name when published (read best-effort from a\nrelay, latest-wins) else the npub. Re-running refreshes the name from a\nnow-readable profile.\n\nThe follow-up step is adding a relay: \\`rig remote add origin <relay-url>\\`\n(a real git remote — \\`git remote -v\\` shows it). A deprecated v0.1\n\\`git config toon.relay\\` is migrated to the origin remote automatically\nwhen no origin exists (the old key stays readable and is removed in v0.3).\n\nWhen the directory is NOT inside a git repository, init does not dead-end: in\na terminal it offers to create one (\\`Initialize a git repository here?\n[y/N]\\`), and \\`--git-init\\` does it non-interactively. Likewise, when NO\nidentity resolves it offers to generate one (\\`Create a new identity now?\n[y/N]\\`), and \\`--generate-identity\\` does it non-interactively (equivalent to\n\\`rig identity create\\` — the phrase is shown once to back up). Nothing — repo\nor identity — is ever created without your yes. \\`--git-init\n--generate-identity\\` is a fully non-interactive fresh setup.\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: the existing\n toon.repoid, then the repo directory basename)\n --git-init when the cwd is not a git repo, run \\`git init\\` here\n first, then proceed (no prompt)\n --relay <url> relay to read your kind:0 profile from for the git\n author name (default: origin/toon.relay, then the\n genesis seed; skipped if none is resolvable)\n --generate-identity when no identity resolves, mint a fresh one (no prompt)\n --json machine-readable report\n -h, --help show this help`;\n\n/** Deps subset `rig init` needs (no publisher — init is free). */\nexport interface InitDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Identity resolver seam (tests); defaults to the real chain. */\n resolveIdentityImpl?: typeof resolveIdentity;\n /** Identity generator seam (tests); defaults to the real mint. */\n createIdentityImpl?: typeof createIdentity;\n /** Git-author resolver seam (tests); defaults to the real kind:0 read. */\n resolveGitAuthorImpl?: typeof resolveGitAuthor;\n}\n\ninterface InitFlags {\n repoId?: string;\n gitInit: boolean;\n relay?: string;\n generateIdentity: boolean;\n json: boolean;\n help: boolean;\n}\n\nfunction parseInitArgs(args: string[]): InitFlags {\n const { values, positionals } = parseArgs({\n args,\n options: {\n 'repo-id': { type: 'string' },\n 'git-init': { type: 'boolean', default: false },\n relay: { type: 'string' },\n 'generate-identity': { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: false,\n });\n if (positionals.length > 0) {\n throw new Error(`rig init takes no positional arguments`);\n }\n const flags: InitFlags = {\n gitInit: values['git-init'] ?? false,\n generateIdentity: values['generate-identity'] ?? false,\n json: values.json ?? false,\n help: values.help ?? false,\n };\n const repoId = values['repo-id'];\n if (repoId !== undefined) {\n if (repoId.trim() === '') throw new Error('--repo-id must not be empty');\n flags.repoId = repoId;\n }\n const relay = values.relay;\n if (relay !== undefined) {\n if (relay.trim() === '') throw new Error('--relay must not be empty');\n flags.relay = relay.trim();\n }\n return flags;\n}\n\n/** True for a WebSocket-scheme URL (the kind:0 profile read speaks only ws(s)). */\nfunction isWebSocketRelay(url: string): boolean {\n return /^wss?:\\/\\//i.test(url);\n}\n\n/**\n * Resolve the relay to read the identity's kind:0 profile from, at init time —\n * BEFORE `rig remote add origin` may have run. Precedence: `--relay` flag →\n * the `origin` remote → the deprecated `toon.relay` → the #264 genesis seed.\n * Only ws(s) URLs qualify (the read is a WebSocket REQ); returns undefined when\n * none resolves, in which case the git author falls back to the npub.\n */\nasync function resolveProfileRelay(\n flagRelay: string | undefined,\n originRelay: string | undefined,\n toonRelays: string[]\n): Promise<string | undefined> {\n const candidates = [\n flagRelay,\n originRelay,\n ...toonRelays,\n ].filter((u): u is string => u !== undefined && isWebSocketRelay(u));\n if (candidates[0] !== undefined) return candidates[0];\n // No relay anywhere: the author falls back to the npub. (There is no\n // built-in network seed since 4.0 — a node is named, never discovered.)\n return undefined;\n}\n\n/** JSON envelope emitted by `rig init --json`. */\ninterface InitJsonOutput {\n command: 'init';\n repoRoot: string;\n /** True when THIS run created the git repository (`--git-init` or a TTY yes). */\n initializedGitRepo: boolean;\n repoId: string;\n /** `toon.owner` — the derived pubkey of the active identity. */\n owner: string;\n identity: {\n source: ResolvedIdentity['source'];\n sourceLabel: string;\n pubkey: string;\n };\n /** Deprecated `git config toon.relay` values (kept readable until v0.3). */\n relays: string[];\n /** True when any relay source is configured (origin remote or toon.relay). */\n relayConfigured: boolean;\n /** Configured git remotes (post-migration). */\n remotes: GitRemoteInfo[];\n /** The single relay URL of the `origin` remote, when it is one. */\n origin: string | null;\n /** True when this run migrated toon.relay to a new `origin` remote. */\n migratedToonRelay: boolean;\n /**\n * The repo-local git commit-author derived from the nostr identity (#302):\n * `user.name` (kind:0 display name when published, else the npub) and\n * `user.email` = `<npub>@nostr`. Always set so `rig commit` works out of the\n * box; `source` records whether the name came from the profile or the npub.\n */\n gitAuthor: { name: string; email: string; source: GitAuthor['source'] };\n /** What this run changed in git config (false = already up to date). */\n changed: { repoId: boolean; owner: boolean };\n /**\n * Present only when THIS run generated the identity (`--generate-identity`\n * or a TTY yes). Like `rig identity create --json`, it carries the seed\n * phrase in `mnemonic` for the scripted path — treat as SECRET.\n */\n generatedIdentity?: {\n mnemonic: string;\n pubkey: string;\n keystorePath: string;\n autoPassword: boolean;\n };\n}\n\n/**\n * Resolve the git worktree root; when the cwd is not inside a repo, create one\n * instead of dead-ending — but ONLY with consent (`--git-init` or an\n * interactive `[y/N]` yes), mirroring the identity generate-on-first-run flow.\n * A refusal (non-interactive, or a prompt no) throws {@link\n * NotAGitRepositoryError}, whose remediation now leads with `rig init\n * --git-init`. `git init` runs in the cwd only (never a parent).\n */\nasync function resolveOrInitGitRepo(\n deps: InitDeps,\n flags: InitFlags\n): Promise<{ repoRoot: string; initialized: boolean }> {\n const { io } = deps;\n try {\n return { repoRoot: await resolveRepoRoot(deps.cwd), initialized: false };\n } catch {\n let doInit = flags.gitInit;\n if (!doInit && io.isInteractive && !flags.json) {\n io.err('Not a git repository — rig keeps its config and objects in one.');\n doInit = await io.confirm('Initialize a git repository here? [y/N] ');\n }\n if (!doInit) throw new NotAGitRepositoryError(deps.cwd);\n\n await initGitRepository(deps.cwd);\n // git init succeeded, so this must now resolve.\n return { repoRoot: await resolveRepoRoot(deps.cwd), initialized: true };\n }\n}\n\n/**\n * Resolve the signing identity; when nothing resolves, generate one instead of\n * dead-ending — but ONLY with consent (`--generate-identity` or an interactive\n * yes). A refusal (non-interactive, or a `[y/N]` no) rethrows the original\n * {@link MissingIdentityError}, whose remediation now leads with\n * `rig identity create`.\n */\nasync function resolveOrGenerateIdentity(\n deps: InitDeps,\n flags: InitFlags\n): Promise<{ identity: ResolvedIdentity; generated?: CreatedIdentity }> {\n const { io, env } = deps;\n const resolve = deps.resolveIdentityImpl ?? resolveIdentity;\n try {\n return { identity: await resolve({ env, cwd: deps.cwd, warn: io.err }) };\n } catch (err) {\n if (!(err instanceof MissingIdentityError)) throw err;\n\n let generate = flags.generateIdentity;\n if (!generate && io.isInteractive && !flags.json) {\n io.err('No identity found — rig needs one to sign and pay.');\n generate = await io.confirm('Create a new identity now? [y/N] ');\n }\n if (!generate) throw err;\n\n const created = await (deps.createIdentityImpl ?? createIdentity)({\n env,\n cwd: deps.cwd,\n force: false,\n warn: io.err,\n ...(deps.resolveIdentityImpl\n ? { resolveIdentityImpl: deps.resolveIdentityImpl }\n : {}),\n });\n // Build the ResolvedIdentity from the fresh mint directly (rather than\n // re-resolving) so a custom-password keystore needs no env var to link.\n const identity: ResolvedIdentity = {\n mnemonic: created.mnemonic,\n accountIndex: created.accountIndex,\n source: 'keystore',\n sourceLabel: created.keystorePath,\n pubkey: created.pubkey,\n };\n return { identity, generated: created };\n }\n}\n\n/** Run `rig init`; returns the process exit code. */\nexport async function runInit(args: string[], deps: InitDeps): Promise<number> {\n const { io } = deps;\n\n let flags: InitFlags;\n try {\n flags = parseInitArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(INIT_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(INIT_USAGE);\n return 0;\n }\n\n try {\n // ── (a) Git repository — create one (consent-gated) when there is none ──\n // A cold start (`mkdir x && rig init`) is no longer a dead end: with\n // consent init runs `git init` here first (prompt, or `--git-init`).\n const { repoRoot, initialized: initializedGitRepo } =\n await resolveOrInitGitRepo(deps, flags);\n\n // ── (b) Identity chain: source + derived pubkey (never the phrase) ──────\n // A chain miss no longer dead-ends: offer or honor identity generation.\n const { identity, generated } = await resolveOrGenerateIdentity(deps, flags);\n\n // ── (c) Write toon.repoid / toon.owner to LOCAL git config ──────────────\n const existing = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? existing.repoId ?? basename(repoRoot);\n const changed = {\n repoId: existing.repoId !== repoId,\n owner: existing.owner !== identity.pubkey,\n };\n await writeToonConfig(repoRoot, { repoId, owner: identity.pubkey });\n\n // ── (d) Relay setup (#249): migrate toon.relay → origin remote ──────────\n // toon.relay is the deprecated v0.1 key. When it is set, single-valued,\n // relay-shaped, and no `origin` remote exists, adopt it as a real git\n // remote. The old key stays readable (paid commands still fall back to\n // it, with a nudge) and is removed in v0.3.\n let remotes = await listGitRemotes(repoRoot);\n let migratedToonRelay = false;\n const legacyRelay = existing.relays[0];\n if (\n !remotes.some((r) => r.name === 'origin') &&\n existing.relays.length === 1 &&\n legacyRelay !== undefined &&\n isRelayUrl(legacyRelay)\n ) {\n await addGitRemote(repoRoot, 'origin', legacyRelay);\n migratedToonRelay = true;\n remotes = await listGitRemotes(repoRoot);\n }\n const origin = remotes.find((r) => r.name === 'origin');\n const originRelay =\n origin !== undefined &&\n origin.urls.length === 1 &&\n isRelayUrl(origin.urls[0] as string)\n ? (origin.urls[0] as string)\n : undefined;\n\n // ── (e) Git commit-author from the nostr identity (#302) ────────────────\n // On a rig repo the nostr key IS the identity: set the repo's LOCAL git\n // author (never --global) so `rig commit` (a git passthrough) stops\n // dead-ending on \"empty ident name not allowed\" and every commit is\n // attributed to the signer. user.name = the kind:0 display name when\n // published (best-effort, latest-wins), else the npub; email `<npub>@nostr`.\n // Re-running refreshes user.name from a now-readable profile.\n const profileRelay = await resolveProfileRelay(\n flags.relay,\n originRelay,\n existing.relays\n );\n const resolveAuthor = deps.resolveGitAuthorImpl ?? resolveGitAuthor;\n const gitAuthor = await resolveAuthor({\n pubkey: identity.pubkey,\n relayUrl: profileRelay,\n ...(profileTimeoutFromEnv(deps.env) !== undefined\n ? { timeoutMs: profileTimeoutFromEnv(deps.env) as number }\n : {}),\n });\n await setGitAuthor(repoRoot, {\n name: gitAuthor.name,\n email: gitAuthor.email,\n });\n\n // ── (f) Report ───────────────────────────────────────────────────────────\n if (flags.json) {\n const output: InitJsonOutput = {\n command: 'init',\n repoRoot,\n initializedGitRepo,\n repoId,\n owner: identity.pubkey,\n identity: {\n source: identity.source,\n sourceLabel: identity.sourceLabel,\n pubkey: identity.pubkey,\n },\n relays: existing.relays,\n relayConfigured: originRelay !== undefined || existing.relays.length > 0,\n remotes,\n origin: originRelay ?? null,\n migratedToonRelay,\n gitAuthor: {\n name: gitAuthor.name,\n email: gitAuthor.email,\n source: gitAuthor.source,\n },\n changed,\n ...(generated\n ? {\n generatedIdentity: {\n mnemonic: generated.mnemonic,\n pubkey: generated.pubkey,\n keystorePath: generated.keystorePath,\n autoPassword: generated.autoPassword,\n },\n }\n : {}),\n };\n io.emitJson(output);\n if (generated) {\n io.err(\n 'rig: `--json` emitted your new seed phrase in ' +\n '`generatedIdentity.mnemonic` — this output is SECRET; store it ' +\n 'safely and do not log or share it.'\n );\n if (generated.shadowedBy) io.err(shadowNote(generated.shadowedBy));\n }\n return 0;\n }\n\n // A freshly minted identity gets its one-time backup banner FIRST, before\n // the init report, so the phrase is the thing the user sees.\n if (generated) {\n for (const line of createdIdentityBanner(generated)) io.out(line);\n if (generated.shadowedBy) io.err(shadowNote(generated.shadowedBy));\n }\n if (initializedGitRepo) io.out(`Created a git repository at ${repoRoot}`);\n io.out(`Initialized rig for ${repoRoot}`);\n io.out(renderIdentityLine(identity));\n io.out(\n ` toon.repoid = ${repoId}` +\n (changed.repoId ? '' : ' (unchanged)') +\n (existing.repoId && changed.repoId ? ` (was ${existing.repoId})` : '')\n );\n io.out(\n ` toon.owner = ${identity.pubkey}` +\n (changed.owner ? '' : ' (unchanged)') +\n (existing.owner && changed.owner ? ` (was ${existing.owner})` : '')\n );\n io.out(\n `Git author: ${gitAuthor.name} <${gitAuthor.email}> ` +\n `(from ${gitAuthor.source === 'profile' ? 'nostr profile' : 'npub'})`\n );\n if (originRelay !== undefined) {\n io.out(\n ` origin = ${originRelay}` +\n (migratedToonRelay ? ' (migrated from git config toon.relay)' : '')\n );\n if (migratedToonRelay) {\n io.out(\n 'note: toon.relay is deprecated — it stays readable as a fallback ' +\n 'and is removed in v0.3; drop it now with ' +\n '`git config --unset-all toon.relay`.'\n );\n }\n io.out('Ready: `rig push` publishes this repo via remote \"origin\".');\n } else if (existing.relays.length > 0) {\n // toon.relay is set but could not be migrated (multi-valued, junk URL,\n // or a non-relay `origin` remote already occupies the name).\n io.out(` toon.relay = ${existing.relays.join(', ')} (deprecated)`);\n io.out(\n origin !== undefined\n ? `The \"origin\" remote (${origin.urls.join(', ')}) is not a single ` +\n 'relay URL, so toon.relay stays the fallback — add the relay ' +\n 'under another name (`rig remote add toon <relay-url>`) and ' +\n 'push with `rig push toon`.'\n : existing.relays.length > 1\n ? `toon.relay has ${existing.relays.length} values and rig ` +\n 'publishes to one relay — migrate the right one: ' +\n '`rig remote add origin <relay-url>`.'\n : 'This value is not a relay URL (ws://, wss://, http://, or ' +\n 'https://) — set a real one: `rig remote add origin <relay-url>`.'\n );\n } else if (origin !== undefined) {\n // The origin name is occupied by a non-relay remote (e.g. a GitHub\n // clone) and no legacy toon.relay exists.\n io.out(\n `No relay configured yet — \"origin\" (${origin.urls.join(', ')}) is ` +\n 'not a relay URL, so add the relay under another name: ' +\n '`rig remote add toon <relay-url>`, then `rig push toon`.'\n );\n } else {\n io.out(\n 'No relay configured yet — add one as the follow-up step: ' +\n '`rig remote add origin <relay-url>` (a real git remote; ' +\n '`git remote -v` shows it). One-off pushes can pass --relay <url>.'\n );\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'init', err);\n }\n}\n","/**\n * Git commit-author from the nostr identity (#302).\n *\n * On a rig repo the nostr key IS the identity, so `rig init` sets the repo's\n * LOCAL git author fields from it — the commit author == the push signer ==\n * the nostr identity, a coherent authorship chain baked permanently into the\n * git objects that land on Arweave. Without this, `rig commit` (a git\n * passthrough, #250) dead-ends on git's \"Author identity unknown / empty ident\n * name not allowed\" for anyone who never set a global git identity.\n *\n * user.email = `<npub>@nostr` — npub is bech32, lowercase-alphanumeric, a\n * valid email local part; `@nostr` is a stable\n * non-routable marker domain.\n * user.name = the identity's kind:0 profile DISPLAY NAME when published\n * (prefer `display_name`, else `name` from the content JSON),\n * read latest-wins (highest created_at) from a resolvable relay,\n * BEST-EFFORT; falls back to the npub when there is no profile,\n * no resolvable relay, or the read fails.\n *\n * The kind:0 read reuses the tolerant NIP-01 machinery from `../remote-state`\n * (double-JSON-encoded EVENT payloads and all). It never throws and never\n * blocks init: a short timeout, and any failure falls back to the npub.\n */\n\nimport { hexToNpub } from '../npub.js';\nimport { queryRelay, type WebSocketFactory } from '../remote-state.js';\n\n/** Nostr metadata event kind (profile). */\nexport const PROFILE_KIND = 0;\n\n/** Default bounded wait for the kind:0 profile read (env-overridable). */\nexport const DEFAULT_PROFILE_TIMEOUT_MS = 3000;\n\n/** Env var overriding the kind:0 read timeout (milliseconds). */\nexport const PROFILE_TIMEOUT_ENV = 'RIG_PROFILE_TIMEOUT_MS';\n\n/** Where `user.name` came from: the nostr profile, or the npub fallback. */\nexport type GitAuthorSource = 'profile' | 'npub';\n\n/** A resolved git commit-author derived from the nostr identity. */\nexport interface GitAuthor {\n /** `user.name`: the kind:0 display name, else the npub. */\n name: string;\n /** `user.email`: `<npub>@nostr`. */\n email: string;\n /** The npub of the identity (bech32). */\n npub: string;\n source: GitAuthorSource;\n}\n\nexport interface ResolveGitAuthorOptions {\n /** Identity pubkey (64-char hex). */\n pubkey: string;\n /**\n * Relay to read the kind:0 profile from (resolved at init time). When\n * undefined or not a ws(s) URL, the profile read is skipped and the npub is\n * used — init must not depend on a relay being reachable.\n */\n relayUrl?: string | undefined;\n /** Bounded wait for the kind:0 read (default {@link DEFAULT_PROFILE_TIMEOUT_MS}). */\n timeoutMs?: number;\n /** WebSocket factory override (defaults to the global WebSocket). */\n webSocketFactory?: WebSocketFactory;\n /** Relay-query seam (tests); defaults to {@link queryRelay}. */\n queryRelayImpl?: typeof queryRelay;\n}\n\n/** True for a WebSocket-scheme URL (the only scheme the kind:0 read speaks). */\nfunction isWebSocketRelay(url: string): boolean {\n return /^wss?:\\/\\//i.test(url);\n}\n\n/**\n * Extract a display name from a kind:0 event's content JSON: prefer\n * `display_name`, then `name`. Returns undefined when neither is a non-empty\n * string or the content is not parseable — the caller then keeps the npub.\n */\nexport function displayNameFromKind0(content: string): string | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n const fields = parsed as Record<string, unknown>;\n for (const key of ['display_name', 'name'] as const) {\n const value = fields[key];\n if (typeof value === 'string' && value.trim() !== '') return value.trim();\n }\n return undefined;\n}\n\n/**\n * Resolve the git commit-author for the identity `pubkey`: `<npub>@nostr` email\n * plus a `user.name` of the published kind:0 display name (latest-wins) or, on\n * any miss, the npub. Best-effort and non-throwing — a relay that is missing,\n * unreachable, slow, or serves no/garbage profile just yields the npub.\n */\nexport async function resolveGitAuthor(\n options: ResolveGitAuthorOptions\n): Promise<GitAuthor> {\n const npub = hexToNpub(options.pubkey);\n const email = `${npub}@nostr`;\n const fallback: GitAuthor = { name: npub, email, npub, source: 'npub' };\n\n const { relayUrl } = options;\n if (relayUrl === undefined || !isWebSocketRelay(relayUrl)) {\n return fallback;\n }\n\n const query = options.queryRelayImpl ?? queryRelay;\n const timeoutMs = options.timeoutMs ?? DEFAULT_PROFILE_TIMEOUT_MS;\n const factory = options.webSocketFactory ?? defaultWebSocketFactory;\n\n try {\n const events = await query(\n relayUrl,\n { kinds: [PROFILE_KIND], authors: [options.pubkey], limit: 20 },\n timeoutMs,\n factory\n );\n // Latest-wins over the whole buffer — a relay may serve a stale kind:0\n // ahead of the newest (issue #157), so never trust first-in-buffer.\n let latest: { created_at: number; content: string } | undefined;\n for (const event of events) {\n if (event.kind !== PROFILE_KIND) continue;\n if (event.pubkey !== options.pubkey) continue;\n if (!latest || event.created_at > latest.created_at) {\n latest = { created_at: event.created_at, content: event.content };\n }\n }\n if (latest) {\n const name = displayNameFromKind0(latest.content);\n if (name !== undefined) {\n return { name, email, npub, source: 'profile' };\n }\n }\n } catch {\n // Best-effort: any failure keeps the npub fallback (init never blocks).\n }\n return fallback;\n}\n\n/** Read {@link PROFILE_TIMEOUT_ENV} as a positive integer, else undefined. */\nexport function profileTimeoutFromEnv(\n env: NodeJS.ProcessEnv\n): number | undefined {\n const raw = env[PROFILE_TIMEOUT_ENV]?.trim();\n if (!raw) return undefined;\n const ms = Number.parseInt(raw, 10);\n return Number.isFinite(ms) && ms > 0 ? ms : undefined;\n}\n\nfunction defaultWebSocketFactory(url: string): ReturnType<WebSocketFactory> {\n const ctor = (\n globalThis as {\n WebSocket?: new (url: string) => ReturnType<WebSocketFactory>;\n }\n ).WebSocket;\n if (!ctor) {\n throw new Error(\n 'No global WebSocket constructor (Node >= 22 required) for the kind:0 read'\n );\n }\n return new ctor(url);\n}\n","/**\n * `rig maintainers list|add|remove <pubkey>` (#287) — manage the declared\n * maintainer set on a repo's kind:30617 announcement.\n *\n * Status authority is CONSUMER-side: rig and rig-web resolve an issue/PR's\n * state ONLY from kind:1630-1633 events signed by the repo owner ∪ its\n * declared maintainers. The owner is ALWAYS an implicit maintainer; this\n * command edits the EXPLICIT set carried by the `[\"maintainers\", …]` tag.\n *\n * list FREE relay read — print owner + declared maintainers\n * add <pubkey> PAID — republish the 30617 with <pubkey> added\n * remove <pubkey> PAID — republish the 30617 with <pubkey> removed\n *\n * add/remove republish the WHOLE announcement (a replaceable event keyed by\n * author + `d` tag), so they preserve the existing name/description and only\n * mutate the maintainers list. Because the 30617 is addressed by its author,\n * only the OWNER's republish is authoritative — running add/remove under a\n * non-owner identity writes that identity's own (irrelevant) announcement, so\n * we refuse it. The daemon has no announcement route, so this always runs the\n * embedded standalone publisher; the confirm gate matches every other paid\n * write (`--yes` skips; a non-TTY without it refuses; `--json` without `--yes`\n * is a pure estimate).\n */\n\nimport { parseArgs } from 'node:util';\nimport { buildRepoAnnouncement, parseMaintainers } from '../nip34-events.js';\nimport { ownerToHex } from '../npub.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport {\n serializeEventReceipt,\n type GitEventResponse,\n} from '../routes.js';\nimport type { EventCommandDeps } from './events.js';\nimport {\n emitCliError,\n InvalidRelayUrlError,\n UnconfiguredRepoAddressError,\n} from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type IdentityReport,\n} from './push.js';\nimport { feeLabel } from './render.js';\nimport {\n resolveRelays,\n singleRelayRefusal,\n type ResolvedRelays,\n} from './remote.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\nconst HEX64_RE = /^[0-9a-f]{64}$/;\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\nexport const MAINTAINERS_USAGE = `Usage: rig maintainers <list|add|remove> [<pubkey>] [options]\n\nManage a repo's declared maintainers (#287). Status authority is consumer-side:\nrig and rig-web honor an issue/PR status (kind:1630-1633) ONLY when its author\nis the repo owner or a declared maintainer. The owner is always an implicit\nmaintainer; this command edits the explicit set on the kind:30617 announcement.\n\nSubcommands:\n list show the owner + declared maintainers — FREE (relay read)\n add <pubkey> add a maintainer (npub or 64-char hex) — PAID: republishes\n the kind:30617 (permanent, non-refundable)\n remove <pubkey> remove a maintainer — PAID: republishes the kind:30617\n\nadd/remove must run under the repo OWNER's identity (only the owner's\nannouncement is authoritative).\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or hex; default: git config)\n --remote <name> publish/read via this configured git remote (default: origin)\n --relay <url> ad-hoc relay override (exactly one for add/remove)\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable envelope\n -h, --help show this help`;\n\ninterface MaintFlags {\n json: boolean;\n yes: boolean;\n help: boolean;\n relay: string[];\n remote?: string;\n repoId?: string;\n owner?: string;\n}\n\nconst MAINT_OPTIONS = {\n json: { type: 'boolean', default: false },\n yes: { type: 'boolean', default: false },\n relay: { type: 'string', multiple: true },\n remote: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n} as const;\n\nfunction pickFlags(values: Record<string, unknown>): MaintFlags {\n const flags: MaintFlags = {\n json: values['json'] === true,\n yes: values['yes'] === true,\n help: values['help'] === true,\n relay: Array.isArray(values['relay']) ? (values['relay'] as string[]) : [],\n };\n if (typeof values['remote'] === 'string') flags.remote = values['remote'];\n if (typeof values['repo-id'] === 'string') flags.repoId = values['repo-id'];\n if (typeof values['owner'] === 'string')\n flags.owner = ownerToHex(values['owner']);\n return flags;\n}\n\ninterface RepoContext {\n repoId: string;\n owner: string;\n relays: string[];\n /** The full relay resolution (source/nudge) — for the single-relay refusal. */\n resolved: ResolvedRelays;\n repoRoot?: string;\n}\n\n/** Resolve repo address (repoId + owner) and relays from flags + git config. */\nasync function resolveContext(\n flags: MaintFlags,\n deps: EventCommandDeps\n): Promise<RepoContext> {\n let repoRoot: string | undefined;\n let toonConfig: { repoId?: string; owner?: string; relays: string[] } = {\n relays: [],\n };\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n toonConfig = await readToonConfig(repoRoot);\n } catch {\n // Not inside a git repo — flags must carry everything.\n }\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const owner = flags.owner ?? toonConfig.owner;\n if (!owner) throw new UnconfiguredRepoAddressError('repository owner');\n\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: flags.remote,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) deps.io.err(resolved.nudge);\n return {\n repoId,\n owner,\n relays: resolved.relays,\n resolved,\n ...(repoRoot !== undefined ? { repoRoot } : {}),\n };\n}\n\n/** Run `rig maintainers …`; returns the process exit code. */\nexport async function runMaintainers(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'list':\n return runList(rest, deps);\n case 'add':\n return runMutate('add', rest, deps);\n case 'remove':\n return runMutate('remove', rest, deps);\n case '--help':\n case '-h':\n case 'help':\n io.out(MAINTAINERS_USAGE);\n return 0;\n default:\n io.err(\n sub === undefined\n ? 'missing subcommand: rig maintainers <list|add|remove>'\n : `unknown rig maintainers subcommand: ${sub}`\n );\n io.err(MAINTAINERS_USAGE);\n return 2;\n }\n}\n\n// ---------------------------------------------------------------------------\n// list (FREE)\n// ---------------------------------------------------------------------------\n\nasync function runList(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n let flags: MaintFlags;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: MAINT_OPTIONS,\n allowPositionals: true,\n });\n if (positionals.length > 0) {\n throw new Error('rig maintainers list takes no positional arguments');\n }\n flags = pickFlags(values);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(MAINTAINERS_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(MAINTAINERS_USAGE);\n return 0;\n }\n\n try {\n const ctx = await resolveContext(flags, deps);\n const wsRelays = ctx.relays.filter((url) => WS_URL_RE.test(url));\n if (wsRelays.length === 0) {\n throw new InvalidRelayUrlError(\n ctx.relays[0] ?? '',\n 'reads need a ws:// or wss:// relay'\n );\n }\n const remote = await fetchRemoteState({\n relayUrls: wsRelays,\n ownerPubkey: ctx.owner,\n repoId: ctx.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n const maintainers = remote.maintainers;\n if (flags.json) {\n io.emitJson({\n command: 'maintainers list',\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n announced: remote.announced,\n owner: ctx.owner,\n maintainers,\n });\n return 0;\n }\n io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);\n io.out(`Owner: ${ctx.owner} (implicit maintainer)`);\n if (!remote.announced) {\n io.out('No kind:30617 announcement found — owner-only authority.');\n return 0;\n }\n if (maintainers.length === 0) {\n io.out('Maintainers: (none declared — owner-only authority)');\n } else {\n io.out(`Maintainers (${maintainers.length}):`);\n for (const m of maintainers) io.out(` ${m}`);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'maintainers list', err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// add / remove (PAID — republish the 30617 under the owner's identity)\n// ---------------------------------------------------------------------------\n\ninterface MaintJsonOutput {\n command: 'maintainers add' | 'maintainers remove';\n repoAddr: { ownerPubkey: string; repoId: string };\n identity: IdentityReport;\n executed: boolean;\n feeEstimate: string | null;\n maintainers: string[];\n result?: GitEventResponse;\n hint?: string;\n}\n\nasync function runMutate(\n op: 'add' | 'remove',\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const command = `maintainers ${op}` as\n | 'maintainers add'\n | 'maintainers remove';\n\n let flags: MaintFlags;\n let pubkey: string;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: MAINT_OPTIONS,\n allowPositionals: true,\n });\n flags = pickFlags(values);\n if (flags.help) {\n io.out(MAINTAINERS_USAGE);\n return 0;\n }\n if (positionals.length !== 1) {\n throw new Error(`expected exactly one <pubkey> to ${op}`);\n }\n pubkey = ownerToHex(positionals[0] as string).toLowerCase();\n if (!HEX64_RE.test(pubkey)) {\n throw new Error(`<pubkey> must resolve to 64-char hex (got ${JSON.stringify(positionals[0])})`);\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(MAINTAINERS_USAGE);\n return 2;\n }\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n const ctx = await resolveContext(flags, deps);\n // A single relay for a paid publish (mirror push/events guard).\n if (ctx.relays.length > 1) {\n io.err(singleRelayRefusal(ctx.resolved, 'Nothing was published or paid.'));\n return 1;\n }\n const relayUrl = ctx.relays[0];\n if (relayUrl === undefined || !WS_URL_RE.test(relayUrl)) {\n throw new InvalidRelayUrlError(\n relayUrl ?? '',\n 'a paid publish needs a ws:// or wss:// relay'\n );\n }\n\n // Standalone only: the daemon has no announcement route.\n const load = deps.loadStandalone ?? defaultLoadStandalone;\n standaloneCtx = await load({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n relayUrl,\n });\n const identity = identityReport(standaloneCtx);\n\n // Only the owner's 30617 is authoritative — refuse a non-owner republish.\n if (identity.pubkey.toLowerCase() !== ctx.owner.toLowerCase()) {\n io.err(\n `rig: only the repo owner (${ctx.owner.slice(0, 8)}…) can change the ` +\n `maintainer set — the active identity is ${identity.pubkey.slice(0, 8)}…. ` +\n 'A non-owner republish would write your own (ignored) announcement. ' +\n 'Nothing was published or paid.'\n );\n return 1;\n }\n\n // Read the current announcement to preserve name/description + base set.\n const remote = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: ctx.owner,\n repoId: ctx.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n // Refuse on an unannounced repo: republishing here would MINT a phantom\n // kind:30617 with a placeholder name (= repoId) and empty description, for\n // real money. Worse, `rig push` only announces when the repo is NOT already\n // announced (see push.ts), so that placeholder would permanently shadow the\n // real name/description the first push intended, with no way to fix it.\n // Managing maintainers presupposes the repo exists — announce it first.\n if (!remote.announced) {\n io.err(\n `rig: 30617:${ctx.owner.slice(0, 8)}…:${ctx.repoId} has no announcement ` +\n 'yet — run `rig push` to publish the repo (with its real ' +\n 'name/description) before managing maintainers. Nothing was published ' +\n 'or paid.'\n );\n return 1;\n }\n const current = remote.announceEvent\n ? parseMaintainers(remote.announceEvent.tags)\n : [];\n const currentSet = new Set(current);\n if (op === 'add' && currentSet.has(pubkey)) {\n io.err(\n `rig: ${pubkey.slice(0, 8)}… is already a maintainer — nothing to do (not published).`\n );\n return 0;\n }\n if (op === 'remove' && !currentSet.has(pubkey)) {\n io.err(\n `rig: ${pubkey.slice(0, 8)}… is not a declared maintainer — nothing to do (not published).`\n );\n return 0;\n }\n const next =\n op === 'add'\n ? [...current, pubkey]\n : current.filter((m) => m !== pubkey);\n\n const name = remote.name ?? ctx.repoId;\n const description = remote.description ?? '';\n const event = buildRepoAnnouncement(ctx.repoId, name, description, next);\n const fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();\n const action = `kind:30617 maintainers ${op} ${pubkey.slice(0, 8)}…`;\n\n // ── Confirm gate ────────────────────────────────────────────────────────\n if (!flags.json) {\n io.out(`Republish ${action}`);\n io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);\n io.out(`Maintainers after: ${next.length === 0 ? '(none)' : next.join(', ')}`);\n io.out(`Fee: ${feeLabel(fee)}. Writes are permanent and non-refundable.`);\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n identity,\n executed: false,\n feeEstimate: fee,\n maintainers: next,\n hint: 'estimate only — re-run with --yes to publish (permanent, non-refundable)',\n } satisfies MaintJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid republish (${feeLabel(fee)})? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was published.');\n return 1;\n }\n }\n\n // ── Execute ───────────────────────────────────────────────────────────────\n const receipt = await standaloneCtx.publisher.publishEvent(event, [\n relayUrl,\n ]);\n const result = serializeEventReceipt(event.kind, receipt);\n\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n identity,\n executed: true,\n feeEstimate: fee,\n maintainers: next,\n result,\n } satisfies MaintJsonOutput);\n } else {\n io.out(\n `Published ${action}: ${result.eventId} paid ${result.feePaid} base units`\n );\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, command, err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * `rig name` — ArNS naming verbs (#367): buy / set / status, owned and paid\n * by the rig mnemonic's Solana key.\n *\n * ArNS is the missing NAMING layer over everything Rig serves from Arweave.\n * Since ar.io's Solana migration, ArNS names are owned and managed by Solana\n * wallets, and `@ar.io/sdk` is Solana-native with prices denominated in mARIO.\n * The rig identity ALREADY has the required key: `@toon-protocol/client`\n * derives a Solana Ed25519 keypair from the same mnemonic that pays for pushes\n * (`m/44'/501'/{index}'/0'`, SLIP-0010 — see packages/client/src/keys) and\n * `rig fund --chain solana` funds it. So the same phrase can own ArNS names and\n * pay for them, with ZERO new key material or config.\n *\n * PAYMENT MODEL — the load-bearing distinction (see {@link MARIO_PAYMENT_NOTE}):\n * `rig name buy` spends **mARIO from the identity's Solana wallet, charged\n * on-chain by the ar.io registry program**. It does NOT move value through the\n * TOON ILP payment channels that `rig push` uses — a name purchase is a\n * Solana-settled registry transaction, not a pay-to-write relay claim.\n *\n * Same discipline as every paid rig command: estimate → confirm → execute,\n * strict `--json` contract, `--yes` for non-TTY. `buy` and `set` are the\n * money/state-moving paths (gated); `status` is FREE (a registry read, like\n * `rig balance`).\n *\n * DEPENDENCY HYGIENE (#367 open question, decided): `@ar.io/sdk` is an\n * OPTIONAL, lazily-imported dependency — it is `import()`ed only inside the\n * command path (via the {@link LoadArns} seam), so the base `rig` install stays\n * lean and runs that never touch names never pay its startup cost. When it is\n * not installed, the command fails with a clean, actionable error\n * ({@link ArnsSdkUnavailableError}) instead of a module-resolution stack trace.\n *\n * SDK WIRING (#376): `@ar.io/sdk` >= 4.0.3 is Solana-native. There is no\n * `SolanaSigner` class and no AO registry process id, and `ARIO.init()` builds\n * NO default rpc — the caller constructs everything from `@solana/kit`:\n * `createSolanaRpc` (all calls), plus `createSolanaRpcSubscriptions` and a\n * `createKeyPairSignerFromBytes` signer for writes only. The FREE read path\n * (`status`) therefore runs signerless ({@link LoadArnsOptions.mode}) — reads\n * being free is the rig discipline everywhere else. This surface is pinned by\n * a live smoke test against the published SDK\n * (`src/__integration__/arns-live-read.integration.test.ts`), because both\n * #376 bugs came from coding against an API no released version exports.\n *\n * DEVNET (#367 open question, revised by #376): post-migration, registry\n * selection is a Solana CLUSTER, not an AO process id — `--network\n * mainnet|devnet` (or `RIG_ARIO_NETWORK`) picks the cluster (devnet applies\n * the SDK's `DEVNET_PROGRAM_IDS`); ar.io deploys nothing on Solana's testnet\n * cluster, so `testnet` is rejected up front. `--process-id <id>` (or\n * `RIG_ARIO_PROCESS_ID`) overrides the ArNS registry program id outright.\n * Defaults to mainnet.\n */\n\nimport { deriveNostrKeyFromMnemonic } from '../standalone/nostr-identity.js';\nimport { randomUUID } from 'node:crypto';\nimport { parseArgs } from 'node:util';\nimport { formatUnits } from './balance.js';\nimport { emitCliError } from './errors.js';\nimport { resolveEffectiveNetwork } from './fund.js';\nimport { resolveIdentity } from './identity.js';\nimport type { CliIo } from './output.js';\nimport type { IdentityReport } from './push.js';\nimport { defaultLoadStandalone } from './push.js';\nimport type { StoreJobRequest, StoreJobResponse } from '../publisher.js';\nimport type { LoadStandalone } from './standalone-context.js';\nimport { renderIdentityLine } from './render.js';\n\n// ---------------------------------------------------------------------------\n// mARIO / ARIO\n// ---------------------------------------------------------------------------\n\n/**\n * $ARIO token decimals: 1 ARIO = 1_000_000 mARIO (mARIO is the base unit\n * `@ar.io/sdk` quotes in). Used only to render a human ARIO figure alongside\n * the exact mARIO amount — the mARIO integer is always the authoritative value.\n */\nexport const ARIO_DECIMALS = 6;\n\n/** Render a mARIO base-unit amount as `<mARIO> mARIO (~<ARIO> ARIO)`. */\nexport function renderMario(mario: bigint): string {\n return `${mario.toString()} mARIO (~${formatUnits(mario.toString(), ARIO_DECIMALS)} ARIO)`;\n}\n\n/**\n * THE load-bearing note (#367): a name purchase spends mARIO on Solana via the\n * ar.io registry program — NOT through TOON ILP payment channels. Exported so\n * the buy human output, the `--json` hint, and the tests all pin one string.\n */\nexport const MARIO_PAYMENT_NOTE =\n \"Payment is mARIO from this identity's Solana wallet, charged on-chain by \" +\n 'the ar.io registry program — NOT through TOON ILP payment channels. Fund ' +\n 'this wallet with `rig fund --chain solana` (or send $ARIO to the Solana ' +\n 'address above).';\n\n/**\n * The brokered (\"buyfor\") counterpart of {@link MARIO_PAYMENT_NOTE}: with\n * `--via <dvm>`, a store DVM pays the mARIO name price from ITS wallet by\n * executing the kind:5095 ArNS-buy job — this identity never holds $ARIO.\n * The client still OWNS the name from inception, because the job carries the\n * processId of an ANT this identity spawned and owns (`ANT.spawn` costs only\n * dust SOL). Exported so the buy output and the tests pin one string.\n */\nexport const DVM_PAYMENT_NOTE =\n 'Brokered buy (--via): the DVM pays the mARIO name price from ITS Solana ' +\n 'wallet via the kind:5095 job; this wallet needs only dust SOL to spawn ' +\n 'the ANT it owns. On the paid path the job fee is enforced by the ' +\n 'connector payment proxy in front of the DVM; when --via targets the DVM ' +\n 'backend directly the job payment is STUBBED (dev/e2e only). The ArNS ' +\n 'purchase itself is real either way, and the name is owned by YOUR ANT ' +\n 'from inception.';\n\n// ---------------------------------------------------------------------------\n// The ar.io SDK seam (lazily imported; tests inject a stub — NEVER the live net)\n// ---------------------------------------------------------------------------\n\n/** A name registration kind: a time-boxed lease or a one-time permabuy. */\nexport type NameType = 'lease' | 'permabuy';\n\n/**\n * The Solana clusters ar.io deploys its programs to; mainnet is the default.\n * (No `testnet`: ar.io has no deployment on Solana's testnet cluster — #376.)\n */\nexport type ArioNetwork = 'mainnet' | 'devnet';\n\n/** One name's current registry record (the free `status` read). */\nexport interface ArnsRecordView {\n /**\n * ANT (Arweave Name Token) process id that owns/serves the name, or `null`\n * when no ANT is attached. The registry's all-ones placeholder\n * ({@link ARNS_NULL_PROCESS_ID}) is normalized to `null` at this seam — a\n * non-null value here always means a real ANT (#79).\n */\n processId: string | null;\n /** `lease` or `permabuy`, when known. */\n type: NameType | null;\n /** Lease/registration start (ms epoch), when known. */\n startTimestamp?: number;\n /** Lease expiry (ms epoch); absent/undefined for a permabuy. */\n endTimestamp?: number;\n /** Included undername slots (ArNS ships 10 per name). */\n undernameLimit?: number;\n}\n\n/** One ANT record target (base name or an undername). */\nexport interface AntRecordTarget {\n /** Arweave txId the record points at (typically a path manifest). */\n transactionId: string;\n /** Record TTL in seconds (gateway cache hint). */\n ttlSeconds: number;\n}\n\n/**\n * A handle on one name's ANT process — used by `set` (write) and `status`\n * (read). The base name record is conventionally the `@` undername.\n */\nexport interface ArnsAnt {\n /** All current record targets, keyed by undername (`@` = the base name). */\n getRecords(): Promise<Record<string, AntRecordTarget>>;\n /** Point the base name at an Arweave txId. */\n setBaseNameRecord(args: {\n transactionId: string;\n ttlSeconds: number;\n }): Promise<{ id: string }>;\n /** Point an undername (`<sub>_<name>`) at an Arweave txId. */\n setUndernameRecord(args: {\n undername: string;\n transactionId: string;\n ttlSeconds: number;\n }): Promise<{ id: string }>;\n}\n\n/**\n * The slice of `@ar.io/sdk` `rig name` uses, behind our own seam so tests can\n * inject a stub and NEVER reach the live ar.io registry (the hard safety rule:\n * no real $ARIO is ever spent, no real registry call is ever made in code we\n * run or in tests).\n */\nexport interface ArnsSdk {\n /** Quote the mARIO cost of an intent (here always `Buy-Name`). */\n getTokenCost(args: {\n intent: 'Buy-Name';\n name: string;\n type: NameType;\n years?: number;\n }): Promise<bigint>;\n /**\n * Register (buy) a name. `processId`, when supplied, binds the purchase to\n * an ANT the caller already owns (both `rig name` buy paths spawn their\n * own ANT first and pass its id here — #79 — so the name is never\n * registered against the registry's placeholder). Returns the settling\n * registry transaction id and, when the SDK echoes it back, the ANT\n * process id actually bound; absent that echo, callers trust the\n * `processId` they requested.\n */\n buyRecord(args: {\n name: string;\n type: NameType;\n years?: number;\n processId?: string;\n }): Promise<{ id: string; processId?: string }>;\n /**\n * Spawn a fresh ANT owned by THIS identity's Solana key (`ANT.spawn` —\n * mints the MPL Core asset + initializes the ario-ant PDAs; costs only\n * rent/fee dust, no $ARIO). The returned `processId` (the asset pubkey) is\n * what a brokered `--via` buy hands the DVM so the client owns the bought\n * name from inception. Write mode only — a signerless SDK must throw.\n */\n spawnAnt(args: {\n name: string;\n }): Promise<{ processId: string; signature: string }>;\n /**\n * Build (do NOT send) a partially-signed ANT record-set transaction for\n * the gas-station path (toon-meta#163): feePayer = the DVM's advertised\n * gas wallet, lifetime = the quoted blockhash, caller = THIS identity's\n * Solana key, which partial-signs. Returns the base64 wire transaction\n * ready for a kind:5096 execute job. Write mode only.\n */\n buildSetRecordTransaction(args: {\n antProcessId: string;\n /** `@` for the base name. */\n undername: string;\n transactionId: string;\n ttlSeconds: number;\n feePayer: string;\n recentBlockhash: string;\n }): Promise<string>;\n /** Read a name's current registry record (free). */\n getArNSRecord(args: { name: string }): Promise<ArnsRecordView | null>;\n /** Bind an ANT handle for a name's process id (for `set` / `status`). */\n ant(processId: string): Promise<ArnsAnt>;\n}\n\n/** What the {@link LoadArns} seam needs to build a targeted SDK. */\nexport interface LoadArnsOptions {\n /**\n * Which capability the caller needs (#376). `read` builds a SIGNERLESS,\n * read-only client — the FREE lookups (`status`, cost quotes) must never\n * require write plumbing. `write` additionally derives a `@solana/kit`\n * signer from `solanaSecretKey` and wires the rpc-subscriptions client that\n * transaction confirmation requires.\n */\n mode: 'read' | 'write';\n /**\n * 64-byte Ed25519 Solana keypair (secretKey ‖ publicKey) that owns and\n * pays — consumed only in `write` mode (readers never touch it).\n */\n solanaSecretKey: Uint8Array;\n /** Solana public key (base58) — for the signer + human messaging. */\n solanaPublicKey: string;\n /** Which cluster's ar.io deployment to target. */\n network: ArioNetwork;\n /** Explicit ArNS registry program id override (wins over `network`). */\n processId?: string;\n}\n\n/** Build a network-targeted {@link ArnsSdk} (tests inject a stub). */\nexport type LoadArns = (options: LoadArnsOptions) => Promise<ArnsSdk>;\n\n/**\n * The Solana System Program id (32 base58 \"1\"s) — the ar.io registry writes\n * this into a record's `processId` when no ANT is actually attached. It is a\n * real, valid program id (not a null the SDK invented), so a buy that never\n * attaches an ANT looks superficially like it worked unless this exact\n * string is checked for wherever an ANT process id is accepted or reported\n * (#79 — a direct buy silently registering against this placeholder is the\n * bug this constant exists to make impossible to miss).\n */\nexport const ARNS_NULL_PROCESS_ID = '11111111111111111111111111111111';\n\n/**\n * Normalize an ANT process id: the real id, or `null` when no ANT is attached\n * (absent, or the registry's all-ones placeholder). Every command that accepts\n * or reports an ANT process id goes through this, so the placeholder can never\n * be mistaken for a working attachment (#79 AC4).\n */\nfunction antProcessIdOf(id: string | null | undefined): string | null {\n if (id === null || id === undefined || id === ARNS_NULL_PROCESS_ID) {\n return null;\n }\n return id;\n}\n\n/**\n * The minimum `@ar.io/sdk` release `rig name` is built against: the first\n * Solana-native surface verified to expose the clients the default loader\n * wires (`ARIO.init`/`ANT.init` over a caller-built `@solana/kit` rpc, signer\n * optional). Mirrored by the `optionalDependencies` pin in package.json.\n */\nexport const MIN_ARIO_SDK_VERSION = '4.0.3';\n\n/**\n * An optional module (`@ar.io/sdk`, or its `@solana/kit` companion) is not\n * installed. Optional-dependency by design (#367): surface a clean,\n * actionable message instead of a module-resolution stack trace. Distinct\n * from {@link ArnsSdkIncompatibleError} — \"not installed\" and \"installed but\n * the wrong API surface\" need different remediations (#376).\n */\nexport class ArnsSdkUnavailableError extends Error {\n constructor(cause?: unknown, module = '@ar.io/sdk') {\n super(\n `\\`rig name\\` needs the optional \\`${module}\\` dependency, which is not ` +\n 'installed. It is intentionally NOT a base `rig` dependency (keeps the ' +\n 'install lean). Add it to use ArNS naming:\\n' +\n ` npm i @ar.io/sdk@^${MIN_ARIO_SDK_VERSION} # or: pnpm add @ar.io/sdk@^${MIN_ARIO_SDK_VERSION}\\n` +\n '(`@solana/kit` installs alongside it) then re-run your `rig name` ' +\n 'command.' +\n (cause instanceof Error ? `\\n(underlying error: ${cause.message})` : '')\n );\n this.name = 'ArnsSdkUnavailableError';\n }\n}\n\n/**\n * `@ar.io/sdk` (or `@solana/kit`) IS installed but exposes an API surface\n * `rig name` cannot drive — e.g. a pre-Solana-migration build. Kept separate\n * from {@link ArnsSdkUnavailableError} so users are never told to install a\n * package they already have (#376: the old message sent users chasing an\n * upgrade that did not exist).\n */\nexport class ArnsSdkIncompatibleError extends Error {\n constructor(detail: string) {\n super(\n `the installed @ar.io/sdk is incompatible with \\`rig name\\`: ${detail}.\\n` +\n `\\`rig name\\` requires @ar.io/sdk >= ${MIN_ARIO_SDK_VERSION} (the ` +\n 'Solana-native release driven via a `@solana/kit` rpc + signer). ' +\n 'Upgrade with:\\n' +\n ' npm i @ar.io/sdk@latest # or: pnpm add @ar.io/sdk@latest'\n );\n this.name = 'ArnsSdkIncompatibleError';\n }\n}\n\n/** Public Solana RPC endpoints (fallbacks when the SDK exports none). */\nconst SOLANA_MAINNET_RPC_URL = 'https://api.mainnet-beta.solana.com';\nconst SOLANA_DEVNET_RPC_URL = 'https://api.devnet.solana.com';\n\n/**\n * The untyped shape of the pieces of `@ar.io/sdk` the default loader reaches\n * for (verified against the published 4.0.3). Kept local (the package is\n * optional and its types are not a build dep) and cast through `unknown` —\n * never `any`, so eslint's no-explicit-any holds.\n */\ninterface RawArioModule {\n ARIO?: {\n init?: (config: unknown) => RawArioInstance;\n };\n ANT?: {\n /** 4.x resolves the ANT program from the asset, hence async. */\n init?: (config: unknown) => Promise<RawAntInstance>;\n /** 4.x Solana `ANT.spawn` — mints the MPL Core asset (write only). */\n spawn?: (\n params: unknown\n ) => Promise<{ processId: string; signature: string }>;\n };\n DEFAULT_SOLANA_RPC_URL?: string;\n MAINNET_RPC_URL?: string;\n DEVNET_RPC_URL?: string;\n /** Devnet (staging) program-id overrides — required off mainnet. */\n DEVNET_PROGRAM_IDS?: {\n core?: string;\n gar?: string;\n arns?: string;\n ant?: string;\n };\n /** Root-exported PDA helper: (mint, undername, antProgramId?) → [pda]. */\n getAntRecordPDA?: (\n mint: unknown,\n undername: string,\n programId?: unknown\n ) => Promise<readonly unknown[]>;\n}\ninterface RawArioInstance {\n getTokenCost: (args: unknown) => Promise<unknown>;\n /** Present only on the writeable (signer-built) client. */\n buyRecord?: (args: unknown) => Promise<unknown>;\n getArNSRecord: (args: unknown) => Promise<unknown>;\n}\ninterface RawAntInstance {\n getRecords: () => Promise<\n Record<string, { transactionId: string; ttlSeconds: number }>\n >;\n /** Present only on the writeable (signer-built) client. */\n setBaseNameRecord?: (args: unknown) => Promise<{ id: string }>;\n setUndernameRecord?: (args: unknown) => Promise<{ id: string }>;\n}\n/** The three `@solana/kit` factories the Solana-native SDK is driven with. */\ninterface RawSolanaKitModule {\n createSolanaRpc?: (url: string) => unknown;\n createSolanaRpcSubscriptions?: (url: string) => unknown;\n createKeyPairSignerFromBytes?: (bytes: Uint8Array) => Promise<unknown>;\n // ── extras the gas-station tx builder uses (all loose-typed on purpose:\n // the optional module's types are not a build dep) ──\n createKeyPairFromBytes?: (bytes: Uint8Array) => Promise<unknown>;\n createNoopSigner?: (addr: unknown) => unknown;\n address?: (s: string) => unknown;\n blockhash?: (s: string) => unknown;\n createTransactionMessage?: (o: { version: number }) => unknown;\n setTransactionMessageFeePayer?: (a: unknown, m: unknown) => unknown;\n setTransactionMessageLifetimeUsingBlockhash?: (\n l: unknown,\n m: unknown\n ) => unknown;\n appendTransactionMessageInstructions?: (ix: unknown[], m: unknown) => unknown;\n compileTransaction?: (m: unknown) => unknown;\n partiallySignTransaction?: (kps: unknown[], tx: unknown) => Promise<unknown>;\n getBase64EncodedWireTransaction?: (tx: unknown) => string;\n}\n/** The `@ar.io/solana-contracts/ant` slice the record-set builder uses. */\ninterface RawAntContractsModule {\n getSetRecordInstructionAsync?: (\n input: Record<string, unknown>,\n config?: { programAddress?: unknown }\n ) => Promise<unknown>;\n}\n\n/**\n * Default {@link LoadArns}: lazily `import('@ar.io/sdk')` + `@solana/kit` and\n * adapt them to our seam. Specifiers are stored in `string`-typed variables so\n * TypeScript does not try to resolve the optional modules at build time; a\n * missing package surfaces as {@link ArnsSdkUnavailableError}, a wrong API\n * surface as {@link ArnsSdkIncompatibleError}.\n *\n * THE #376 LESSON, load-bearing: the SDK provides NO defaults. Bare\n * `ARIO.init()` throws and `ARIO.init({})` produces a client whose every read\n * fails — the caller must build the rpc (`createSolanaRpc`) explicitly, and\n * for writes also `rpcSubscriptions` + a `createKeyPairSignerFromBytes`\n * signer. Read mode constructs NO signer at all, so free lookups need zero\n * key material at the SDK layer.\n *\n * NOTE: no test drives this adapter against the live registry except the\n * env-gated smoke test (`__integration__/arns-live-read.integration.test.ts`,\n * FREE reads only) — every money-moving path runs ONLY against injected\n * stubs, and no real $ARIO is ever spent by code we run.\n */\nexport const defaultLoadArns: LoadArns = async (options) => {\n // Cast to `string` (not a literal type) so TypeScript does not try to\n // resolve the OPTIONAL modules at build time — a missing package must\n // surface as a clean runtime error, not a compile failure.\n const sdkSpecifier = '@ar.io/sdk' as string;\n let mod: RawArioModule;\n try {\n mod = (await import(sdkSpecifier)) as unknown as RawArioModule;\n } catch (err) {\n throw new ArnsSdkUnavailableError(err);\n }\n // `@solana/kit` carries the rpc/signer factories the Solana-native SDK is\n // driven with. It is a dependency of `@ar.io/sdk` AND declared in rig's own\n // optionalDependencies so strict (pnpm-style) layouts resolve it here too.\n const kitSpecifier = '@solana/kit' as string;\n let kit: RawSolanaKitModule;\n try {\n kit = (await import(kitSpecifier)) as unknown as RawSolanaKitModule;\n } catch (err) {\n throw new ArnsSdkUnavailableError(err, '@solana/kit');\n }\n\n const arioInit = mod.ARIO?.init;\n const antInit = mod.ANT?.init;\n if (!arioInit || !antInit) {\n throw new ArnsSdkIncompatibleError('it exposes no ARIO.init / ANT.init');\n }\n const {\n createSolanaRpc,\n createSolanaRpcSubscriptions,\n createKeyPairSignerFromBytes,\n } = kit;\n if (\n !createSolanaRpc ||\n !createSolanaRpcSubscriptions ||\n !createKeyPairSignerFromBytes\n ) {\n throw new ArnsSdkIncompatibleError(\n 'the resolved @solana/kit exposes no createSolanaRpc / ' +\n 'createSolanaRpcSubscriptions / createKeyPairSignerFromBytes'\n );\n }\n\n // Cluster targeting: rpc endpoint + (off mainnet) program-id overrides.\n const rpcUrl =\n options.network === 'devnet'\n ? (mod.DEVNET_RPC_URL ?? SOLANA_DEVNET_RPC_URL)\n : (mod.DEFAULT_SOLANA_RPC_URL ??\n mod.MAINNET_RPC_URL ??\n SOLANA_MAINNET_RPC_URL);\n const devnetIds =\n options.network === 'devnet' ? mod.DEVNET_PROGRAM_IDS : undefined;\n if (options.network === 'devnet' && devnetIds === undefined) {\n throw new ArnsSdkIncompatibleError(\n 'it exposes no DEVNET_PROGRAM_IDS — devnet targeting needs the ' +\n \"SDK's staging program ids\"\n );\n }\n const antProgramId = devnetIds?.ant;\n const programOverrides = {\n ...(devnetIds?.core !== undefined ? { coreProgramId: devnetIds.core } : {}),\n ...(devnetIds?.gar !== undefined ? { garProgramId: devnetIds.gar } : {}),\n ...(devnetIds?.arns !== undefined ? { arnsProgramId: devnetIds.arns } : {}),\n ...(antProgramId !== undefined ? { antProgramId } : {}),\n // --process-id / RIG_ARIO_PROCESS_ID: explicit ArNS registry program\n // override (wins over the cluster default).\n ...(options.processId !== undefined\n ? { arnsProgramId: options.processId }\n : {}),\n };\n\n // Build the transport(s) explicitly — see the #376 lesson above. Write mode\n // alone derives the signer (from the identity's 64-byte Ed25519 keypair)\n // and the ws subscriptions client that transaction confirmation needs.\n const rpc = createSolanaRpc(rpcUrl);\n const writeExtras =\n options.mode === 'write'\n ? {\n signer: await createKeyPairSignerFromBytes(options.solanaSecretKey),\n rpcSubscriptions: createSolanaRpcSubscriptions(\n rpcUrl.replace(/^http/, 'ws')\n ),\n }\n : {};\n const ario = arioInit({ rpc, ...writeExtras, ...programOverrides });\n\n return {\n getTokenCost: async (args) => BigInt(String(await ario.getTokenCost(args))),\n buyRecord: async (args) => {\n if (typeof ario.buyRecord !== 'function') {\n throw new ArnsSdkIncompatibleError(\n 'the signed ARIO client exposes no buyRecord'\n );\n }\n return (await ario.buyRecord(args)) as { id: string; processId?: string };\n },\n spawnAnt: async (args) => {\n const spawn = mod.ANT?.spawn;\n if (typeof spawn !== 'function') {\n throw new ArnsSdkIncompatibleError('it exposes no ANT.spawn');\n }\n if (options.mode !== 'write') {\n // Mirrors the SDK's own contract: spawning signs a transaction, so a\n // signerless (read) client must never attempt it.\n throw new ArnsSdkIncompatibleError(\n 'ANT.spawn requires the write-mode SDK (a signer) — this client ' +\n 'was built signerless'\n );\n }\n const result = await spawn({\n rpc,\n ...writeExtras,\n state: { name: args.name },\n ...(antProgramId !== undefined ? { antProgramId } : {}),\n });\n return { processId: result.processId, signature: result.signature };\n },\n buildSetRecordTransaction: async (args) => {\n if (options.mode !== 'write') {\n throw new ArnsSdkIncompatibleError(\n 'buildSetRecordTransaction requires the write-mode SDK (a client ' +\n 'partial-signature) — this client was built signerless'\n );\n }\n const contractsSpecifier = '@ar.io/solana-contracts/ant' as string;\n let contracts: RawAntContractsModule;\n try {\n contracts = (await import(\n contractsSpecifier\n )) as unknown as RawAntContractsModule;\n } catch (err) {\n throw new ArnsSdkUnavailableError(err, '@ar.io/solana-contracts');\n }\n const getSetRecordInstructionAsync =\n contracts.getSetRecordInstructionAsync;\n const getAntRecordPDA = mod.getAntRecordPDA;\n const {\n createKeyPairFromBytes,\n createNoopSigner,\n address: toAddr,\n blockhash: toBlockhash,\n createTransactionMessage,\n setTransactionMessageFeePayer,\n setTransactionMessageLifetimeUsingBlockhash,\n appendTransactionMessageInstructions,\n compileTransaction,\n partiallySignTransaction,\n getBase64EncodedWireTransaction,\n } = kit;\n if (\n !getSetRecordInstructionAsync ||\n !getAntRecordPDA ||\n !createKeyPairFromBytes ||\n !createNoopSigner ||\n !toAddr ||\n !toBlockhash ||\n !createTransactionMessage ||\n !setTransactionMessageFeePayer ||\n !setTransactionMessageLifetimeUsingBlockhash ||\n !appendTransactionMessageInstructions ||\n !compileTransaction ||\n !partiallySignTransaction ||\n !getBase64EncodedWireTransaction\n ) {\n throw new ArnsSdkIncompatibleError(\n 'the installed @ar.io/sdk / @ar.io/solana-contracts / @solana/kit ' +\n 'do not expose the record-set transaction builder surface'\n );\n }\n\n const asset = toAddr(args.antProcessId);\n const antProgram =\n antProgramId !== undefined ? toAddr(antProgramId) : undefined;\n const [recordPda] = await getAntRecordPDA(\n asset,\n args.undername,\n antProgram\n );\n // The client is the record CALLER (authority) — a noop signer here so\n // the compiled account meta is marked signer; the real signature comes\n // from partiallySignTransaction below. The DVM's gas wallet is ONLY\n // the fee payer.\n const ix = await getSetRecordInstructionAsync(\n {\n asset,\n record: recordPda,\n caller: createNoopSigner(toAddr(options.solanaPublicKey)),\n undername: args.undername,\n target: args.transactionId,\n targetProtocol: 0,\n ttlSeconds: args.ttlSeconds,\n priority: null,\n recordOwner: null,\n },\n antProgram !== undefined ? { programAddress: antProgram } : undefined\n );\n\n let message = createTransactionMessage({ version: 0 });\n message = setTransactionMessageFeePayer(toAddr(args.feePayer), message);\n message = setTransactionMessageLifetimeUsingBlockhash(\n {\n blockhash: toBlockhash(args.recentBlockhash),\n lastValidBlockHeight: 0n,\n },\n message\n );\n message = appendTransactionMessageInstructions([ix], message);\n\n const keyPair = await createKeyPairFromBytes(options.solanaSecretKey);\n const signed = await partiallySignTransaction(\n [keyPair],\n compileTransaction(message)\n );\n return getBase64EncodedWireTransaction(signed);\n },\n getArNSRecord: async (args) => {\n // 4.x throws on an unregistered name; our seam reports `null` so\n // `status` can render \"available\" instead of an error.\n let raw: {\n processId?: string;\n type?: NameType;\n startTimestamp?: number;\n endTimestamp?: number;\n undernameLimit?: number;\n };\n try {\n raw = (await ario.getArNSRecord(args)) as typeof raw;\n } catch (err) {\n if (err instanceof Error && /not found/i.test(err.message)) return null;\n throw err;\n }\n // Solana-native records carry cluster unix timestamps in SECONDS; the\n // seam contract (and the human expiry render) is ms epoch.\n return {\n // #79 AC4: the registry writes the all-ones placeholder when no ANT\n // is attached. The seam contract is \"a process id or null\", so the\n // placeholder is normalized to null right here — every caller then\n // sees \"no ANT\" instead of a valid-looking System Program address.\n processId: antProcessIdOf(raw.processId),\n type: raw.type ?? null,\n ...(raw.startTimestamp !== undefined\n ? { startTimestamp: raw.startTimestamp * 1000 }\n : {}),\n ...(raw.endTimestamp !== undefined\n ? { endTimestamp: raw.endTimestamp * 1000 }\n : {}),\n ...(raw.undernameLimit !== undefined\n ? { undernameLimit: raw.undernameLimit }\n : {}),\n };\n },\n ant: async (pid) => {\n const ant = await antInit({\n processId: pid,\n rpc,\n ...writeExtras,\n ...(antProgramId !== undefined ? { antProgramId } : {}),\n });\n return {\n getRecords: async () => {\n // Pin the seam shape: 4.x records carry extra fields (index,\n // targetProtocol, …) that must not leak into the `--json` contract.\n const records = await ant.getRecords();\n const targets: Record<string, AntRecordTarget> = {};\n for (const [undername, record] of Object.entries(records)) {\n targets[undername] = {\n transactionId: record.transactionId,\n ttlSeconds: record.ttlSeconds,\n };\n }\n return targets;\n },\n setBaseNameRecord: async (a) => {\n if (typeof ant.setBaseNameRecord !== 'function') {\n throw new ArnsSdkIncompatibleError(\n 'the signed ANT client exposes no setBaseNameRecord'\n );\n }\n return ant.setBaseNameRecord(a);\n },\n setUndernameRecord: async (a) => {\n if (typeof ant.setUndernameRecord !== 'function') {\n throw new ArnsSdkIncompatibleError(\n 'the signed ANT client exposes no setUndernameRecord'\n );\n }\n return ant.setUndernameRecord(a);\n },\n };\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// The brokered-buy DVM job seam (#buyfor)\n// ---------------------------------------------------------------------------\n\n/**\n * The NIP-90 job kind for a brokered ArNS name purchase — mirrors the store\n * repo's `ARNS_BUY_KIND` (the DVM registers this next to its kind:5094\n * Arweave storage job).\n */\nexport const ARNS_BUY_JOB_KIND = 5095;\n\n/**\n * Paid transport for one NIP-90 job to a store node's DVM (#101).\n *\n * This is {@link Publisher.submitStoreJob} narrowed to a function, so the two\n * job seams below depend on the capability rather than on a whole publisher.\n */\nexport type SubmitStoreJob = (\n request: StoreJobRequest\n) => Promise<StoreJobResponse>;\n\n/** One brokered buy job, ready to submit to a DVM. */\nexport interface DvmBuyJobRequest {\n /**\n * The store node's ILP destination that `--via` resolved. Carried for error\n * messages only — the paid transport is {@link DvmBuyJobRequest.submit},\n * which is already bound to this destination.\n */\n destination: string;\n name: string;\n type: NameType;\n /** Lease years; null for a permabuy. */\n years: number | null;\n /** The CLIENT's freshly-spawned ANT (asset pubkey) — the owner-to-be. */\n processId: string;\n /**\n * Paid transport to that node's DVM. The job event is signed by the\n * publisher's own identity, exactly as a kind:5094 store write is, so no\n * key material travels through this seam.\n */\n submit: SubmitStoreJob;\n}\n\n/** What the DVM reports back for an executed buy job. */\nexport interface DvmBuyJobReceipt {\n /** Registry transaction signature of the DVM-paid buy. */\n registryTxId: string;\n /** The mARIO the DVM quoted/paid, when reported. */\n quotedMario: string | null;\n /** The permissionless `syncAttributes` reconcile tx, when it succeeded. */\n syncAttributesTxId: string | null;\n}\n\n/** Submit one kind:5095 job (tests inject a stub — NEVER the live net). */\nexport type SubmitDvmBuyJob = (\n request: DvmBuyJobRequest\n) => Promise<DvmBuyJobReceipt>;\n\n/** A DVM refused or failed a brokered buy job. */\nexport class DvmBuyJobError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DvmBuyJobError';\n }\n}\n\n/**\n * Default {@link SubmitDvmBuyJob}: carry the kind:5095 job to the store node's\n * DVM over the PAID path (#101).\n *\n * This used to `fetch(${viaUrl}/store)` directly. No connector serves `/store`\n * and none should: the store sits behind the connector's payment termination,\n * so a publicly reachable one would be an anonymous free gateway to a paid\n * handler — exactly the failure ADR 0020 exists to close. The job now travels\n * as a kind:5094 store write does, inside a paid ILP packet with `/store` as\n * the envelope target beneath the route's handler path.\n *\n * The job's `param` tags are unchanged, so the handler sees the identical\n * event either way.\n */\nexport const defaultSubmitDvmBuyJob: SubmitDvmBuyJob = async (request) => {\n let answer;\n try {\n answer = await request.submit({\n kind: ARNS_BUY_JOB_KIND,\n params: [\n ['name', request.name],\n ['type', request.type],\n ...(request.years !== null\n ? ([['years', String(request.years)]] as [string, string][])\n : []),\n ['processId', request.processId],\n ],\n });\n } catch (err) {\n throw new DvmBuyJobError(\n `could not reach the DVM at ${request.destination}: ` +\n `${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n if (!answer.accept) {\n throw new DvmBuyJobError(\n `the DVM at ${request.destination} rejected the kind:${ARNS_BUY_JOB_KIND} ` +\n `buy job (HTTP ${answer.status}${answer.code ? `, ${answer.code}` : ''})` +\n `${answer.message ? `: ${answer.message}` : ''}`\n );\n }\n const registryTxId = answer.result?.['registryTxId'];\n if (typeof registryTxId !== 'string' || registryTxId.length === 0) {\n throw new DvmBuyJobError(\n `the DVM accepted the job but returned no registryTxId — response: ` +\n JSON.stringify(answer.result ?? null)\n );\n }\n const quotedMario = answer.result?.['quotedMario'];\n const syncAttributesTxId = answer.result?.['syncAttributesTxId'];\n return {\n registryTxId,\n quotedMario: typeof quotedMario === 'string' ? quotedMario : null,\n syncAttributesTxId:\n typeof syncAttributesTxId === 'string' ? syncAttributesTxId : null,\n };\n};\n\n// ---------------------------------------------------------------------------\n// The gas-station job seam (kind:5096 — toon-meta#163)\n// ---------------------------------------------------------------------------\n\n/** The NIP-90 job kind for a gas-station (fee-payer-as-a-service) job. */\nexport const GAS_STATION_JOB_KIND = 5096;\n\n/** A kind:5096 quote — the merged quote/blockhash deadline contract. */\nexport interface GasStationQuote {\n quoteId: string;\n /** The DVM's advertised fee-payer address — set as the tx feePayer. */\n feePayer: string;\n /** The delta cap the DVM will enforce (lamports, base-10 string). */\n maxLamports: string;\n /** Build + partial-sign against exactly this blockhash. */\n recentBlockhash: string;\n /** ms epoch — submit before this or re-quote. */\n expiresAt: number;\n}\n\n/** A landed kind:5096 execute result. */\nexport interface GasStationExecuteResult {\n signature: string;\n slot: string | null;\n feeLamportsActual: string | null;\n replayed?: boolean;\n}\n\n/** The DVM refused or failed a gas-station job (machine-readable reason). */\nexport class GasStationJobError extends Error {\n constructor(\n public readonly reason: string,\n message: string\n ) {\n super(message);\n this.name = 'GasStationJobError';\n }\n}\n\n/** kind:5096 client seam (tests inject a stub — NEVER the live net). */\nexport interface GasStationClient {\n quote(args: {\n /** Store node's ILP destination, for error messages. */\n destination: string;\n /** Optional draft wire tx for an accurate (rent-aware) maxLamports. */\n transaction?: string;\n /** Paid transport to that node's DVM. */\n submit: SubmitStoreJob;\n }): Promise<GasStationQuote>;\n execute(args: {\n destination: string;\n transaction: string;\n quoteId: string;\n idempotencyKey: string;\n submit: SubmitStoreJob;\n }): Promise<GasStationExecuteResult>;\n}\n\n/**\n * Carry one kind:5096 job to the DVM over the PAID path (#101).\n *\n * Same change as the buy job above, and for the same reason: `/store` is an\n * envelope target beneath the route's handler, not a public URL path.\n */\nasync function submitGasStationJob(\n destination: string,\n params: [string, string][],\n submit: SubmitStoreJob\n): Promise<Record<string, unknown>> {\n let answer;\n try {\n answer = await submit({ kind: GAS_STATION_JOB_KIND, params });\n } catch (err) {\n throw new GasStationJobError(\n 'unreachable',\n `could not reach the DVM at ${destination}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (!answer.accept || !answer.result) {\n throw new GasStationJobError(\n String(answer.code ?? 'rejected'),\n `the DVM at ${destination} rejected the kind:${GAS_STATION_JOB_KIND} job (HTTP ${answer.status}${answer.code ? `, ${answer.code}` : ''})${answer.message ? `: ${answer.message}` : ''}`\n );\n }\n const result = answer.result;\n if (result['status'] === 'failed') {\n throw new GasStationJobError(\n String(result['reason'] ?? 'failed'),\n `gas-station job failed: ${String(result['reason'] ?? 'unknown')} — ${String(result['detail'] ?? '')}`\n );\n }\n return result;\n}\n\n/**\n * Default {@link GasStationClient}: signed kind:5096 events POSTed to the\n * DVM's payment-oblivious `/store` backend — the identical HTTP request the\n * connector payment proxy replays on the paid path (RouteTermination).\n */\nexport const defaultGasStationClient: GasStationClient = {\n quote: async (args) => {\n const result = await submitGasStationJob(\n args.destination,\n [\n ['phase', 'quote'],\n ...(args.transaction !== undefined\n ? ([['transaction', args.transaction]] as [string, string][])\n : []),\n ],\n args.submit\n );\n const { quoteId, feePayer, maxLamports, recentBlockhash, expiresAt } =\n result as Partial<GasStationQuote>;\n if (\n typeof quoteId !== 'string' ||\n typeof feePayer !== 'string' ||\n typeof maxLamports !== 'string' ||\n typeof recentBlockhash !== 'string' ||\n typeof expiresAt !== 'number'\n ) {\n throw new GasStationJobError(\n 'bad_response',\n `the DVM quote is missing fields: ${JSON.stringify(result)}`\n );\n }\n return { quoteId, feePayer, maxLamports, recentBlockhash, expiresAt };\n },\n execute: async (args) => {\n const result = await submitGasStationJob(\n args.destination,\n [\n ['phase', 'execute'],\n ['transaction', args.transaction],\n ['quoteId', args.quoteId],\n ['idempotencyKey', args.idempotencyKey],\n ],\n args.submit\n );\n const signature = result['signature'];\n if (typeof signature !== 'string' || signature.length === 0) {\n throw new GasStationJobError(\n 'bad_response',\n `the DVM execute result carries no signature: ${JSON.stringify(result)}`\n );\n }\n return {\n signature,\n slot: typeof result['slot'] === 'string' ? result['slot'] : null,\n feeLamportsActual:\n typeof result['feeLamportsActual'] === 'string'\n ? result['feeLamportsActual']\n : null,\n ...(result['replayed'] === true ? { replayed: true } : {}),\n };\n },\n};\n\n// ---------------------------------------------------------------------------\n// Deps + usage\n// ---------------------------------------------------------------------------\n\n/** What `rig name` needs from the command environment. */\nexport interface NameDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n /** Working directory (project-local `.env` walk for the identity). */\n cwd: string;\n /** ar.io SDK loader seam; defaults to the lazy `@ar.io/sdk` import. */\n loadArns?: LoadArns;\n /** kind:5095 job submitter seam; defaults to the paid ILP submission. */\n submitDvmBuyJob?: SubmitDvmBuyJob;\n /** kind:5096 gas-station client seam; defaults to the paid ILP submission. */\n gasStation?: GasStationClient;\n /**\n * Standalone-session factory for the `--via` paid path (#101); defaults to\n * `rig push`'s. Tests inject a fake so no session is ever opened and no\n * packet is ever paid for.\n */\n loadStandalone?: LoadStandalone;\n /**\n * TOON-network resolution seam for the default `--via` DVM (defaults to\n * `rig fund`'s {@link resolveEffectiveNetwork}; tests inject). The devnet\n * DVM is only defaulted when the TOON side ALSO resolves to devnet.\n */\n resolveToonNetwork?: typeof resolveEffectiveNetwork;\n}\n\n/**\n * The deployed devnet store DVM — defaulted as `--via` for buy/set when BOTH\n * the ArNS `--network` and the TOON network resolve to devnet and the user\n * neither named a DVM (`--via`/`RIG_ARNS_DVM_DESTINATION`) nor opted out\n * (`--direct`).\n */\nexport const DEVNET_DVM_DESTINATION = 'g.toon.ario';\n\n/**\n * @deprecated `--via` names an ILP destination, not an HTTP endpoint (#101).\n * Kept as an alias so an importer of the old name still compiles; it now holds\n * the same destination as {@link DEVNET_DVM_DESTINATION}.\n */\nexport const DEVNET_DVM_URL = DEVNET_DVM_DESTINATION;\n\nexport const NAME_USAGE = `Usage: rig name <buy|set|status> <name> [options]\n\nArNS naming for Arweave-served artifacts. A name registered on the ar.io\nregistry resolves at every ar.io gateway (https://<name>.<gateway>/), pointing\nat whatever Arweave txId its ANT record targets (10 undernames included).\n\nNames are OWNED and PAID FOR by this rig identity's Solana key — the same\nmnemonic that pays for pushes (derived at m/44'/501'/0'/0'). Fund it with\n\\`rig fund --chain solana\\`. Purchases spend mARIO on Solana via the ar.io\nregistry program — NOT through TOON ILP payment channels.\n\nCommands:\n name buy <name> [--years n | --permabuy] [--via <destination>]\n quote (mARIO) → confirm → register. The spawned ANT is\n owned by this identity's Solana key. Default: 1-year\n lease. PAID — spends mARIO from the Solana wallet.\n With --via: BROKERED — this identity spawns and owns\n the ANT (dust SOL only), then a store DVM executes the\n kind:5095 buy job and pays the mARIO from ITS wallet;\n the name is owned by your ANT from inception.\n name set <name> <txId> [--undername <sub>] [--ttl <seconds>] [--via <destination>]\n point the name (or an undername) at an Arweave txId\n (typically a deployed path manifest). Signs an ANT\n record update with the Solana key. With --via: the\n gas-station path (kind:5096) — you author and\n partial-sign, the DVM co-signs as fee payer and pays\n the lamports; needs ZERO SOL in this wallet.\n <txId> may instead be given via --tx-id <id> — use\n that instead of the positional when the txId leads\n with '-' or '_' (Arweave txids are base64url). For a\n leading '-' write --tx-id=<id> (the '=' form), since\n \"--tx-id -XYZ...\" is itself ambiguous to the parser.\n name status <name> FREE: registry record (lease/permabuy, expiry), ANT\n process id, current target txId(s), TTL, undernames.\n\nOptions:\n --years <n> lease length in years (buy; default 1; mutually\n exclusive with --permabuy)\n --permabuy permanent registration instead of a lease (buy)\n --undername <sub> target the undername <sub>_<name> instead of the base\n name (set)\n --ttl <seconds> record TTL in seconds (set; default 3600)\n --tx-id <id> set only: the Arweave txId to point at, as an\n explicit option instead of the positional (mutually\n exclusive with the positional <txId>). For a value\n leading with '-' use --tx-id=<id>.\n --network <net> cluster: mainnet | devnet (default mainnet; or\n RIG_ARIO_NETWORK). ar.io has no Solana-testnet\n deployment. Non-mainnet gateway resolution is\n unverified.\n --process-id <id> explicit ArNS registry program id — a Solana program\n address (overrides --network; or RIG_ARIO_PROCESS_ID)\n --via <destination> broker buy/set through a store node's DVM, naming its\n ILP DESTINATION (or RIG_ARNS_DVM_DESTINATION), e.g.\n --via ${DEVNET_DVM_DESTINATION}. The DVM pays the mARIO;\n you own the name via your spawned ANT.\n The job travels as a PAID packet, exactly as a git-object\n store write does — the store sits behind the connector's\n payment termination, so there is no unpaid endpoint to\n aim at. That node's ingress, route price and payment\n channel are all discovered from its own announce, so the\n destination is the only thing you supply.\n Costs one store-route packet per job (two for set:\n quote + execute).\n DEVNET DEFAULT: with --network devnet and the TOON\n network on devnet too, buy/set default to the deployed\n devnet store DVM (${DEVNET_DVM_DESTINATION})\n unless --direct opts out.\n --direct force the direct wallet-paid path: never default (or\n read RIG_ARNS_DVM_DESTINATION as) a --via DVM. Mutually\n exclusive with an explicit --via.\n --yes skip the confirmation (required when not a TTY) for\n buy/set\n --json machine-readable envelope; for buy/set without --yes it\n is a pure estimate (nothing is bought or written)\n -h, --help show this help`;\n\n// ---------------------------------------------------------------------------\n// Shared setup: identity → Solana key → SDK\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 3600;\nconst DEFAULT_LEASE_YEARS = 1;\nconst NETWORKS: readonly ArioNetwork[] = ['mainnet', 'devnet'];\n\n/** Resolved wallet context shared by every `rig name` action. */\ninterface NameContext {\n identity: IdentityReport;\n solanaAddress: string;\n network: ArioNetwork;\n processId: string | undefined;\n sdk: ArnsSdk;\n /** Nostr secret key of the identity — signs brokered kind:5095 jobs. */\n nostrSecretKey: Uint8Array;\n}\n\n/**\n * Resolve the rig identity, derive its Solana key (the owner/payer), and build\n * the (stub-injected in tests) ArNS SDK targeted at the chosen registry.\n * `mode` decides whether the SDK gets write plumbing: every FREE lookup —\n * `status`, the buy quote, the set preview — runs `read` (signerless, #376);\n * `buy`/`set` escalate to `write` only at execute time, after the confirm\n * gate.\n */\n/**\n * Open a paid session against the store node `--via` names, and hand back its\n * job seam plus the teardown the caller must run (#101).\n *\n * `storeDestination` is the whole configuration this needs. From it, the\n * machinery `rig push` already uses discovers that node's BTP ingress from its\n * own kind:10032 announce, opens (or resumes) a payment channel against its\n * settlement address, and reads its route price to floor the claim — the same\n * store leg #98 built, pointed somewhere chosen per invocation.\n *\n * ⚠️ The caller owns the returned `stop`. A session left open holds the\n * identity lock and an started embedded client.\n */\nasync function openStoreJobSession(\n deps: NameDeps,\n destination: string\n): Promise<{ submit: SubmitStoreJob; stop: () => Promise<void> }> {\n const ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => deps.io.err(line),\n storeDestination: destination,\n });\n const submitStoreJob = ctx.publisher.submitStoreJob;\n if (!submitStoreJob) {\n await ctx.stop();\n throw new Error(\n 'the active publisher cannot submit a store job (submitStoreJob ' +\n 'unavailable) — `rig name --via` requires the standalone publisher'\n );\n }\n return {\n submit: (request) => submitStoreJob.call(ctx.publisher, request),\n stop: () => ctx.stop(),\n };\n}\n\nasync function resolveNameContext(\n deps: NameDeps,\n network: ArioNetwork,\n processId: string | undefined,\n mode: 'read' | 'write'\n): Promise<NameContext> {\n const { io, env } = deps;\n const resolved = await resolveIdentity({\n env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n });\n const identity: IdentityReport = {\n pubkey: resolved.pubkey,\n source: resolved.source,\n sourceLabel: resolved.sourceLabel,\n };\n // Dynamic import: `@toon-protocol/client` is heavy — the same lazy load\n // `rig fund`/`rig balance` use to derive the multi-chain identity.\n const client = await import('@toon-protocol/client');\n const derived = client.deriveFullIdentity(resolved.mnemonic, {\n accountIndex: resolved.accountIndex,\n scheme: 'legacy',\n });\n const solanaAddress = derived.solana.publicKey;\n if (!solanaAddress) {\n throw new Error(\n 'no Solana key could be derived for this identity — ArNS names are ' +\n \"owned by the Solana key (m/44'/501'/0'/0'). Ensure the optional \" +\n 'Solana derivation deps are installed.'\n );\n }\n const sdk = await (deps.loadArns ?? defaultLoadArns)({\n mode,\n solanaSecretKey: derived.solana.secretKey,\n solanaPublicKey: solanaAddress,\n network,\n ...(processId !== undefined ? { processId } : {}),\n });\n const nostrSecretKey = deriveNostrKeyFromMnemonic(\n resolved.mnemonic,\n resolved.accountIndex\n ).secretKey;\n return { identity, solanaAddress, network, processId, sdk, nostrSecretKey };\n}\n\n// ---------------------------------------------------------------------------\n// Parsed flags\n// ---------------------------------------------------------------------------\n\ninterface NameFlags {\n years?: number;\n permabuy: boolean;\n undername?: string;\n ttl: number;\n network: ArioNetwork;\n processId?: string;\n /** Brokered buy: the DVM endpoint to submit the kind:5095 job to. */\n via?: string;\n /**\n * Opt out of the devnet default `--via` DVM: force the direct wallet-paid\n * path even when both networks resolve to devnet.\n */\n direct: boolean;\n /**\n * `set` only: the Arweave txId as an explicit option, so it never has to\n * sit in the hyphen-ambiguous positional slot — Arweave txids are\n * base64url and roughly 1 in 32 lead with `-` or `_`, which Node's\n * `parseArgs` (strict by default) misreads as an unknown flag (#399).\n */\n txId?: string;\n yes: boolean;\n json: boolean;\n}\n\nfunction parseNameFlags(\n args: string[],\n env: NodeJS.ProcessEnv\n): {\n positionals: string[];\n flags: NameFlags;\n} {\n const { values, positionals } = parseArgs({\n args,\n allowPositionals: true,\n options: {\n years: { type: 'string' },\n permabuy: { type: 'boolean', default: false },\n undername: { type: 'string' },\n ttl: { type: 'string' },\n network: { type: 'string' },\n 'process-id': { type: 'string' },\n via: { type: 'string' },\n direct: { type: 'boolean', default: false },\n 'tx-id': { type: 'string' },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n return {\n positionals: ['--help'],\n flags: {\n permabuy: false,\n ttl: 0,\n network: 'mainnet',\n direct: false,\n yes: false,\n json: false,\n },\n };\n }\n\n let years: number | undefined;\n if (values.years !== undefined) {\n years = Number(values.years);\n if (!Number.isInteger(years) || years <= 0) {\n throw new Error(\n `--years must be a positive integer, got ${JSON.stringify(values.years)}`\n );\n }\n }\n if (years !== undefined && values.permabuy) {\n throw new Error('--years and --permabuy are mutually exclusive');\n }\n\n let ttl = DEFAULT_TTL_SECONDS;\n if (values.ttl !== undefined) {\n ttl = Number(values.ttl);\n if (!Number.isInteger(ttl) || ttl <= 0) {\n throw new Error(\n `--ttl must be a positive integer number of seconds, got ${JSON.stringify(values.ttl)}`\n );\n }\n }\n\n const networkRaw = values.network ?? env['RIG_ARIO_NETWORK'] ?? 'mainnet';\n if (!NETWORKS.includes(networkRaw as ArioNetwork)) {\n throw new Error(\n `--network must be one of ${NETWORKS.join(' | ')}, got ${JSON.stringify(networkRaw)}`\n );\n }\n const processId = values['process-id'] ?? env['RIG_ARIO_PROCESS_ID'];\n\n if (values.direct && values.via !== undefined) {\n throw new Error(\n '--direct and --via are mutually exclusive: --direct forces the ' +\n 'wallet-paid path, --via brokers through a DVM'\n );\n }\n // --direct beats the ambient env var too (explicit opt-out).\n // `RIG_ARNS_DVM_URL` is the pre-#101 spelling, still read so an existing\n // environment keeps working, but it now carries a destination.\n const viaRaw = values.direct\n ? undefined\n : (values.via ??\n env['RIG_ARNS_DVM_DESTINATION'] ??\n env['RIG_ARNS_DVM_URL']);\n let via: string | undefined;\n if (viaRaw !== undefined) {\n // #101: `--via` names an ILP DESTINATION, not an HTTP endpoint. The store\n // sits behind the connector's payment termination and no connector serves\n // a public `/store`, so a URL here is a leftover from the broken direct\n // path rather than a usable value — reject it with the fix rather than\n // letting it fail later as an unroutable address.\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(viaRaw)) {\n throw new Error(\n `--via names an ILP destination, not a URL (got ${JSON.stringify(viaRaw)}). ` +\n `Brokered ArNS jobs travel as paid packets to a store node, e.g. ` +\n `--via ${DEVNET_DVM_DESTINATION}. The node's endpoint, price and ` +\n `payment channel are discovered from its own announce.`\n );\n }\n if (!/^g\\.[a-z0-9]+(\\.[a-z0-9-]+)*$/i.test(viaRaw)) {\n throw new Error(\n `--via must be an ILP destination like ${DEVNET_DVM_DESTINATION}, ` +\n `got ${JSON.stringify(viaRaw)}`\n );\n }\n via = viaRaw;\n }\n\n return {\n positionals,\n flags: {\n ...(years !== undefined ? { years } : {}),\n permabuy: values.permabuy ?? false,\n ...(values.undername !== undefined\n ? { undername: values.undername }\n : {}),\n ttl,\n network: networkRaw as ArioNetwork,\n ...(processId !== undefined ? { processId } : {}),\n ...(via !== undefined ? { via } : {}),\n direct: values.direct ?? false,\n ...(values['tx-id'] !== undefined ? { txId: values['tx-id'] } : {}),\n yes: values.yes ?? false,\n json: values.json ?? false,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// buy\n// ---------------------------------------------------------------------------\n\ninterface NameBuyJson {\n command: 'name';\n action: 'buy';\n name: string;\n type: NameType;\n years: number | null;\n network: ArioNetwork;\n processId: string | null;\n /** Brokered buy: the DVM endpoint the kind:5095 job goes to (else null). */\n via: string | null;\n identity: IdentityReport;\n solanaAddress: string;\n /** The mARIO quote (base units, string) + a human ARIO figure. */\n quote: { mARIO: string; ARIO: string };\n /** How the purchase settles — always Solana/registry, never ILP. */\n payment: string;\n executed: boolean;\n hint?: string;\n /**\n * The ANT this identity spawned and owns (execute only) — both the\n * brokered and direct paths spawn one (#79).\n */\n spawn?: { processId: string; signature: string };\n result?: {\n registryTxId: string;\n antProcessId: string | null;\n /** Brokered buy: the DVM's permissionless trait reconcile tx, if any. */\n syncAttributesTxId?: string | null;\n /** Brokered buy: the mARIO the DVM reported paying, if any. */\n dvmQuotedMario?: string | null;\n };\n}\n\nasync function runBuy(\n name: string,\n flags: NameFlags,\n deps: NameDeps\n): Promise<number> {\n const { io } = deps;\n const type: NameType = flags.permabuy ? 'permabuy' : 'lease';\n const years = type === 'lease' ? (flags.years ?? DEFAULT_LEASE_YEARS) : null;\n\n // Signerless context: the quote is a FREE read (#376); write plumbing is\n // built only after the confirm gate, right before money moves.\n const ctx = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'read'\n );\n\n // ── Estimate (quote the mARIO cost) ──────────────────────────────────────\n const mario = await ctx.sdk.getTokenCost({\n intent: 'Buy-Name',\n name,\n type,\n ...(years !== null ? { years } : {}),\n });\n const quote = {\n mARIO: mario.toString(),\n ARIO: formatUnits(mario.toString(), ARIO_DECIMALS),\n };\n\n const via = flags.via ?? null;\n const paymentNote = via === null ? MARIO_PAYMENT_NOTE : DVM_PAYMENT_NOTE;\n\n const buildJson = (\n executed: boolean,\n extra: Partial<NameBuyJson> = {}\n ): NameBuyJson => ({\n command: 'name',\n action: 'buy',\n name,\n type,\n years,\n network: ctx.network,\n processId: ctx.processId ?? null,\n via,\n identity: ctx.identity,\n solanaAddress: ctx.solanaAddress,\n quote,\n payment: paymentNote,\n executed,\n ...extra,\n });\n\n // ── Human estimate table ─────────────────────────────────────────────────\n if (!flags.json) {\n io.out(\n `Buy ArNS name \"${name}\" — ${type}` +\n (years !== null ? ` (${years} year${years === 1 ? '' : 's'})` : '') +\n ` on ${ctx.network}` +\n (via !== null ? ` — brokered via DVM ${via}` : '')\n );\n io.out(\n via === null\n ? ` Cost: ${renderMario(mario)}`\n : ` Name cost (paid by the DVM): ${renderMario(mario)}`\n );\n io.out(` Solana wallet: ${ctx.solanaAddress}`);\n io.out(` ${paymentNote}`);\n io.out(renderIdentityLine(ctx.identity));\n }\n\n // ── Confirm gate ─────────────────────────────────────────────────────────\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson(\n buildJson(false, {\n hint:\n via === null\n ? 'estimate only — re-run with --yes to buy (spends mARIO on Solana, non-refundable)'\n : 'estimate only — re-run with --yes to spawn your ANT and submit the kind:5095 buy job to the DVM',\n })\n );\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n via === null\n ? 'refusing to spend mARIO without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for a pure estimate)'\n : 'refusing to spawn an ANT and submit a paid DVM job without ' +\n 'confirmation in a non-interactive session — re-run with --yes ' +\n '(or use --json for a pure estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n via === null\n ? `Proceed — buy \"${name}\" for ${renderMario(mario)} from your Solana wallet? [y/N] `\n : `Proceed — spawn your ANT and have the DVM at ${via} buy \"${name}\" ` +\n `for ${renderMario(mario)} from ITS wallet? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was bought or paid.');\n return 1;\n }\n }\n\n // ── Execute — build the signed SDK (write mode) only now, confirmed ──────\n const signed = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'write'\n );\n\n if (via !== null) {\n // ── Brokered (\"buyfor\"): spawn OUR ANT, then the DVM buys for it ───────\n // 1. ANT.spawn with this identity's Solana key — the client owns the ANT\n // (and therefore the name, from inception). Costs dust SOL, no $ARIO.\n const spawn = await signed.sdk.spawnAnt({ name });\n if (!flags.json) {\n io.out(`Spawned ANT ${spawn.processId} (tx ${spawn.signature})`);\n }\n // 2. Submit the kind:5095 job carrying OUR processId; the DVM executes\n // buyRecord with ITS funded signer. The job rides a PAID ILP packet to\n // the store node `--via` names (#101), so a session is opened for it and\n // closed whatever happens — it holds the identity lock.\n const submit = deps.submitDvmBuyJob ?? defaultSubmitDvmBuyJob;\n const session = await openStoreJobSession(deps, via);\n let receipt;\n try {\n receipt = await submit({\n destination: via,\n name,\n type,\n years,\n processId: spawn.processId,\n submit: session.submit,\n });\n } finally {\n await session.stop();\n }\n const result = {\n registryTxId: receipt.registryTxId,\n antProcessId: spawn.processId,\n syncAttributesTxId: receipt.syncAttributesTxId,\n dvmQuotedMario: receipt.quotedMario,\n };\n\n if (flags.json) {\n io.emitJson(\n buildJson(true, {\n spawn: { processId: spawn.processId, signature: spawn.signature },\n result,\n })\n );\n } else {\n io.out(\n `Registered \"${name}\" via the DVM — registry tx ${result.registryTxId}`\n );\n io.out(` ANT process (owned by YOU): ${spawn.processId}`);\n if (receipt.syncAttributesTxId) {\n io.out(` Trait sync: ${receipt.syncAttributesTxId}`);\n } else {\n // Proven on devnet: the deployed ario-ant program gates SyncAttributes\n // to the NFT holder, so the DVM cannot reconcile the traits — you can.\n io.out(\n ' Trait sync: not run by the DVM (holder-gated on this ' +\n 'deployment) — as the ANT holder you can reconcile with ' +\n 'syncAttributes later; resolution works regardless.'\n );\n }\n io.out(\n `Point it at content with \\`rig name set ${name} <txId>\\`, then it ` +\n `resolves at https://${name}.<gateway>/`\n );\n }\n return 0;\n }\n\n // ── Direct: register with our own funded wallet (the #367 path) ──────────\n // #79: this identity spawns ITS OWN ANT first (dust SOL, same as the\n // brokered path) and passes its processId into buyRecord, so the name is\n // bound to a real ANT from inception instead of collapsing to the\n // registry's all-ones placeholder.\n const spawn = await signed.sdk.spawnAnt({ name });\n if (!flags.json) {\n io.out(`Spawned ANT ${spawn.processId} (tx ${spawn.signature})`);\n }\n const receipt = await signed.sdk.buyRecord({\n name,\n type,\n ...(years !== null ? { years } : {}),\n processId: spawn.processId,\n });\n // The ANT actually bound: the SDK's echo when it returns one, otherwise the\n // id we asked it to attach (4.0.3's Solana `buyRecord` resolves to `{ id }`\n // alone, so in practice this is the ANT we just spawned). Normalized like\n // every other ANT id, so the placeholder reads as \"no ANT\" here too.\n const antProcessId = antProcessIdOf(receipt.processId ?? spawn.processId);\n const result = { registryTxId: receipt.id, antProcessId };\n const spawnInfo = { processId: spawn.processId, signature: spawn.signature };\n\n if (antProcessId === null) {\n // The purchase went through — the spend is real and on-chain — but no\n // ANT is attached, so the name cannot resolve. Exit non-zero and surface\n // the registry tx either way: never exit 0 on a null ANT (#79), and\n // never lose the tx that makes the spend recoverable.\n const hint =\n `bought \"${name}\" (registry tx ${result.registryTxId}) but no ANT is ` +\n 'attached — the spend is on-chain and recoverable, but the name ' +\n 'cannot resolve until an ANT is attached to it';\n if (flags.json) {\n io.emitJson(buildJson(true, { spawn: spawnInfo, result, hint }));\n } else {\n io.err(hint);\n }\n return 1;\n }\n\n if (flags.json) {\n io.emitJson(buildJson(true, { spawn: spawnInfo, result }));\n } else {\n io.out(`Registered \"${name}\" — registry tx ${result.registryTxId}`);\n io.out(` ANT process: ${result.antProcessId}`);\n io.out(\n `Point it at content with \\`rig name set ${name} <txId>\\`, then it ` +\n `resolves at https://${name}.<gateway>/`\n );\n }\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// set\n// ---------------------------------------------------------------------------\n\ninterface NameSetJson {\n command: 'name';\n action: 'set';\n name: string;\n undername: string | null;\n txId: string;\n ttl: number;\n network: ArioNetwork;\n processId: string | null;\n /** Gas-station path: the DVM endpoint the kind:5096 job goes to. */\n via: string | null;\n identity: IdentityReport;\n solanaAddress: string;\n antProcessId: string;\n executed: boolean;\n hint?: string;\n /** Gas-station path: the quote the DVM enforced. */\n gasStation?: {\n quoteId: string;\n feePayer: string;\n maxLamports: string;\n expiresAt: number;\n feeLamportsActual: string | null;\n };\n result?: { messageId: string };\n}\n\nasync function runSet(\n name: string,\n txId: string,\n flags: NameFlags,\n deps: NameDeps\n): Promise<number> {\n const { io } = deps;\n // Signerless context: the record lookup / preview is a FREE read (#376);\n // write plumbing is built only after the confirm gate.\n const ctx = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'read'\n );\n\n const record = await ctx.sdk.getArNSRecord({ name });\n if (!record) {\n throw new Error(\n `no ArNS record for \"${name}\" on ${ctx.network} — buy it first with ` +\n `\\`rig name buy ${name}\\` (or check \\`rig name status ${name}\\`)`\n );\n }\n const antProcessId = antProcessIdOf(record.processId);\n if (antProcessId === null) {\n // #79 AC4: the placeholder is \"no ANT\", not a process id. Signing a\n // record update against it would target the Solana System Program and\n // cannot succeed, so refuse here rather than build and sign a doomed tx.\n throw new Error(\n `\"${name}\" is registered on ${ctx.network} but has NO ANT attached ` +\n `(the registry placeholder ${ARNS_NULL_PROCESS_ID}) — \\`rig name set\\` ` +\n `needs a real ANT process, so there is nothing to write to. Check ` +\n `\\`rig name status ${name}\\`; the name has to be re-bound to an ANT ` +\n `before it can resolve.`\n );\n }\n const undername = flags.undername ?? null;\n const via = flags.via ?? null;\n\n const buildJson = (\n executed: boolean,\n extra: Partial<NameSetJson> = {}\n ): NameSetJson => ({\n command: 'name',\n action: 'set',\n name,\n undername,\n txId,\n ttl: flags.ttl,\n network: ctx.network,\n processId: ctx.processId ?? null,\n via,\n identity: ctx.identity,\n solanaAddress: ctx.solanaAddress,\n antProcessId,\n executed,\n ...extra,\n });\n\n const targetLabel = undername\n ? `undername \"${undername}_${name}\"`\n : `base name \"${name}\"`;\n\n if (!flags.json) {\n io.out(\n `Set ${targetLabel} → txId ${txId} (ttl ${flags.ttl}s) on ${ctx.network}` +\n (via !== null ? ` — gas paid by the DVM at ${via} (kind:5096)` : '')\n );\n io.out(` ANT process: ${antProcessId}`);\n io.out(` Signed by the identity's Solana key (${ctx.solanaAddress}).`);\n if (via !== null) {\n io.out(\n ' Gas station: you author + partial-sign the record update; the ' +\n 'DVM co-signs as fee payer and pays the lamports (toon-meta#163). ' +\n 'Direct backend targeting stubs the job payment (dev/e2e).'\n );\n }\n io.out(renderIdentityLine(ctx.identity));\n }\n\n // ── Confirm gate (a signed ANT record update) ────────────────────────────\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson(\n buildJson(false, {\n hint:\n via === null\n ? 'estimate only — re-run with --yes to write the ANT record'\n : 'estimate only — re-run with --yes to quote the gas-station and write the ANT record (DVM pays the gas)',\n })\n );\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to write an ANT record without confirmation in a ' +\n 'non-interactive session — re-run with --yes (or --json to preview)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed — point ${targetLabel} at ${txId}?` +\n (via !== null ? ' (the DVM pays the gas)' : '') +\n ' [y/N] '\n );\n if (!proceed) {\n io.err('aborted — the ANT record was not changed.');\n return 1;\n }\n }\n\n // ── Execute (sign + submit the ANT record update) ────────────────────────\n // Only now — confirmed — build the signed SDK (write mode).\n const signed = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'write'\n );\n\n if (via !== null) {\n // ── Gas-station path (toon-meta#163): author + partial-sign locally,\n // the DVM co-signs as fee payer and broadcasts. ────────────────────\n const gas = deps.gasStation ?? defaultGasStationClient;\n // Both phases ride PAID ILP packets to the store node `--via` names\n // (#101). One session covers the pair: the quote's blockhash deadline\n // makes re-opening between them a way to expire your own quote.\n const session = await openStoreJobSession(deps, via);\n let quote: GasStationQuote;\n let executed: GasStationExecuteResult;\n try {\n // Quote: learn the fee payer + the quoted blockhash (merged deadline).\n quote = await gas.quote({\n destination: via,\n submit: session.submit,\n });\n // Build + partial-sign against exactly the quoted blockhash.\n const wireTx = await signed.sdk.buildSetRecordTransaction({\n antProcessId,\n undername: undername ?? '@',\n transactionId: txId,\n ttlSeconds: flags.ttl,\n feePayer: quote.feePayer,\n recentBlockhash: quote.recentBlockhash,\n });\n executed = await gas.execute({\n destination: via,\n transaction: wireTx,\n quoteId: quote.quoteId,\n idempotencyKey: randomUUID(),\n submit: session.submit,\n });\n } finally {\n await session.stop();\n }\n const gasStation = {\n quoteId: quote.quoteId,\n feePayer: quote.feePayer,\n maxLamports: quote.maxLamports,\n expiresAt: quote.expiresAt,\n feeLamportsActual: executed.feeLamportsActual,\n };\n const result = { messageId: executed.signature };\n\n if (flags.json) {\n io.emitJson(buildJson(true, { gasStation, result }));\n } else {\n io.out(\n `Updated — record-set tx ${executed.signature} (gas paid by ${quote.feePayer})`\n );\n const host = undername ? `${undername}_${name}` : name;\n io.out(\n ` Resolves at https://${host}.<gateway>/ (allow for gateway cache/TTL).`\n );\n }\n return 0;\n }\n\n const ant = await signed.sdk.ant(antProcessId);\n const receipt = undername\n ? await ant.setUndernameRecord({\n undername,\n transactionId: txId,\n ttlSeconds: flags.ttl,\n })\n : await ant.setBaseNameRecord({\n transactionId: txId,\n ttlSeconds: flags.ttl,\n });\n const result = { messageId: receipt.id };\n\n if (flags.json) {\n io.emitJson(buildJson(true, { result }));\n } else {\n io.out(`Updated — ANT message ${result.messageId}`);\n const host = undername ? `${undername}_${name}` : name;\n io.out(\n ` Resolves at https://${host}.<gateway>/ (allow for gateway cache/TTL).`\n );\n }\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// status (FREE)\n// ---------------------------------------------------------------------------\n\ninterface NameStatusJson {\n command: 'name';\n action: 'status';\n name: string;\n network: ArioNetwork;\n processId: string | null;\n registered: boolean;\n /**\n * #79 AC4: the name is registered but no ANT is attached (the registry's\n * all-ones placeholder) — it cannot resolve, and `rig name set` cannot fix\n * it. Never reported as success: status also exits non-zero in this case.\n */\n antMissing: boolean;\n identity: IdentityReport;\n solanaAddress: string;\n record: {\n antProcessId: string | null;\n type: NameType | null;\n startTimestamp: number | null;\n endTimestamp: number | null;\n undernameLimit: number | null;\n } | null;\n /** ANT record targets keyed by undername (`@` = base name). */\n targets: Record<string, AntRecordTarget> | null;\n /** Set when the status is not a clean bill of health (`antMissing`). */\n hint?: string;\n}\n\nasync function runStatus(\n name: string,\n flags: NameFlags,\n deps: NameDeps\n): Promise<number> {\n const { io } = deps;\n // FREE read: signerless SDK — a status lookup must never need write plumbing.\n const ctx = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'read'\n );\n\n const record = await ctx.sdk.getArNSRecord({ name });\n // #79 AC4: never report the registry's placeholder as the name's ANT. A\n // registered name with no ANT attached cannot resolve, so it is a failure\n // to be diagnosed — not a healthy registration.\n const antProcessId = antProcessIdOf(record?.processId);\n const antMissing = record !== null && antProcessId === null;\n const antMissingHint =\n `\"${name}\" is registered on ${ctx.network} but has NO ANT attached ` +\n `(the registry placeholder ${ARNS_NULL_PROCESS_ID}) — it cannot resolve, ` +\n `and \\`rig name set\\` cannot write records against it. The name has to be ` +\n `re-bound to an ANT.`;\n let targets: Record<string, AntRecordTarget> | null = null;\n if (antProcessId !== null) {\n const ant = await ctx.sdk.ant(antProcessId);\n targets = await ant.getRecords();\n }\n\n if (flags.json) {\n io.emitJson({\n command: 'name',\n action: 'status',\n name,\n network: ctx.network,\n processId: ctx.processId ?? null,\n registered: record !== null,\n antMissing,\n identity: ctx.identity,\n solanaAddress: ctx.solanaAddress,\n record: record\n ? {\n antProcessId,\n type: record.type,\n startTimestamp: record.startTimestamp ?? null,\n endTimestamp: record.endTimestamp ?? null,\n undernameLimit: record.undernameLimit ?? null,\n }\n : null,\n targets,\n ...(antMissing ? { hint: antMissingHint } : {}),\n } satisfies NameStatusJson);\n return antMissing ? 1 : 0;\n }\n\n io.out(`ArNS name \"${name}\" on ${ctx.network}:`);\n if (!record) {\n io.out(' not registered — available to `rig name buy`.');\n io.out(renderIdentityLine(ctx.identity));\n return 0;\n }\n io.out(` ANT process: ${antProcessId ?? 'NONE — no ANT is attached'}`);\n io.out(` Type: ${record.type ?? '(unknown)'}`);\n if (record.type === 'permabuy') {\n io.out(' Expiry: never (permabuy)');\n } else if (record.endTimestamp !== undefined) {\n io.out(` Expiry: ${new Date(record.endTimestamp).toISOString()}`);\n }\n if (record.undernameLimit !== undefined) {\n io.out(` Undernames included: ${record.undernameLimit}`);\n }\n if (targets && Object.keys(targets).length > 0) {\n io.out(' Records:');\n for (const [under, target] of Object.entries(targets)) {\n const label = under === '@' ? '(base)' : `${under}_${name}`;\n io.out(\n ` ${label} → ${target.transactionId} (ttl ${target.ttlSeconds}s)`\n );\n }\n } else if (antMissing) {\n io.out(' Records: none — there is no ANT to hold them.');\n } else {\n io.out(' Records: none set — point one with `rig name set`.');\n }\n io.out(renderIdentityLine(ctx.identity));\n if (antMissing) {\n io.err(antMissingHint);\n return 1;\n }\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// Dispatch\n// ---------------------------------------------------------------------------\n\n/** Run `rig name <sub> …`; returns the process exit code. */\nexport async function runName(args: string[], deps: NameDeps): Promise<number> {\n const { io } = deps;\n const sub = args[0];\n\n if (sub === undefined) {\n // Usage error → stderr + exit 2 (matches every other rig-owned command).\n io.err(NAME_USAGE);\n return 2;\n }\n if (sub === '--help' || sub === '-h' || sub === 'help') {\n io.out(NAME_USAGE);\n return 0;\n }\n if (!['buy', 'set', 'status'].includes(sub)) {\n io.err(`unknown \\`rig name\\` subcommand: ${JSON.stringify(sub)}`);\n io.err(NAME_USAGE);\n return 2;\n }\n\n let positionals: string[];\n let flags: NameFlags;\n try {\n const parsed = parseNameFlags(args.slice(1), deps.env);\n positionals = parsed.positionals;\n flags = parsed.flags;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(NAME_USAGE);\n return 2;\n }\n if (positionals[0] === '--help') {\n io.out(NAME_USAGE);\n return 0;\n }\n\n const name = positionals[0];\n if (name === undefined) {\n io.err(`\\`rig name ${sub}\\` needs a <name>`);\n io.err(NAME_USAGE);\n return 2;\n }\n\n // Default `--via` DVM on the shared devnet (#demo): buy/set broker through\n // the deployed store DVM when the user neither named a DVM (--via /\n // RIG_ARNS_DVM_URL) nor opted out (--direct). Hard-gated BOTH ways: the\n // ArNS `--network` must be devnet (a mainnet purchase must never silently\n // switch payment paths) AND the TOON network must resolve to devnet (same\n // inference `rig fund` drips on — explicit config, devnet origin, or the\n // genesis-seed fresh install).\n if (\n (sub === 'buy' || sub === 'set') &&\n !flags.direct &&\n flags.via === undefined &&\n flags.network === 'devnet'\n ) {\n let toonDevnet = false;\n try {\n const resolved = await (\n deps.resolveToonNetwork ?? resolveEffectiveNetwork\n )({ env: deps.env, cwd: deps.cwd });\n toonDevnet = resolved.effectiveNetwork === 'devnet';\n } catch {\n // Unreadable client config — leave the wallet-paid path untouched.\n }\n if (toonDevnet) {\n flags = { ...flags, via: DEVNET_DVM_DESTINATION };\n io.err(\n `Brokering via the devnet store DVM ${DEVNET_DVM_DESTINATION} ` +\n `(no --via given; pass --direct for a wallet-paid ${sub}).`\n );\n }\n }\n\n try {\n if (sub === 'buy') return await runBuy(name, flags, deps);\n if (sub === 'status') return await runStatus(name, flags, deps);\n // set: `rig name set <name> <txId>` — or `rig name set <name> --tx-id\n // <id>` (#399: a positional txId leading with `-`/`_` is hyphen-\n // ambiguous with Node's strict `parseArgs`).\n if (flags.txId !== undefined && positionals[1] !== undefined) {\n io.err('`--tx-id` and a positional <txId> are mutually exclusive');\n io.err(NAME_USAGE);\n return 2;\n }\n const txId = flags.txId ?? positionals[1];\n if (txId === undefined) {\n io.err(\n '`rig name set` needs a <txId> (the Arweave transaction to point at) ' +\n '— as a positional or via --tx-id'\n );\n io.err(NAME_USAGE);\n return 2;\n }\n return await runSet(name, txId, flags, deps);\n } catch (err) {\n return emitCliError(io, flags.json, 'name', err);\n }\n}\n","/**\n * `rig site publish [ref]` + `rig site url [ref]` — a pushed repo as a\n * permaweb site (#368).\n *\n * Every `rig push` already stores a repo's raw blob bytes on Arweave and, with\n * #368's per-file Content-Type, a gateway serves each blob as its real media\n * type. `rig site publish` adds the last piece: it walks a ref's root tree,\n * joins each file path to the Arweave txId the cumulative kind:30618 `arweave`\n * map already records for that blob (no GraphQL, no re-upload), builds the\n * ar.io path manifest, and uploads THAT as one paid store write. The manifest\n * txId is the site's canonical URL: `https://<gateway>/<txid>/`. Point an ArNS\n * name at it (#367, `rig name set`) for a stable, human name.\n *\n * PAID DISCIPLINE (mirrors `rig push`): estimate → confirm → execute, strict\n * `--json` (one document on stdout), `--yes` required to spend in a non-TTY.\n * Without `--yes`, `--json` is a pure estimate (nothing uploaded, exit 0).\n *\n * `--force-reupload` re-pays to upload the ref's blobs THROUGH the #368\n * mime-typed path before building the manifest, for repos pushed before\n * per-file Content-Type existed (whose blobs would otherwise serve as\n * `application/octet-stream`). Content-addressed dedupe means a plain re-push\n * would skip them, so this is the explicit escape hatch.\n *\n * `rig site url [ref]` is FREE: it reads the manifest txId the last publish\n * recorded locally (../cli/site-record.ts) and prints the URL — no client\n * start, no relay query, no payment.\n */\n\nimport { uploadChargeFor } from '../publisher.js';\nimport { PREFERRED_GATEWAY } from '../gateway-preference.js';\nimport { parseArgs } from 'node:util';\nimport {\n buildArweaveManifest,\n type ManifestEntry,\n} from '../arweave-manifest.js';\nimport { resolveConflictingPath } from '../mime.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport type { RemoteState } from '../remote-state.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n selectRefspecs,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport { emitCliError, UnconfiguredRepoAddressError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport { renderIdentityLine } from './render.js';\nimport { resolveRelays, singleRelayRefusal } from './remote.js';\nimport { readSiteRecord, writeSiteRecord } from './site-record.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\n/** The ar.io path-manifest media type (spec-mandated `output` tag value). */\nexport const MANIFEST_CONTENT_TYPE = 'application/x.arweave-manifest+json';\n\n/**\n * Default Arweave/ar.io gateway the printed site URL uses: the shared list's\n * first MAINNET gateway ({@link PREFERRED_GATEWAY}), so this and `rig push`\n * cannot drift apart. A site is ONE manifest txid, so only the primary is\n * printed here — pass `--gateway` (or `RIG_ARWEAVE_GATEWAY`) to re-print\n * against another when one is down.\n */\nexport const DEFAULT_GATEWAY = PREFERRED_GATEWAY;\n\nexport const SITE_USAGE = `Usage: rig site <publish|url> [ref] [options]\n\nServe a pushed repo as a permanent, path-routed website. \\`rig push\\` already\nstored the file bytes on Arweave; \\`rig site publish\\` builds the ar.io path\nmanifest (paths → Arweave txids, index → index.html) and uploads it as ONE\npaid store write, printing the site URL. \\`rig site url\\` re-prints the URL of\nthe last publish for free.\n\nThe repo must be set up with \\`rig init\\`; the relay is the \"origin\" remote\n(\\`rig push\\` reads the same). \\`ref\\` defaults to the current branch.\n\nCommands:\n publish [ref] build + upload the path manifest (paid); prints the URL and\n a \\`rig name set\\` suggestion (#367)\n url [ref] print the last-published site URL for a ref (free)\n\nOptions (publish):\n --index <path> path served at / (default: index.html)\n --spa single-page app: serve index for any unknown path\n (sets the manifest \\`fallback\\` to the index txid)\n --fallback <path> explicit fallback path for unknown routes (overrides\n --spa); must be one of the site's files\n --force-reupload re-pay to re-upload the ref's blobs with #368 per-file\n Content-Type before building the manifest — for repos\n pushed before mime-typing existed (else they serve as\n application/octet-stream)\n --gateway <url> gateway base for the printed URL (default: ${DEFAULT_GATEWAY};\n env RIG_ARWEAVE_GATEWAY also sets it)\n --relay <url> ad-hoc relay override (bypasses configured remotes)\n --repo-id <id> repository id (default: git config toon.repoid)\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable envelope; without --yes it is a pure\n estimate (nothing uploaded)\n -h, --help show this help`;\n\n/** Deps for `rig site` — the same seam `rig push` uses (tests inject fakes). */\nexport type SiteDeps = PushDeps;\n\n// ---------------------------------------------------------------------------\n// Arg parsing\n// ---------------------------------------------------------------------------\n\ninterface SiteFlags {\n index: string;\n spa: boolean;\n fallback?: string;\n forceReupload: boolean;\n gateway?: string;\n relay: string[];\n repoId?: string;\n yes: boolean;\n json: boolean;\n help: boolean;\n positionals: string[];\n}\n\nfunction parseSiteArgs(args: string[]): SiteFlags {\n const { values, positionals } = parseArgs({\n args,\n options: {\n index: { type: 'string' },\n spa: { type: 'boolean', default: false },\n fallback: { type: 'string' },\n 'force-reupload': { type: 'boolean', default: false },\n gateway: { type: 'string' },\n relay: { type: 'string', multiple: true },\n 'repo-id': { type: 'string' },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n const flags: SiteFlags = {\n index: values.index ?? 'index.html',\n spa: values.spa ?? false,\n forceReupload: values['force-reupload'] ?? false,\n relay: values.relay ?? [],\n yes: values.yes ?? false,\n json: values.json ?? false,\n help: values.help ?? false,\n positionals,\n };\n if (values.fallback !== undefined) flags.fallback = values.fallback;\n if (values.gateway !== undefined) flags.gateway = values.gateway;\n if (values['repo-id'] !== undefined) flags.repoId = values['repo-id'];\n return flags;\n}\n\n// ---------------------------------------------------------------------------\n// JSON envelopes\n// ---------------------------------------------------------------------------\n\ninterface SitePublishJson {\n command: 'site publish';\n repoId: string;\n ref: string;\n identity: IdentityReport;\n executed: boolean;\n forceReupload: boolean;\n /** Number of files the manifest routes. */\n fileCount: number;\n index: string;\n fallback?: string;\n estimate: {\n manifestBytes: number;\n reuploadBytes: number;\n /** Total fee to spend, base units (string — bigint is not JSON-safe). */\n totalFee: string;\n };\n manifest?: { txId: string; url: string };\n nameHint?: string;\n hint?: string;\n}\n\ninterface SiteUrlJson {\n command: 'site url';\n repoId: string;\n ref: string;\n found: boolean;\n manifestTxId?: string;\n url?: string;\n updatedAt?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction normalizeGateway(gateway: string): string {\n return gateway.replace(/\\/+$/, '');\n}\n\nfunction siteUrl(gateway: string, manifestTxId: string): string {\n return `${normalizeGateway(gateway)}/${manifestTxId}/`;\n}\n\n/** A 43-char placeholder txId for accurate manifest-size estimation. */\nconst PLACEHOLDER_TX = 'A'.repeat(43);\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\n/** Route `rig site <sub>`; returns the process exit code. */\nexport async function runSite(args: string[], deps: SiteDeps): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n\n if (sub === 'publish') return runSitePublish(rest, deps);\n if (sub === 'url') return runSiteUrl(rest, deps);\n if (sub === undefined || sub === '-h' || sub === '--help' || sub === 'help') {\n io.out(SITE_USAGE);\n return sub === undefined ? 2 : 0;\n }\n io.err(`unknown site subcommand ${JSON.stringify(sub)}`);\n io.err(SITE_USAGE);\n return 2;\n}\n\n// ---------------------------------------------------------------------------\n// site publish\n// ---------------------------------------------------------------------------\n\nasync function runSitePublish(args: string[], deps: SiteDeps): Promise<number> {\n const { io } = deps;\n\n let flags: SiteFlags;\n try {\n flags = parseSiteArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(SITE_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(SITE_USAGE);\n return 0;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n // ── Repo + config ──────────────────────────────────────────────────────\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const reader = new GitRepoReader(repoRoot);\n\n // ── Ref selection (single ref; default current branch) ─────────────────\n const selected = await selectRefspecs(\n reader,\n flags.positionals,\n false,\n false\n );\n if (selected.length !== 1) {\n throw new Error(\n `rig site publish builds ONE ref into a site — got ${selected.length} ` +\n `(${selected.join(', ')}); pass a single branch or tag`\n );\n }\n const ref = selected[0] as string;\n\n // ── Relay resolution (origin default; same path as push) ───────────────\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: undefined,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) io.err(resolved.nudge);\n const relaysUsed = resolved.relays;\n if (relaysUsed.length > 1) {\n io.err(singleRelayRefusal(resolved, 'Nothing was uploaded or paid.'));\n return 1;\n }\n\n // ── Standalone session (identity + publisher) ──────────────────────────\n ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n ...(relaysUsed[0] !== undefined ? { relayUrl: relaysUsed[0] } : {}),\n });\n const identity = identityReport(ctx);\n if (!ctx.publisher.uploadBlob) {\n throw new Error(\n 'the active publisher cannot upload a raw manifest blob ' +\n '(uploadBlob unavailable) — `rig site` requires the standalone publisher'\n );\n }\n\n // ── Files + the known sha→txId map from the cumulative refs event ──────\n const blobs = await reader.listBlobs(ref);\n if (blobs.length === 0) {\n throw new Error(`ref ${JSON.stringify(ref)} has no files to serve`);\n }\n const shaToPaths = new Map<string, string[]>();\n for (const { path, sha } of blobs) {\n const paths = shaToPaths.get(sha) ?? [];\n paths.push(path);\n shaToPaths.set(sha, paths);\n }\n const uniqueShas = [...shaToPaths.keys()];\n\n const remoteState: RemoteState = await ctx.fetchRemote({\n ownerPubkey: ctx.ownerPubkey,\n repoId,\n relayUrls: relaysUsed,\n });\n const known = new Map(remoteState.shaToTxId);\n // Resolve any sha the refs event didn't carry (GraphQL fallback) — free.\n const gaps = uniqueShas.filter((sha) => !known.has(sha));\n if (gaps.length > 0) {\n const found = await remoteState.resolveMissing(gaps);\n for (const [sha, txId] of found) known.set(sha, txId);\n }\n\n // ── Fallback (SPA) path resolution ─────────────────────────────────────\n const fallbackPath =\n flags.fallback ?? (flags.spa ? flags.index : undefined);\n const pathSet = new Set(blobs.map((b) => b.path));\n if (fallbackPath !== undefined && !pathSet.has(fallbackPath)) {\n throw new Error(\n `fallback path ${JSON.stringify(fallbackPath)} is not one of the ` +\n \"site's files — pick an existing path (or the --index file for --spa)\"\n );\n }\n if (!pathSet.has(flags.index)) {\n io.err(\n `warning: no ${JSON.stringify(flags.index)} in this ref — the site ` +\n 'will 404 at / until you add one (or pass --index <path>)'\n );\n }\n\n // ── Without --force-reupload every file must already be on Arweave ──────\n if (!flags.forceReupload) {\n const unpublished = uniqueShas.filter((sha) => !known.has(sha));\n if (unpublished.length > 0) {\n const paths = unpublished\n .flatMap((sha) => shaToPaths.get(sha) ?? [])\n .slice(0, 10);\n throw new Error(\n `${unpublished.length} file(s) in ${ref} are not on Arweave yet ` +\n `(e.g. ${paths.join(', ')}) — run \\`rig push\\` first, or ` +\n '`rig site publish --force-reupload` to upload them now (paid).'\n );\n }\n }\n\n // ── Fee estimate ───────────────────────────────────────────────────────\n // An upload costs the store route's schedule for its size (ADR 0065) —\n // the same rule the publisher's claim follows.\n const feeRates = await ctx.publisher.getFeeRates();\n // Preview manifest with known/placeholder 43-char txids: byte-accurate for\n // the fee (every txid is 43 chars, so the real manifest is the same size).\n const previewEntries: ManifestEntry[] = blobs.map((b) => ({\n path: b.path,\n txId: known.get(b.sha) ?? PLACEHOLDER_TX,\n }));\n const previewManifest = buildArweaveManifest(\n previewEntries,\n flags.index,\n fallbackPath ? PLACEHOLDER_TX : undefined\n );\n const manifestBytes = Buffer.byteLength(JSON.stringify(previewManifest));\n\n let reuploadBytes = 0;\n let reuploadFee = 0n;\n if (flags.forceReupload) {\n const { objects } = await reader.statObjects(uniqueShas);\n reuploadBytes = objects.reduce((sum, o) => sum + o.size, 0);\n reuploadFee = objects.reduce(\n (sum, o) => sum + uploadChargeFor(feeRates, o.size),\n 0n\n );\n }\n const manifestFee = uploadChargeFor(feeRates, manifestBytes);\n const totalFee = manifestFee + reuploadFee;\n\n const gateway =\n flags.gateway ?? deps.env['RIG_ARWEAVE_GATEWAY'] ?? DEFAULT_GATEWAY;\n\n const baseJson = (): Omit<SitePublishJson, 'executed'> => ({\n command: 'site publish',\n repoId,\n ref,\n identity,\n forceReupload: flags.forceReupload,\n fileCount: blobs.length,\n index: flags.index,\n ...(fallbackPath ? { fallback: fallbackPath } : {}),\n estimate: {\n manifestBytes,\n reuploadBytes,\n totalFee: totalFee.toString(),\n },\n });\n\n // ── Confirm gate ───────────────────────────────────────────────────────\n if (!flags.json) {\n io.out(`Site publish plan for ${ref} (repo ${repoId}):`);\n io.out(` files: ${blobs.length}`);\n io.out(\n ` index: ${flags.index}${pathSet.has(flags.index) ? '' : ' (missing!)'}`\n );\n if (fallbackPath) io.out(` fallback: ${fallbackPath}`);\n if (flags.forceReupload) {\n io.out(\n ` re-upload ${uniqueShas.length} blob(s), ${reuploadBytes} bytes (paid)`\n );\n }\n io.out(` manifest: ${manifestBytes} bytes`);\n io.out(` total fee: ${totalFee} base units`);\n io.out(renderIdentityLine(identity));\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n ...baseJson(),\n executed: false,\n hint: 'estimate only — re-run with --yes to upload the manifest (permanent, non-refundable)',\n } satisfies SitePublishJson);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid site publish (total ${totalFee} base units)? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was uploaded.');\n return 1;\n }\n }\n\n // ── Execute ────────────────────────────────────────────────────────────\n // #368 force-reupload: re-pay to upload each blob THROUGH the mime-typed\n // git-object path so the store tags it with the right Content-Type; the\n // returned (fresh) txids feed the manifest.\n if (flags.forceReupload) {\n const { objects, missing } = await reader.readObjects(uniqueShas);\n if (missing.length > 0) {\n throw new Error(\n `objects vanished from the local repository: ${missing.join(', ')}`\n );\n }\n const bodyBySha = new Map(objects.map((o) => [o.sha, o.body]));\n for (const sha of uniqueShas) {\n const body = bodyBySha.get(sha);\n if (!body) throw new Error(`internal: no body for ${sha}`);\n // A blob reached by conflicting-extension paths uploads as\n // octet-stream (deterministic, no arbitrary favoring); otherwise its\n // single content type.\n const uploadPath = resolveConflictingPath(shaToPaths.get(sha) ?? []);\n const receipt = await ctx.publisher.uploadGitObject({\n sha,\n type: 'blob',\n body,\n repoId,\n ...(uploadPath ? { path: uploadPath } : {}),\n });\n known.set(sha, receipt.txId);\n }\n }\n\n const entries: ManifestEntry[] = blobs.map((b) => {\n const txId = known.get(b.sha);\n if (!txId) {\n throw new Error(`internal: no Arweave txid for ${b.path} (${b.sha})`);\n }\n return { path: b.path, txId };\n });\n const fallbackTxId =\n fallbackPath !== undefined\n ? entries.find((e) => e.path === fallbackPath)?.txId\n : undefined;\n const manifest = buildArweaveManifest(entries, flags.index, fallbackTxId);\n const manifestBody = Buffer.from(JSON.stringify(manifest), 'utf8');\n\n const receipt = await ctx.publisher.uploadBlob({\n body: manifestBody,\n contentType: MANIFEST_CONTENT_TYPE,\n repoId,\n });\n const url = siteUrl(gateway, receipt.txId);\n writeSiteRecord(deps.env, {\n repoId,\n ref,\n owner: ctx.ownerPubkey,\n manifestTxId: receipt.txId,\n gateway: normalizeGateway(gateway),\n updatedAt: Date.now(),\n });\n\n const nameHint = `Point a name at it (see #367): rig name set <name> ${receipt.txId}`;\n if (flags.json) {\n io.emitJson({\n ...baseJson(),\n executed: true,\n manifest: { txId: receipt.txId, url },\n nameHint,\n } satisfies SitePublishJson);\n } else {\n io.out(`Site published: ${url}`);\n io.out(nameHint);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'site publish', err);\n } finally {\n if (ctx) {\n try {\n await ctx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// site url (free)\n// ---------------------------------------------------------------------------\n\nasync function runSiteUrl(args: string[], deps: SiteDeps): Promise<number> {\n const { io } = deps;\n\n let flags: SiteFlags;\n try {\n flags = parseSiteArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(SITE_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(SITE_USAGE);\n return 0;\n }\n\n try {\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const reader = new GitRepoReader(repoRoot);\n\n const selected = await selectRefspecs(\n reader,\n flags.positionals,\n false,\n false\n );\n if (selected.length !== 1) {\n throw new Error(\n `rig site url takes ONE ref — got ${selected.length} (${selected.join(', ')})`\n );\n }\n const ref = selected[0] as string;\n\n const record = readSiteRecord(deps.env, repoId, ref);\n if (!record) {\n const detail =\n `no site published for ${ref} (repo ${repoId}) yet — run ` +\n '`rig site publish` first (the manifest txid is only known after a paid publish)';\n if (flags.json) {\n io.emitJson({\n command: 'site url',\n repoId,\n ref,\n found: false,\n } satisfies SiteUrlJson);\n }\n io.err(detail);\n return 1;\n }\n\n const url = siteUrl(record.gateway, record.manifestTxId);\n if (flags.json) {\n io.emitJson({\n command: 'site url',\n repoId,\n ref,\n found: true,\n manifestTxId: record.manifestTxId,\n url,\n updatedAt: record.updatedAt,\n } satisfies SiteUrlJson);\n } else {\n io.out(url);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'site url', err);\n }\n}\n","/**\n * Arweave path manifest builder for `rig site` permaweb deploys (#368).\n *\n * MIRROR of `@toon-protocol/rig-web`'s\n * `packages/rig-web/src/web/deploy-manifest.ts` — copied rather than imported\n * because `rig` (a CLI) must not take a runtime dependency on `rig-web` (a\n * browser-only frontend). The two are intentionally kept in sync; this copy\n * additionally supports the manifest spec's optional `fallback` field (SPA\n * routing), which the site verb needs but the rig-web deploy script does not.\n *\n * Generates the JSON manifest ar.io gateways use to serve a multi-file\n * Arweave deployment as a virtual path-routed site: one manifest transaction\n * whose id becomes the site's canonical `https://<gateway>/<txid>/` URL.\n *\n * spec: https://specs.ar.io/arweave-standards/ao/index-1/manifest\n */\n\nexport interface ArweaveManifest {\n manifest: 'arweave/paths';\n version: '0.2.0';\n /**\n * Omitted when `indexPath` isn't one of the manifest's `paths` — an `index`\n * pointing at a path the manifest doesn't carry makes gateways 404 the site\n * root (indistinguishable from ArNS propagation lag; see #398).\n */\n index?: { path: string };\n /**\n * Optional SPA fallback: the transaction served for any path not present in\n * `paths` (e.g. client-routed `/about` on a single-page app). Omitted for a\n * plain static site.\n */\n fallback?: { id: string };\n paths: Record<string, { id: string }>;\n}\n\nexport interface ManifestEntry {\n /** Relative URL path, e.g. `index.html` or `assets/main.js`. */\n path: string;\n /** Arweave transaction id the file's bytes are stored under. */\n txId: string;\n}\n\nconst DEFAULT_INDEX = 'index.html';\n\n/**\n * Build an Arweave path manifest from a list of uploaded files.\n *\n * Each entry maps a relative URL path to the Arweave transaction id where\n * that file was uploaded. The resulting manifest is uploaded as its own\n * Arweave transaction; its id becomes the canonical URL for the deployment.\n *\n * @param entries path → txId for every file the site serves.\n * @param indexPath the path served at `/` (default `index.html`).\n * @param fallbackTxId optional SPA fallback transaction id (spec `fallback`).\n */\nexport function buildArweaveManifest(\n entries: ManifestEntry[],\n indexPath = DEFAULT_INDEX,\n fallbackTxId?: string\n): ArweaveManifest {\n const paths: Record<string, { id: string }> = {};\n for (const { path, txId } of entries) {\n paths[path] = { id: txId };\n }\n return {\n manifest: 'arweave/paths',\n version: '0.2.0',\n ...(Object.hasOwn(paths, indexPath) ? { index: { path: indexPath } } : {}),\n ...(fallbackTxId ? { fallback: { id: fallbackTxId } } : {}),\n paths,\n };\n}\n","/**\n * Local record of the last-published site manifest per (repo, ref) — the\n * lookup `rig site url` reads for FREE (#368).\n *\n * A site manifest's txId is only knowable AFTER the paid manifest upload (it\n * is the hash of the signed Arweave data item), and it changes every publish.\n * There is no free network lookup for \"the current manifest of this repo\"\n * until an ArNS name points at it (#367). So `rig site publish` records what\n * it just published here, and `rig site url` reads it back — no client start,\n * no relay query, no payment.\n *\n * Stored under `TOON_CLIENT_HOME` (default `~/.toon-client`) as\n * `site-manifests.json`, keyed by `<repoId>\\0<ref>` (local, single-user\n * scope — the owner pubkey is stored as a field, not part of the key). A\n * corrupt/unreadable file is treated as empty for reads and overwritten on\n * write, never fatal to a free lookup.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const SITE_MANIFEST_FILENAME = 'site-manifests.json';\n\n/** One recorded site publish. */\nexport interface SiteManifestRecord {\n repoId: string;\n /** Full refname the site was built from, e.g. `refs/heads/main`. */\n ref: string;\n /** Owner pubkey (hex) the manifest was published under. */\n owner: string;\n /** The manifest transaction id (43-char base64url). */\n manifestTxId: string;\n /** Gateway base the printed URL used, e.g. `https://arweave.net`. */\n gateway: string;\n /** Unix milliseconds of the publish. */\n updatedAt: number;\n}\n\ntype SiteManifestFile = Record<string, SiteManifestRecord>;\n\nfunction storeDir(env: NodeJS.ProcessEnv): string {\n return env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n}\n\nfunction storePath(env: NodeJS.ProcessEnv): string {\n return join(storeDir(env), SITE_MANIFEST_FILENAME);\n}\n\nfunction keyOf(repoId: string, ref: string): string {\n return `${repoId}\\0${ref}`;\n}\n\nfunction readFile(env: NodeJS.ProcessEnv): SiteManifestFile {\n try {\n const parsed = JSON.parse(readFileSync(storePath(env), 'utf8')) as unknown;\n if (parsed && typeof parsed === 'object') return parsed as SiteManifestFile;\n return {};\n } catch {\n // Missing or corrupt → empty (a free lookup must never throw on this).\n return {};\n }\n}\n\n/** The recorded manifest for (repoId, ref), or `undefined` if none. */\nexport function readSiteRecord(\n env: NodeJS.ProcessEnv,\n repoId: string,\n ref: string\n): SiteManifestRecord | undefined {\n return readFile(env)[keyOf(repoId, ref)];\n}\n\n/** Record (or overwrite) the manifest just published for (repoId, ref). */\nexport function writeSiteRecord(\n env: NodeJS.ProcessEnv,\n record: SiteManifestRecord\n): void {\n const dir = storeDir(env);\n mkdirSync(dir, { recursive: true });\n const file = readFile(env);\n file[keyOf(record.repoId, record.ref)] = record;\n writeFileSync(storePath(env), `${JSON.stringify(file, null, 2)}\\n`, 'utf8');\n}\n","/**\n * The rig CLI output layer (#265): the strict `--json` stdout guarantee.\n *\n * CONTRACT — when `--json` is set on a rig-owned command, stdout carries\n * EXACTLY ONE parseable JSON document and nothing else. Agents consume this\n * stream (`rig … --json | jq`), so any stray banner, progress line, warning,\n * deprecation nudge, or third-party `console.log` on stdout breaks pipelines\n * (the #260 addendum: `[Bootstrap] …` logs from the embedded client's core\n * polluted `rig push --json`). Everything human-facing goes to stderr.\n *\n * Three layers enforce the contract (composed in ./rig.ts; the enforcement\n * matrix in ./strict-json.test.ts mirrors that composition):\n *\n * 1. {@link makeCliIo} — the ONLY output surface commands use. In JSON mode\n * `out()` (human lines) reroutes to stderr and `emitJson()` is the sole\n * writer that reaches the real stdout.\n * 2. {@link redirectStdoutToStderr} — a process-level guard for code the io\n * seam cannot reach: dependencies that `console.log` directly (the\n * embedded `@toon-protocol/client`'s core bootstrap does). Installed\n * before any command code runs, it reroutes EVERY `process.stdout.write`\n * to stderr; only the writer it returns (wired into `emitJson`) still\n * reaches the real stdout.\n * 3. {@link RigIo.ensureSingleJsonDoc} — the backstop for paths that bail\n * out before emitting an envelope (usage errors, pre-payment refusals):\n * after dispatch it emits one error envelope built from the collected\n * stderr lines, so stdout is never empty in JSON mode.\n *\n * GIT PASSTHROUGH IS EXEMPT: `--json` is a per-subcommand flag on rig-owned\n * verbs, not a global rig flag. Any verb rig does not own goes to system git\n * with the EXACT argv tail and inherited stdio — `rig status --json` runs\n * `git status --json` (git rejects it), and flags BEFORE the subcommand\n * (`rig --json status`) are not rig's either: the whole argv passes through\n * to git verbatim. {@link isJsonInvocation} implements exactly that boundary.\n */\n\n// ---------------------------------------------------------------------------\n// The io seam\n// ---------------------------------------------------------------------------\n\n/** Terminal I/O seam — every rig-owned command writes ONLY through this. */\nexport interface CliIo {\n /**\n * One HUMAN-facing line: stdout normally, stderr when `--json` is active\n * (chatter must never pollute the machine stream).\n */\n out(line: string): void;\n /** One human-facing line to stderr (warnings, nudges, errors). */\n err(line: string): void;\n /**\n * THE machine-readable JSON document of a `--json` run — serialized here\n * (2-space indent) and written to the REAL stdout. Must be a command's\n * single stdout emission; call it at most once per invocation.\n */\n emitJson(payload: unknown): void;\n /** True when stdin+stdout are TTYs (interactive confirm possible). */\n isInteractive: boolean;\n /** Ask a y/N question; resolves true on explicit yes. */\n confirm(question: string): Promise<boolean>;\n}\n\n/** {@link CliIo} plus the JSON-mode bookkeeping the entrypoint needs. */\nexport interface RigIo extends CliIo {\n /** True when this invocation runs in `--json` mode. */\n readonly jsonMode: boolean;\n /** True once `emitJson` has written the machine document. */\n readonly emittedJson: boolean;\n /**\n * The #265 backstop: called once after dispatch (see ./rig.ts). In JSON\n * mode, when NO machine document was emitted (usage error, pre-payment\n * refusal, unexpected crash), emits one error envelope carrying the\n * human-facing lines the run wrote to stderr — so `--json` stdout always\n * parses. No-op outside JSON mode or after a real emission.\n */\n ensureSingleJsonDoc(exitCode: number): void;\n}\n\n/** Sinks + terminal facts {@link makeCliIo} builds a {@link RigIo} from. */\nexport interface CliIoOptions {\n /** Whether this invocation is a rig-owned command with `--json`. */\n jsonMode: boolean;\n /**\n * Write to the REAL stdout (in JSON mode: the pre-guard writer returned by\n * {@link redirectStdoutToStderr}). Receives full text including newlines.\n */\n writeStdout(text: string): void;\n /** Write to stderr. Receives full text including newlines. */\n writeStderr(text: string): void;\n isInteractive: boolean;\n confirm(question: string): Promise<boolean>;\n}\n\n/**\n * Build the {@link RigIo} for one invocation. Centralizes the #265 routing:\n * human lines → stderr in JSON mode, and `emitJson` as the only stdout path.\n */\nexport function makeCliIo(options: CliIoOptions): RigIo {\n const { jsonMode, writeStdout, writeStderr } = options;\n let emittedJson = false;\n /** Human lines collected in JSON mode — the backstop envelope's detail. */\n const humanLines: string[] = [];\n\n const toStderr = (line: string): void => {\n if (jsonMode) humanLines.push(line);\n writeStderr(`${line}\\n`);\n };\n\n return {\n jsonMode,\n get emittedJson() {\n return emittedJson;\n },\n out: (line) => {\n if (jsonMode) {\n toStderr(line);\n } else {\n writeStdout(`${line}\\n`);\n }\n },\n err: toStderr,\n emitJson: (payload) => {\n emittedJson = true;\n writeStdout(`${JSON.stringify(payload, null, 2)}\\n`);\n },\n isInteractive: options.isInteractive,\n confirm: options.confirm,\n ensureSingleJsonDoc(exitCode: number): void {\n if (!jsonMode || emittedJson) return;\n const detail =\n humanLines.join('\\n') ||\n (exitCode === 0\n ? 'the command produced no machine output'\n : 'the command failed before emitting machine output — see stderr');\n this.emitJson(\n exitCode === 0\n ? { error: null, exitCode, detail }\n : { error: 'error', exitCode, detail }\n );\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// JSON-mode detection (and the git-passthrough exemption)\n// ---------------------------------------------------------------------------\n\n/**\n * The verbs rig owns — everything else is `git <argv…>` verbatim. Must match\n * the ./dispatch.ts switch (dispatch.test.ts pins both directions).\n */\nexport const RIG_OWNED_VERBS: ReadonlySet<string> = new Set([\n 'init',\n 'identity',\n 'remote',\n 'clone',\n 'fetch',\n 'push',\n 'site',\n 'issue',\n 'comment',\n 'pr',\n 'maintainers',\n 'channel',\n 'channels',\n 'fund',\n 'balance',\n 'chain',\n 'entry',\n 'name',\n]);\n\n/**\n * True when this argv is a rig-owned command run with `--json` — the strict\n * stdout contract applies. Deliberately NOT true for:\n *\n * - non-owned verbs (`rig status --json` IS `git status --json`: inherited\n * stdio, git's own semantics, rig adds nothing);\n * - flags before the subcommand (`rig --json status`): rig has no global\n * flags besides help/--version, so the argv passes to git verbatim;\n * - `--json` after a bare `--` (parseArgs treats those tokens as\n * positionals, so rig's flag parsers never see it as a flag either).\n *\n * Mirrors a plain token scan rather than each command's full parseArgs\n * config: the one divergence is `--json` consumed as a STRING option's value\n * (e.g. `rig push --relay --json`) — a pathological invocation that ends up\n * with chatter on stderr and a backstop envelope on stdout, which still\n * honors the parse guarantee.\n */\nexport function isJsonInvocation(argv: string[]): boolean {\n const [verb, ...rest] = argv;\n if (verb === undefined || !RIG_OWNED_VERBS.has(verb)) return false;\n for (const arg of rest) {\n if (arg === '--') return false;\n if (arg === '--json') return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Process-level stdout guard (third-party console.log defense)\n// ---------------------------------------------------------------------------\n\n/** Handle on an installed stdout guard. */\nexport interface StdoutGuard {\n /** Write to the REAL stdout (bypasses the redirection). */\n write(text: string): void;\n /** Undo the patch (tests; the one-shot CLI process never needs it). */\n restore(): void;\n}\n\n/**\n * Reroute every `process.stdout.write` — including `console.log` from\n * dependencies rig cannot re-route at the io seam, like the embedded\n * client's `[Bootstrap] …` logs (#260) — to stderr. Returns the ONLY writer\n * that still reaches the real stdout; ./rig.ts wires it into\n * {@link makeCliIo}'s `writeStdout` so `emitJson` output is the single\n * survivor on the machine stream.\n *\n * @param realWrite Override the saved real-stdout writer (tests capture it);\n * defaults to the unpatched `process.stdout.write`.\n */\n// ---------------------------------------------------------------------------\n// Process-level stderr calmer (third-party bootstrap noise defense, #280)\n// ---------------------------------------------------------------------------\n\n/** Handle on an installed stderr calmer. */\nexport interface StderrCalmer {\n /** Undo the patch (tests; the one-shot CLI process never needs it). */\n restore(): void;\n}\n\n/** The embedded client's core self-announce failure log line. */\nconst ANNOUNCE_FAILED_RE = /\\[Bootstrap\\] Announce failed/;\n/** … specifically the EXPECTED pre-payment 402 refusal (x402 challenge). */\nconst ANNOUNCE_402_RE = /402|payment required/i;\n\n/**\n * The calm reframe of the announce-402: what happened, why it is expected,\n * and that the command is unaffected — instead of a full x402 challenge JSON\n * dump. Exported so tests pin the exact line.\n */\nexport const ANNOUNCE_402_INFO =\n 'rig: skipped the optional identity self-announce — the payment peer ' +\n 'charges for announces and this identity has not paid for one (expected ' +\n 'on a fresh or unfunded identity); harmless, the command continues.\\n';\n\n/**\n * Reframe the embedded client's scary-but-harmless bootstrap announce noise\n * (#280). The core's bootstrap tries a PAID self-announce and `console.warn`s\n * the refusal — `[Bootstrap] Announce failed …: … (402 Payment Required):\n * {…x402…}` — straight to stderr, which rig's io seam cannot reach. A\n * first-run user reads that as their (succeeding!) push having failed.\n *\n * This process-level guard patches `process.stderr.write`:\n *\n * - an announce-402 line becomes {@link ANNOUNCE_402_INFO} once per\n * process (repeats are dropped — one calm line, not one per peer);\n * - announce failures that are NOT the expected 402 (network errors, peer\n * misconfig) pass through untouched — those ARE signal;\n * - everything else passes through untouched.\n *\n * Installed unconditionally in ./rig.ts before dispatch. Composes with\n * {@link redirectStdoutToStderr}: that guard forwards to `process.stderr.write`\n * via a dynamic property lookup, so rerouted stdout noise is calmed too.\n */\nexport function calmBootstrapNoise(): StderrCalmer {\n const original = process.stderr.write;\n let reframed = false;\n const patched = ((\n chunk: Uint8Array | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void\n ): boolean => {\n let text = chunk;\n if (typeof chunk === 'string' && ANNOUNCE_FAILED_RE.test(chunk)) {\n if (ANNOUNCE_402_RE.test(chunk)) {\n text = reframed ? '' : ANNOUNCE_402_INFO;\n reframed = true;\n }\n }\n if (typeof encodingOrCb === 'function') {\n // `original` is `typeof process.stderr.write`, an overloaded function\n // type; `.call()` on it only resolves against the LAST overload\n // (chunk, encoding, cb), so the 2-arg (chunk, cb) call needs an\n // explicit narrow to the matching overload signature.\n const writeWithCallback = original as (\n chunk: Uint8Array | string,\n cb?: (err?: Error | null) => void\n ) => boolean;\n return writeWithCallback.call(process.stderr, text, encodingOrCb);\n }\n return original.call(process.stderr, text, encodingOrCb, cb);\n }) as typeof process.stderr.write;\n process.stderr.write = patched;\n return {\n restore: () => {\n if (process.stderr.write === patched) process.stderr.write = original;\n },\n };\n}\n\nexport function redirectStdoutToStderr(\n realWrite?: (text: string) => void\n): StdoutGuard {\n const original = process.stdout.write;\n const real = realWrite ?? original.bind(process.stdout);\n const patched = ((\n chunk: Uint8Array | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void\n ): boolean =>\n typeof encodingOrCb === 'function'\n ? process.stderr.write(chunk, encodingOrCb)\n : process.stderr.write(\n chunk,\n encodingOrCb,\n cb\n )) as typeof process.stdout.write;\n process.stdout.write = patched;\n return {\n write: (text) => {\n real(text);\n },\n restore: () => {\n if (process.stdout.write === patched) process.stdout.write = original;\n },\n };\n}\n"],"mappings":"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","names":["createInterface","parseArgs","ctx","io","parseArgs","io","parseArgs","io","rigPage","io","parseArgs","mkdirSync","readFileSync","writeFileSync","homedir","join","parseArgs","join","homedir","readFileSync","mkdirSync","writeFileSync","io","parseArgs","parseArgs","io","parseArgs","result","dirname","join","parseArgs","parseArgs","io","dirname","join","parseArgs","REPOSITORY_ANNOUNCEMENT_KIND","STATUS_APPLIED_KIND","STATUS_CLOSED_KIND","STATUS_DRAFT_KIND","STATUS_OPEN_KIND","parseArgs","WS_URL_RE","repoATag","io","parseArgs","HEX64_RE","io","parseArgs","STATUS_OPEN_KIND","STATUS_APPLIED_KIND","STATUS_CLOSED_KIND","STATUS_DRAFT_KIND","REPOSITORY_ANNOUNCEMENT_KIND","args","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","parseArgs","configPathFor","join","homedir","readFileSync","mkdirSync","dirname","writeFileSync","io","parseArgs","state","parseArgs","WS_URL_RE","io","parseArgs","readFileSync","homedir","join","parseArgs","CHAIN_ARG_LIST","join","homedir","readFileSync","io","parseArgs","argv","resolve","mkdirSync","dirname","parseArgs","mkdirSync","dirname","parseArgs","io","basename","parseArgs","defaultWebSocketFactory","parseArgs","isWebSocketRelay","io","resolve","basename","parseArgs","HEX64_RE","WS_URL_RE","io","runList","parseArgs","parseArgs","spawn","io","parseArgs","spawn","receipt","result","parseArgs","mkdirSync","readFileSync","writeFileSync","homedir","join","storeDir","storePath","readFile","parseArgs","io","receipt","require","argv","io","argv","createInterface"]}
1
+ {"version":3,"sources":["../../src/cli/rig.ts","../../src/cli/dispatch.ts","../../src/cli/balance.ts","../../src/cli/daemon-session.ts","../../src/cli/errors.ts","../../src/cli/push.ts","../../src/rig-pointer.ts","../../src/gateway-preference.ts","../../src/cli/rig-pointer-record.ts","../../src/cli/render.ts","../../src/cli/git-config.ts","../../src/cli/remote.ts","../../src/cli/chain.ts","../../src/cli/channel.ts","../../src/cli/clone.ts","../../src/cli/events.ts","../../src/cli/tracker.ts","../../src/cli/entry.ts","../../src/cli/fetch.ts","../../src/cli/fund.ts","../../src/cli/git-passthrough.ts","../../src/cli/identity-cmd.ts","../../src/cli/init.ts","../../src/cli/git-author.ts","../../src/cli/maintainers.ts","../../src/cli/repo-command.ts","../../src/cli/name.ts","../../src/cli/payout.ts","../../src/cli/site.ts","../../src/arweave-manifest.ts","../../src/cli/site-record.ts","../../src/cli/output.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * `rig` — the git-native TOON CLI shipped by `@toon-protocol/rig` (epic\n * #222; standalone-only since #248; git passthrough since #250).\n *\n * rig-owned subcommands (see ./dispatch.ts):\n * init one-shot repo setup (identity + toon.* git config)\n * remote relays as git remotes (#249): add/remove/list\n * push estimate → confirm → execute (#229)\n * issue | comment | pr single NIP-34 event publishes (#231), incl.\n * `pr status` (moved from `rig status` in #250)\n * channel payment channels (#262/#263): list, open,\n * close, settle\n * fund | balance client money lifecycle (#263): devnet faucet\n * drip; wallet + channel balances\n *\n * Everything else is `git <argv...>` verbatim: `rig status` runs git status.\n *\n * STRICT `--json` STDOUT (#265): when a rig-owned command runs with `--json`,\n * stdout carries exactly one JSON document — the process-level stdout guard\n * reroutes every other write (including dependencies' `console.log`) to\n * stderr, the io layer sends human lines to stderr, and the post-dispatch\n * backstop emits an error envelope for paths that bailed before emitting.\n * The git passthrough is exempt: it inherits stdio verbatim (./output.ts).\n * The enforcement matrix in ./strict-json.test.ts mirrors this composition.\n */\n\nimport { createInterface } from 'node:readline/promises';\nimport { dispatch } from './dispatch.js';\nimport {\n calmBootstrapNoise,\n isJsonInvocation,\n makeCliIo,\n redirectStdoutToStderr,\n type RigIo,\n} from './output.js';\n\n/** Real terminal I/O: stdout/stderr sinks + readline y/N confirm. */\nfunction makeIo(jsonMode: boolean): RigIo {\n // Reframe the embedded client's expected announce-402 stderr noise (#280)\n // — installed for every mode, before any command code can run.\n calmBootstrapNoise();\n // In --json mode, patch process.stdout FIRST — before any command (or its\n // dynamically imported dependencies) can write — and keep the only real\n // stdout writer for the machine document.\n const guard = jsonMode ? redirectStdoutToStderr() : undefined;\n return makeCliIo({\n jsonMode,\n writeStdout: guard\n ? guard.write\n : (text) => {\n process.stdout.write(text);\n },\n writeStderr: (text) => {\n process.stderr.write(text);\n },\n isInteractive: Boolean(process.stdin.isTTY && process.stdout.isTTY),\n confirm: async (question) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n try {\n const answer = (await rl.question(question)).trim().toLowerCase();\n return answer === 'y' || answer === 'yes';\n } finally {\n rl.close();\n }\n },\n });\n}\n\n/**\n * Exit as soon as stdio is flushed (#279). By the time dispatch resolves,\n * every command has finished its work and awaited its teardown — but the\n * embedded `@toon-protocol/client` can leave a keep-alive socket behind\n * that holds the Node event loop open for ~30 more seconds. That lingering\n * handle — not discovery or negotiation — was the bulk of the uniform\n * \"~32s per paid command\" tax the #279 study measured. Nothing rig can\n * reach unrefs it, so the one-shot CLI does what one-shot CLIs do: flush\n * and exit.\n */\nfunction exitWhenFlushed(code: number): void {\n process.exitCode = code;\n let pending = 2;\n const done = (): void => {\n pending -= 1;\n if (pending === 0) process.exit(code);\n };\n process.stdout.write('', done);\n process.stderr.write('', done);\n}\n\nconst argv = process.argv.slice(2);\nconst io = makeIo(isJsonInvocation(argv));\n\ndispatch(argv, {\n io,\n env: process.env,\n cwd: process.cwd(),\n}).then(\n (code) => {\n io.ensureSingleJsonDoc(code);\n exitWhenFlushed(code);\n },\n (err: unknown) => {\n process.stderr.write(\n `rig: unexpected error: ${err instanceof Error ? (err.stack ?? err.message) : String(err)}\\n`\n );\n io.ensureSingleJsonDoc(1);\n exitWhenFlushed(1);\n }\n);\n","/**\n * `rig` subcommand dispatch (#250): rig-owned verbs first, git for the rest.\n *\n * rig owns exactly: init, identity, remote, clone, fetch, push, site, issue,\n * comment, pr, maintainers, channel (+ the `channels` list shorthand), fund,\n * balance, chain, entry, name, help/-h/--help, and --version. EVERY other\n * subcommand is executed as `git <argv...>` verbatim (./git-passthrough.ts)\n * — `rig status` IS `git status`, `rig add -p`, `rig commit`, `rig rebase\n * -i`, … all land in git with rig's stdio and git's exit code. Owned verbs\n * always win: `rig push` is the paid TOON push and shadows `git push`, and\n * `rig clone`/`rig fetch` (#278) are the free TOON transports shadowing\n * their git counterparts (plain-git clone/fetch/push stay available by\n * calling git directly).\n *\n * The NIP-34 status publish that used to be `rig status` lives at\n * `rig pr status` since #250 (BREAKING) — bare `rig status` is git's.\n *\n * `--json` (#265) follows the same ownership boundary: it is a flag OF the\n * owned subcommands, never a global rig flag. `rig --json status` starts\n * with a verb rig does not own (`--json`), so the WHOLE argv passes through\n * to git verbatim — rig neither consumes the flag nor applies the strict\n * stdout contract to git's inherited stdio. The owned-verb list is pinned to\n * ./output.ts's RIG_OWNED_VERBS (strict-json.test.ts keeps them in sync).\n */\n\nimport { createRequire } from 'node:module';\nimport { runBalance } from './balance.js';\nimport { runChain } from './chain.js';\nimport { runChannel } from './channel.js';\nimport { runClone } from './clone.js';\nimport { runComment, runIssue, runPr, type EventCommandDeps } from './events.js';\nimport { runEntry } from './entry.js';\nimport { runFetch } from './fetch.js';\nimport { runFund } from './fund.js';\nimport { runGitPassthrough, type GitRunner } from './git-passthrough.js';\nimport { runIdentity } from './identity-cmd.js';\nimport { runInit } from './init.js';\nimport { runMaintainers } from './maintainers.js';\nimport { runName, type LoadArns } from './name.js';\nimport { runPayout } from './payout.js';\nimport { runPush, PUSH_USAGE } from './push.js';\nimport { runRemote } from './remote.js';\nimport { runSite } from './site.js';\n\nexport const USAGE = `rig — git with a TOON remote (pay-to-write Nostr + Arweave)\n\nUsage: rig <command> [options]\n\nCommands rig owns:\n identity create generate a fresh identity (BIP-39) into the\n encrypted keystore — the phrase is shown ONCE;\n back it up. This is your first step on a new box\n identity show the active identity's source + derived pubkey\n (never the phrase)\n identity import write an EXISTING phrase (read from stdin) to the\n encrypted keystore\n init set up this repo: resolve your identity (or offer\n to generate one) and write the toon.* git config\n remote add <name> <url> add a relay as a REAL git remote (\"origin\" is\n remote remove <name> the default publish target); remove/list manage\n remote list them — \\`git remote -v\\` shows the same data\n clone <relay-url> <owner>/<repo-id> [dir]\n clone a TOON repo (free): relay state + Arweave\n objects (SHA-1 verified) → a real git repository,\n push/pull-capable out of the box\n fetch [remote] fetch remote refs + missing objects (free) and\n update refs/remotes/<remote>/*; no merge. Shadows\n git fetch (plain \\`git fetch\\` stays available)\n push [remote] [refspecs...] plan, price, confirm, and execute a paid push\n to TOON (defaults to the \"origin\" remote). rig\n push is the TOON transport and shadows git push;\n plain-git pushes remain available by running\n \\`git push\\` directly\n site publish [ref] deploy a pushed repo as a permaweb site: build the\n ar.io path manifest (paths → Arweave txids) and\n upload it as one paid store write; prints the URL\n site url [ref] print the last-published site URL for a ref (free)\n issue create file an issue (kind:1621) against a repo\n issue list | show <id> read the repo's issues + comments (free)\n pr list | show <id> read the repo's patches; show prints the full\n patch text (free)\n comment <root-event-id> comment (kind:1622) on an issue or patch\n pr create publish a patch (kind:1617) with real\n \\`git format-patch\\` content\n pr status <event-id> <state> set an issue/patch status (kind:1630-1633):\n open | applied | closed | draft\n maintainers list show the repo's declared maintainers (free); add/\n maintainers add <pubkey> remove republish the kind:30617 to change who may\n maintainers remove <pubkey> author authoritative issue/PR status (owner is\n always an implicit maintainer)\n payout show show the repo's declared payout pointer (free);\n payout set <address> set/clear republish the kind:30617 — no pointer\n payout clear means the serving node keeps 100% of\n repo-scoped write fees (v1: evm addresses only)\n fund drip devnet faucet funds to this identity's\n wallet (free); on other networks prints the\n address(es) to fund externally\n balance wallet balances + payment-channel holdings\n (free — chain reads and local state only)\n chain [set <c>|unset] choose which chain/USDC settles paid writes\n (evm|sol|mina); free — reads/writes local config\n entry <url> | entry clear choose the connector that prices and settles paid\n writes — one URL is the whole configuration, since\n its GET /ilp describes it; --relay <wss-url>\n records the free-read relay beside it; free —\n writes local config\n name buy <name> ArNS naming (#367): buy points a human name at an\n name set <name> <txId> Arweave txId, owned + paid by this identity's\n name status <name> Solana key. buy spends mARIO on Solana via the\n ar.io registry (NOT ILP); status is free. Needs\n the optional \\`@ar.io/sdk\\` dependency\n channel list show the payment channels paid commands hold\n (free — reads local state; \\`rig channels\\` is a\n shorthand for \\`rig channel list\\`)\n channel open explicitly open (or resume) the channel for a\n peer; --deposit adds collateral (on-chain)\n channel deploy-zkapp pre-deploy this identity's dedicated Mina\n PaymentChannel zkApp (on-chain; the Mina open\n path otherwise does this automatically)\n channel close <channelId> start the settlement challenge window (on-chain)\n channel settle <channelId> release collateral after the window (on-chain)\n\nAny other command is passed through to git verbatim: \\`rig status\\` runs\n\\`git status\\`, and \\`rig add -p\\`, \\`rig commit\\`, \\`rig log --oneline\\`,\n\\`rig rebase -i\\`, … behave exactly like git (same output, same exit code).\n\nRun \\`rig <command> --help\\` for a rig command's flags. \\`rig init\\`,\n\\`rig remote\\`, \\`rig clone\\`, \\`rig fetch\\`, \\`rig issue list/show\\`,\n\\`rig pr list/show\\`, \\`rig fund\\`, \\`rig balance\\`, and \\`rig channel list\\`\nare free; push/issue create/comment/pr create/pr status are paid writes —\npermanent and non-refundable —\nand channel open/close/settle are on-chain wallet transactions; each states\nwhat it will spend and asks for confirmation before doing so (--yes skips,\n--json emits machine output).\n\nWith --json, stdout carries exactly ONE JSON document (everything human-facing\ngoes to stderr), so \\`rig <command> --json | jq\\` always parses. --json is a\nper-subcommand flag on the commands rig owns, NOT a global rig flag: it does\nnot apply to the git passthrough (\\`rig status --json\\` runs\n\\`git status --json\\`), and flags placed before the subcommand\n(\\`rig --json status\\`) pass through to git untouched.\n\nSTANDALONE MODE: by default rig delegates paid commands to a running\ntoon-clientd that holds the same identity (it owns the payment channel and its\nbootstrap is warm). To bypass the daemon and always sign for yourself, set\nRIG_STANDALONE=1 in your environment (the durable, applies-to-everything\nswitch) or pass --standalone / --no-daemon to a paid command. rig then runs\nfully embedded; a per-identity lockfile still stops two rig processes from\nracing the channel. If a daemon is ALSO actively writing on this identity,\nstop it (its pid is in ~/.toon-client/daemon.pid) to avoid a claim race.`;\n\n/** Dispatch deps: the event-command deps plus an injectable git runner. */\nexport interface DispatchDeps extends EventCommandDeps {\n /** Runs the git passthrough (default: real spawned git; tests inject). */\n runGit?: GitRunner;\n /**\n * `rig name` ArNS SDK loader seam (#367): defaults to the lazy `@ar.io/sdk`\n * import; tests inject a stub so no real ar.io registry call is ever made.\n */\n loadArns?: LoadArns;\n}\n\n/**\n * Version of the @toon-protocol/rig package this CLI shipped in. Resolved at\n * runtime relative to this module, which tsup may emit either as the\n * dist/cli/rig.js entry or a dist/ chunk — hence the short upward walk.\n */\nexport function rigVersion(): string {\n const require = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = require(rel) as { name?: string; version?: string };\n if (pkg.name === '@toon-protocol/rig' && pkg.version) return pkg.version;\n } catch {\n // keep walking up\n }\n }\n return 'unknown';\n}\n\n/** Route one rig invocation (argv WITHOUT node/script); returns the exit code. */\nexport async function dispatch(\n argv: string[],\n deps: DispatchDeps\n): Promise<number> {\n const [command, ...rest] = argv;\n const { io } = deps;\n\n switch (command) {\n case 'init':\n return runInit(rest, deps);\n case 'identity':\n return runIdentity(rest, deps);\n case 'remote':\n return runRemote(rest, deps);\n // The #278 read path — FREE (relay + Arweave gateway reads, no payment).\n case 'clone':\n return runClone(rest, deps);\n case 'fetch':\n return runFetch(rest, deps);\n case 'push':\n return runPush(rest, deps);\n case 'site':\n return runSite(rest, deps);\n case 'issue':\n return runIssue(rest, deps);\n case 'comment':\n return runComment(rest, deps);\n case 'pr':\n return runPr(rest, deps);\n case 'maintainers':\n return runMaintainers(rest, deps);\n case 'payout':\n return runPayout(rest, deps);\n case 'channel':\n return runChannel(rest, deps);\n case 'channels':\n // Alias (#demo): bare `rig channels` (plus flags) is `rig channel list`;\n // a subcommand word still routes normally (`rig channels open` works).\n return runChannel(\n rest[0] !== undefined && !rest[0].startsWith('-')\n ? rest\n : ['list', ...rest],\n deps\n );\n case 'fund':\n return runFund(rest, deps);\n case 'balance':\n return runBalance(rest, deps);\n case 'chain':\n return runChain(rest, deps);\n case 'entry':\n return runEntry(rest, deps);\n case 'name':\n return runName(rest, deps);\n case 'help':\n case '--help':\n case '-h':\n io.out(USAGE);\n io.out('');\n io.out(PUSH_USAGE);\n return 0;\n case '--version':\n io.out(`rig ${rigVersion()}`);\n return 0;\n case undefined:\n io.err(USAGE);\n return 2;\n default:\n // Git passthrough (#250): rig does not own this verb, so the EXACT\n // argv tail goes to system git — flags, quoting, and exit code intact.\n return (deps.runGit ?? runGitPassthrough)(argv, {\n cwd: deps.cwd,\n env: deps.env,\n err: (line) => io.err(line),\n });\n }\n}\n","/**\n * `rig balance` — the combined money view for the active identity (#263):\n * on-chain wallet balances plus open payment-channel holdings.\n *\n * FREE: no payment, no nonce guard, no channel, no relay. The wallet section\n * reuses the client's full multi-chain reader (`ToonClient.getWalletBalances()`\n * on the UNSTARTED embedded client, #299): for every configured chain it shows\n * the native coin (ETH / SOL / MINA) AND USDC. The Solana/Mina addresses are\n * derived from the mnemonic on demand — the same keys `start()` registers and\n * `rig fund` prints — so all chains appear even before a start. The EVM chain\n * key is the settlement chain (it wins over the network preset's primary), so a\n * devnet identity funded on `evm:anvil:31337` shows that chain's balances, not\n * the preset chain's zero (the #260-era getBalances mismatch). Each chain reads\n * independently; an unreachable RPC degrades to a per-chain notice.\n * The channel section joins the #262 peer→channel map with the claim\n * watermark: deposited / claimed / available per recorded channel of THIS\n * identity. A write uplink is NOT required (`requireUplink: false`) — reads\n * work from a read-only config.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n channelStatus,\n ChannelMapStore,\n resolveChannelPaths,\n} from '../standalone/channel-map.js';\nimport type {\n WalletChainBalanceInfo,\n WalletTokenAmountInfo,\n} from '../standalone/money.js';\nimport { emitCliError } from './errors.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport { renderIdentityLine } from './render.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\nexport const BALANCE_USAGE = `Usage: rig balance [--json]\n\nShow the active identity's money: the full on-chain wallet view — native coin\nplus USDC on every configured chain (EVM / Solana / Mina) — and recorded\npayment-channel holdings (deposited / claimed / available). Free — reads chain\nRPCs and local state only; nothing is signed or paid. An unreachable chain RPC\ndegrades to a per-chain notice without failing the others.\n\nOptions:\n --json machine-readable envelope (base units as strings)\n -h, --help show this help`;\n\n/** What `rig balance` needs — the shared paid-command deps (loader seam). */\nexport type BalanceDeps = PushDeps;\n\n/** One recorded channel in the balance view. */\ninterface ChannelBalanceJson {\n channelId: string;\n destination: string;\n peerId: string;\n chain: string;\n status: 'open' | 'closing' | 'settleable' | 'settled';\n depositTotal: string | null;\n cumulativeClaimed: string | null;\n nonce: number | null;\n /** depositTotal − cumulativeClaimed, when both are known (floored at 0). */\n available: string | null;\n /**\n * cumulativeClaimed − depositTotal, when both are known (floored at 0).\n * Non-zero means the cumulative signed claims exceed the recorded on-chain\n * collateral: the peer accepted (and may keep accepting) claims it cannot\n * fully redeem on-chain until the deposit is topped up — the on-chain\n * TokenNetwork caps redemption at the deposit. `available 0` alone cannot\n * distinguish \"exactly spent\" from \"overdrawn\", hence this field.\n */\n overdrawn: string | null;\n}\n\n/** `--json` envelope. */\ninterface BalanceJson {\n command: 'balance';\n identity: IdentityReport;\n wallet: WalletChainBalanceInfo[];\n channels: ChannelBalanceJson[];\n}\n\n/**\n * Format a base-unit integer string as a human decimal using `decimals`.\n * No decimals known → the base-unit string verbatim. Trims trailing zeros but\n * keeps at least one fractional digit only when non-integer.\n */\nexport function formatUnits(amount: string, decimals?: number): string {\n if (decimals === undefined || decimals <= 0) return amount;\n const neg = amount.startsWith('-');\n const digits = (neg ? amount.slice(1) : amount).padStart(decimals + 1, '0');\n const whole = digits.slice(0, digits.length - decimals);\n const frac = digits.slice(digits.length - decimals).replace(/0+$/, '');\n return (neg ? '-' : '') + (frac ? `${whole}.${frac}` : whole);\n}\n\n/** `SYMBOL amount` for one asset, formatted with its decimals. */\nfunction renderAmount(a: WalletTokenAmountInfo): string {\n return `${a.symbol ?? 'token'} ${formatUnits(a.amount, a.decimals)}`;\n}\n\n/** Env override for the wallet-read timeout; `0` opts out (wait forever). */\nconst WALLET_READ_TIMEOUT_ENV = 'RIG_BALANCE_WALLET_TIMEOUT_MS';\n/** Default cap on the wallet read — generous, only trips a genuine hang. */\nconst DEFAULT_WALLET_READ_TIMEOUT_MS = 20_000;\n\n/** Resolve the wallet-read timeout (ms): valid non-negative env override, else default. */\nexport function walletReadTimeoutMs(env: NodeJS.ProcessEnv): number {\n const raw = env[WALLET_READ_TIMEOUT_ENV];\n if (raw === undefined || raw === '') return DEFAULT_WALLET_READ_TIMEOUT_MS;\n const n = Number(raw);\n return Number.isFinite(n) && n >= 0 ? n : DEFAULT_WALLET_READ_TIMEOUT_MS;\n}\n\n/**\n * The wallet read exceeded {@link walletReadTimeoutMs}. This is the guard that\n * turns the silent-exit bug into a loud, actionable failure: on the Mina\n * settlement path a wallet read can neither resolve nor keep a live handle\n * open (a hung GraphQL endpoint, a nonexistent on-chain account, o1js-adjacent\n * work), so awaiting it UNBOUNDED lets Node's event loop drain and the one-shot\n * CLI exits 0 with no output at all. The bounded read's live timer prevents\n * that drain and forces a decision instead.\n */\nexport class WalletReadTimeoutError extends Error {\n constructor(public readonly timeoutMs: number) {\n super(\n `wallet balance read timed out after ${timeoutMs}ms — the chain ` +\n 'RPC/GraphQL endpoint is unreachable or hanging. (A nonexistent Mina ' +\n 'account reads as 0, so a hang points at the endpoint, not an empty ' +\n 'balance.) Recorded channels are unaffected; retry, or set ' +\n `${WALLET_READ_TIMEOUT_ENV}=0 to wait indefinitely.`\n );\n this.name = 'WalletReadTimeoutError';\n }\n}\n\n/**\n * Read the multi-chain wallet view under a hard time bound. The `setTimeout`\n * is deliberately NOT `unref()`ed: its live handle is exactly what keeps the\n * one-shot CLI's event loop from draining to a silent exit-0 while the read\n * hangs. A late rejection from the losing promise is swallowed so it never\n * surfaces as an unhandled rejection after the race is decided.\n */\nexport async function readWalletBounded(\n read: () => Promise<WalletChainBalanceInfo[]>,\n timeoutMs: number\n): Promise<WalletChainBalanceInfo[]> {\n const settled = read();\n // A `0` (or negative) timeout opts out of the bound entirely (wait forever).\n if (timeoutMs <= 0) return settled;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const guard = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new WalletReadTimeoutError(timeoutMs)), timeoutMs);\n });\n // Don't let the loser reject into an unhandled rejection post-race.\n settled.catch(() => undefined);\n try {\n return await Promise.race([settled, guard]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\n/** Run `rig balance`; returns the process exit code. */\nexport async function runBalance(\n args: string[],\n deps: BalanceDeps\n): Promise<number> {\n const { io, env } = deps;\n let json = false;\n try {\n const { values } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(BALANCE_USAGE);\n return 0;\n }\n json = values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(BALANCE_USAGE);\n return 2;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n // Free read: works without a proxy/BTP write uplink.\n requireUplink: false,\n });\n const identity = identityReport(ctx);\n\n // ── Channels: #262 map ⋈ claim watermark, THIS identity only ────────────\n // Read FIRST: a purely local read that is always available (a corrupt map\n // is still a clear error via the outer catch), so the report can show\n // recorded channels even when the on-chain wallet read below fails.\n const store = new ChannelMapStore(resolveChannelPaths(env));\n const channels: ChannelBalanceJson[] = store\n .list()\n .filter((record) => record.identity === identity.pubkey)\n .map((record) => {\n const watermark = store.readWatermark(record.channelId);\n const deposited = record.depositTotal;\n const claimed = watermark?.cumulativeAmount;\n let available: string | null = null;\n let overdrawn: string | null = null;\n if (deposited !== undefined && claimed !== undefined) {\n const remaining = BigInt(deposited) - BigInt(claimed);\n available = (remaining > 0n ? remaining : 0n).toString();\n overdrawn = (remaining < 0n ? -remaining : 0n).toString();\n }\n return {\n channelId: record.channelId,\n destination: record.destination,\n peerId: record.peerId,\n chain: record.chain,\n status: channelStatus(watermark),\n depositTotal: deposited ?? null,\n cumulativeClaimed: claimed ?? null,\n nonce: watermark?.nonce ?? null,\n available,\n overdrawn,\n };\n });\n\n // ── Wallet: the client's full multi-chain view (#299) — native + USDC ───\n // BOUNDED. An unbounded await here is the silent-exit bug: on the Mina path\n // the read can neither resolve nor keep the event loop alive, so the CLI\n // drains and exits 0 with no output. The bound turns any such hang into a\n // loud, non-zero failure that STILL prints the identity + channels.\n let wallet: WalletChainBalanceInfo[] = [];\n let walletError: Error | undefined;\n if (ctx.money) {\n const money = ctx.money;\n try {\n wallet = await readWalletBounded(\n () => money.walletChainBalances(),\n walletReadTimeoutMs(env)\n );\n } catch (err) {\n walletError = err instanceof Error ? err : new Error(String(err));\n }\n }\n\n if (json) {\n // A wallet-read failure is a hard error in the machine contract: emit the\n // single error envelope (never a partial + a silent 0).\n if (walletError) return emitCliError(io, json, 'balance', walletError);\n io.emitJson({\n command: 'balance',\n identity,\n wallet,\n channels,\n } satisfies BalanceJson);\n return 0;\n }\n\n io.out(renderIdentityLine(identity));\n io.out('');\n io.out('Wallet (on-chain):');\n if (walletError) {\n // Loud, actionable — never a silent gap. The channels below still print.\n io.out(` wallet balances unavailable — ${walletError.message}`);\n } else if (wallet.length === 0) {\n io.out(' (no chain configured for this identity — nothing to read)');\n }\n for (const chain of wallet) {\n io.out(` ${chain.chainKey.padEnd(11)} ${chain.address}`);\n if (chain.unreadable) {\n io.out(\n ` unreadable (RPC unreachable)` +\n (chain.error ? ` — ${chain.error}` : '')\n );\n continue;\n }\n const assets = [...(chain.native ? [chain.native] : []), ...chain.tokens];\n if (assets.length === 0) {\n io.out(' (no balance readable)');\n continue;\n }\n io.out(` ${assets.map(renderAmount).join(' ')}`);\n }\n io.out('');\n io.out('Channels (recorded):');\n if (channels.length === 0) {\n io.out(\n ' none — paid commands record their channel on first use; ' +\n '`rig channel open` records one explicitly.'\n );\n }\n for (const c of channels) {\n io.out(\n ` ${c.channelId} [${c.status}] deposited ${c.depositTotal ?? '?'} ` +\n `claimed ${c.cumulativeClaimed ?? '?'} available ${c.available ?? '?'}` +\n ` (${c.chain} → ${c.destination})`\n );\n if (c.overdrawn !== null && BigInt(c.overdrawn) > 0n) {\n io.out(\n ` OVERDRAWN by ${c.overdrawn}: cumulative claims exceed the ` +\n `recorded deposit — the peer accepted claims only partially ` +\n `covered by on-chain collateral. Top up with ` +\n `\\`rig channel open --deposit <amount>\\`.`\n );\n }\n }\n // Non-zero when the wallet read failed — the report is printed, but the\n // command reports failure (never a silent success on a broken read).\n return walletError ? 1 : 0;\n } catch (err) {\n return emitCliError(io, json, 'balance', err);\n } finally {\n if (ctx) {\n try {\n await ctx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * Daemon-as-accelerator delegation for paid rig commands (#279).\n *\n * Standalone remains the DEFAULT and the guarantee: every paid command works\n * with no daemon anywhere. But standalone pays a fixed bootstrap tax (relay\n * discovery, peer negotiation, channel resume) on every invocation, while a\n * running `toon-clientd` already holds all of that state warm. When the\n * daemon holds the SAME identity, the pre-#279 nonce guard refused outright\n * (two writers would race the payment channel's cumulative-claim watermark).\n * #279 refines that: the same-identity case now DELEGATES the operation to\n * the daemon's loopback `/git/*` routes — one process (the daemon) owns the\n * watermark, which is exactly the safety property the refusal protected, and\n * the command finishes in daemon time instead of bootstrap time.\n *\n * Decision matrix ({@link resolvePaidSession}):\n *\n * daemon reachable + SAME identity → delegate (`path: 'daemon'`)\n * daemon reachable + other identity → standalone (its channels are keyed\n * to its own pubkey — no shared state)\n * daemon unreachable / not a daemon → standalone\n *\n * TRUST BOUNDARY: the daemon is trusted only because it is (a) loopback and\n * (b) proven to hold the same identity — the `GET /status` identity check\n * happens BEFORE any request body is sent. A same-identity daemon already\n * holds the mnemonic-derived keys and the channel, so delegating adds no\n * authority it does not have.\n *\n * Commands the daemon has NO route for — `rig fund`, `rig balance`,\n * `rig channel open|close|settle` — always run standalone; the on-chain\n * channel mutations among them still REFUSE under a same-identity daemon\n * (the nonce guard in ../standalone/nonce-guard.ts), because close/settle\n * must not race the daemon's live claims.\n *\n * The `DaemonGitClient` is a plain-fetch client, deliberately NOT built on\n * `@toon-protocol/client-mcp`'s ControlClient — that package depends on this\n * one (its daemon Publisher wraps our planner), so importing it back would\n * be circular. Route conventions (loopback base URL, JSON bodies, the error\n * envelope with structured 409 `non_fast_forward` / 413 `oversize_objects`\n * payloads) are mirrored here; the wire types live in `../routes.ts` for\n * client-mcp to adopt. Same duplication contract as\n * `../standalone/nonce-guard.ts` — keep in sync.\n */\n\nimport { defaultDaemonPort, standaloneForced } from '../standalone/nonce-guard.js';\nimport type {\n GitCommentRequest,\n GitErrorEnvelope,\n GitEstimateRequest,\n GitEstimateResponse,\n GitEventResponse,\n GitIssueRequest,\n GitPatchRequest,\n GitPushRequest,\n GitPushResponse,\n GitStatusRequest,\n} from '../routes.js';\nimport { resolveIdentity, type IdentitySourceKind } from './identity.js';\nimport type {\n LoadStandalone,\n StandaloneContext,\n} from './standalone-context.js';\n\n// ---------------------------------------------------------------------------\n// Daemon probe (GET /status — identity check BEFORE anything is sent)\n// ---------------------------------------------------------------------------\n\n/** Result of probing the toon-clientd loopback `/status`. */\nexport interface DaemonProbe {\n /** Control API base URL probed, e.g. `http://127.0.0.1:8787`. */\n baseUrl: string;\n /** True when `/status` answered 200 with parseable JSON. */\n reachable: boolean;\n /** `identity.nostrPubkey` from the status body (when reachable). */\n identity?: string;\n /** `ready` from the status body (channel open, publish-ready). */\n ready?: boolean;\n /** Daemon's default relay URL (`relay.url`). */\n relayUrl?: string;\n /**\n * Daemon's flat per-event publish fee (`feePerEvent`, base units, decimal\n * string) — what the single-event subcommands quote before confirming.\n */\n feePerEvent?: string;\n /**\n * Optional-route capabilities the daemon advertises (`capabilities` in the\n * `/status` body, #306). `'git'` means the `/git/*` write path exists. A\n * daemon older than the field itself omits it entirely — so an UNDEFINED or\n * absent-of-`'git'` value must be read as \"no git support\" (fail closed),\n * NOT delegated to (it would 404 mid-operation).\n */\n capabilities?: string[];\n}\n\n/**\n * True when the probed daemon advertises the `/git/*` write path (#306).\n * Fails closed: a daemon that predates the `capabilities` field reports\n * `undefined` here, which is treated as \"no git routes\" so rig raises a clear\n * upgrade error instead of delegating into a mid-operation 404.\n */\nexport function daemonSupportsGit(probe: DaemonProbe): boolean {\n return Array.isArray(probe.capabilities) && probe.capabilities.includes('git');\n}\n\n/** Injectable probe signature (tests fake this instead of the network). */\nexport type ProbeDaemon = (\n env: NodeJS.ProcessEnv,\n fetchImpl: typeof fetch\n) => Promise<DaemonProbe>;\n\n/** Loopback control API base URL (port: `TOON_CLIENT_HTTP_PORT`, else 8787). */\nexport function daemonBaseUrl(env: NodeJS.ProcessEnv): string {\n const raw = env['TOON_CLIENT_HTTP_PORT'];\n const parsed = raw ? Number(raw) : NaN;\n const port =\n Number.isFinite(parsed) && parsed > 0 ? parsed : defaultDaemonPort();\n return `http://127.0.0.1:${port}`;\n}\n\n/**\n * Probe `GET /status` on the loopback control API. Anything short of a 200\n * with JSON (no listener, timeout, some other local service) reports\n * unreachable — the caller then runs standalone.\n */\nexport async function probeDaemon(\n env: NodeJS.ProcessEnv,\n fetchImpl: typeof fetch,\n timeoutMs = 1500\n): Promise<DaemonProbe> {\n const baseUrl = daemonBaseUrl(env);\n try {\n const res = await fetchImpl(`${baseUrl}/status`, {\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return { baseUrl, reachable: false };\n const body = (await res.json()) as {\n ready?: unknown;\n identity?: { nostrPubkey?: unknown };\n relay?: { url?: unknown };\n feePerEvent?: unknown;\n capabilities?: unknown;\n };\n const probe: DaemonProbe = { baseUrl, reachable: true };\n const pubkey = body?.identity?.nostrPubkey;\n if (typeof pubkey === 'string' && pubkey !== '') probe.identity = pubkey;\n if (typeof body?.ready === 'boolean') probe.ready = body.ready;\n if (typeof body?.relay?.url === 'string' && body.relay.url !== '') {\n probe.relayUrl = body.relay.url;\n }\n if (typeof body?.feePerEvent === 'string' && body.feePerEvent !== '') {\n probe.feePerEvent = body.feePerEvent;\n }\n // Only keep string entries — an old daemon omits the field entirely, and\n // daemonSupportsGit() reads a missing/garbage value as \"no git routes\".\n if (Array.isArray(body?.capabilities)) {\n probe.capabilities = body.capabilities.filter(\n (c): c is string => typeof c === 'string'\n );\n }\n return probe;\n } catch {\n return { baseUrl, reachable: false };\n }\n}\n\n// ---------------------------------------------------------------------------\n// /git/* loopback client (plain fetch — see module doc for the no-import rule)\n// ---------------------------------------------------------------------------\n\n/** The daemon answered a `/git/*` route with a non-2xx error envelope. */\nexport class DaemonRouteError extends Error {\n constructor(\n /** HTTP status code (409 non_fast_forward, 413 oversize_objects, …). */\n public readonly status: number,\n /** The parsed error envelope (structured payloads at the top level). */\n public readonly envelope: GitErrorEnvelope\n ) {\n super(envelope.detail ?? envelope.error);\n this.name = 'DaemonRouteError';\n }\n}\n\n/**\n * A same-identity daemon holds the identity but is too old to serve the\n * `/git/*` routes (#306 — version skew: git routes added in #227, delegation\n * in #279). Raised at the capability pre-flight (no `'git'` in `/status`\n * `capabilities`), and as defense-in-depth when a git route still 404s despite\n * a positive probe. NOT auto-fell-back to standalone on purpose: a\n * same-identity daemon holding the identity makes the #228 nonce guard REFUSE\n * standalone anyway (both writers would race the channel's cumulative-claim\n * watermark) — so the only correct, non-racy resolution is upgrading or\n * stopping the daemon.\n */\nexport class DaemonTooOldForGitError extends Error {\n constructor(\n /** Control API base URL the stale daemon answered on. */\n public readonly baseUrl: string,\n /** The shared Nostr pubkey (hex), when known — shortened in the message. */\n public readonly pubkey?: string\n ) {\n const holds =\n pubkey !== undefined && pubkey !== ''\n ? ` holds this identity (${pubkey.slice(0, 8)}…)`\n : ' holds this identity';\n super(\n `toon-clientd at ${baseUrl}${holds} but is too old to handle git ` +\n 'operations (missing /git routes). Upgrade the daemon ' +\n '(npm i -g @toon-protocol/client-mcp@latest, then restart it) — or ' +\n 'stop it to let rig run standalone.'\n );\n this.name = 'DaemonTooOldForGitError';\n }\n}\n\n/** The daemon vanished between the identity probe and the operation. */\nexport class DaemonUnreachableError extends Error {\n constructor(\n public readonly baseUrl: string,\n cause: unknown\n ) {\n super(\n `toon-clientd stopped answering at ${baseUrl} after the identity ` +\n `probe — nothing was paid. Re-run: rig falls back to standalone ` +\n `automatically when no daemon responds` +\n (cause instanceof Error ? ` (${cause.message})` : '')\n );\n this.name = 'DaemonUnreachableError';\n }\n}\n\nexport class DaemonGitClient {\n constructor(\n private readonly baseUrl: string,\n private readonly fetchImpl: typeof fetch,\n /** Shared identity pubkey, for the too-old error message on a 404. */\n private readonly pubkey?: string\n ) {}\n\n gitEstimate(req: GitEstimateRequest): Promise<GitEstimateResponse> {\n return this.post<GitEstimateResponse>('/git/estimate', req);\n }\n\n gitPush(req: GitPushRequest): Promise<GitPushResponse> {\n return this.post<GitPushResponse>('/git/push', req);\n }\n\n gitIssue(req: GitIssueRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/issue', req);\n }\n\n gitComment(req: GitCommentRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/comment', req);\n }\n\n gitPatch(req: GitPatchRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/patch', req);\n }\n\n gitStatus(req: GitStatusRequest): Promise<GitEventResponse> {\n return this.post<GitEventResponse>('/git/status', req);\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n let res: Response;\n try {\n res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n } catch (err) {\n throw new DaemonUnreachableError(this.baseUrl, err);\n }\n // Defense in depth (#306): a 404 on a `/git/*` route means the route is\n // not registered — a daemon too old for the git write path, despite the\n // capability pre-flight having (wrongly) passed. Surface the same\n // actionable upgrade error rather than the opaque \"HTTP 404\" envelope.\n if (res.status === 404) {\n throw new DaemonTooOldForGitError(this.baseUrl, this.pubkey);\n }\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text === '' ? {} : JSON.parse(text);\n } catch {\n throw new DaemonRouteError(res.status, {\n error: 'invalid_response',\n detail: `daemon returned non-JSON (HTTP ${res.status}): ${text.slice(0, 200)}`,\n });\n }\n if (!res.ok) {\n const envelope =\n parsed && typeof parsed === 'object' && 'error' in parsed\n ? (parsed as GitErrorEnvelope)\n : { error: 'http_error', detail: `HTTP ${res.status}` };\n throw new DaemonRouteError(res.status, envelope);\n }\n return parsed as T;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Paid-session resolution (the decision matrix)\n// ---------------------------------------------------------------------------\n\n/** Which transport a paid command ran on (stderr line + `--json` field). */\nexport type SessionPath = 'daemon' | 'standalone';\n\n/** The delegated fast path: a same-identity daemon owns the operation. */\nexport interface DaemonSession {\n path: 'daemon';\n client: DaemonGitClient;\n baseUrl: string;\n /** Locally-resolved identity (source tier + pubkey — never the phrase). */\n identity: {\n pubkey: string;\n source: IdentitySourceKind;\n sourceLabel: string;\n };\n /** Daemon's flat per-event fee (base units, decimal), when reported. */\n feePerEvent?: string;\n /** Daemon's configured relay URL, when reported (mismatch warning). */\n daemonRelayUrl?: string;\n}\n\n/** The default path: the embedded, nonce-guarded standalone context. */\nexport interface StandaloneSession {\n path: 'standalone';\n ctx: StandaloneContext;\n}\n\nexport type PaidSession = DaemonSession | StandaloneSession;\n\nexport interface ResolveSessionOptions {\n env: NodeJS.ProcessEnv;\n /** Working directory (identity `.env` walk / standalone loader). */\n cwd: string;\n /** Stderr line sink (the chosen-path line always prints here). */\n warn(line: string): void;\n /** Standalone factory (`deps.loadStandalone ?? defaultLoadStandalone`). */\n loadStandalone: LoadStandalone;\n /** Relay-origin for the standalone #264 network bootstrap, when resolved. */\n relayUrl?: string;\n /** Fetch impl for probe + delegated requests (tests). Default: global. */\n fetchImpl?: typeof fetch;\n /** Probe override (tests). Default: {@link probeDaemon}. */\n probeDaemon?: ProbeDaemon;\n}\n\n/**\n * Decide how this paid command pays (see the module-doc matrix) and return a\n * ready session. The chosen path is announced on stderr either way, BEFORE\n * the expensive work starts. Identity is confirmed against the daemon's\n * `/status` before anything else is sent to it.\n */\nexport async function resolvePaidSession(\n options: ResolveSessionOptions\n): Promise<PaidSession> {\n const fetchImpl = options.fetchImpl ?? fetch;\n\n // Force-standalone override (RIG_STANDALONE / `rig --standalone`): skip the\n // daemon probe outright and run embedded, even when a same-identity daemon\n // is up and supports the /git routes. The user has explicitly opted out of\n // delegation; createStandaloneContext skips the same-identity refusal too,\n // and the NonceLock still guards against concurrent standalone processes.\n if (standaloneForced(options.env)) {\n options.warn(\n 'rig: paid path: standalone (RIG_STANDALONE set — toon-clientd bypassed)'\n );\n const ctx = await options.loadStandalone({\n env: options.env,\n cwd: options.cwd,\n warn: options.warn,\n ...(options.relayUrl !== undefined ? { relayUrl: options.relayUrl } : {}),\n });\n return { path: 'standalone', ctx };\n }\n\n const probe = await (options.probeDaemon ?? probeDaemon)(\n options.env,\n fetchImpl\n );\n\n if (probe.reachable && probe.identity !== undefined) {\n // Local identity resolution only happens when there is a daemon to\n // compare against — the standalone loader resolves it itself otherwise.\n const identity = await resolveIdentity({\n env: options.env,\n cwd: options.cwd,\n warn: options.warn,\n });\n if (identity.pubkey === probe.identity) {\n // Capability pre-flight (#306): a same-identity daemon that predates the\n // `/git/*` routes (older client-mcp) has `/status` but 404s every git\n // route. Delegating would dead-end with an opaque 404, and blindly\n // falling back to standalone is unsafe — the #228 nonce guard REFUSES\n // standalone while a same-identity daemon is up (cumulative-claim race).\n // Fail closed with a clear upgrade/stop remediation instead.\n if (!daemonSupportsGit(probe)) {\n throw new DaemonTooOldForGitError(probe.baseUrl, identity.pubkey);\n }\n options.warn(\n `rig: paid path: daemon — toon-clientd at ${probe.baseUrl} holds ` +\n `this identity (${identity.pubkey.slice(0, 8)}…), delegating`\n );\n return {\n path: 'daemon',\n client: new DaemonGitClient(probe.baseUrl, fetchImpl, identity.pubkey),\n baseUrl: probe.baseUrl,\n identity: {\n pubkey: identity.pubkey,\n source: identity.source,\n sourceLabel: identity.sourceLabel,\n },\n ...(probe.feePerEvent !== undefined\n ? { feePerEvent: probe.feePerEvent }\n : {}),\n ...(probe.relayUrl !== undefined\n ? { daemonRelayUrl: probe.relayUrl }\n : {}),\n };\n }\n options.warn(\n `rig: paid path: standalone — the toon-clientd at ${probe.baseUrl} ` +\n `runs a different identity (${probe.identity.slice(0, 8)}…), no ` +\n 'shared channel state'\n );\n } else {\n options.warn(\n `rig: paid path: standalone (no toon-clientd at ${probe.baseUrl})`\n );\n }\n\n const ctx = await options.loadStandalone({\n env: options.env,\n cwd: options.cwd,\n warn: options.warn,\n ...(options.relayUrl !== undefined ? { relayUrl: options.relayUrl } : {}),\n });\n return { path: 'standalone', ctx };\n}\n","/**\n * Error UX for the `rig` commands: map structured planner/publisher errors\n * to actionable terminal output (and a machine-readable envelope for\n * `--json`). The CLI is standalone-only (#248), so everything here is either\n * a local planner error, an identity/config-chain error, or a tagged error\n * surfaced from the embedded publisher (matched by name — those classes live\n * behind the lazy `@toon-protocol/client` dynamic import).\n */\n\nimport { MAX_OBJECT_SIZE } from '../objects.js';\nimport {\n NonFastForwardError,\n OversizeObjectsError,\n type OversizeObject,\n type RejectedRefUpdate,\n} from '../push.js';\nimport { GitError } from '../repo-reader.js';\nimport {\n DaemonRouteError,\n DaemonTooOldForGitError,\n DaemonUnreachableError,\n} from './daemon-session.js';\nimport { MissingIdentityError } from './identity.js';\nimport type { CliIo } from './output.js';\n\n/** Normalized error description: terminal lines + `--json` envelope. */\nexport interface DescribedError {\n /** Stable machine code. */\n code: string;\n /** Human-facing lines (message first, remediation after). */\n lines: string[];\n /** Machine envelope for `--json` output (structured payload included). */\n json: Record<string, unknown>;\n}\n\n/**\n * A command could not resolve the NIP-34 repo address\n * (`30617:<ownerPubkey>:<repoId>`) from flags or the `toon.*` git config\n * keys `rig init` writes.\n */\nexport class UnconfiguredRepoAddressError extends Error {\n constructor(\n /** Which half of the address is missing. */\n public readonly missing: 'repository id' | 'repository owner'\n ) {\n super(\n `no ${missing} configured — this command addresses the repo as ` +\n '30617:<ownerPubkey>:<repoId>. Run `rig init` once inside the repo ' +\n '(it writes toon.repoid/toon.owner to the local git config), or ' +\n `pass ${missing === 'repository id' ? '--repo-id <id>' : '--owner <pubkey>'} ` +\n \"explicitly (use --owner for repos you don't own).\"\n );\n this.name = 'UnconfiguredRepoAddressError';\n }\n}\n\n/** A relay URL (flag, `rig remote add`, or a remote's stored URL) is junk. */\nexport class InvalidRelayUrlError extends Error {\n constructor(\n public readonly url: string,\n /** What was being resolved, e.g. `remote \"origin\"`. */\n context: string\n ) {\n super(\n `${context}: ${JSON.stringify(url)} is not a relay URL — relays are ` +\n 'ws://, wss://, http://, or https://'\n );\n this.name = 'InvalidRelayUrlError';\n }\n}\n\n/** A paid command addressed a git remote that is not configured. */\nexport class UnknownRemoteError extends Error {\n constructor(public readonly remote: string) {\n super(\n `no remote named ${JSON.stringify(remote)} is configured — ` +\n '`rig remote list` shows configured remotes; add it with ' +\n `\\`rig remote add ${remote} <relay-url>\\``\n );\n this.name = 'UnknownRemoteError';\n }\n}\n\n/**\n * The addressed git remote carries multiple URLs (`git remote set-url --add`\n * done by hand). rig publishes to exactly one relay per paid command, so this\n * is refused BEFORE anything is fetched, uploaded, or paid (the #243\n * single-relay guard, extended to remotes).\n */\nexport class MultiUrlRemoteError extends Error {\n constructor(\n public readonly remote: string,\n public readonly urls: string[]\n ) {\n super(\n `remote ${JSON.stringify(remote)} has ${urls.length} URLs ` +\n `(${urls.join(', ')}) — rig supports one relay URL per remote. ` +\n `Fix it with \\`git remote set-url ${remote} <relay-url>\\`. ` +\n 'Nothing was uploaded, published, or paid.'\n );\n this.name = 'MultiUrlRemoteError';\n }\n}\n\n/** No relay resolved: no --relay, no usable remote, no legacy toon.relay. */\nexport class NoOriginConfiguredError extends Error {\n constructor(\n /** URL of an existing `origin` remote that is NOT a relay, if any. */\n nonRelayOriginUrl?: string\n ) {\n super(\n 'no origin configured — run `rig remote add origin <relay-url>` ' +\n '(or pass --relay <url> for a one-off publish).' +\n (nonRelayOriginUrl !== undefined\n ? `\\nThe existing \"origin\" remote (${nonRelayOriginUrl}) is not a ` +\n 'relay URL, so rig ignores it — add the relay under another ' +\n 'name (`rig remote add toon <relay-url>`) and target it ' +\n 'explicitly (`rig push toon` / `--remote toon`).'\n : '')\n );\n this.name = 'NoOriginConfiguredError';\n }\n}\n\n/** A rig command ran outside any git repository. */\nexport class NotAGitRepositoryError extends Error {\n constructor(cwd: string) {\n super(\n `not a git repository: ${cwd}\\n` +\n 'rig can create one for you: re-run `rig init --git-init` (in a ' +\n 'terminal, plain `rig init` offers the same via a prompt). Or run ' +\n '`git init` yourself first, then re-run.'\n );\n this.name = 'NotAGitRepositoryError';\n }\n}\n\nfunction nonFastForwardLines(refs: RejectedRefUpdate[]): string[] {\n return [\n 'Push rejected: non-fast-forward update for:',\n ...refs.map(\n (r) =>\n ` ${r.refname} remote ${r.remoteSha.slice(0, 7)} is not an ancestor of local ${r.localSha.slice(0, 7)}`\n ),\n 'The remote moved since your last push. Re-run with --force to overwrite it',\n 'WARNING: --force rewrites the published ref history for every reader of this repo.',\n ];\n}\n\nfunction oversizeLines(objects: OversizeObject[]): string[] {\n return [\n `Push rejected: ${objects.length} object(s) exceed the ${MAX_OBJECT_SIZE}-byte (95KB) upload limit:`,\n ...objects.map((o) => ` ${o.path ?? o.sha} ${o.type}, ${o.size} bytes`),\n 'Objects over 95KB are a hard error in v1 — split or remove the file(s) from history to push.',\n 'Large-object support is tracked in toon-client#235.',\n ];\n}\n\n/**\n * Normalize any command-path error for rendering. `command` names the rig\n * subcommand for the generic \"rig <command> failed\" lines.\n */\nexport function describeError(err: unknown, command = 'push'): DescribedError {\n if (err instanceof UnconfiguredRepoAddressError) {\n return {\n code: 'unconfigured_repo_address',\n lines: err.message.split('\\n'),\n json: { error: 'unconfigured_repo_address', detail: err.message },\n };\n }\n if (err instanceof NotAGitRepositoryError) {\n return {\n code: 'not_a_git_repository',\n lines: err.message.split('\\n'),\n json: { error: 'not_a_git_repository', detail: err.message },\n };\n }\n if (err instanceof InvalidRelayUrlError) {\n return {\n code: 'invalid_relay_url',\n lines: err.message.split('\\n'),\n json: { error: 'invalid_relay_url', detail: err.message, url: err.url },\n };\n }\n if (err instanceof UnknownRemoteError) {\n return {\n code: 'unknown_remote',\n lines: err.message.split('\\n'),\n json: {\n error: 'unknown_remote',\n detail: err.message,\n remote: err.remote,\n },\n };\n }\n if (err instanceof MultiUrlRemoteError) {\n return {\n code: 'multi_url_remote',\n lines: err.message.split('\\n'),\n json: {\n error: 'multi_url_remote',\n detail: err.message,\n remote: err.remote,\n urls: err.urls,\n },\n };\n }\n if (err instanceof NoOriginConfiguredError) {\n return {\n code: 'no_origin_configured',\n lines: err.message.split('\\n'),\n json: { error: 'no_origin_configured', detail: err.message },\n };\n }\n if (err instanceof MissingIdentityError) {\n return {\n code: 'missing_identity',\n lines: err.message.split('\\n'),\n json: { error: 'missing_identity', detail: err.message },\n };\n }\n if (err instanceof NonFastForwardError) {\n return {\n code: 'non_fast_forward',\n lines: nonFastForwardLines(err.refs),\n json: { error: 'non_fast_forward', detail: err.message, refs: err.refs },\n };\n }\n if (err instanceof OversizeObjectsError) {\n return {\n code: 'oversize_objects',\n lines: oversizeLines(err.objects),\n json: {\n error: 'oversize_objects',\n detail: err.message,\n objects: err.objects,\n },\n };\n }\n if (err instanceof GitError) {\n return {\n code: 'git_error',\n lines: [`git failed: ${err.message}`],\n json: { error: 'git_error', detail: err.message },\n };\n }\n // `rig name` (#367): the optional `@ar.io/sdk` dependency is not installed.\n // Matched by name (the class lives in name.ts) so tsup chunk duplication can\n // never break instanceof — same rationale as the standalone-path errors below.\n if (err instanceof Error && err.name === 'ArnsSdkUnavailableError') {\n return {\n code: 'arns_sdk_unavailable',\n lines: err.message.split('\\n'),\n json: { error: 'arns_sdk_unavailable', detail: err.message },\n };\n }\n // `rig name` (#376): `@ar.io/sdk` IS installed but its API surface doesn't\n // match — kept distinct from \"not installed\" so the remediation (upgrade,\n // not install) is right. Matched by name for the same chunk-duplication\n // rationale as above.\n if (err instanceof Error && err.name === 'ArnsSdkIncompatibleError') {\n return {\n code: 'arns_sdk_incompatible',\n lines: err.message.split('\\n'),\n json: { error: 'arns_sdk_incompatible', detail: err.message },\n };\n }\n\n // Delegated-daemon path (#279): the daemon's /git/* error envelope carries\n // the same structured payloads the local planner throws — render them\n // identically so the two paths are indistinguishable to the user.\n if (err instanceof DaemonRouteError) {\n const envelope = err.envelope;\n if (\n envelope.error === 'non_fast_forward' &&\n Array.isArray(envelope['refs'])\n ) {\n return {\n code: 'non_fast_forward',\n lines: nonFastForwardLines(envelope['refs'] as RejectedRefUpdate[]),\n json: { ...envelope },\n };\n }\n if (\n envelope.error === 'oversize_objects' &&\n Array.isArray(envelope['objects'])\n ) {\n return {\n code: 'oversize_objects',\n lines: oversizeLines(envelope['objects'] as OversizeObject[]),\n json: { ...envelope },\n };\n }\n const retryHint =\n envelope.retryable === true\n ? ['The daemon reports this as retryable — re-run shortly.']\n : [];\n return {\n code: envelope.error,\n lines: [\n `daemon rejected the operation (HTTP ${err.status}): ` +\n (envelope.detail ?? envelope.error),\n ...retryHint,\n ],\n json: { ...envelope },\n };\n }\n if (err instanceof DaemonUnreachableError) {\n return {\n code: 'daemon_unreachable',\n lines: err.message.split('\\n'),\n json: { error: 'daemon_unreachable', detail: err.message },\n };\n }\n // Version skew (#306): a same-identity daemon too old for the /git/* routes.\n // The message already carries the upgrade + stop-daemon remediation.\n if (err instanceof DaemonTooOldForGitError) {\n return {\n code: 'daemon_too_old_for_git',\n lines: err.message.split('\\n'),\n json: {\n error: 'daemon_too_old_for_git',\n detail: err.message,\n baseUrl: err.baseUrl,\n ...(err.pubkey !== undefined ? { pubkey: err.pubkey } : {}),\n },\n };\n }\n\n // Standalone-path tagged errors (matched by name — the classes live behind\n // the optional dynamic import).\n const name = err instanceof Error ? err.name : '';\n const message = err instanceof Error ? err.message : String(err);\n if (name === 'DaemonIdentityConflictError') {\n return {\n code: 'daemon_identity_conflict',\n lines: [\n message,\n 'Paid writes delegate to a same-identity daemon automatically; ' +\n 'seeing this means the daemon appeared mid-run or this operation ' +\n 'has no daemon route — stop the daemon and re-run.',\n ],\n json: { error: 'daemon_identity_conflict', detail: message },\n };\n }\n if (name === 'MissingUplinkError') {\n return {\n code: 'missing_uplink',\n lines: [message],\n json: { error: 'missing_uplink', detail: message },\n };\n }\n // Peer→channel map corruption (#262) — matched by name so tsup chunk\n // duplication between the cli and standalone entries can't break instanceof.\n if (name === 'ChannelMapCorruptError') {\n return {\n code: 'channel_map_corrupt',\n lines: [message],\n json: { error: 'channel_map_corrupt', detail: message },\n };\n }\n // Settle attempted before the challenge window elapsed (#263) — the client\n // throws this retryable error BEFORE spending gas; surface when to retry.\n if (name === 'SettleTooEarlyError') {\n const settleableAt = (err as { settleableAt?: unknown }).settleableAt;\n return {\n code: 'settle_too_early',\n lines: [\n message,\n 'The settlement challenge window is still open — nothing was spent. ' +\n 'Re-run `rig channel settle` after the settleable time.',\n ],\n json: {\n error: 'settle_too_early',\n detail: message,\n ...(typeof settleableAt === 'string' ? { settleableAt } : {}),\n },\n };\n }\n\n // The #278 read path — matched by name (same tsup chunk-duplication\n // rationale as above; the classes live in clone.ts / object-fetch.ts /\n // materialize.ts).\n if (name === 'RepoNotFoundError') {\n return {\n code: 'repo_not_found',\n lines: message.split('\\n'),\n json: { error: 'repo_not_found', detail: message },\n };\n }\n if (name === 'MissingRemoteObjectsError') {\n const missing = (err as { missing?: unknown }).missing;\n return {\n code: 'missing_remote_objects',\n lines: message.split('\\n'),\n json: {\n error: 'missing_remote_objects',\n detail: message,\n ...(Array.isArray(missing) ? { missing } : {}),\n },\n };\n }\n if (name === 'ObjectIntegrityError' || name === 'ObjectWriteMismatchError') {\n return {\n code: 'object_integrity',\n lines: message.split('\\n'),\n json: { error: 'object_integrity', detail: message },\n };\n }\n\n return {\n code: 'error',\n lines: [`rig ${command} failed: ${message}`],\n json: { error: 'error', detail: message },\n };\n}\n\n/**\n * The one command-error emitter (#265): the machine envelope (tagged with\n * the command name) goes to stdout via `emitJson` when `--json` is active,\n * and the human-facing lines ALWAYS go to stderr — so JSON consumers get the\n * parseable envelope while a human tailing stderr still sees the detail.\n * Returns the exit code (always 1) so callers can `return emitCliError(…)`.\n */\nexport function emitCliError(\n io: CliIo,\n json: boolean,\n command: string,\n err: unknown\n): 1 {\n const described = describeError(err, command);\n if (json) io.emitJson({ command, ...described.json });\n for (const line of described.lines) io.err(line);\n return 1;\n}\n","/**\n * `rig push [remote] [refspecs...]` — estimate → confirm → execute (#229,\n * standalone since #248, git-like remote resolution since #249,\n * daemon-as-accelerator since #279).\n *\n * STANDALONE is the default and the guarantee: plan locally (`planPush`) and\n * execute through the embedded, nonce-guarded StandalonePublisher (loaded\n * via dynamic import so runs that fail earlier never need\n * `@toon-protocol/client`). The identity comes from the RIG_MNEMONIC\n * precedence chain (./identity.ts).\n *\n * DAEMON FAST PATH (#279, ./daemon-session.ts): when a running toon-clientd\n * holds the SAME identity, the whole estimate→push pipeline is delegated to\n * its loopback `/git/estimate` + `/git/push` routes instead of refusing —\n * the daemon already owns the channel watermark and its bootstrap is warm,\n * so the command finishes in seconds. A daemon on a different identity, or\n * no daemon, runs standalone. The chosen path prints to stderr and lands in\n * the `--json` envelope as `path`.\n *\n * Repo addressing comes from the `toon.*` git config keys `rig init` writes\n * (`--repo-id` overrides); an unconfigured repo is a hard \"run `rig init`\n * first\" error — nothing is written as a side effect of pushing.\n *\n * The relay comes from the repo's git remotes (#249): when the first\n * positional matches a configured remote name it is the push target,\n * otherwise it is a refspec and the remote defaults to `origin`. `--relay`\n * is an ad-hoc override that bypasses remotes (all positionals are then\n * refspecs); the deprecated v0.1 `git config toon.relay` still works with a\n * migration nudge. See ./remote.ts for the full resolution order.\n *\n * Money is only spent after the confirm gate: `--yes`, or an interactive\n * y/N prompt (a non-TTY session without `--yes` refuses). `--json` emits the\n * wire-shaped plan/receipts for agent consumers; without `--yes` it becomes\n * a pure estimate (plan JSON, nothing executed, exit 0).\n */\n\nimport { createHash } from 'node:crypto';\nimport { parseArgs } from 'node:util';\nimport {\n DEFAULT_RIG_WEB_BUNDLE,\n DEFAULT_RIG_WEB_GATEWAY,\n DEFAULT_RIG_WEB_URL,\n RIG_WEB_ENTRY_CSS_ENV,\n RIG_WEB_GATEWAY_ENV,\n RIG_WEB_ENTRY_JS_ENV,\n RIG_WEB_TX_ENV,\n RIG_WEB_URL_ENV,\n generateRigPointerHtml,\n} from '../rig-pointer.js';\nimport { PREFERRED_GATEWAY, mirrorGatewaysFor } from '../gateway-preference.js';\nimport { hexToNpub } from '../npub.js';\nimport { planPush, executePush } from '../push.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport {\n readRigPointerRecord,\n writeRigPointerRecord,\n} from './rig-pointer-record.js';\nimport { renderIdentityLine, renderPlan, renderResult } from './render.js';\nimport {\n serializePushPlan,\n serializePushResult,\n type GitEstimateResponse,\n type GitPushResponse,\n} from '../routes.js';\nimport { uploadChargeFor, type FeeRates } from '../publisher.js';\nimport {\n resolvePaidSession,\n type PaidSession,\n type ProbeDaemon,\n type SessionPath,\n} from './daemon-session.js';\nimport { RIG_STANDALONE_ENV } from '../standalone/nonce-guard.js';\nimport { emitCliError, UnconfiguredRepoAddressError } from './errors.js';\nimport {\n listGitRemotes,\n readToonConfig,\n resolveRepoRoot,\n} from './git-config.js';\nimport type { IdentitySourceKind } from './identity.js';\nimport { resolveRelays, singleRelayRefusal } from './remote.js';\nimport type {\n LoadStandalone,\n StandaloneContext,\n} from './standalone-context.js';\n\n// ---------------------------------------------------------------------------\n// Dependency seam (real wiring in rig.ts; tests inject fakes)\n// ---------------------------------------------------------------------------\n\n/**\n * Terminal I/O seam — lives in ./output.ts since #265 (the strict `--json`\n * stdout layer); re-exported here because every command module historically\n * imports it from push.ts.\n */\nexport type { CliIo } from './output.js';\nimport type { CliIo } from './output.js';\n\nexport interface PushDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Standalone factory; defaults to the real dynamic-import loader. */\n loadStandalone?: LoadStandalone;\n /** Fetch for the daemon probe + delegated `/git/*` requests (tests). */\n fetchImpl?: typeof fetch;\n /** Daemon `/status` probe override (tests fake the loopback daemon). */\n probeDaemon?: ProbeDaemon;\n}\n\n/**\n * Return deps with the force-standalone override switched on — the\n * `--standalone` / `--no-daemon` per-command flag, equivalent to running with\n * `RIG_STANDALONE=1` in the environment. Every paid path reads the override\n * from `env` ({@link standaloneForced}), so injecting it here makes the flag\n * bypass the daemon for both session resolution and the embedded publisher's\n * guard. Generic so the event commands keep their extra deps.\n */\nexport function withForcedStandalone<D extends PushDeps>(deps: D): D {\n return { ...deps, env: { ...deps.env, [RIG_STANDALONE_ENV]: '1' } };\n}\n\n/**\n * Resolve the paid session for a command from its deps (#279): probe for a\n * same-identity toon-clientd (→ delegate) before falling back to the\n * standalone loader. Shared by push and the single-event commands.\n */\nexport function loadPaidSession(\n deps: PushDeps,\n relayUrl: string | undefined\n): Promise<PaidSession> {\n return resolvePaidSession({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => deps.io.err(line),\n loadStandalone: deps.loadStandalone ?? defaultLoadStandalone,\n ...(relayUrl !== undefined ? { relayUrl } : {}),\n ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}),\n ...(deps.probeDaemon ? { probeDaemon: deps.probeDaemon } : {}),\n });\n}\n\n/**\n * Default standalone factory (shared by every paid command). Dynamic import:\n * `standalone-mode` (and its `@toon-protocol/client` dependency) only loads\n * once a command actually needs to sign or pay.\n */\nexport const defaultLoadStandalone: LoadStandalone = async (options) => {\n const mod = await import('./standalone-mode.js');\n return mod.createStandaloneContext(options);\n};\n\n/** Identity report shared by every paid command's `--json` envelope. */\nexport interface IdentityReport {\n /** Derived Nostr pubkey (hex) of the active identity. */\n pubkey: string;\n /** Which tier of the RIG_MNEMONIC precedence chain supplied it. */\n source: IdentitySourceKind;\n /** Human-facing source label, e.g. `RIG_MNEMONIC env` or a file path. */\n sourceLabel: string;\n}\n\n/** Build the identity report of a loaded standalone context. */\nexport function identityReport(ctx: StandaloneContext): IdentityReport {\n return {\n pubkey: ctx.ownerPubkey,\n source: ctx.identitySource,\n sourceLabel: ctx.identitySourceLabel,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\nexport const PUSH_USAGE = `Usage: rig push [remote] [refspecs...] [options]\n\nPush local git refs to TOON: uploads the object delta to Arweave (paid) and\npublishes the NIP-34 refs event (kind:30618; kind:30617 announce on first\npush). Writes are permanent and non-refundable.\n\nThe repo must be set up once with \\`rig init\\` (writes toon.repoid/toon.owner\nto the local git config); the identity comes from RIG_MNEMONIC (env or a\nproject .env), or the ~/.toon-client keystore/config.\n\nThe relay is a git remote: \\`rig push\\` publishes via \"origin\" (set up with\n\\`rig remote add origin <relay-url>\\`); \\`rig push <remote> [refspecs...]\\`\npublishes via a named remote. When the first positional matches a configured\nremote name it is the remote; otherwise it is a refspec and the remote\ndefaults to origin. Refspecs are branch/tag names or full refnames; default\nis the current branch.\n\nEvery push also keeps the repo's RIG PAGE current: a permanent Arweave\npage that RENDERS this repo in place — it boots the FULL Rig (rig-web)\nfrom its Arweave deployment with this repo pinned, everything served from\nArweave + the relay. The pointer is content-addressed, so it is paid for\nonce and reused for free until the relay or Rig deployment changes.\n--no-rig-page skips it.\n\nOptions:\n --force allow non-fast-forward ref updates (overwrites remote history)\n --all push all local branches\n --tags push all local tags\n --no-rig-page skip the Rig-page pointer upload for this push\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable plan/receipts; without --yes it is a pure\n estimate (nothing executed)\n --relay <url> ad-hoc relay override (exactly one) — bypasses the\n configured remotes; every positional is then a refspec.\n The deprecated v0.1 \\`git config toon.relay\\` still works\n as a fallback, with a migration nudge\n --repo-id <id> repository id / NIP-34 d-tag (default: git config\n toon.repoid — run \\`rig init\\` to set it)\n --standalone always run embedded, bypassing a running toon-clientd\n (alias: --no-daemon). Same as RIG_STANDALONE=1 — set that\n env var to make it the durable default\n -h, --help show this help`;\n\n// ---------------------------------------------------------------------------\n// Refspec selection\n// ---------------------------------------------------------------------------\n\n/**\n * Build the \"no such local ref\" error: name the missing ref, then point at the\n * current branch (with a `did you mean` using the real branch name) or, when\n * HEAD is detached/unborn, list the local branches. This is deliberately NOT\n * the ref-deletion guard — a branch that simply doesn't exist is the common\n * case (e.g. the docs say `main` but the repo is on `master`), and mentioning\n * \"ref deletion\" there is a confusing red herring.\n */\nfunction noSuchRefMessage(\n spec: string,\n head: string | undefined,\n refs: readonly { refname: string }[],\n remoteName: string\n): string {\n const branches = refs\n .filter((r) => r.refname.startsWith('refs/heads/'))\n .map((r) => r.refname.slice('refs/heads/'.length));\n const current =\n head && head.startsWith('refs/heads/')\n ? head.slice('refs/heads/'.length)\n : undefined;\n let msg = `no local branch or tag ${JSON.stringify(spec)}`;\n if (current) {\n msg +=\n ` — your current branch is ${JSON.stringify(current)} ` +\n `(did you mean \\`rig push ${remoteName} ${current}\\`?)`;\n } else if (branches.length > 0) {\n msg += ` — local branches: ${branches.join(', ')}`;\n } else {\n msg += ' — this repository has no branches yet (make a commit first)';\n }\n return msg;\n}\n\n/**\n * Expand positional refspecs / `--all` / `--tags` into full refnames using\n * the local ref list; default (no selection) is the current branch.\n * `remoteName` (default `origin`) only shapes the `did you mean` hint on a\n * missing ref.\n */\nexport async function selectRefspecs(\n reader: GitRepoReader,\n positionals: string[],\n all: boolean,\n tags: boolean,\n remoteName = 'origin'\n): Promise<string[]> {\n const { head, refs } = await reader.listRefs();\n const byName = new Set(refs.map((r) => r.refname));\n\n const selected: string[] = [];\n const add = (refname: string): void => {\n if (!selected.includes(refname)) selected.push(refname);\n };\n\n for (const spec of positionals) {\n if (byName.has(spec)) {\n add(spec);\n } else if (byName.has(`refs/heads/${spec}`)) {\n add(`refs/heads/${spec}`);\n } else if (byName.has(`refs/tags/${spec}`)) {\n add(`refs/tags/${spec}`);\n } else if (spec.startsWith(':')) {\n // git deletion syntax (`rig push origin :branch`) — the one case where\n // \"out of scope in v1\" genuinely applies.\n throw new Error(\n `deleting remote refs (${JSON.stringify(spec)}) is out of scope in v1`\n );\n } else {\n throw new Error(noSuchRefMessage(spec, head, refs, remoteName));\n }\n }\n if (all) {\n for (const ref of refs) {\n if (ref.refname.startsWith('refs/heads/')) add(ref.refname);\n }\n }\n if (tags) {\n for (const ref of refs) {\n if (ref.refname.startsWith('refs/tags/')) add(ref.refname);\n }\n }\n if (selected.length === 0) {\n if (!head) {\n throw new Error(\n 'HEAD is detached and no refspec was given — pass a branch/tag name, --all, or --tags'\n );\n }\n add(head);\n }\n return selected;\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\ninterface PushFlags {\n force: boolean;\n all: boolean;\n tags: boolean;\n /** Deploy/refresh the per-repo Rig page (default; --no-rig-page skips). */\n rigPage: boolean;\n yes: boolean;\n json: boolean;\n relay: string[];\n repoId?: string;\n /** Force embedded standalone, bypassing the daemon (--standalone/--no-daemon). */\n standalone: boolean;\n help: boolean;\n positionals: string[];\n}\n\nfunction parsePushArgs(args: string[]): PushFlags {\n const { values, positionals } = parseArgs({\n args,\n options: {\n force: { type: 'boolean', default: false },\n all: { type: 'boolean', default: false },\n tags: { type: 'boolean', default: false },\n 'no-rig-page': { type: 'boolean', default: false },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n relay: { type: 'string', multiple: true },\n 'repo-id': { type: 'string' },\n standalone: { type: 'boolean', default: false },\n 'no-daemon': { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n const flags: PushFlags = {\n force: values.force ?? false,\n all: values.all ?? false,\n tags: values.tags ?? false,\n rigPage: !(values['no-rig-page'] ?? false),\n yes: values.yes ?? false,\n json: values.json ?? false,\n relay: values.relay ?? [],\n standalone: (values.standalone ?? false) || (values['no-daemon'] ?? false),\n help: values.help ?? false,\n positionals,\n };\n const repoId = values['repo-id'];\n if (repoId !== undefined) flags.repoId = repoId;\n return flags;\n}\n\n// ---------------------------------------------------------------------------\n// Rig pointer (per-repo Rig page — see ../rig-pointer.ts)\n// ---------------------------------------------------------------------------\n\n/** The Rig-pointer step resolved for THIS push, before the confirm gate. */\ninterface RigPointerPlan {\n /** 'upload' pays for a (new/changed) pointer; 'unchanged' reuses for free. */\n action: 'upload' | 'unchanged';\n html: string;\n contentHash: string;\n bytes: number;\n /** Fee for the upload action, base units (0n when unchanged). */\n fee: bigint;\n /** Recorded txId (unchanged action only). */\n recordedTxId?: string;\n}\n\n/** Rig-page report in receipts / the `--json` envelope. */\nexport interface RigPageReport {\n /** What happened: fresh upload, free reuse, or skipped (flag/daemon path). */\n status: 'published' | 'unchanged' | 'skipped';\n txId?: string;\n /** Permanent pointer URL on the preferred ar.io gateway. */\n url?: string;\n feePaid?: string;\n detail?: string;\n}\n\n/**\n * Gateway for printed Rig-page URLs: the shared list's first MAINNET gateway\n * ({@link PREFERRED_GATEWAY} — never ar.io's testnet), `RIG_ARWEAVE_GATEWAY`\n * overriding, same as `rig site`. Distinct from the BUNDLE gateway embedded in\n * the pointer HTML ({@link DEFAULT_RIG_WEB_GATEWAY}), which tracks where the\n * rig-web deploy lives.\n */\nfunction pointerGateway(env: NodeJS.ProcessEnv): string {\n return (env['RIG_ARWEAVE_GATEWAY'] ?? PREFERRED_GATEWAY).replace(/\\/+$/, '');\n}\n\n/**\n * Every OTHER gateway from the shared list, printed under the primary.\n *\n * All of them, not just one: a gateway can be flat DOWN, not merely behind.\n * Observed 2026-08-15 — `ar-io.dev` answered `503` on its own root while the\n * page was live and byte-identical on both other gateways, and a single\n * printed alternate is one outage away from leaving the reader with no\n * working link and the impression their push failed.\n */\nfunction mirrorGateways(primary: string): string[] {\n return mirrorGatewaysFor(primary);\n}\n\n/** Build the Rig-pointer plan: deterministic pointer + content-addressed skip. */\nfunction planRigPointer(args: {\n env: NodeJS.ProcessEnv;\n ownerPubkey: string;\n repoId: string;\n relay: string;\n /** The store route's terms; the pointer's upload is priced by its size. */\n feeRates: FeeRates;\n}): RigPointerPlan {\n const html = generateRigPointerHtml({\n bundle: {\n manifestTx: args.env[RIG_WEB_TX_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.manifestTx,\n entryJs: args.env[RIG_WEB_ENTRY_JS_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.entryJs,\n entryCss:\n args.env[RIG_WEB_ENTRY_CSS_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.entryCss,\n },\n gateway: (args.env[RIG_WEB_GATEWAY_ENV] ?? DEFAULT_RIG_WEB_GATEWAY).replace(\n /\\/+$/,\n ''\n ),\n rigWebUrl: args.env[RIG_WEB_URL_ENV] ?? DEFAULT_RIG_WEB_URL,\n relay: args.relay,\n ownerNpub: hexToNpub(args.ownerPubkey),\n repoId: args.repoId,\n });\n const contentHash = createHash('sha256').update(html).digest('hex');\n const bytes = Buffer.byteLength(html);\n const record = readRigPointerRecord(args.env, args.repoId);\n if (\n record &&\n record.contentHash === contentHash &&\n record.owner === args.ownerPubkey\n ) {\n return {\n action: 'unchanged',\n html,\n contentHash,\n bytes,\n fee: 0n,\n recordedTxId: record.pointerTxId,\n };\n }\n return {\n action: 'upload',\n html,\n contentHash,\n bytes,\n fee: uploadChargeFor(args.feeRates, bytes),\n };\n}\n\n/** JSON envelope emitted by `--json` runs (agents consume this). */\ninterface PushJsonOutput {\n command: 'push';\n repoId: string;\n /** Which transport paid: delegated daemon or embedded standalone (#279). */\n path: SessionPath;\n /** Active identity: source tier + derived pubkey (never the phrase). */\n identity: IdentityReport;\n /** True when the paid execute step ran. */\n executed: boolean;\n /** True when every selected ref already matched the remote (no-op). */\n upToDate: boolean;\n plan: GitEstimateResponse;\n result?: GitPushResponse;\n /** Per-repo Rig-page outcome (absent on estimates / early exits). */\n rigPage?: RigPageReport;\n hint?: string;\n}\n\n/** Run `rig push`; returns the process exit code. */\nexport async function runPush(args: string[], deps: PushDeps): Promise<number> {\n const { io } = deps;\n\n let flags: PushFlags;\n try {\n flags = parsePushArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PUSH_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(PUSH_USAGE);\n return 0;\n }\n // --standalone/--no-daemon: force embedded, bypassing any running daemon\n // (same as RIG_STANDALONE=1 for this one invocation).\n if (flags.standalone) deps = withForcedStandalone(deps);\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n // ── Repo + config resolution (rig init writes these) ────────────────────\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const reader = new GitRepoReader(repoRoot);\n\n // ── Remote-vs-refspec resolution (git-like: `rig push [remote] [refspecs…]`)\n // The first positional is the remote when it names a configured git\n // remote; with --relay the remotes are bypassed and every positional is\n // a refspec.\n let remoteName: string | undefined;\n let refspecArgs = flags.positionals;\n if (flags.relay.length === 0 && refspecArgs.length > 0) {\n const first = refspecArgs[0] as string;\n const remoteNames = new Set(\n (await listGitRemotes(repoRoot)).map((r) => r.name)\n );\n if (remoteNames.has(first)) {\n remoteName = first;\n refspecArgs = refspecArgs.slice(1);\n } else {\n // Not a remote, so it must be a refspec — distinguish a typo'd /\n // unconfigured remote from a bad refspec with one combined error.\n const { refs } = await reader.listRefs();\n const known = new Set(refs.map((r) => r.refname));\n if (\n !known.has(first) &&\n !known.has(`refs/heads/${first}`) &&\n !known.has(`refs/tags/${first}`)\n ) {\n throw new Error(\n `${JSON.stringify(first)} is neither a configured remote nor a ` +\n 'local branch/tag — add the relay remote ' +\n `(\\`rig remote add ${first} <relay-url>\\`; \\`rig remote list\\` ` +\n 'shows configured remotes) or fix the refspec'\n );\n }\n }\n }\n const refspecs = await selectRefspecs(\n reader,\n refspecArgs,\n flags.all,\n flags.tags,\n remoteName ?? 'origin'\n );\n\n // ── Relay resolution (#249: --relay > named remote > origin > toon.relay)\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) io.err(resolved.nudge);\n const relaysUsed = resolved.relays;\n // StandalonePublisher publishes to exactly one relay (its publishEvent\n // throws on >1). Multiple relays can arrive here without explicit intent\n // (repeated --relay flags, an old multi-valued git config `toon.relay`).\n // Refuse up front, before anything is fetched, uploaded, or paid.\n if (relaysUsed.length > 1) {\n io.err(singleRelayRefusal(resolved, 'Nothing was uploaded or paid.'));\n return 1;\n }\n\n // ── Paid session (#279): same-identity daemon → delegate; else the\n // standalone context (identity chain + nonce guard).\n const session = await loadPaidSession(deps, relaysUsed[0]);\n const path = session.path;\n let identity: IdentityReport;\n if (session.path === 'standalone') {\n standaloneCtx = session.ctx;\n identity = identityReport(standaloneCtx);\n } else {\n identity = session.identity;\n }\n\n if (toonConfig.owner && toonConfig.owner !== identity.pubkey) {\n io.err(\n `warning: git config toon.owner (${toonConfig.owner.slice(0, 8)}…) differs from ` +\n `the active identity (${identity.pubkey.slice(0, 8)}…) — this push publishes ` +\n \"under the ACTIVE identity's repo namespace, not the configured owner's. \" +\n 'Re-run `rig init` to adopt the active identity.'\n );\n }\n\n // ── Estimate ────────────────────────────────────────────────────────────\n // Standalone plans locally; the daemon path delegates the plan to\n // `POST /git/estimate` (same wire shape — ../routes.ts).\n let plan: GitEstimateResponse;\n let execute: () => Promise<GitPushResponse>;\n let pointerPlan: RigPointerPlan | undefined;\n let rigPageSkipDetail: string | undefined;\n if (session.path === 'standalone') {\n const ctx = session.ctx;\n const remoteState = await ctx.fetchRemote({\n ownerPubkey: ctx.ownerPubkey,\n repoId,\n relayUrls: relaysUsed,\n });\n const feeRates = await ctx.publisher.getFeeRates();\n const pushPlan = await planPush({\n repoReader: reader,\n remoteState,\n feeRates,\n repoId,\n refs: refspecs,\n force: flags.force,\n });\n plan = serializePushPlan(pushPlan);\n execute = async () =>\n serializePushResult(\n pushPlan,\n await executePush({\n plan: pushPlan,\n publisher: ctx.publisher,\n remoteState,\n repoReader: reader,\n relayUrls: relaysUsed,\n })\n );\n // ── Rig page (the repo's rig-web page) — planned BEFORE the\n // confirm gate so its fee is part of what the user approves.\n if (!flags.rigPage) {\n rigPageSkipDetail = 'skipped (--no-rig-page)';\n } else if (relaysUsed[0] === undefined) {\n rigPageSkipDetail = 'skipped (no relay resolved for the pointer)';\n } else if (!ctx.publisher.uploadBlob) {\n rigPageSkipDetail =\n 'skipped (the active publisher cannot upload raw blobs)';\n } else {\n pointerPlan = planRigPointer({\n env: deps.env,\n ownerPubkey: ctx.ownerPubkey,\n repoId,\n relay: relaysUsed[0],\n feeRates,\n });\n }\n } else {\n const client = session.client;\n plan = await client.gitEstimate({\n repoPath: repoRoot,\n repoId,\n refspecs,\n force: flags.force,\n relayUrls: relaysUsed,\n });\n execute = () =>\n client.gitPush({\n repoPath: repoRoot,\n repoId,\n refspecs,\n force: flags.force,\n relayUrls: relaysUsed,\n confirm: true,\n });\n // The delegated daemon owns the paid pipeline but exposes no raw-blob\n // upload route yet — the pointer refreshes on the next standalone push.\n rigPageSkipDetail =\n 'skipped on the daemon path (refreshes on the next standalone push)';\n }\n\n // ── Rig-page pointer publish (shared by the normal path and the\n // up-to-date refresh below; never fails a succeeded push) ────────────────\n const gateway = pointerGateway(deps.env);\n const publishPointer = async (\n pointer: RigPointerPlan\n ): Promise<RigPageReport> => {\n try {\n // Guarded at plan time: a plan only exists when uploadBlob is available.\n const ctx = standaloneCtx as StandaloneContext;\n const receipt = await (\n ctx.publisher.uploadBlob as NonNullable<\n typeof ctx.publisher.uploadBlob\n >\n )({\n body: Buffer.from(pointer.html, 'utf8'),\n contentType: 'text/html',\n repoId,\n });\n writeRigPointerRecord(deps.env, {\n repoId,\n owner: identity.pubkey,\n pointerTxId: receipt.txId,\n contentHash: pointer.contentHash,\n updatedAt: Date.now(),\n });\n return {\n status: 'published',\n txId: receipt.txId,\n url: `${gateway}/${receipt.txId}`,\n feePaid: receipt.feePaid.toString(),\n };\n } catch (err) {\n // The record was not updated, so the next push retries the upload.\n return {\n status: 'skipped',\n detail: `pointer upload failed (push itself succeeded; the next push retries): ${\n err instanceof Error ? err.message : String(err)\n }`,\n };\n }\n };\n const printRigPage = (rigPage: RigPageReport): void => {\n if (rigPage.url) {\n io.out(\n `Rig page: ${rigPage.url}` +\n (rigPage.status === 'published'\n ? ` paid ${rigPage.feePaid}`\n : '') +\n ' (renders this repo from Arweave)'\n );\n const mirrors = rigPage.txId ? mirrorGateways(gateway) : [];\n if (mirrors.length > 0 && rigPage.txId) {\n const txId = rigPage.txId;\n io.out(\n ' also: (same page — try these if the address above does ' +\n 'not load; gateways index fresh uploads at different speeds, ' +\n 'and any one of them can be down)'\n );\n for (const mirror of mirrors) {\n io.out(` ${mirror}/${txId}`);\n }\n }\n } else if (rigPage.detail) {\n io.err(`rig page: ${rigPage.detail}`);\n }\n };\n\n // ── Up-to-date short-circuit (never publish a no-op refs event) ─────────\n // A STALE Rig page still refreshes here: the pointer changes when the Rig\n // build / relay / gateway changes, not the refs — requiring a dummy\n // commit to roll it forward would be absurd.\n const upToDate = plan.refUpdates.every((u) => u.kind === 'up-to-date');\n if (upToDate) {\n if (pointerPlan?.action !== 'upload') {\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: true,\n plan,\n } satisfies PushJsonOutput);\n } else {\n io.out('Everything up-to-date — nothing to push (and nothing paid).');\n }\n return 0;\n }\n\n if (!flags.json) {\n io.out(\n 'Everything up-to-date — refs unchanged, but the Rig page is stale ' +\n '(new Rig build, relay, or gateway):'\n );\n io.out(` rig page ${pointerPlan.bytes} bytes ${pointerPlan.fee}`);\n io.out(renderIdentityLine(identity));\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: true,\n plan,\n hint: 'refs up-to-date; the Rig page is stale — re-run with --yes to refresh it (or --no-rig-page to skip)',\n } satisfies PushJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or --no-rig-page to skip the refresh)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Refresh the Rig page (total ${pointerPlan.fee} base units)? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was uploaded or published.');\n return 1;\n }\n }\n const rigPage = await publishPointer(pointerPlan);\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: true,\n plan,\n rigPage,\n } satisfies PushJsonOutput);\n } else {\n printRigPage(rigPage);\n }\n return 0;\n }\n\n // ── Confirm gate ────────────────────────────────────────────────────────\n // The confirmed total covers the push plan PLUS a (new/changed) Rig\n // pointer; an unchanged pointer is free and printed as such.\n const confirmTotal =\n BigInt(plan.estimate.totalFee) + (pointerPlan?.fee ?? 0n);\n if (!flags.json) {\n for (const line of renderPlan(plan)) io.out(line);\n if (pointerPlan?.action === 'upload') {\n io.out(\n ` rig page ${pointerPlan.bytes} bytes ${pointerPlan.fee}` +\n ` (repo page — paid once, reused until relay/rig-web changes)`\n );\n io.out(` total with rig page ${confirmTotal}`);\n }\n io.out(renderIdentityLine(identity));\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: false,\n upToDate: false,\n plan,\n hint: 'estimate only — re-run with --yes to upload and publish (permanent, non-refundable)',\n } satisfies PushJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid push (total ${confirmTotal} base units)? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was uploaded or published.');\n return 1;\n }\n }\n\n // ── Execute ─────────────────────────────────────────────────────────────\n const result = await execute();\n\n // ── Rig-page pointer (after the push succeeded; never fails it) ─────────\n let rigPage: RigPageReport;\n if (!pointerPlan) {\n rigPage = {\n status: 'skipped',\n ...(rigPageSkipDetail ? { detail: rigPageSkipDetail } : {}),\n };\n } else if (pointerPlan.action === 'unchanged') {\n rigPage = {\n status: 'unchanged',\n txId: pointerPlan.recordedTxId as string,\n url: `${gateway}/${pointerPlan.recordedTxId}`,\n };\n } else {\n rigPage = await publishPointer(pointerPlan);\n }\n\n // ── Receipts ────────────────────────────────────────────────────────────\n if (flags.json) {\n io.emitJson({\n command: 'push',\n repoId,\n path,\n identity,\n executed: true,\n upToDate: false,\n plan,\n result,\n rigPage,\n } satisfies PushJsonOutput);\n } else {\n for (const line of renderResult(result)) io.out(line);\n printRigPage(rigPage);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'push', err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * Per-repo Rig pointer — the permanent Arweave page that RENDERS a pushed\n * repo in place, deployed by `rig push` the way GitHub Pages tracks a repo.\n * User-facing name: the repo's \"Rig page\".\n *\n * The pointer boots the FULL React Rig from its Arweave deployment: it pins\n * `window.__RIG_CONFIG__ = {relay, owner, repo}`, presets the HashRouter\n * route in its own URL fragment, and loads rig-web's entry css/js from the\n * deployment's path manifest (`rig-web/scripts/deploy-arweave.mjs` — every\n * build output uploaded GZIPPED under ArDrive Turbo's free tier with a\n * `Content-Encoding` tag the gateways serve as a header, so the whole app\n * fits without a funded wallet). Module-relative imports resolve against the\n * MODULE's URL, so the entire chunk graph loads from the manifest while the\n * address bar stays on the pointer.\n *\n * A `<noscript>`/delayed fallback links to the Pages deployment\n * ({@link DEFAULT_RIG_WEB_URL}). The earlier single-file rig-lite build\n * (`rig-web/lite/rig-lite.js`) remains in-tree as the ultra-light option.\n *\n * The generated HTML is DETERMINISTIC for a given (bundle, gateway,\n * rigWebUrl, relay, owner, repoId) so `rig push` can content-address it:\n * the pointer uploads once and every later push skips the fee until one of\n * those inputs changes (../cli/rig-pointer-record.ts).\n */\n\n/** One released Arweave deployment of rig-web (manifest + entry assets). */\nexport interface RigWebBundle {\n /** The ar.io path-manifest txId (`https://<gateway>/<tx>/` serves the app). */\n manifestTx: string;\n /** Entry module path inside the manifest (hashed per build). */\n entryJs: string;\n /** Entry stylesheet path inside the manifest (hashed per build). */\n entryCss: string;\n}\n\n/**\n * The current rig-web deployment on Arweave (deployed 2026-07-17 via\n * `deploy-arweave.mjs`, 122 files, free tier). Override per-field with\n * `RIG_WEB_TX` / `RIG_WEB_ENTRY_JS` / `RIG_WEB_ENTRY_CSS`.\n */\nexport const DEFAULT_RIG_WEB_BUNDLE: RigWebBundle = {\n manifestTx: 'Iy8sHYVnoevSpwDC2lqUoIg8BWdes9NmMbgmPd81UpU',\n entryJs: 'assets/index-BuKzYubR.js',\n entryCss: 'assets/index-H5D6cmfa.css',\n};\n\n/** Env vars overriding the bundle (e.g. a newer deploy before release). */\nexport const RIG_WEB_TX_ENV = 'RIG_WEB_TX';\nexport const RIG_WEB_ENTRY_JS_ENV = 'RIG_WEB_ENTRY_JS';\nexport const RIG_WEB_ENTRY_CSS_ENV = 'RIG_WEB_ENTRY_CSS';\n\n/**\n * Gateway the pointer loads the rig-web BUNDLE from. Tied to where the\n * bundle deploy lives (mainnet, via Turbo), NOT to where `rig push`\n * uploads repo data: the assets are stored GZIPPED with a\n * `Content-Encoding` tag that `arweave.net` serves as a real header —\n * `ar-io.dev` drops it and ships raw gzip bytes, which the browser then\n * fails to parse (\"Invalid or unexpected token\", blank page). Override\n * with `RIG_WEB_GATEWAY` alongside a bundle override.\n */\nexport const DEFAULT_RIG_WEB_GATEWAY = 'https://arweave.net';\n\n/** Env var overriding the bundle gateway. */\nexport const RIG_WEB_GATEWAY_ENV = 'RIG_WEB_GATEWAY';\n\n/** Pages deployment for the no-JS / delayed fallback link (tracks main). */\nexport const DEFAULT_RIG_WEB_URL = 'https://toon-protocol.github.io/rig';\n\n/** Env var overriding the fallback URL. */\nexport const RIG_WEB_URL_ENV = 'RIG_WEB_URL';\n\nexport interface RigPointerOptions {\n /** The Arweave rig-web deployment the pointer boots. */\n bundle: RigWebBundle;\n /** Gateway base the app loads from (no trailing /). */\n gateway: string;\n /** Fallback rig-web deployment for the no-JS link (no trailing /). */\n rigWebUrl: string;\n /** Relay the Rig should read the repo from (`wss://…`). */\n relay: string;\n /** Repo owner as npub (rig-web routes are `#/<npub>/<repo>`). */\n ownerNpub: string;\n /** Repository id (NIP-34 d-tag). */\n repoId: string;\n}\n\n/** The repo's HashRouter fragment, with the relay threaded through. */\nexport function repoHashRoute(\n options: Pick<RigPointerOptions, 'relay' | 'ownerNpub' | 'repoId'>\n): string {\n const { relay, ownerNpub, repoId } = options;\n // Route + query INSIDE the fragment — rig-web's relay resolution reads\n // `[?&]relay=` from the fragment (rig-web/README.md \"Relay resolution\n // order\"), so this works on any static host with no rewrites.\n return `#/${encodeURIComponent(ownerNpub)}/${encodeURIComponent(repoId)}?relay=${encodeURIComponent(relay)}`;\n}\n\n/** The full-Rig fallback URL for a repo (Pages deployment). */\nexport function rigWebRoute(\n options: Pick<RigPointerOptions, 'rigWebUrl' | 'relay' | 'ownerNpub' | 'repoId'>\n): string {\n return `${options.rigWebUrl.replace(/\\/+$/, '')}/${repoHashRoute(options)}`;\n}\n\n/** Escape a string for safe embedding in an HTML attribute/text position. */\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/**\n * Generate the pointer HTML: the full-Rig boot-in-place shell. Loads only\n * the immutable Arweave deployment it exists to boot; degrades to a\n * fallback link with JS disabled.\n */\nexport function generateRigPointerHtml(options: RigPointerOptions): string {\n const gateway = options.gateway.replace(/\\/+$/, '');\n const base = `${gateway}/${options.bundle.manifestTx}`;\n const cssHref = `${base}/${options.bundle.entryCss}`;\n const jsSrc = `${base}/${options.bundle.entryJs}`;\n const fallback = rigWebRoute(options);\n const safeFallback = escapeHtml(fallback);\n const title = escapeHtml(`${options.repoId} — Rig`);\n\n // Escape `<` so hostile config values can never break out of the script.\n const config = JSON.stringify({\n relay: options.relay,\n owner: options.ownerNpub,\n repo: options.repoId,\n }).replace(/</g, '\\\\u003c');\n const hashRoute = JSON.stringify(repoHashRoute(options)).replace(\n /</g,\n '\\\\u003c'\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\"><head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n <meta name=\"description\" content=\"Decentralized Git on Nostr &amp; TOON Protocol\">\n <title>${title}</title>\n <link rel=\"icon\" href=\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>&#x2692;</text></svg>\">\n <script>window.__RIG_CONFIG__=${config};if(!location.hash||location.hash===\"#\")location.replace(${hashRoute})</script>\n <link rel=\"stylesheet\" href=\"${escapeHtml(cssHref)}\">\n <script type=\"module\" crossorigin src=\"${escapeHtml(jsSrc)}\"></script>\n</head><body>\n <div id=\"app\"></div>\n <noscript><p>JavaScript is off — open <a href=\"${safeFallback}\">${title}</a> in the hosted Rig.</p></noscript>\n <p hidden data-fallback>If nothing loads, open <a href=\"${safeFallback}\">${title}</a> in the hosted Rig.</p>\n <script>setTimeout(function(){var p=document.querySelector(\"[data-fallback]\");var app=document.getElementById(\"app\");if(p&&(!app||!app.childElementCount))p.hidden=false},8000)</script>\n</body></html>\n`;\n}\n","/**\n * Which Arweave gateway rig PRINTS.\n *\n * Fetches try every gateway in `@toon-protocol/arweave`'s shared list, so the\n * order there only matters for redundancy. A printed URL is different: it is\n * the one link a reader clicks. `ar-io.dev` heads the shared list but is\n * ar.io's TESTNET gateway — its ArNS resolver runs against the Solana devnet\n * contracts and it serves testnet-bundler uploads that never reach Arweave —\n * so a mainnet upload printed there is a guaranteed 404 (toon-client#577\n * reorders the shared list). Until then rig prefers the first MAINNET gateway\n * of that list and never prints the testnet one as the primary.\n */\n\nimport { ARWEAVE_GATEWAYS } from '@toon-protocol/arweave';\n\nconst TESTNET_GATEWAY = /(^|\\.)ar-io\\.dev$/i;\n\n/** Every gateway that is not ar.io's testnet. Malformed URLs are not gateways. */\nexport function isMainnetGateway(url: string): boolean {\n try {\n return !TESTNET_GATEWAY.test(new URL(url).hostname);\n } catch {\n return false;\n }\n}\n\n/** The gateway a printed URL defaults to: the shared list's first mainnet one. */\nexport const PREFERRED_GATEWAY: string =\n ARWEAVE_GATEWAYS.find(isMainnetGateway) ?? 'https://arweave.net';\n\n/** The shared list minus one gateway, for \"also at\" mirrors under a primary. */\nexport function mirrorGatewaysFor(primary: string): string[] {\n const p = primary.replace(/\\/+$/, '');\n return ARWEAVE_GATEWAYS.filter((g) => g.replace(/\\/+$/, '') !== p);\n}\n","/**\n * Local record of the last-published Rig pointer per repo — what lets\n * `rig push` keep the per-repo Rig page (../rig-pointer.ts) current like\n * GitHub Pages WITHOUT re-paying on every push.\n *\n * The pointer HTML is deterministic for (rigWebUrl, relay, owner, repoId),\n * so its sha-256 is recorded alongside the uploaded txId: while the hash\n * matches, later pushes reuse the recorded URL for free; when any input\n * changes (relay moved, rig-web base flipped to the Arweave bundle), the\n * next push uploads a fresh pointer and the record rolls forward.\n *\n * Same storage conventions as ./site-record.ts: a JSON file under\n * `TOON_CLIENT_HOME` (default `~/.toon-client`), keyed by repoId (local,\n * single-user scope); corrupt/missing files are treated as empty for reads\n * and overwritten on write.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const RIG_POINTER_FILENAME = 'rig-pointers.json';\n\n/** One recorded Rig-pointer publish. */\nexport interface RigPointerRecord {\n repoId: string;\n /** Owner pubkey (hex) the pointer was published under. */\n owner: string;\n /** The pointer transaction id (43-char base64url). */\n pointerTxId: string;\n /** sha-256 (hex) of the pointer HTML that was uploaded. */\n contentHash: string;\n /** Unix milliseconds of the publish. */\n updatedAt: number;\n}\n\ntype RigPointerFile = Record<string, RigPointerRecord>;\n\nfunction storeDir(env: NodeJS.ProcessEnv): string {\n return env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n}\n\nfunction storePath(env: NodeJS.ProcessEnv): string {\n return join(storeDir(env), RIG_POINTER_FILENAME);\n}\n\nfunction readAll(env: NodeJS.ProcessEnv): RigPointerFile {\n try {\n const parsed = JSON.parse(readFileSync(storePath(env), 'utf8')) as unknown;\n if (parsed && typeof parsed === 'object') return parsed as RigPointerFile;\n return {};\n } catch {\n // Missing or corrupt → empty (never fatal to a push).\n return {};\n }\n}\n\n/** The recorded pointer for a repo, if any. */\nexport function readRigPointerRecord(\n env: NodeJS.ProcessEnv,\n repoId: string\n): RigPointerRecord | undefined {\n return readAll(env)[repoId];\n}\n\n/** Record a pointer publish (overwrites the repo's previous record). */\nexport function writeRigPointerRecord(\n env: NodeJS.ProcessEnv,\n record: RigPointerRecord\n): void {\n const all = readAll(env);\n all[record.repoId] = record;\n mkdirSync(storeDir(env), { recursive: true });\n writeFileSync(storePath(env), `${JSON.stringify(all, null, 2)}\\n`);\n}\n","/**\n * Human-facing rendering for `rig push`: the pre-push confirm table and the\n * post-push receipts. Machine consumers use `--json` instead (the raw wire\n * shapes from ../routes.ts) — nothing here is meant to be parsed.\n */\n\nimport type {\n GitEstimateResponse,\n GitEventResponse,\n GitPushResponse,\n GitRefUpdate,\n GitRepoAddr,\n} from '../routes.js';\n\n/** Group thousands for readability: 1234567 → '1,234,567'. */\nexport function formatNumber(value: number | string | bigint): string {\n return String(value).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction shortSha(sha: string | null): string {\n return sha ? sha.slice(0, 7) : '(none)';\n}\n\nfunction refLine(update: GitRefUpdate): string {\n const arrow = `${shortSha(update.remoteSha)} → ${shortSha(update.localSha)}`;\n return ` ${update.refname} ${arrow} (${update.kind})`;\n}\n\n/**\n * One-line identity report: derived pubkey + which chain tier supplied the\n * mnemonic (never the phrase itself).\n */\nexport function renderIdentityLine(identity: {\n pubkey: string;\n sourceLabel: string;\n}): string {\n return `Identity: ${identity.pubkey} (from ${identity.sourceLabel})`;\n}\n\n/** The pre-push confirm table (refs, objects, itemized fees, warning). */\nexport function renderPlan(plan: GitEstimateResponse): string[] {\n const lines: string[] = [];\n lines.push(\n `Push plan for repo \"${plan.repoId}\"` +\n (plan.announceNeeded ? ' — first push, will announce (kind:30617)' : '')\n );\n lines.push('Refs:');\n for (const update of plan.refUpdates) lines.push(refLine(update));\n\n const est = plan.estimate;\n const skipped = Object.keys(plan.knownShaToTxId).length;\n const emptySkipped = est.skippedEmptyCount ?? 0;\n lines.push(\n `Objects: ${est.objectCount} to upload` +\n ` (${formatNumber(est.totalObjectBytes)} bytes)` +\n (skipped > 0 ? `; ${skipped} already on Arweave (free)` : '') +\n (emptySkipped > 0\n ? `; ${emptySkipped} empty blob${emptySkipped === 1 ? '' : 's'} skipped ` +\n '(reconstructed on clone)'\n : '')\n );\n lines.push('Fees (base units):');\n lines.push(\n ` upload ${est.objectCount} object(s), ${formatNumber(est.totalObjectBytes)} bytes` +\n ` ${formatNumber(est.uploadFee)}`\n );\n lines.push(` events ${est.eventCount} event(s) ${formatNumber(est.eventFees)}`);\n lines.push(` total ${formatNumber(est.totalFee)}`);\n lines.push('Writes are permanent and non-refundable.');\n return lines;\n}\n\n/** Human label for a per-event fee that may be unknown (older daemons). */\nexport function feeLabel(fee: string | undefined): string {\n return fee !== undefined\n ? `${formatNumber(fee)} base units`\n : \"the publisher's configured per-event fee\";\n}\n\n/**\n * Pre-publish summary for the single-event subcommands\n * (issue/comment/pr/status): what is published, against which repo address,\n * at what fee — the confirm gate follows these lines.\n */\nexport function renderEventPlan(opts: {\n /** e.g. `issue \"Fix the flux\" (kind:1621)`. */\n action: string;\n addr: GitRepoAddr;\n /** Active identity (source + derived pubkey). */\n identity: { pubkey: string; sourceLabel: string };\n /** Per-event fee (base units, decimal string), when known. */\n fee?: string;\n}): string[] {\n return [\n `Publish ${opts.action}`,\n `Repo: 30617:${opts.addr.ownerPubkey}:${opts.addr.repoId}`,\n renderIdentityLine(opts.identity),\n `Fee: ${feeLabel(opts.fee)}. Writes are permanent and non-refundable.`,\n ];\n}\n\n/** Receipt line for one published single-event git write. */\nexport function renderEventReceipt(\n action: string,\n result: GitEventResponse\n): string[] {\n const lines = [\n `Published ${action}: ${result.eventId} paid ${formatNumber(result.feePaid)} base units`,\n ];\n if (result.channelBalanceAfter !== undefined) {\n lines.push(\n `Channel balance after: ${formatNumber(result.channelBalanceAfter)} base units`\n );\n }\n return lines;\n}\n\n/** Post-push receipts: per-object skipped/paid, event ids, paid-vs-estimate. */\nexport function renderResult(result: GitPushResponse): string[] {\n const lines: string[] = [];\n lines.push(`Pushed \"${result.repoId}\":`);\n const paid = result.uploads.filter((u) => !u.skipped);\n const skipped = result.uploads.filter((u) => u.skipped);\n for (const upload of result.uploads) {\n lines.push(\n ` object ${upload.sha.slice(0, 12)} ${upload.skipped ? 'skipped (already stored)' : `paid ${formatNumber(upload.feePaid)}`}` +\n ` ar:${upload.txId}`\n );\n }\n lines.push(\n `Uploads: ${paid.length} paid, ${skipped.length} skipped (content-addressed).`\n );\n const emptySkipped = result.estimate.skippedEmptyCount ?? 0;\n if (emptySkipped > 0) {\n lines.push(\n `Empty blobs: ${emptySkipped} skipped (zero-byte, not uploaded — ` +\n 'reconstructed on clone).'\n );\n }\n if (result.announceReceipt) {\n lines.push(\n `Announcement (kind:30617): ${result.announceReceipt.eventId}` +\n ` paid ${formatNumber(result.announceReceipt.feePaid)}`\n );\n }\n lines.push(\n `Refs event (kind:30618): ${result.refsReceipt.eventId}` +\n ` paid ${formatNumber(result.refsReceipt.feePaid)}`\n );\n lines.push(\n `Total paid: ${formatNumber(result.totalFeePaid)} base units` +\n ` (estimate was ${formatNumber(result.estimate.totalFee)})`\n );\n return lines;\n}\n","/**\n * Repo-local `rig` configuration, persisted in git's own storage:\n *\n * toon.repoid NIP-34 repository identifier (`d` tag)\n * toon.owner repository owner's Nostr pubkey (hex) — the identity that\n * signs kind:30617/30618 (`a`-tag `30617:<owner>:<repoId>`)\n * toon.relay relay URL(s), multi-valued — DEPRECATED since #249 (relays\n * live in real git remotes now; the key stays readable as a\n * fallback and is removed in v0.3)\n *\n * plus the REAL git remotes (`remote.<name>.url`) that #249 maps relays onto:\n * `rig remote add origin <relay-url>` is `git remote add`, so `git remote -v`\n * shows rig's relays and plain git tooling round-trips them.\n *\n * All access goes through `execFile git` with argument arrays (same\n * injection posture as GitRepoReader — never a shell).\n */\n\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\n/** The rig-relevant git config keys of one repository. */\nexport interface ToonRepoConfig {\n repoId?: string;\n owner?: string;\n relays: string[];\n}\n\nasync function git(\n repoPath: string,\n args: string[],\n allowExitCodes: number[] = []\n): Promise<{ stdout: string; exitCode: number }> {\n try {\n const { stdout } = await execFileAsync('git', args, {\n cwd: repoPath,\n encoding: 'utf-8',\n });\n return { stdout, exitCode: 0 };\n } catch (err) {\n const e = err as NodeJS.ErrnoException & {\n code?: number | string;\n stdout?: string;\n stderr?: string;\n };\n const exitCode = typeof e.code === 'number' ? e.code : undefined;\n if (exitCode !== undefined && allowExitCodes.includes(exitCode)) {\n return { stdout: e.stdout ?? '', exitCode };\n }\n throw new Error(\n `git ${args.join(' ')} failed${exitCode !== undefined ? ` (exit ${exitCode})` : ''}: ` +\n `${(e.stderr ?? e.message ?? '').trim()}`\n );\n }\n}\n\n/**\n * Resolve the repository worktree root for `cwd` via\n * `git rev-parse --show-toplevel`. Throws a clear error when `cwd` is not\n * inside a git repository.\n */\nexport async function resolveRepoRoot(cwd: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['rev-parse', '--show-toplevel'],\n { cwd, encoding: 'utf-8' }\n );\n const root = stdout.trim();\n if (!root) throw new Error('empty rev-parse output');\n return root;\n } catch (err) {\n const e = err as { stderr?: string; message?: string };\n throw new Error(\n `not a git repository (run rig inside a repo): ${(e.stderr ?? e.message ?? '').trim()}`\n );\n }\n}\n\n/**\n * `git init` in `dir` — create a fresh repository there (never a shell). Runs\n * ONLY in `dir` itself, never a parent, and is idempotent (git init on an\n * existing repo is a no-op). Used by `rig init` when it offers to create the\n * repo for the user (consent-gated), mirroring how it offers to mint an\n * identity on a cold start.\n *\n * The initial branch is forced to `main`, deterministically — a stock git\n * without `init.defaultBranch=main` would otherwise create `master`, and every\n * rig doc/quickstart says `main` (so `rig push origin main` / `rig checkout\n * main` would then fail against a repo whose only branch is `master`). git\n * ≥ 2.28 takes `--initial-branch=main`; older git falls back to pointing the\n * unborn HEAD at `refs/heads/main` (no commits yet, so this just renames the\n * pending branch).\n */\nexport async function initGitRepository(dir: string): Promise<void> {\n try {\n await git(dir, ['init', '--initial-branch=main']);\n } catch {\n await git(dir, ['init']);\n await git(dir, ['symbolic-ref', 'HEAD', 'refs/heads/main']);\n }\n}\n\n/** Read the `toon.*` git config keys of the repository at `repoPath`. */\nexport async function readToonConfig(repoPath: string): Promise<ToonRepoConfig> {\n // exit 1 = key unset (git config --get convention) — tolerated everywhere.\n const [repoId, owner, relays] = await Promise.all([\n git(repoPath, ['config', '--get', 'toon.repoid'], [1]),\n git(repoPath, ['config', '--get', 'toon.owner'], [1]),\n git(repoPath, ['config', '--get-all', 'toon.relay'], [1]),\n ]);\n const config: ToonRepoConfig = {\n relays: relays.stdout\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean),\n };\n const id = repoId.stdout.trim();\n if (repoId.exitCode === 0 && id) config.repoId = id;\n const own = owner.stdout.trim();\n if (owner.exitCode === 0 && own) config.owner = own;\n return config;\n}\n\n/** One configured git remote: its name + (possibly multiple) fetch URLs. */\nexport interface GitRemoteInfo {\n name: string;\n urls: string[];\n}\n\n/**\n * URLs of the git remote `name` (`remote.<name>.url`, multi-valued when\n * `git remote set-url --add` was used). `[]` when the remote does not exist.\n */\nexport async function getGitRemoteUrls(\n repoPath: string,\n name: string\n): Promise<string[]> {\n // exit 1 = key unset / invalid key — either way, no such remote.\n const { stdout } = await git(\n repoPath,\n ['config', '--get-all', `remote.${name}.url`],\n [1]\n );\n return stdout\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n}\n\n/** All configured git remotes with their URLs (`git remote -v` data). */\nexport async function listGitRemotes(\n repoPath: string\n): Promise<GitRemoteInfo[]> {\n const { stdout } = await git(repoPath, ['remote']);\n const names = stdout\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n const remotes: GitRemoteInfo[] = [];\n for (const name of names) {\n remotes.push({ name, urls: await getGitRemoteUrls(repoPath, name) });\n }\n return remotes;\n}\n\n/** The repo-local git author identity (`user.name` + `user.email`). */\nexport interface GitAuthorConfig {\n name?: string;\n email?: string;\n}\n\n/**\n * Read the repository's LOCAL `user.name` / `user.email` (never `--global`).\n * A `--local --get` miss is exit 1 (tolerated) and yields `undefined` — so\n * this reports only what THIS repo overrides, not any inherited global value.\n */\nexport async function readGitAuthor(\n repoPath: string\n): Promise<GitAuthorConfig> {\n const [name, email] = await Promise.all([\n git(repoPath, ['config', '--local', '--get', 'user.name'], [1]),\n git(repoPath, ['config', '--local', '--get', 'user.email'], [1]),\n ]);\n const config: GitAuthorConfig = {};\n const n = name.stdout.trim();\n if (name.exitCode === 0 && n) config.name = n;\n const e = email.stdout.trim();\n if (email.exitCode === 0 && e) config.email = e;\n return config;\n}\n\n/**\n * Set the repository's LOCAL git author identity — `git config --local`, so it\n * overrides any global `user.name`/`user.email` FOR THIS REPO ONLY and never\n * touches `~/.gitconfig`. On a rig repo the nostr key is the identity, so the\n * commit author == push signer == nostr identity (a coherent authorship chain\n * baked into the git objects on Arweave).\n */\nexport async function setGitAuthor(\n repoPath: string,\n author: { name: string; email: string }\n): Promise<void> {\n await git(repoPath, ['config', '--local', 'user.name', author.name]);\n await git(repoPath, ['config', '--local', 'user.email', author.email]);\n}\n\n/** `git remote add <name> <url>` — real git remote storage, never a shell. */\nexport async function addGitRemote(\n repoPath: string,\n name: string,\n url: string\n): Promise<void> {\n await git(repoPath, ['remote', 'add', name, url]);\n}\n\n/** `git remote remove <name>`. */\nexport async function removeGitRemote(\n repoPath: string,\n name: string\n): Promise<void> {\n await git(repoPath, ['remote', 'remove', name]);\n}\n\n/**\n * Persist the `toon.*` keys (repo-local config). Only supplied fields are\n * written; `relays` replaces the whole multi-valued list.\n */\nexport async function writeToonConfig(\n repoPath: string,\n config: { repoId?: string; owner?: string; relays?: string[] }\n): Promise<void> {\n if (config.repoId !== undefined) {\n await git(repoPath, ['config', 'toon.repoid', config.repoId]);\n }\n if (config.owner !== undefined) {\n await git(repoPath, ['config', 'toon.owner', config.owner]);\n }\n if (config.relays !== undefined && config.relays.length > 0) {\n // Replace the whole list: unset-all (exit 5 = key did not exist) + re-add.\n await git(repoPath, ['config', '--unset-all', 'toon.relay'], [5]);\n for (const relay of config.relays) {\n await git(repoPath, ['config', '--add', 'toon.relay', relay]);\n }\n }\n}\n","/**\n * Relays as origins (#249): the `rig remote` subcommand and the relay\n * resolution every paid command shares.\n *\n * Remotes are stored as REAL git remotes (`git remote add/remove` under the\n * hood), so `git remote -v` shows them and plain git tooling round-trips the\n * config — no parallel store. Paid commands resolve their relay as:\n *\n * 1. `--relay <url>` ad-hoc override, bypasses remotes\n * 2. a named remote `rig push <remote>` / `--remote <name>`\n * 3. the `origin` remote the default target\n * 4. git config `toon.relay` DEPRECATED v0.1 fallback (one-line nudge;\n * the key is removed in v0.3)\n * 5. error \"no origin configured — run `rig remote\n * add origin <relay-url>`\"\n *\n * A remote with multiple URLs (`git remote set-url --add` done by hand) is\n * refused BEFORE anything is fetched, uploaded, or paid: rig publishes to\n * exactly one relay per paid command (the #243 single-relay guard). One\n * carve-out: a default `origin` whose URLs are ALL non-relay is a plain git\n * remote — it is skipped like any single non-relay origin, never refused.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n emitCliError,\n InvalidRelayUrlError,\n MultiUrlRemoteError,\n NoOriginConfiguredError,\n NotAGitRepositoryError,\n UnknownRemoteError,\n} from './errors.js';\nimport {\n addGitRemote,\n getGitRemoteUrls,\n listGitRemotes,\n readToonConfig,\n removeGitRemote,\n resolveRepoRoot,\n} from './git-config.js';\nimport type { CliIo } from './push.js';\n\n// ---------------------------------------------------------------------------\n// Relay URL validation\n// ---------------------------------------------------------------------------\n\nconst RELAY_PROTOCOLS = new Set(['ws:', 'wss:', 'http:', 'https:']);\n\n/** True when `url` parses and uses a relay scheme (ws/wss/http/https). */\nexport function isRelayUrl(url: string): boolean {\n try {\n return RELAY_PROTOCOLS.has(new URL(url).protocol);\n } catch {\n return false;\n }\n}\n\n/** Throw {@link InvalidRelayUrlError} unless `url` is a relay URL. */\nexport function assertRelayUrl(url: string, context: string): void {\n if (!isRelayUrl(url)) throw new InvalidRelayUrlError(url, context);\n}\n\n// ---------------------------------------------------------------------------\n// Relay resolution (shared by push + the event commands)\n// ---------------------------------------------------------------------------\n\n/** Where the resolved relay came from. */\nexport type RelaySource = 'relay-flag' | 'remote' | 'toon.relay';\n\nexport interface ResolvedRelays {\n /** Relay URLs to publish to (paid commands still enforce exactly one). */\n relays: string[];\n source: RelaySource;\n /** The git remote that supplied the URL (source === 'remote'). */\n remoteName?: string;\n /** One-line stderr note (toon.relay deprecation), when applicable. */\n nudge?: string;\n}\n\nexport interface ResolveRelaysOptions {\n /** `--relay` flag values (may be >1 — the command-level guard refuses). */\n relayFlags: string[];\n /** Explicitly requested remote (`rig push <remote>` / `--remote <name>`). */\n remoteName?: string | undefined;\n /** Repo worktree root; undefined when not inside a git repository. */\n repoRoot?: string | undefined;\n /** Deprecated `git config toon.relay` values (v0.1 fallback). */\n toonRelays: string[];\n}\n\n/**\n * Resolve the relay(s) for a paid command. Throws (before any payment):\n * {@link UnknownRemoteError}, {@link MultiUrlRemoteError},\n * {@link InvalidRelayUrlError}, {@link NoOriginConfiguredError}.\n */\nexport async function resolveRelays(\n opts: ResolveRelaysOptions\n): Promise<ResolvedRelays> {\n // 1. Ad-hoc --relay override: bypasses the configured remotes entirely.\n if (opts.relayFlags.length > 0) {\n return { relays: opts.relayFlags, source: 'relay-flag' };\n }\n\n // 2. Explicitly named remote: must exist, carry ONE URL, and be a relay.\n if (opts.remoteName !== undefined) {\n const urls =\n opts.repoRoot !== undefined\n ? await getGitRemoteUrls(opts.repoRoot, opts.remoteName)\n : [];\n if (urls.length === 0) throw new UnknownRemoteError(opts.remoteName);\n if (urls.length > 1) throw new MultiUrlRemoteError(opts.remoteName, urls);\n const url = urls[0] as string;\n assertRelayUrl(url, `remote ${JSON.stringify(opts.remoteName)}`);\n return { relays: urls, source: 'remote', remoteName: opts.remoteName };\n }\n\n // 3. Default remote: origin — when it looks like a relay. A PURELY\n // non-relay origin (e.g. a GitHub clone URL, even one with several\n // mirror push URLs) is skipped, not an error: rig shares git's remote\n // namespace, so pre-existing git origins must not break paid commands\n // that can still resolve via toon.relay. But the moment ANY of a\n // multi-URL origin's URLs is relay-shaped, the publish target is\n // ambiguous — refuse before anything is fetched, uploaded, or paid\n // (the #243 single-relay guard).\n let nonRelayOriginUrl: string | undefined;\n if (opts.repoRoot !== undefined) {\n const urls = await getGitRemoteUrls(opts.repoRoot, 'origin');\n if (urls.length === 1 && isRelayUrl(urls[0] as string)) {\n return { relays: urls, source: 'remote', remoteName: 'origin' };\n }\n if (urls.length > 1 && urls.some(isRelayUrl)) {\n throw new MultiUrlRemoteError('origin', urls);\n }\n // Reachable only when every remaining URL is non-relay (single relay URL\n // returned above; multi-URL with any relay URL threw above), so urls[0]\n // is guaranteed non-relay — NoOriginConfiguredError's message relies on\n // that (\"the existing origin is not a relay URL\").\n if (urls.length > 0) nonRelayOriginUrl = urls[0] as string;\n }\n\n // 4. Deprecated v0.1 fallback: git config toon.relay (nudges to migrate).\n if (opts.toonRelays.length > 0) {\n return {\n relays: opts.toonRelays,\n source: 'toon.relay',\n nudge:\n 'note: git config toon.relay is deprecated (removed in v0.3) — ' +\n `migrate: rig remote add origin ${opts.toonRelays[0]}`,\n };\n }\n\n // 5. Nothing resolved.\n throw new NoOriginConfiguredError(nonRelayOriginUrl);\n}\n\n/**\n * Refusal line for >1 resolved relays: the StandalonePublisher publishes to\n * exactly one relay per paid command, and multiple can arrive without\n * explicit intent (repeated --relay flags, a multi-valued toon.relay).\n * `nothingHappened` names what was NOT done, e.g. 'Nothing was uploaded or\n * paid.'\n */\nexport function singleRelayRefusal(\n resolved: ResolvedRelays,\n nothingHappened: string\n): string {\n const fix =\n resolved.source === 'relay-flag'\n ? 'pass exactly one --relay <url>'\n : 'trim git config toon.relay to one URL (better: migrate — ' +\n '`rig remote add origin <relay-url>`)';\n return (\n `rig publishes to a single relay, but ${resolved.relays.length} are ` +\n `configured (${resolved.relays.join(', ')}) — ${fix}. ${nothingHappened}`\n );\n}\n\n// ---------------------------------------------------------------------------\n// rig remote <add|remove|list>\n// ---------------------------------------------------------------------------\n\nexport const REMOTE_USAGE = `Usage: rig remote <add|remove|list> [args] [options]\n\nManage the relays this repo publishes to. Remotes are stored as REAL git\nremotes (\\`git remote -v\\` shows them; plain git tooling round-trips). Paid\ncommands publish via the \"origin\" remote by default; \\`rig push <remote>\\`\nand \\`--remote <name>\\` target another one. Free — nothing is published or\npaid.\n\nCommands:\n add <name> <relay-url> add a remote pointing at a relay (the URL must be\n ws://, wss://, http://, or https://)\n remove <name> remove a remote\n list list remote names + URLs (the default subcommand)\n\nOptions:\n --json machine-readable envelope (all subcommands)\n -h, --help show this help`;\n\n/** Deps subset `rig remote` needs (free — no publisher, no identity). */\nexport interface RemoteDeps {\n io: CliIo;\n cwd: string;\n}\n\n/** Run `rig remote …`; returns the process exit code. */\nexport async function runRemote(\n args: string[],\n deps: RemoteDeps\n): Promise<number> {\n const { io } = deps;\n\n let sub: string | undefined;\n let rest: string[];\n let json: boolean;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) {\n io.out(REMOTE_USAGE);\n return 0;\n }\n json = values.json ?? false;\n [sub, ...rest] = positionals;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(REMOTE_USAGE);\n return 2;\n }\n\n // Argument-shape validation (exit 2) before touching the repository.\n switch (sub) {\n case undefined:\n case 'list':\n if (rest.length > 0) {\n io.err(`rig remote list takes no arguments (got ${rest.join(' ')})`);\n io.err(REMOTE_USAGE);\n return 2;\n }\n break;\n case 'add': {\n if (rest.length !== 2) {\n io.err('usage: rig remote add <name> <relay-url>');\n io.err(REMOTE_USAGE);\n return 2;\n }\n const url = rest[1] as string;\n if (!isRelayUrl(url)) {\n io.err(\n `cannot add remote: ${JSON.stringify(url)} is not a relay URL — ` +\n 'relays are ws://, wss://, http://, or https://'\n );\n return 2;\n }\n break;\n }\n case 'remove':\n if (rest.length !== 1) {\n io.err('usage: rig remote remove <name>');\n io.err(REMOTE_USAGE);\n return 2;\n }\n break;\n default:\n io.err(`unknown rig remote subcommand: ${sub}`);\n io.err(REMOTE_USAGE);\n return 2;\n }\n\n try {\n let repoRoot: string;\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n } catch {\n throw new NotAGitRepositoryError(deps.cwd);\n }\n\n switch (sub) {\n case undefined:\n case 'list': {\n const remotes = await listGitRemotes(repoRoot);\n if (json) {\n io.emitJson({ command: 'remote', remotes });\n return 0;\n }\n if (remotes.length === 0) {\n io.out(\n 'no remotes configured — add one: rig remote add origin <relay-url>'\n );\n return 0;\n }\n for (const remote of remotes) {\n for (const url of remote.urls) {\n io.out(\n `${remote.name}\\t${url}` +\n (isRelayUrl(url) ? '' : '\\t(not a relay URL — ignored by rig)')\n );\n }\n if (remote.urls.length > 1) {\n io.err(\n `warning: remote \"${remote.name}\" has ${remote.urls.length} ` +\n 'URLs — rig supports one relay URL per remote (fix with ' +\n `\\`git remote set-url ${remote.name} <relay-url>\\`)`\n );\n }\n }\n return 0;\n }\n\n case 'add': {\n const [name, url] = rest as [string, string];\n const existing = await getGitRemoteUrls(repoRoot, name);\n if (existing.length > 0) {\n const detail =\n `remote ${JSON.stringify(name)} already exists ` +\n `(${existing.join(', ')}) — nothing changed. Point it ` +\n `somewhere else with \\`git remote set-url ${name} <relay-url>\\`, ` +\n `or \\`rig remote remove ${name}\\` first.`;\n if (json) {\n io.emitJson({\n command: 'remote',\n error: 'remote_exists',\n detail,\n remote: name,\n urls: existing,\n });\n }\n io.err(detail);\n return 1;\n }\n await addGitRemote(repoRoot, name, url);\n if (!json) io.out(`Added remote ${name} → ${url}`);\n if (name === 'origin') {\n if (!json) {\n io.out(\n '`rig push` and the event commands now publish here by default.'\n );\n }\n const toonConfig = await readToonConfig(repoRoot);\n if (toonConfig.relays.length > 0) {\n io.err(\n `note: git config toon.relay (${toonConfig.relays.join(', ')}) ` +\n 'is deprecated and now shadowed by the origin remote — drop ' +\n 'it with `git config --unset-all toon.relay` (the key is ' +\n 'removed in v0.3).'\n );\n }\n }\n if (json) {\n io.emitJson({ command: 'remote', action: 'add', name, url });\n }\n return 0;\n }\n\n case 'remove': {\n const name = rest[0] as string;\n const existing = await getGitRemoteUrls(repoRoot, name);\n if (existing.length === 0) {\n const detail =\n `no remote named ${JSON.stringify(name)} — ` +\n '`rig remote list` shows configured remotes.';\n if (json) {\n io.emitJson({\n command: 'remote',\n error: 'unknown_remote',\n detail,\n remote: name,\n });\n }\n io.err(detail);\n return 1;\n }\n await removeGitRemote(repoRoot, name);\n if (json) {\n io.emitJson({ command: 'remote', action: 'remove', name });\n } else {\n io.out(`Removed remote ${name}`);\n }\n return 0;\n }\n\n /* v8 ignore next 2 -- unreachable: validated above */\n default:\n return 2;\n }\n } catch (err) {\n return emitCliError(io, json, 'remote', err);\n }\n}\n","/**\n * `rig chain` — choose which chain (and therefore which USDC token) settles\n * paid `rig` writes.\n *\n * Each supported chain has its own USDC: EVM (Base Sepolia), Solana devnet, and\n * Mina devnet. \"Which USDC is spent\" == \"which settlement chain rig picks\", and\n * that is a session/config-level choice — there is no per-`rig push` flag. This\n * command persists the choice to the shared client config's `chain` field\n * (`~/.toon-client/config.json`) — the exact knob `resolveNetworkTopology`\n * reads (env `TOON_CLIENT_CHAIN` ?? config `chain`), so the next paid command\n * settles on the named chain.\n *\n * rig chain show the current preference (and what USDC it maps to)\n * rig chain set <chain> pin the settlement chain: evm | sol | mina (or a\n * full id like evm:base:84532)\n * rig chain unset clear the pin — revert to automatic selection\n *\n * A FREE command: it only reads/writes the local config file, never the relay\n * or a chain. When nothing is pinned, rig auto-selects (most-recent open\n * channel → first announced chain your wallet holds USDC on → first announced\n * EVM chain); `rig chain` reports that state.\n *\n * Precedence caveats surfaced to the user: the `TOON_CLIENT_CHAIN` env var\n * overrides the config field, and a `supportedChains` array (if set) takes\n * precedence over `chain` — writing `chain` while either is set warns that the\n * pin may not take effect until they are cleared/changed.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport type { CliIo } from './output.js';\n\n/** Canonical settlement families and the USDC each one spends. */\nconst FAMILY_USDC: Record<string, string> = {\n evm: 'EVM USDC (Base Sepolia on devnet)',\n solana: 'Solana USDC',\n mina: 'Mina USDC',\n};\n\n/**\n * Accepted `set` values → the canonical string written to config. Short aliases\n * mirror `rig fund` (`sol`, `eth`). A full chain id (with a `:`) is stored\n * verbatim; a bare family is stored as the canonical family, which the resolver\n * matches against the first announced chain of that family.\n */\nconst FAMILY_ALIASES: Record<string, string> = {\n evm: 'evm',\n eth: 'evm',\n sol: 'solana',\n solana: 'solana',\n mina: 'mina',\n};\n\n/** Human list of accepted `set` arguments (for usage/errors). */\nconst CHAIN_ARG_LIST = 'evm | sol | solana | mina (or a full id like evm:base:84532)';\n\nexport const CHAIN_USAGE = `Usage: rig chain [set <chain> | unset]\n\nChoose which chain — and therefore which USDC token — settles paid \\`rig\\`\nwrites. The choice is saved to the client config's \\`chain\\` field and applies to\nevery subsequent paid command (there is no per-command chain flag). Free: only\nthe local config file is touched.\n\n rig chain show the current settlement-chain preference\n rig chain set <chain> pin the settlement chain / USDC:\n evm → EVM USDC (Base Sepolia on devnet)\n sol → Solana USDC\n mina → Mina USDC\n (a full id like evm:base:84532 or solana:devnet also\n works; \\`solana\\` is accepted for \\`sol\\`, \\`eth\\` for \\`evm\\`)\n rig chain unset clear the pin — revert to automatic selection\n\nWhen nothing is pinned, rig auto-selects: your most-recently-used open channel's\nchain, else the first announced chain your wallet holds USDC on, else the first\nannounced EVM chain.\n\nOptions:\n --json machine-readable envelope\n -h, --help show this help`;\n\n/** What `rig chain` needs from the command environment. */\nexport interface ChainDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n}\n\n/** The slice of the shared client config `rig chain` reads/writes. */\ninterface ChainConfigFile {\n chain?: string;\n supportedChains?: string[];\n [key: string]: unknown;\n}\n\n/** `--json` envelope. */\ninterface ChainJson {\n command: 'chain';\n /** The effective settlement-chain preference, or null when unset (auto). */\n chain: string | null;\n /** Where the effective value came from. */\n source: 'env' | 'config' | 'supportedChains' | 'auto';\n /** The USDC token family the effective chain spends (null when auto). */\n usdc: string | null;\n /** The value written to the config `chain` field (set/unset only). */\n wrote?: string | null;\n configPath: string;\n /** Precedence warnings that may keep the pin from taking effect. */\n warnings?: string[];\n}\n\n/** Resolve the client config directory + path (mirrors readFundConfig). */\nfunction configPathFor(env: NodeJS.ProcessEnv): string {\n const dir = env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n return join(dir, 'config.json');\n}\n\nfunction readChainConfig(configPath: string): ChainConfigFile {\n try {\n return JSON.parse(readFileSync(configPath, 'utf8')) as ChainConfigFile;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw new Error(\n `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** Read-merge-write: preserve every other field, only touch `chain`. */\nfunction writeChainConfig(configPath: string, file: ChainConfigFile): void {\n mkdirSync(dirname(configPath), { recursive: true });\n writeFileSync(configPath, `${JSON.stringify(file, null, 2)}\\n`, 'utf8');\n}\n\n/**\n * Normalize a `set` argument to the string stored in config. A value with a\n * `:` is a full chain id (family must be evm/solana/mina); otherwise it is a\n * family alias. Throws a usage error on anything else.\n */\nfunction normalizeChain(raw: string): string {\n if (raw.includes(':')) {\n const family = raw.split(':')[0]?.toLowerCase() ?? '';\n if (!(family in FAMILY_USDC)) {\n throw new Error(\n `unknown chain family in ${JSON.stringify(raw)} — must start with evm:, solana:, or mina:`\n );\n }\n return raw;\n }\n const canonical = FAMILY_ALIASES[raw.toLowerCase()];\n if (!canonical) {\n throw new Error(`chain must be one of ${CHAIN_ARG_LIST}, got ${JSON.stringify(raw)}`);\n }\n return canonical;\n}\n\n/** The USDC family label for a stored chain value (family or full id). */\nfunction usdcFor(chain: string): string {\n const family = (chain.includes(':') ? (chain.split(':')[0] ?? chain) : chain).toLowerCase();\n return FAMILY_USDC[family] ?? `${family} USDC`;\n}\n\n/** Run `rig chain`; returns the process exit code. */\nexport async function runChain(args: string[], deps: ChainDeps): Promise<number> {\n const { io, env } = deps;\n\n let positionals: string[];\n let json = false;\n try {\n const parsed = parseArgs({\n args,\n allowPositionals: true,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (parsed.values.help) {\n io.out(CHAIN_USAGE);\n return 0;\n }\n positionals = parsed.positionals;\n json = parsed.values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHAIN_USAGE);\n return 2;\n }\n\n const [sub, ...subRest] = positionals;\n if (sub !== undefined && sub !== 'set' && sub !== 'unset') {\n io.err(`unknown subcommand ${JSON.stringify(sub)} — expected \\`set\\`, \\`unset\\`, or no argument`);\n io.err(CHAIN_USAGE);\n return 2;\n }\n if (sub === 'set' && subRest.length !== 1) {\n io.err(\n subRest.length === 0\n ? `rig chain set needs a chain: ${CHAIN_ARG_LIST}`\n : `rig chain set takes exactly one chain, got ${subRest.length}: ${subRest.join(' ')}`\n );\n io.err(CHAIN_USAGE);\n return 2;\n }\n if (sub === 'unset' && subRest.length !== 0) {\n io.err(`rig chain unset takes no arguments, got: ${subRest.join(' ')}`);\n io.err(CHAIN_USAGE);\n return 2;\n }\n // Normalize the `set` value here (not inside the emitCliError-wrapped block)\n // so an unknown chain is a USAGE error (exit 2), not a runtime error.\n let setValue: string | undefined;\n if (sub === 'set') {\n try {\n setValue = normalizeChain(subRest[0] as string);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHAIN_USAGE);\n return 2;\n }\n }\n\n try {\n const configPath = configPathFor(env);\n const file = readChainConfig(configPath);\n const envChain = env['TOON_CLIENT_CHAIN'];\n const supported0 = file.supportedChains?.[0];\n\n // Precedence warnings shared by set/unset: env overrides config, and a\n // supportedChains array overrides the plain `chain` field.\n const precedenceWarnings = (targetField: 'chain' | null): string[] => {\n const w: string[] = [];\n if (envChain !== undefined) {\n w.push(\n `TOON_CLIENT_CHAIN=${envChain} is set in the environment and overrides the config ` +\n `${targetField === 'chain' ? 'value you just wrote' : 'file'} — unset it for the config to take effect.`\n );\n }\n if (supported0 !== undefined) {\n w.push(\n `config \\`supportedChains\\` is set (first entry ${JSON.stringify(supported0)}) and takes ` +\n 'precedence over `chain` — clear or reorder it for this pin to take effect.'\n );\n }\n return w;\n };\n\n // ── set ────────────────────────────────────────────────────────────────\n if (sub === 'set') {\n const value = setValue as string;\n file.chain = value;\n writeChainConfig(configPath, file);\n const warnings = precedenceWarnings('chain');\n if (json) {\n io.emitJson({\n command: 'chain',\n chain: envChain ?? value,\n source: envChain !== undefined ? 'env' : 'config',\n usdc: usdcFor(envChain ?? value),\n wrote: value,\n configPath,\n ...(warnings.length ? { warnings } : {}),\n } satisfies ChainJson);\n return 0;\n }\n io.out(`Settlement chain set to ${value} → spends ${usdcFor(value)}.`);\n io.out(`Saved to ${configPath}. Applies to the next paid command (e.g. \\`rig push\\`).`);\n for (const w of warnings) io.err(`warning: ${w}`);\n return 0;\n }\n\n // ── unset ──────────────────────────────────────────────────────────────\n if (sub === 'unset') {\n const had = file.chain;\n delete file.chain;\n writeChainConfig(configPath, file);\n // After unset, what still pins the chain (env / supportedChains), if any.\n const stillPinned = envChain ?? supported0;\n if (json) {\n io.emitJson({\n command: 'chain',\n chain: stillPinned ?? null,\n source: envChain !== undefined ? 'env' : supported0 !== undefined ? 'supportedChains' : 'auto',\n usdc: stillPinned ? usdcFor(stillPinned) : null,\n wrote: null,\n configPath,\n ...(precedenceWarnings(null).length ? { warnings: precedenceWarnings(null) } : {}),\n } satisfies ChainJson);\n return 0;\n }\n io.out(\n had !== undefined\n ? `Cleared the settlement-chain pin (was ${had}).`\n : 'No settlement-chain pin was set.'\n );\n if (stillPinned !== undefined) {\n io.out(`Still pinned to ${stillPinned} by ${envChain !== undefined ? 'TOON_CLIENT_CHAIN' : 'config supportedChains'} → ${usdcFor(stillPinned)}.`);\n } else {\n io.out('Reverted to automatic selection (most-recent channel → first funded announced chain → first EVM).');\n }\n return 0;\n }\n\n // ── show (no subcommand) ────────────────────────────────────────────────\n const effective = envChain ?? file.chain ?? supported0;\n const source: ChainJson['source'] =\n envChain !== undefined\n ? 'env'\n : file.chain !== undefined\n ? 'config'\n : supported0 !== undefined\n ? 'supportedChains'\n : 'auto';\n if (json) {\n io.emitJson({\n command: 'chain',\n chain: effective ?? null,\n source,\n usdc: effective ? usdcFor(effective) : null,\n configPath,\n } satisfies ChainJson);\n return 0;\n }\n if (effective !== undefined) {\n const via =\n source === 'env'\n ? 'TOON_CLIENT_CHAIN env'\n : source === 'config'\n ? `config \\`chain\\` (${configPath})`\n : `config \\`supportedChains[0]\\``;\n io.out(`Settlement chain: ${effective} → spends ${usdcFor(effective)} (from ${via}).`);\n io.out('Change it with `rig chain set <evm|sol|mina>`, or `rig chain unset` for auto.');\n } else {\n io.out('Settlement chain: (auto) — no pin set.');\n io.out('rig picks your most-recent open channel, else the first announced chain your');\n io.out('wallet holds USDC on, else the first announced EVM chain.');\n io.out('Pin one with `rig chain set <evm|sol|mina>`.');\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'chain', err);\n }\n}\n","/**\n * `rig channel` — the payment channels paid rig commands hold (#262), plus\n * the explicit money lifecycle (#263): open / close / settle.\n *\n * Paid commands open a channel lazily on first use and RECORD it in the\n * peer→channel map under `TOON_CLIENT_HOME` (default `~/.toon-client`,\n * `rig-channels.json`), so later invocations resume the same channel instead\n * of opening (and funding) a new one per run. `rig channel list` reads that\n * map plus the client's nonce-watermark store (`channels.json`) and shows\n * current holdings — a FREE command: local files only, no client start, no\n * network, no payment (and therefore no `@toon-protocol/client` import).\n *\n * The lifecycle subcommands are ON-CHAIN wallet operations (gas + collateral\n * movement, not relay claims), so they follow the push confirm idiom: print\n * what will happen, then require `--yes` (mandatory in a non-TTY session) or\n * an interactive y/N confirm; `--json` without `--yes` is a pure plan.\n *\n * open the SAME resume-or-open path lazy paid writes use (factored, not\n * forked): resumes the recorded channel when one is live, else\n * opens + records a fresh one; `--deposit` adds collateral on top.\n * close starts the settlement challenge window for a recorded channel —\n * the channel stops paying immediately; collateral is released by\n * `settle` once the window elapses.\n * settle releases the remaining collateral after the challenge window\n * (the client refuses a too-early settle BEFORE spending gas).\n *\n * close/settle recover deposits stranded by pre-#262 one-channel-per-run\n * behaviour: any channel present in the map can be driven to settled.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n channelStatus,\n ChannelMapStore,\n resolveChannelPaths,\n type ChannelMapRecord,\n type WatermarkEntry,\n} from '../standalone/channel-map.js';\nimport { emitCliError } from './errors.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type CliIo,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport { renderIdentityLine } from './render.js';\nimport type { StandaloneContext } from './standalone-context.js';\nimport type { StandaloneMoneyOps } from '../standalone/money.js';\n\nexport const CHANNEL_USAGE = `Usage: rig channel <subcommand>\n\nManage the payment channels paid rig commands hold with relay/store peers.\nPaid commands open a channel lazily on first use and record it under\nTOON_CLIENT_HOME (default ~/.toon-client, rig-channels.json), so later\ninvocations resume the same channel instead of opening a new one per run.\n\nSubcommands:\n list [--json] show recorded channels — peer, chain, channel id, deposit,\n cumulative claimed, status. Free: reads local state only.\n\n open [--peer <ilp-destination>] [--deposit <base-units>]\n explicitly open the payment channel for a peer — the SAME\n path paid commands use lazily: resumes the recorded live\n channel if one exists (no on-chain spend), else opens and\n records a fresh one (locks the peer-negotiated initial\n deposit on-chain). --peer is the ILP destination to anchor\n to (default: the configured destination, e.g. the devnet\n apex); --deposit adds that much extra collateral after the\n open/resume. On-chain: asks for confirmation (--yes skips).\n\n close <channelId>\n close a recorded channel — an on-chain tx that starts the\n settlement challenge window (the peer's settlementTimeout).\n The channel stops paying immediately; the remaining\n collateral stays locked until \\`rig channel settle\\` after\n the window elapses. Asks for confirmation (--yes skips).\n\n settle <channelId>\n settle a closed channel once its challenge window elapsed —\n an on-chain tx that releases the remaining collateral back\n to your wallet. Refused (without spending gas) while the\n window is still open. Asks for confirmation (--yes skips).\n\nCommon options: --json (machine-readable envelopes; without --yes lifecycle\ncommands emit a pure plan and execute nothing), --yes, -h/--help.`;\n\n/**\n * What `rig channel` needs from the command environment — the shared paid\n * command deps (io/env/cwd + injectable standalone loader): `list` uses only\n * io/env, the lifecycle subcommands load the standalone context.\n */\nexport type ChannelDeps = PushDeps;\n\n/** One channel in the `--json` envelope (unknowns are null, bigints strings). */\ninterface ChannelJson {\n channelId: string;\n peerId: string;\n identity: string;\n destination: string;\n chain: string;\n tokenNetwork: string;\n depositTotal: string | null;\n cumulativeClaimed: string | null;\n nonce: number | null;\n status: 'open' | 'closing' | 'settleable' | 'settled';\n openedAt: string;\n lastUsedAt: string;\n}\n\n/** Route one `rig channel …` invocation; returns the exit code. */\nexport async function runChannel(\n args: string[],\n deps: ChannelDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'list':\n return runChannelList(rest, deps);\n case 'open':\n return runChannelOpen(rest, deps);\n case 'close':\n return runChannelWithdrawStep(rest, deps, 'close');\n case 'settle':\n return runChannelWithdrawStep(rest, deps, 'settle');\n case 'help':\n case '--help':\n case '-h':\n io.out(CHANNEL_USAGE);\n return 0;\n case undefined:\n io.err(CHANNEL_USAGE);\n return 2;\n default:\n io.err(`rig channel: unknown subcommand ${JSON.stringify(sub)}`);\n io.err(CHANNEL_USAGE);\n return 2;\n }\n}\n\n// ---------------------------------------------------------------------------\n// list (#262)\n// ---------------------------------------------------------------------------\n\nfunction runChannelList(args: string[], deps: ChannelDeps): number {\n const { io, env } = deps;\n let json = false;\n try {\n const { values } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(CHANNEL_USAGE);\n return 0;\n }\n json = values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHANNEL_USAGE);\n return 2;\n }\n\n try {\n const paths = resolveChannelPaths(env);\n const store = new ChannelMapStore(paths);\n const records = store.list();\n const rows = records.map((record) => describeChannel(record, store));\n\n if (json) {\n io.emitJson({ command: 'channel list', channels: rows });\n return 0;\n }\n if (rows.length === 0) {\n io.out(\n 'No payment channels recorded — paid rig commands (push, issue, ' +\n 'comment, pr) record the channel they open on first use, and ' +\n '`rig channel open` records an explicit one.'\n );\n return 0;\n }\n io.out(\n `${rows.length} payment channel${rows.length === 1 ? '' : 's'} ` +\n `recorded in ${paths.mapPath}:`\n );\n for (const row of rows) {\n io.out('');\n for (const line of renderChannel(row)) io.out(line);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'channel list', err);\n }\n}\n\n/** Join one map record with its watermark state. */\nfunction describeChannel(\n record: ChannelMapRecord,\n store: ChannelMapStore\n): ChannelJson {\n const watermark: WatermarkEntry | undefined = store.readWatermark(\n record.channelId\n );\n return {\n channelId: record.channelId,\n peerId: record.peerId,\n identity: record.identity,\n destination: record.destination,\n chain: record.chain,\n tokenNetwork: record.tokenNetwork,\n depositTotal: record.depositTotal ?? null,\n cumulativeClaimed: watermark?.cumulativeAmount ?? null,\n nonce: watermark?.nonce ?? null,\n status: channelStatus(watermark),\n openedAt: record.openedAt,\n lastUsedAt: record.lastUsedAt,\n };\n}\n\nfunction renderChannel(row: ChannelJson): string[] {\n const claimed =\n row.cumulativeClaimed === null\n ? 'unknown (no local claim state)'\n : `${row.cumulativeClaimed} base units (nonce ${row.nonce})`;\n return [\n `channel ${row.channelId} [${row.status}]`,\n ` peer ${row.destination} (${row.peerId})`,\n ` identity ${row.identity.slice(0, 8)}…`,\n ` chain ${row.chain}` +\n (row.tokenNetwork ? ` token-network ${row.tokenNetwork}` : ''),\n ` deposited ${row.depositTotal ?? 'unrecorded'}` +\n (row.depositTotal ? ' base units' : ''),\n ` claimed ${claimed}`,\n ` opened ${row.openedAt} (last used ${row.lastUsedAt})`,\n ];\n}\n\n// ---------------------------------------------------------------------------\n// Shared money-command plumbing (#263)\n// ---------------------------------------------------------------------------\n\n/** Load the standalone context and require its money-ops surface. */\nasync function loadMoneyContext(\n deps: ChannelDeps,\n options?: { channelDestination?: string }\n): Promise<{ ctx: StandaloneContext; money: StandaloneMoneyOps }> {\n const ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => deps.io.err(line),\n ...(options?.channelDestination\n ? { channelDestination: options.channelDestination }\n : {}),\n });\n const money = ctx.money;\n if (!money) {\n await ctx.stop().catch(() => undefined);\n throw new Error(\n 'this standalone loader does not expose money operations — ' +\n 'channel open/close/settle need a loader with the money lifecycle'\n );\n }\n return { ctx, money };\n}\n\n/**\n * The push-idiom confirm gate for an ON-CHAIN money operation. Returns the\n * exit code to bail out with, or undefined to proceed. In `--json` mode\n * without `--yes` the caller emits its plan envelope (exit 0) — this gate\n * signals that with `'json-plan'`.\n */\nasync function confirmOnChain(\n io: CliIo,\n flags: { yes: boolean; json: boolean },\n question: string\n): Promise<'proceed' | 'json-plan' | number> {\n if (flags.yes) return 'proceed';\n if (flags.json) return 'json-plan';\n if (!io.isInteractive) {\n io.err(\n 'refusing to move on-chain funds without confirmation in a ' +\n 'non-interactive session — re-run with --yes (or use --json for a plan)'\n );\n return 1;\n }\n const proceed = await io.confirm(question);\n if (proceed) return 'proceed';\n io.err('aborted — no on-chain transaction was sent.');\n return 1;\n}\n\n/** Format a string-encoded unix-seconds timestamp for humans. */\nfunction formatUnixSeconds(value: string): string {\n const ms = Number(value) * 1000;\n return Number.isFinite(ms) ? new Date(ms).toISOString() : `t=${value}s`;\n}\n\n/** Whole seconds from now until a string-encoded unix-seconds timestamp. */\nfunction secondsUntil(value: string, nowSec: number): number {\n return Number(value) - nowSec;\n}\n\n// ---------------------------------------------------------------------------\n// open\n// ---------------------------------------------------------------------------\n\ninterface ChannelOpenJson {\n command: 'channel open';\n identity: IdentityReport;\n executed: boolean;\n plan: { destination: string | null; deposit: string | null };\n result?: {\n channelId: string;\n resumed: boolean;\n destination: string;\n chain: string | null;\n peerId: string | null;\n depositTotal: string | null;\n depositAdded: string | null;\n depositTxHash: string | null;\n };\n hint?: string;\n}\n\nasync function runChannelOpen(\n args: string[],\n deps: ChannelDeps\n): Promise<number> {\n const { io } = deps;\n let peer: string | undefined;\n let deposit: bigint | undefined;\n let yes = false;\n let json = false;\n try {\n const { values } = parseArgs({\n args,\n options: {\n peer: { type: 'string' },\n deposit: { type: 'string' },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(CHANNEL_USAGE);\n return 0;\n }\n peer = values.peer;\n yes = values.yes ?? false;\n json = values.json ?? false;\n if (values.deposit !== undefined) {\n if (!/^\\d+$/.test(values.deposit) || BigInt(values.deposit) <= 0n) {\n throw new Error(\n `--deposit must be a positive base-unit integer, got ${JSON.stringify(values.deposit)}`\n );\n }\n deposit = BigInt(values.deposit);\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHANNEL_USAGE);\n return 2;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n const loaded = await loadMoneyContext(deps, {\n ...(peer ? { channelDestination: peer } : {}),\n });\n ctx = loaded.ctx;\n const identity = identityReport(ctx);\n const plan = {\n destination: peer ?? null,\n deposit: deposit?.toString() ?? null,\n };\n\n if (!json) {\n io.out('Channel open plan:');\n io.out(` peer (ILP) ${peer ?? '(configured default destination)'}`);\n io.out(\n ` deposit ${deposit !== undefined ? `+${deposit} base units of extra collateral after the open/resume` : 'none beyond the peer-negotiated initial deposit'}`\n );\n io.out(renderIdentityLine(identity));\n io.out(\n 'If a live channel is already recorded for this peer it is RESUMED ' +\n '(no on-chain spend); otherwise an on-chain channel open locks the ' +\n 'peer-negotiated initial deposit from your wallet (plus gas).'\n );\n }\n\n const gate = await confirmOnChain(\n io,\n { yes, json },\n 'Proceed with on-chain channel open? [y/N] '\n );\n if (gate === 'json-plan') {\n io.emitJson({\n command: 'channel open',\n identity,\n executed: false,\n plan,\n hint: 'plan only — re-run with --yes to open (on-chain: locks collateral and spends gas)',\n } satisfies ChannelOpenJson);\n return 0;\n }\n if (gate !== 'proceed') return gate;\n\n const outcome = await loaded.money.openChannel(\n deposit !== undefined ? { deposit } : undefined\n );\n\n if (json) {\n io.emitJson({\n command: 'channel open',\n identity,\n executed: true,\n plan,\n result: {\n channelId: outcome.channelId,\n resumed: outcome.resumed,\n destination: outcome.destination,\n chain: outcome.chain ?? null,\n peerId: outcome.peerId ?? null,\n depositTotal: outcome.depositTotal ?? null,\n depositAdded: outcome.depositAdded ?? null,\n depositTxHash: outcome.depositTxHash ?? null,\n },\n } satisfies ChannelOpenJson);\n return 0;\n }\n io.out(\n outcome.resumed\n ? `Resumed recorded channel ${outcome.channelId} — no on-chain open was needed.`\n : `Opened channel ${outcome.channelId}${outcome.chain ? ` on ${outcome.chain}` : ''} and recorded it for reuse.`\n );\n io.out(` peer ${outcome.destination}${outcome.peerId ? ` (${outcome.peerId})` : ''}`);\n if (outcome.depositAdded) {\n io.out(\n ` deposited +${outcome.depositAdded} base units` +\n (outcome.depositTxHash ? ` (tx ${outcome.depositTxHash})` : '')\n );\n }\n if (outcome.depositTotal) {\n io.out(` collateral ${outcome.depositTotal} base units total on-chain`);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'channel open', err);\n } finally {\n await stopQuietly(ctx);\n }\n}\n\n// ---------------------------------------------------------------------------\n// close / settle (the two halves of withdraw)\n// ---------------------------------------------------------------------------\n\ninterface WithdrawJson {\n command: 'channel close' | 'channel settle';\n identity: IdentityReport;\n executed: boolean;\n channelId: string;\n result?: {\n txHash: string | null;\n closedAt?: string;\n settleableAt?: string;\n };\n hint?: string;\n}\n\n/**\n * Fail-fast local pre-checks from the recorded watermark timers — before any\n * identity resolution or client start (chain state stays authoritative: the\n * client re-checks before spending gas).\n */\nfunction withdrawPrecheck(\n step: 'close' | 'settle',\n channelId: string,\n watermark: WatermarkEntry | undefined,\n nowSec: number\n): string | undefined {\n const status = channelStatus(watermark, nowSec);\n if (status === 'settled') {\n return `channel ${channelId} is already settled — nothing left to ${step}.`;\n }\n if (step === 'close') {\n if (status === 'closing' || status === 'settleable') {\n const at = watermark?.settleableAt;\n return (\n `channel ${channelId} is already closing — ` +\n (status === 'settleable'\n ? 'its challenge window has elapsed; run `rig channel settle` to release the collateral.'\n : `settleable at ${at ? formatUnixSeconds(at) : 'the end of its challenge window'} (run \\`rig channel settle\\` then).`)\n );\n }\n return undefined;\n }\n // settle\n if (status === 'open') {\n return (\n `channel ${channelId} is not closed — run \\`rig channel close ${channelId}\\` ` +\n 'first (settle only releases collateral after the challenge window of a closed channel).'\n );\n }\n if (status === 'closing' && watermark?.settleableAt !== undefined) {\n const remain = secondsUntil(watermark.settleableAt, nowSec);\n return (\n `channel ${channelId} is not settleable yet — the challenge window is ` +\n `still open (${remain}s remain, settleable at ${formatUnixSeconds(watermark.settleableAt)}). ` +\n 'Nothing was spent; re-run after that time.'\n );\n }\n return undefined;\n}\n\nasync function runChannelWithdrawStep(\n args: string[],\n deps: ChannelDeps,\n step: 'close' | 'settle'\n): Promise<number> {\n const { io, env } = deps;\n const command = `channel ${step}` as WithdrawJson['command'];\n let channelId: string | undefined;\n let yes = false;\n let json = false;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) {\n io.out(CHANNEL_USAGE);\n return 0;\n }\n yes = values.yes ?? false;\n json = values.json ?? false;\n if (positionals.length !== 1) {\n throw new Error(\n `rig channel ${step} takes exactly one <channelId> (got ${positionals.length}) — \\`rig channel list\\` shows recorded channels`\n );\n }\n channelId = positionals[0] as string;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CHANNEL_USAGE);\n return 2;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n // ── Local state: the recorded channel + its watermark (free, fail-fast) ──\n const store = new ChannelMapStore(resolveChannelPaths(env));\n const record = store.list().find((r) => r.channelId === channelId);\n if (!record) {\n throw new Error(\n `no recorded channel ${JSON.stringify(channelId)} — \\`rig channel list\\` shows the channels this identity holds`\n );\n }\n const watermark = store.readWatermark(channelId);\n const nowSec = Math.floor(Date.now() / 1000);\n const refusal = withdrawPrecheck(step, channelId, watermark, nowSec);\n if (refusal) throw new Error(refusal);\n\n // ── Identity (must match the channel's opener — its claims/keys) ────────\n const loaded = await loadMoneyContext(deps);\n ctx = loaded.ctx;\n const identity = identityReport(ctx);\n if (record.identity !== identity.pubkey) {\n throw new Error(\n `channel ${channelId} was opened by identity ${record.identity.slice(0, 8)}… ` +\n `but the active identity is ${identity.pubkey.slice(0, 8)}… ` +\n `(from ${identity.sourceLabel}) — on-chain ${step} must be signed by ` +\n \"the opener's wallet key. Switch RIG_MNEMONIC (or the keystore) to that identity.\"\n );\n }\n\n // ── Plan + confirm gate ──────────────────────────────────────────────────\n if (!json) {\n const claimed = watermark?.cumulativeAmount;\n io.out(`Channel ${step} plan:`);\n io.out(` channel ${channelId} [${channelStatus(watermark, nowSec)}]`);\n io.out(` peer ${record.destination} (${record.peerId})`);\n io.out(` chain ${record.chain}`);\n io.out(\n ` deposited ${record.depositTotal ?? 'unrecorded'}` +\n (claimed !== undefined ? ` claimed ${claimed} base units` : '')\n );\n io.out(renderIdentityLine(identity));\n if (step === 'close') {\n io.out(\n 'Closing is an ON-CHAIN transaction (gas) that starts the settlement ' +\n 'challenge window: the channel stops paying immediately, and the ' +\n 'remaining collateral stays locked until `rig channel settle` ' +\n 'succeeds after the window elapses.'\n );\n } else {\n io.out(\n 'Settling is an ON-CHAIN transaction (gas) that releases the ' +\n \"remaining collateral back to your wallet. The chain's challenge \" +\n 'window is authoritative — a too-early settle is refused before ' +\n 'any gas is spent.'\n );\n }\n }\n const gate = await confirmOnChain(\n io,\n { yes, json },\n `Proceed with on-chain channel ${step}? [y/N] `\n );\n if (gate === 'json-plan') {\n io.emitJson({\n command,\n identity,\n executed: false,\n channelId,\n hint: `plan only — re-run with --yes to ${step} (on-chain transaction)`,\n } satisfies WithdrawJson);\n return 0;\n }\n if (gate !== 'proceed') return gate;\n\n // ── Execute ──────────────────────────────────────────────────────────────\n if (step === 'close') {\n const result = await loaded.money.closeChannel(record);\n if (json) {\n io.emitJson({\n command,\n identity,\n executed: true,\n channelId,\n result: {\n txHash: result.txHash ?? null,\n closedAt: result.closedAt,\n settleableAt: result.settleableAt,\n },\n } satisfies WithdrawJson);\n return 0;\n }\n io.out(\n `Channel ${channelId} is closing` +\n (result.txHash ? ` (tx ${result.txHash})` : '') +\n '.'\n );\n io.out(\n ` challenge window: settleable at ${formatUnixSeconds(result.settleableAt)} ` +\n `(~${Math.max(0, secondsUntil(result.settleableAt, nowSec))}s from now)`\n );\n io.out(\n ` run \\`rig channel settle ${channelId}\\` after that time to release the collateral.`\n );\n return 0;\n }\n\n const result = await loaded.money.settleChannel(record);\n if (json) {\n io.emitJson({\n command,\n identity,\n executed: true,\n channelId,\n result: { txHash: result.txHash ?? null },\n } satisfies WithdrawJson);\n return 0;\n }\n io.out(\n `Channel ${channelId} settled` +\n (result.txHash ? ` (tx ${result.txHash})` : '') +\n ' — the remaining collateral was released to your wallet.'\n );\n return 0;\n } catch (err) {\n return emitCliError(io, json, command, err);\n } finally {\n await stopQuietly(ctx);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Small shared helpers\n// ---------------------------------------------------------------------------\n\nasync function stopQuietly(ctx: StandaloneContext | undefined): Promise<void> {\n if (!ctx) return;\n try {\n await ctx.stop();\n } catch {\n // best-effort teardown\n }\n}\n","/**\n * `rig clone` (#278) — bootstrap a repository from TOON, no payments anywhere:\n *\n * rig clone <relay-url> <owner-npub-or-hex>/<repo-id> [dir]\n *\n * Pipeline: fetch kind:30617/30618 from the relay (../remote-state.ts) →\n * download every object the refs need from Arweave gateways with SHA-1\n * verification (../read-pipeline.ts) → materialize a REAL git repository via\n * git plumbing (../materialize.ts): `git hash-object -w --stdin -t <type>`\n * per object (written SHA re-checked), `git update-ref` per ref, HEAD from\n * the 30618 symref, worktree checkout. The clone is immediately push/pull\n * capable: toon.repoid/toon.owner are configured and the relay is added as\n * the `origin` remote.\n *\n * ATOMICITY: everything lands in a temp dir next to the destination and is\n * renamed into place only on full success — a failed clone never leaves a\n * partial/corrupt repository. Missing objects (Arweave propagation lag) are\n * an honest error listing the SHAs; corrupt objects are an integrity error.\n */\n\nimport { mkdtemp, mkdir, readdir, rename, rm, rmdir } from 'node:fs/promises';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport {\n setHeadSymref,\n isSafeRefname,\n runGit,\n updateRef,\n writeGitObjects,\n} from '../materialize.js';\nimport { npubToHex, ownerToHex } from '../npub.js';\nimport {\n collectRepoObjects,\n missingObjectsMessage,\n type MissingObject,\n} from '../read-pipeline.js';\nimport { fetchRemoteState, type RemoteState } from '../remote-state.js';\nimport { emitCliError } from './errors.js';\nimport type { ReadCommandDeps } from './read-seams.js';\n\nexport const CLONE_USAGE = `Usage: rig clone <relay-url> <owner>/<repo-id> [dir] [options]\n\nClone a TOON repository — FREE (relay reads + Arweave gateway downloads; no\npayments, no channel, no identity needed). <relay-url> is a ws:// or wss://\nNIP-01 relay; <owner> is the repo owner's pubkey as npub1… or 64-char hex;\n[dir] defaults to <repo-id>.\n\nFetches the kind:30617/30618 repository state, downloads every git object\nthe refs need from Arweave gateways (SHA-1 verified — corrupt content is\nrejected), and materializes a real git repository: objects via git plumbing,\nrefs, HEAD, checked-out worktree, toon.* config, and the relay preconfigured\nas the \"origin\" remote — so \\`rig fetch\\`, \\`rig push\\`, and the issue/pr\ncommands work immediately.\n\nNote: recently pushed objects can take 10-20 minutes to become fetchable\nfrom Arweave gateways. A clone right after a push may report missing\nobjects — retry after propagation.\n\nOptions:\n --concurrency <n> parallel gateway downloads (default 8)\n --json machine-readable result envelope\n -h, --help show this help`;\n\n/** Repo has no announcement AND no state on the relay. */\nexport class RepoNotFoundError extends Error {\n constructor(relay: string, owner: string, repoId: string) {\n super(\n `repository 30617:${owner}:${repoId} not found on ${relay} — ` +\n 'no kind:30617 announcement or kind:30618 state event exists there. ' +\n 'Check the relay URL, the owner pubkey (npub or hex), and the repo id.'\n );\n this.name = 'RepoNotFoundError';\n }\n}\n\n/** Reachable objects could not be downloaded (Arweave propagation lag). */\nexport class MissingRemoteObjectsError extends Error {\n constructor(\n public readonly missing: MissingObject[],\n context: string\n ) {\n super(missingObjectsMessage(missing, context));\n this.name = 'MissingRemoteObjectsError';\n }\n}\n\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\ninterface CloneArgs {\n relayUrl: string;\n owner: string;\n repoId: string;\n dir: string | undefined;\n concurrency: number | undefined;\n json: boolean;\n}\n\nfunction parseCloneArgs(args: string[]): CloneArgs | { help: true } {\n const { values, positionals } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n concurrency: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) return { help: true };\n if (positionals.length < 2 || positionals.length > 3) {\n throw new Error('expected: rig clone <relay-url> <owner>/<repo-id> [dir]');\n }\n const [relayUrl, addr, dir] = positionals as [string, string, string?];\n if (!WS_URL_RE.test(relayUrl)) {\n throw new Error(\n `<relay-url> must be ws:// or wss:// (got ${JSON.stringify(relayUrl)})`\n );\n }\n const slash = addr.indexOf('/');\n if (slash <= 0 || slash === addr.length - 1) {\n throw new Error(\n `expected <owner>/<repo-id> (npub or 64-char hex owner), got ${JSON.stringify(addr)}`\n );\n }\n const owner = ownerToHex(addr.slice(0, slash));\n const repoId = addr.slice(slash + 1);\n let concurrency: number | undefined;\n if (values.concurrency !== undefined) {\n concurrency = Number.parseInt(values.concurrency, 10);\n if (!Number.isSafeInteger(concurrency) || concurrency < 1) {\n throw new Error(`--concurrency must be a positive integer`);\n }\n }\n return {\n relayUrl,\n owner,\n repoId,\n dir,\n concurrency,\n json: values.json === true,\n };\n}\n\n/** True when `dir` does not exist or is an empty directory. */\nasync function isUsableDestination(dir: string): Promise<boolean> {\n try {\n const entries = await readdir(dir);\n return entries.length === 0;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'ENOENT';\n }\n}\n\n/** Pick the branch `git init --initial-branch` should use. */\nfunction initialBranch(headSymref: string | null): string {\n if (headSymref?.startsWith('refs/heads/')) {\n const name = headSymref.slice('refs/heads/'.length);\n if (name && isSafeRefname(headSymref)) return name;\n }\n return 'main';\n}\n\n/** Run `rig clone …`; returns the process exit code. */\nexport async function runClone(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let parsed: CloneArgs;\n try {\n const result = parseCloneArgs(args);\n if ('help' in result) {\n io.out(CLONE_USAGE);\n return 0;\n }\n parsed = result;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(CLONE_USAGE);\n return 2;\n }\n\n const { relayUrl, owner, repoId, json } = parsed;\n const dest = resolve(deps.cwd, parsed.dir ?? repoId);\n let tempDir: string | undefined;\n\n try {\n if (!(await isUsableDestination(dest))) {\n throw new Error(\n `destination path ${JSON.stringify(dest)} already exists and is not an empty directory`\n );\n }\n\n if (!json) io.out(`Cloning into '${basename(dest)}'...`);\n\n // ── Remote state (kind:30617 + 30618) ───────────────────────────────────\n const remoteState: RemoteState = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: owner,\n repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n ...(deps.resolveSha ? { resolveSha: deps.resolveSha } : {}),\n });\n if (!remoteState.announced && remoteState.refsEvent === null) {\n throw new RepoNotFoundError(relayUrl, owner, repoId);\n }\n\n // Refs from the 30618, filtered through the hostile-relay refname gate.\n const refs = new Map<string, string>();\n for (const [refname, sha] of remoteState.refs) {\n if (!isSafeRefname(refname)) {\n io.err(\n `warning: skipping unsafe ref name from relay: ${JSON.stringify(refname)}`\n );\n continue;\n }\n refs.set(refname, sha);\n }\n if (refs.size === 0) {\n io.err(\n 'warning: the repository has no refs yet (announced but never pushed) — ' +\n 'cloning an empty repository'\n );\n }\n\n // ── Download + verify the object closure (FREE) ─────────────────────────\n const tips = [...new Set(refs.values())];\n const collected = await collectRepoObjects({\n tips,\n shaToTxId: remoteState.shaToTxId,\n resolveMissing: (shas) => remoteState.resolveMissing(shas),\n ...(deps.fetchFn ? { fetchFn: deps.fetchFn } : {}),\n ...(parsed.concurrency !== undefined\n ? { concurrency: parsed.concurrency }\n : {}),\n });\n if (collected.missing.length > 0) {\n throw new MissingRemoteObjectsError(\n collected.missing,\n `cannot clone ${owner.slice(0, 8)}…/${repoId}`\n );\n }\n for (const { sha, txId } of collected.skippedUnavailable) {\n io.err(\n `warning: unreachable object ${sha} (tx ${txId}) could not be downloaded — ` +\n 'not needed by any ref, continuing'\n );\n }\n\n // ── Materialize into a temp dir, move into place on success ────────────\n const parent = dirname(dest);\n await mkdir(parent, { recursive: true });\n tempDir = await mkdtemp(join(parent, `.${basename(dest)}.rig-clone-`));\n\n await runGit(tempDir, [\n 'init',\n '--quiet',\n `--initial-branch=${initialBranch(remoteState.headSymref)}`,\n ]);\n const written = await writeGitObjects(tempDir, collected.objects.values());\n for (const [refname, sha] of refs) {\n await updateRef(tempDir, refname, sha);\n // Remote-tracking refs, exactly like `git clone` — so `rig fetch`\n // reports honest deltas and `rig merge origin/<branch>` works.\n if (refname.startsWith('refs/heads/')) {\n const branch = refname.slice('refs/heads/'.length);\n await updateRef(tempDir, `refs/remotes/origin/${branch}`, sha);\n }\n }\n const head =\n remoteState.headSymref !== null &&\n isSafeRefname(remoteState.headSymref) &&\n refs.has(remoteState.headSymref)\n ? remoteState.headSymref\n : ([...refs.keys()].find((r) => r.startsWith('refs/heads/')) ?? null);\n if (head !== null) {\n await setHeadSymref(tempDir, head);\n await runGit(tempDir, ['reset', '--hard', '--quiet']);\n }\n\n // toon.* config + origin remote: immediately push/pull-capable.\n await runGit(tempDir, ['config', 'toon.repoid', repoId]);\n await runGit(tempDir, ['config', 'toon.owner', owner]);\n await runGit(tempDir, ['remote', 'add', 'origin', relayUrl]);\n if (head !== null) {\n // Upstream config for the checked-out branch, like `git clone`.\n const branch = head.slice('refs/heads/'.length);\n await runGit(tempDir, ['config', `branch.${branch}.remote`, 'origin']);\n await runGit(tempDir, ['config', `branch.${branch}.merge`, head]);\n }\n\n // Atomic move into place (destination may exist as an empty directory).\n try {\n await rmdir(dest);\n } catch {\n // ENOENT — the destination does not exist yet; rename creates it.\n }\n await rename(tempDir, dest);\n tempDir = undefined;\n\n // ── Report ──────────────────────────────────────────────────────────────\n if (json) {\n io.emitJson({\n command: 'clone',\n repoAddr: { ownerPubkey: owner, repoId },\n relay: relayUrl,\n directory: dest,\n head,\n refs: Object.fromEntries(refs),\n name: remoteState.name,\n objectsDownloaded: written,\n executed: true,\n });\n } else {\n io.out(`Downloaded ${written} object(s) from Arweave (SHA-1 verified).`);\n for (const [refname, sha] of refs) {\n io.out(` ${sha.slice(0, 7)} ${refname}`);\n }\n if (head !== null) io.out(`HEAD is now at ${head}`);\n io.out(\n `Configured toon.repoid=${repoId}, toon.owner=${owner.slice(0, 8)}…, ` +\n `origin → ${relayUrl}`\n );\n io.out('Done.');\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'clone', err);\n } finally {\n if (tempDir !== undefined) {\n await rm(tempDir, { recursive: true, force: true }).catch(\n () => undefined\n );\n }\n }\n}\n\n// Re-exported for the acceptance flow + tests (owner column rendering).\nexport { npubToHex };\n","/**\n * The single-event `rig` subcommands (#231): issue / comment / pr, where\n * `pr` nests `create` and `status` (#250 moved the NIP-34 status publish\n * from top-level `rig status` to `rig pr status` — bare `rig status` now\n * passes through to `git status`).\n *\n * One shared pipeline behind four thin arg-parsers, mirroring `rig push`\n * (./push.ts) exactly: repo addressing from the `toon.*` git config keys\n * `rig init` writes (`--repo-id`/`--owner` override; actionable \"run\n * `rig init`\" error when unconfigured), a fee-quoting confirm gate (`--yes`\n * skips; a non-TTY session without it refuses; `--json` without `--yes` is a\n * pure estimate), and two transports (#279, ./daemon-session.ts):\n *\n * standalone (default + guarantee) — build the NIP-34 event locally\n * (../nip34-events.ts — the same builders the toon-clientd daemon uses)\n * and pay-to-publish through the embedded, nonce-guarded\n * StandalonePublisher;\n * daemon (automatic fast path) — when a running toon-clientd holds the\n * SAME identity, delegate to its loopback POST\n * /git/issue|comment|patch|status route instead: the daemon builds,\n * signs, and pays from its warm bootstrap, and it owns the channel\n * watermark (the safety goal the old refusal protected). NOTE: the\n * single-event daemon routes publish via the daemon's own configured\n * relay route — a resolved relay that differs from it draws a warning.\n *\n * The relay resolves like `rig push` (#249): `--remote <name>`\n * (default: the `origin` git remote), `--relay <url>` as an ad-hoc override\n * that bypasses remotes, deprecated `git config toon.relay` as a nudged\n * fallback. Publishes go to a SINGLE relay; multiple configured relays and\n * multi-URL remotes are refused before anything is paid (same guard as push).\n *\n * `rig pr create --range` runs REAL `git format-patch --stdout <range>` in\n * the local repository and publishes its output as the kind:1617 content —\n * one event for the whole series (cover-letter threading is out of scope in\n * v1; see the usage text).\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { parseArgs } from 'node:util';\nimport {\n REPOSITORY_ANNOUNCEMENT_KIND,\n STATUS_APPLIED_KIND,\n STATUS_CLOSED_KIND,\n STATUS_DRAFT_KIND,\n STATUS_OPEN_KIND,\n} from '@toon-protocol/core/nip34';\nimport {\n authorizedStatusAuthors,\n buildComment,\n buildIssue,\n buildPatch,\n buildStatus,\n type StatusKind,\n type UnsignedEvent,\n} from '../nip34-events.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport {\n serializeEventReceipt,\n type GitEventResponse,\n type GitRepoAddr,\n type GitStatusValue,\n} from '../routes.js';\nimport {\n type DaemonGitClient,\n type SessionPath,\n} from './daemon-session.js';\nimport { emitCliError, UnconfiguredRepoAddressError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot, type ToonRepoConfig } from './git-config.js';\nimport {\n identityReport,\n loadPaidSession,\n withForcedStandalone,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport type { ReadSeams } from './read-seams.js';\nimport { resolveRelays, singleRelayRefusal } from './remote.js';\nimport { feeLabel, renderEventPlan, renderEventReceipt } from './render.js';\nimport type { StandaloneContext } from './standalone-context.js';\nimport {\n ISSUE_LIST_USAGE,\n ISSUE_SHOW_USAGE,\n PR_LIST_USAGE,\n PR_SHOW_USAGE,\n runIssueList,\n runIssueShow,\n runPrList,\n runPrShow,\n} from './tracker.js';\n\n// ---------------------------------------------------------------------------\n// Deps\n// ---------------------------------------------------------------------------\n\n/**\n * Push deps plus a stdin reader (issue-body fallback) and the #278 read-path\n * seams (relay WebSocket / gateway fetch / SHA resolver — used by the FREE\n * `issue list|show` and `pr list|show` subcommands); tests inject all.\n */\nexport interface EventCommandDeps extends PushDeps, ReadSeams {\n /** Read all of stdin as UTF-8 (default: the real process stdin). */\n readStdin?: () => Promise<string>;\n}\n\nconst defaultReadStdin = async (): Promise<string> => {\n // Never block waiting for keyboard input (e.g. stdout piped but stdin a\n // TTY): an interactive stdin yields no body, which surfaces as the clear\n // \"body is empty\" error instead of a hang.\n if (process.stdin.isTTY) return '';\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf-8');\n};\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\n/** Flags every single-event subcommand shares (mirrors `rig push`). */\nconst COMMON_FLAGS_USAGE = ` --repo-id <id> repository id / NIP-34 d-tag (default: git config\n toon.repoid — run \\`rig init\\` to set it)\n --owner <pubkey> repository owner pubkey, 64-char hex (default: git config\n toon.owner, then the active identity)\n --remote <name> publish via this configured git remote (default: the\n \"origin\" remote — \\`rig remote add origin <relay-url>\\`)\n --relay <url> ad-hoc relay override (exactly one) — bypasses the\n configured remotes. The deprecated v0.1 \\`git config\n toon.relay\\` still works as a fallback, with a nudge\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable receipt; without --yes it is a pure\n estimate (nothing published, exit 0)\n --standalone always run embedded, bypassing a running toon-clientd\n (alias: --no-daemon; same as RIG_STANDALONE=1)\n -h, --help show this help`;\n\nexport const ISSUE_USAGE = `Usage: rig issue create --title <title> [options]\n\nFile an issue (kind:1621) against a TOON repo — a paid publish; writes are\npermanent and non-refundable. The repo address (30617:<owner>:<repoId>) comes\nfrom the toon.* git config keys \\`rig init\\` writes.\n\nBody source (exactly one): --body, --body-file, or piped stdin.\n\nOptions:\n --title <title> issue title (subject tag) [required]\n --body <text> issue body (Markdown)\n --body-file <path> read the issue body from a file\n --label <label> label (t tag); repeatable\n${COMMON_FLAGS_USAGE}\n\nRelated (FREE reads — no payment):\n rig issue list [--state open|closed|all] list the repo's issues\n rig issue show <event-id> one issue + its comments`;\n\nexport const COMMENT_USAGE = `Usage: rig comment <root-event-id> --body <text> [options]\n\nComment (kind:1622) on an issue or patch — a paid publish; writes are\npermanent and non-refundable. <root-event-id> is the 64-char hex id of the\nkind:1621 issue / kind:1617 patch being commented on.\n\nOptions:\n --body <text> comment body (Markdown) [required]\n --parent-author <pubkey> pubkey of the TARGET event's author (p threading\n tag; default: the repo owner)\n --marker <root|reply> e-tag marker (default: root — commenting directly\n on the issue/patch)\n${COMMON_FLAGS_USAGE}`;\n\nexport const PR_CREATE_USAGE = `Usage: rig pr create --title <title> (--range <range> | --patch-file <path>) [options]\n\nPublish a patch (kind:1617) whose content is REAL \\`git format-patch\\` output —\na paid publish; writes are permanent and non-refundable. --range runs\n\\`git format-patch --stdout <range>\\` in the local repository and derives the\ncommit/parent-commit tags; --patch-file publishes a pre-generated patch\nverbatim. A multi-commit range publishes ONE kind:1617 event carrying the\nfull series text — cover-letter threading (one event per commit) is out of\nscope in v1.\n\nThe PR body (--body/--body-file) is carried in a dedicated \\`description\\`\ntag, not in the event content — the content stays pure format-patch output so\n\\`rig pr show … | git am\\` keeps working.\n\nOptions:\n --title <title> patch/PR title (subject tag) [required]\n --range <range> revision range for format-patch: <rev>, <rev>..<rev>,\n or <rev>...<rev> (mutually exclusive with --patch-file)\n --patch-file <path> literal patch text to publish\n --body <text> PR description (Markdown; description tag)\n --body-file <path> read the PR description from a file\n --branch <name> branch name (t tag)\n${COMMON_FLAGS_USAGE}`;\n\nexport const PR_STATUS_USAGE = `Usage: rig pr status <target-event-id> <open|applied|closed|draft> [options]\n\nSet the status of an issue or patch — a paid publish; writes are permanent\nand non-refundable. Publishes kind:1630 (open), 1631 (applied), 1632\n(closed), or 1633 (draft) against the 64-char hex id of the target event,\nwith the repo a-tag attached so readers can scope a status stream to the\nrepository. (This command was \\`rig status\\` before v2 — bare \\`rig status\\`\nnow passes through to \\`git status\\`.)\n\nOptions:\n${COMMON_FLAGS_USAGE}`;\n\nexport const PR_USAGE = `${PR_CREATE_USAGE}\n\n${PR_STATUS_USAGE}\n\n${PR_LIST_USAGE}\n\n${PR_SHOW_USAGE}`;\n\n// ---------------------------------------------------------------------------\n// Shared flag parsing\n// ---------------------------------------------------------------------------\n\nconst HEX64_RE = /^[0-9a-f]{64}$/;\n\nfunction assertHex64(value: string, what: string): void {\n if (!HEX64_RE.test(value)) {\n throw new Error(\n `${what} must be a 64-char lowercase hex id (got ${JSON.stringify(value)})`\n );\n }\n}\n\n/** parseArgs options every subcommand accepts (mirrors `rig push`). */\nconst COMMON_OPTIONS = {\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n relay: { type: 'string', multiple: true },\n remote: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n standalone: { type: 'boolean', default: false },\n 'no-daemon': { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n} as const;\n\ninterface CommonFlags {\n yes: boolean;\n json: boolean;\n relay: string[];\n remote?: string;\n repoId?: string;\n owner?: string;\n /** Force embedded standalone, bypassing the daemon (--standalone/--no-daemon). */\n standalone: boolean;\n help: boolean;\n}\n\nfunction pickCommon(values: Record<string, unknown>): CommonFlags {\n const flags: CommonFlags = {\n yes: values['yes'] === true,\n json: values['json'] === true,\n relay: Array.isArray(values['relay']) ? (values['relay'] as string[]) : [],\n standalone: values['standalone'] === true || values['no-daemon'] === true,\n help: values['help'] === true,\n };\n const remote = values['remote'];\n if (typeof remote === 'string') flags.remote = remote;\n const repoId = values['repo-id'];\n if (typeof repoId === 'string') flags.repoId = repoId;\n const owner = values['owner'];\n if (typeof owner === 'string') {\n assertHex64(owner, '--owner');\n flags.owner = owner;\n }\n return flags;\n}\n\n// ---------------------------------------------------------------------------\n// Shared publish pipeline\n// ---------------------------------------------------------------------------\n\ntype EventCommand = 'issue' | 'comment' | 'pr' | 'pr status';\n\ninterface RunEventOptions {\n command: EventCommand;\n flags: CommonFlags;\n deps: EventCommandDeps;\n /** Human action label WITHOUT the kind, e.g. `issue \"Fix the flux\"`. */\n actionLabel: string;\n /**\n * Build the unsigned NIP-34 event for the resolved repo address — the\n * publish payload, and the source of truth for the kind. May do real work\n * (pr runs format-patch here), so failures land in the normal error path.\n * ALWAYS called (both paths) — the kind drives rendering, and the daemon\n * path reuses locally-derived values (e.g. the format-patch output).\n */\n buildEvent: (addr: GitRepoAddr) => Promise<UnsignedEvent>;\n /**\n * Drive the matching daemon `/git/*` route (#279 delegated fast path).\n * Called only after the same-identity check and the confirm gate.\n */\n sendDaemon: (\n client: DaemonGitClient,\n addr: GitRepoAddr\n ) => Promise<GitEventResponse>;\n /**\n * Optional pre-confirm hook (#287): runs AFTER the identity + repo address\n * are resolved and the event is built, but BEFORE the plan is rendered and\n * the confirm gate. Used by `pr status` to WARN when the active identity is\n * not an authorized maintainer of the target repo (the write is still\n * allowed — the relay is permissionless — but clients honoring repo\n * authority will ignore it). Failures here must be non-fatal: emit a soft\n * note and proceed. The warning prints to stderr so the existing confirm\n * gate (or --yes) still governs whether money moves.\n */\n preConfirm?: (args: {\n identity: IdentityReport;\n addr: GitRepoAddr;\n relayUrl: string | undefined;\n }) => Promise<void>;\n}\n\n/** JSON envelope emitted by `--json` runs (agents consume this). */\ninterface EventJsonOutput {\n command: EventCommand;\n repoAddr: GitRepoAddr;\n /** Which transport paid: delegated daemon or embedded standalone (#279). */\n path: SessionPath;\n /** Active identity: source tier + derived pubkey (never the phrase). */\n identity: IdentityReport;\n /** NIP-34 kind this command publishes. */\n kind: number;\n /** True when the paid publish ran. */\n executed: boolean;\n /** Per-event fee (base units, decimal string). */\n feeEstimate: string | null;\n result?: GitEventResponse;\n hint?: string;\n}\n\n/**\n * The estimate → confirm → execute flow shared by all four subcommands.\n * Money moves only after the confirm gate and the single-relay guard.\n */\nasync function runEvent(opts: RunEventOptions): Promise<number> {\n const { command, flags, actionLabel } = opts;\n // --standalone/--no-daemon: force embedded for this invocation (same as\n // RIG_STANDALONE=1). Every paid path reads the override from `env`.\n const deps = flags.standalone\n ? withForcedStandalone(opts.deps)\n : opts.deps;\n const { io } = deps;\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n // ── Repo addressing (best-effort git config; flags can stand alone) ─────\n let repoRoot: string | undefined;\n let toonConfig: ToonRepoConfig = { relays: [] };\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n toonConfig = await readToonConfig(repoRoot);\n } catch {\n // Not inside a git repository — --repo-id/--owner must carry the address.\n }\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n\n // ── Relay resolution (#249: --relay > --remote > origin > toon.relay) ───\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: flags.remote,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) io.err(resolved.nudge);\n const relaysUsed = resolved.relays;\n // Same pre-pay guard as push: StandalonePublisher publishes to exactly\n // one relay, and multiple can arrive without explicit intent (repeated\n // --relay flags, an old multi-valued git config `toon.relay`). Refuse\n // before anything is paid.\n if (relaysUsed.length > 1) {\n io.err(singleRelayRefusal(resolved, 'Nothing was published or paid.'));\n return 1;\n }\n\n // ── Paid session (#279): same-identity daemon → delegate; else the\n // standalone context (identity chain + nonce guard) + per-event fee.\n const session = await loadPaidSession(deps, relaysUsed[0]);\n const path = session.path;\n let identity: IdentityReport;\n let fee: string | undefined;\n if (session.path === 'standalone') {\n standaloneCtx = session.ctx;\n identity = identityReport(standaloneCtx);\n fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();\n } else {\n identity = session.identity;\n fee = session.feePerEvent;\n // The single-event /git/* routes publish via the daemon's own\n // configured relay route (no relayUrls field on the wire) — surface a\n // mismatch instead of silently ignoring the resolved relay.\n const resolvedRelay = relaysUsed[0];\n if (\n resolvedRelay !== undefined &&\n session.daemonRelayUrl !== undefined &&\n session.daemonRelayUrl !== resolvedRelay\n ) {\n io.err(\n `rig: the daemon publishes via its configured relay ` +\n `(${session.daemonRelayUrl}), not the resolved relay ` +\n `(${resolvedRelay}) — stop the daemon to force the standalone ` +\n 'path if that matters'\n );\n }\n }\n\n const owner = flags.owner ?? toonConfig.owner ?? identity.pubkey;\n const addr: GitRepoAddr = { ownerPubkey: owner, repoId };\n\n // Built once: the publish payload AND the kind for rendering.\n const event = await opts.buildEvent(addr);\n const action = `kind:${event.kind} ${actionLabel}`;\n\n // ── Authority pre-check (#287) — warn (do not block) before the gate ────\n if (opts.preConfirm) {\n await opts.preConfirm({ identity, addr, relayUrl: relaysUsed[0] });\n }\n\n // ── Confirm gate (identical semantics to `rig push`) ────────────────────\n if (!flags.json) {\n for (const line of renderEventPlan({\n action,\n addr,\n identity,\n ...(fee !== undefined ? { fee } : {}),\n })) {\n io.out(line);\n }\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: addr,\n path,\n identity,\n kind: event.kind,\n executed: false,\n feeEstimate: fee ?? null,\n hint: 'estimate only — re-run with --yes to publish (permanent, non-refundable)',\n } satisfies EventJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid publish (${feeLabel(fee)})? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was published.');\n return 1;\n }\n }\n\n // ── Execute ─────────────────────────────────────────────────────────────\n let result: GitEventResponse;\n if (session.path === 'standalone') {\n const receipt = await session.ctx.publisher.publishEvent(\n event,\n relaysUsed\n );\n result = serializeEventReceipt(event.kind, receipt);\n } else {\n result = await opts.sendDaemon(session.client, addr);\n }\n\n // ── Receipts ────────────────────────────────────────────────────────────\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: addr,\n path,\n identity,\n kind: result.kind,\n executed: true,\n feeEstimate: fee ?? null,\n result,\n } satisfies EventJsonOutput);\n } else {\n for (const line of renderEventReceipt(action, result)) io.out(line);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, command, err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// rig issue create\n// ---------------------------------------------------------------------------\n\n/** Run `rig issue …`; returns the process exit code. */\nexport async function runIssue(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n if (sub === '--help' || sub === '-h' || sub === 'help') {\n io.out(ISSUE_USAGE);\n io.out('');\n io.out(ISSUE_LIST_USAGE);\n io.out('');\n io.out(ISSUE_SHOW_USAGE);\n return 0;\n }\n // FREE read subcommands (#278): relay queries only, no payment path.\n if (sub === 'list') return runIssueList(rest, deps);\n if (sub === 'show') return runIssueShow(rest, deps);\n if (sub !== 'create') {\n io.err(\n sub === undefined\n ? 'missing subcommand: rig issue <create|list|show>'\n : `unknown rig issue subcommand: ${sub}`\n );\n io.err(ISSUE_USAGE);\n return 2;\n }\n\n let flags: CommonFlags;\n let title: string;\n let bodyFlag: string | undefined;\n let bodyFile: string | undefined;\n let labels: string[];\n try {\n const { values } = parseArgs({\n args: rest,\n options: {\n ...COMMON_OPTIONS,\n title: { type: 'string' },\n body: { type: 'string' },\n 'body-file': { type: 'string' },\n label: { type: 'string', multiple: true },\n },\n allowPositionals: false,\n });\n flags = pickCommon(values);\n if (!flags.help && (values.title === undefined || values.title === '')) {\n throw new Error('--title is required');\n }\n if (values.body !== undefined && values['body-file'] !== undefined) {\n throw new Error('--body and --body-file are mutually exclusive');\n }\n title = values.title ?? '';\n bodyFlag = values.body;\n bodyFile = values['body-file'];\n labels = values.label ?? [];\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(ISSUE_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(ISSUE_USAGE);\n return 0;\n }\n\n // Body source: --body → --body-file → piped stdin.\n let body: string;\n if (bodyFlag !== undefined) {\n body = bodyFlag;\n } else if (bodyFile !== undefined) {\n try {\n body = await readFile(bodyFile, 'utf-8');\n } catch (err) {\n io.err(\n `cannot read --body-file ${bodyFile}: ${err instanceof Error ? err.message : String(err)}`\n );\n return 2;\n }\n } else if (!io.isInteractive) {\n body = await (deps.readStdin ?? defaultReadStdin)();\n } else {\n io.err('an issue body is required: pass --body/--body-file or pipe stdin');\n io.err(ISSUE_USAGE);\n return 2;\n }\n if (body.trim() === '') {\n io.err('the issue body is empty — nothing to publish');\n return 2;\n }\n\n return runEvent({\n command: 'issue',\n flags,\n deps,\n actionLabel: `issue ${JSON.stringify(title)}`,\n buildEvent: async (addr) =>\n buildIssue(addr.ownerPubkey, addr.repoId, title, body, labels),\n sendDaemon: (client, addr) =>\n client.gitIssue({\n repoAddr: addr,\n title,\n body,\n ...(labels.length > 0 ? { labels } : {}),\n }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// rig comment\n// ---------------------------------------------------------------------------\n\n/** Run `rig comment …`; returns the process exit code. */\nexport async function runComment(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let flags: CommonFlags;\n let rootEventId: string;\n let body: string;\n let parentAuthor: string | undefined;\n let marker: 'root' | 'reply';\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n ...COMMON_OPTIONS,\n body: { type: 'string' },\n 'parent-author': { type: 'string' },\n marker: { type: 'string' },\n },\n allowPositionals: true,\n });\n flags = pickCommon(values);\n if (flags.help) {\n io.out(COMMENT_USAGE);\n return 0;\n }\n if (positionals.length !== 1) {\n throw new Error(\n positionals.length === 0\n ? '<root-event-id> is required'\n : `expected exactly one <root-event-id>, got ${positionals.length} positionals`\n );\n }\n rootEventId = positionals[0] as string;\n assertHex64(rootEventId, '<root-event-id>');\n if (values.body === undefined || values.body === '') {\n throw new Error('--body is required');\n }\n body = values.body;\n parentAuthor = values['parent-author'];\n if (parentAuthor !== undefined) assertHex64(parentAuthor, '--parent-author');\n const rawMarker = values.marker ?? 'root';\n if (rawMarker !== 'root' && rawMarker !== 'reply') {\n throw new Error(`--marker must be root or reply (got ${JSON.stringify(rawMarker)})`);\n }\n marker = rawMarker;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(COMMENT_USAGE);\n return 2;\n }\n\n return runEvent({\n command: 'comment',\n flags,\n deps,\n actionLabel: `comment on ${rootEventId.slice(0, 8)}…`,\n buildEvent: async (addr) =>\n buildComment(\n addr.ownerPubkey,\n addr.repoId,\n rootEventId,\n parentAuthor ?? addr.ownerPubkey,\n body,\n marker\n ),\n sendDaemon: (client, addr) =>\n client.gitComment({\n repoAddr: addr,\n rootEventId,\n body,\n ...(parentAuthor !== undefined\n ? { parentAuthorPubkey: parentAuthor }\n : {}),\n marker,\n }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// rig pr create\n// ---------------------------------------------------------------------------\n\n/** `From <sha> <date>` separator lines of `git format-patch --stdout` output. */\nconst PATCH_FROM_RE = /^From ([0-9a-f]{40}) /gm;\n\n/** Commit SHAs of a format-patch series, in patch (oldest-first) order. */\nexport function extractPatchShas(patchText: string): string[] {\n return [...patchText.matchAll(PATCH_FROM_RE)].map((m) => m[1] as string);\n}\n\n/** Run `rig pr …` (nested dispatch: create | status); returns the exit code. */\nexport async function runPr(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'create':\n return runPrCreate(rest, deps);\n case 'status':\n return runPrStatus(rest, deps);\n // FREE read subcommands (#278): relay queries only, no payment path.\n case 'list':\n return runPrList(rest, deps);\n case 'show':\n return runPrShow(rest, deps);\n case '--help':\n case '-h':\n case 'help':\n io.out(PR_USAGE);\n return 0;\n default:\n io.err(\n sub === undefined\n ? 'missing subcommand: rig pr <create|status|list|show>'\n : `unknown rig pr subcommand: ${sub}`\n );\n io.err(PR_USAGE);\n return 2;\n }\n}\n\n/** `rig pr create` — kind:1617 patch publish. */\nasync function runPrCreate(\n rest: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let flags: CommonFlags;\n let title: string;\n let range: string | undefined;\n let patchFile: string | undefined;\n let branch: string | undefined;\n let bodyFlag: string | undefined;\n let bodyFile: string | undefined;\n try {\n const { values } = parseArgs({\n args: rest,\n options: {\n ...COMMON_OPTIONS,\n title: { type: 'string' },\n range: { type: 'string' },\n 'patch-file': { type: 'string' },\n body: { type: 'string' },\n 'body-file': { type: 'string' },\n branch: { type: 'string' },\n },\n allowPositionals: false,\n });\n flags = pickCommon(values);\n if (flags.help) {\n io.out(PR_CREATE_USAGE);\n return 0;\n }\n if (values.title === undefined || values.title === '') {\n throw new Error('--title is required');\n }\n if ((values.range === undefined) === (values['patch-file'] === undefined)) {\n throw new Error('exactly one of --range or --patch-file is required');\n }\n if (values.body !== undefined && values['body-file'] !== undefined) {\n throw new Error('--body and --body-file are mutually exclusive');\n }\n title = values.title;\n range = values.range;\n patchFile = values['patch-file'];\n branch = values.branch;\n bodyFlag = values.body;\n bodyFile = values['body-file'];\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PR_CREATE_USAGE);\n return 2;\n }\n\n // PR description (optional): --body → --body-file. Carried in the event's\n // `description` tag — NEVER prepended to the content, which must stay pure\n // `git format-patch` output for `git am` (leading prose hard-fails git's\n // patch-format detection).\n let body: string | undefined;\n if (bodyFlag !== undefined) {\n body = bodyFlag;\n } else if (bodyFile !== undefined) {\n try {\n body = await readFile(bodyFile, 'utf-8');\n } catch (err) {\n io.err(\n `cannot read --body-file ${bodyFile}: ${err instanceof Error ? err.message : String(err)}`\n );\n return 2;\n }\n }\n if (body !== undefined && body.trim() === '') {\n io.err('the PR body is empty — drop --body/--body-file or pass text');\n return 2;\n }\n\n // Captured by buildEvent for the daemon path: what is SHOWN locally (the\n // built kind:1617 content) is exactly what the delegated /git/patch\n // publishes — the daemon never re-derives the series.\n let builtPatchText: string | undefined;\n let builtCommits: { sha: string; parentSha: string }[] = [];\n\n return runEvent({\n command: 'pr',\n flags,\n deps,\n actionLabel: `patch ${JSON.stringify(title)}`,\n buildEvent: async (addr) => {\n let patchText: string;\n let commits: { sha: string; parentSha: string }[];\n if (range !== undefined) {\n // REAL format-patch output from the local repository (v1 publishes\n // the whole series as ONE event; see PR_USAGE).\n const reader = new GitRepoReader(await resolveRepoRoot(deps.cwd));\n patchText = await reader.formatPatch(range);\n if (patchText === '') {\n throw new Error(\n `range ${JSON.stringify(range)} selects no commits — nothing to publish`\n );\n }\n // commit/parent-commit tags for exactly the commits the series\n // carries (parsed from the patch itself, so the tags can never drift\n // from the content). Root commits have no parent and contribute no\n // tag pair.\n const shas = extractPatchShas(patchText);\n const parents = await reader.commitParents(shas);\n commits = shas.flatMap((sha) => {\n const parentSha = parents.get(sha)?.[0];\n return parentSha ? [{ sha, parentSha }] : [];\n });\n } else {\n patchText = await readFile(patchFile as string, 'utf-8');\n if (patchText.trim() === '') {\n throw new Error(`--patch-file ${patchFile} is empty — nothing to publish`);\n }\n commits = [];\n }\n builtPatchText = patchText;\n builtCommits = commits;\n return buildPatch(\n addr.ownerPubkey,\n addr.repoId,\n title,\n commits,\n branch,\n patchText,\n body\n );\n },\n sendDaemon: (client, addr) => {\n if (builtPatchText === undefined) {\n throw new Error('internal: patch text not built before delegation');\n }\n return client.gitPatch({\n repoAddr: addr,\n title,\n patchText: builtPatchText,\n ...(body !== undefined ? { description: body } : {}),\n ...(builtCommits.length > 0 ? { commits: builtCommits } : {}),\n ...(branch !== undefined ? { branch } : {}),\n });\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// rig pr status (top-level `rig status` before #250 — now git's)\n// ---------------------------------------------------------------------------\n\n/** NIP-34 status kinds by wire value (mirrors the daemon's mapping). */\nconst STATUS_KIND_BY_VALUE: Record<GitStatusValue, StatusKind> = {\n open: STATUS_OPEN_KIND,\n applied: STATUS_APPLIED_KIND,\n closed: STATUS_CLOSED_KIND,\n draft: STATUS_DRAFT_KIND,\n};\n\nfunction isStatusValue(value: string): value is GitStatusValue {\n return Object.hasOwn(STATUS_KIND_BY_VALUE, value);\n}\n\n/** `rig pr status` — kind:1630-1633 status publish. */\nasync function runPrStatus(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let flags: CommonFlags;\n let targetEventId: string;\n let status: GitStatusValue;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: COMMON_OPTIONS,\n allowPositionals: true,\n });\n flags = pickCommon(values);\n if (flags.help) {\n io.out(PR_STATUS_USAGE);\n return 0;\n }\n if (positionals.length !== 2) {\n throw new Error(\n 'expected exactly two arguments: <target-event-id> <open|applied|closed|draft>'\n );\n }\n targetEventId = positionals[0] as string;\n assertHex64(targetEventId, '<target-event-id>');\n const rawStatus = positionals[1] as string;\n if (!isStatusValue(rawStatus)) {\n throw new Error(\n `status must be one of open | applied | closed | draft (got ${JSON.stringify(rawStatus)})`\n );\n }\n status = rawStatus;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PR_STATUS_USAGE);\n return 2;\n }\n\n return runEvent({\n command: 'pr status',\n flags,\n deps,\n actionLabel: `status ${status} on ${targetEventId.slice(0, 8)}…`,\n buildEvent: async (addr) => {\n const event = buildStatus(targetEventId, STATUS_KIND_BY_VALUE[status]);\n // NIP-34 status events also carry the repo `a` tag so readers can scope\n // a status stream to the repository without resolving the target first\n // (mirrors the daemon's gitStatus).\n event.tags.push([\n 'a',\n `${REPOSITORY_ANNOUNCEMENT_KIND}:${addr.ownerPubkey}:${addr.repoId}`,\n ]);\n return event;\n },\n // Authority warning (#287): a status event only moves an issue/PR's\n // resolved state for repo-authority-honoring clients if its author is the\n // owner or a declared maintainer. Warn clearly when the active identity is\n // neither — the publish still happens (permissionless relay; the caller\n // may be acting on their own repo/fork), but the futility is made obvious.\n preConfirm: (args) => warnIfNotMaintainer(deps, args),\n sendDaemon: (client, addr) =>\n client.gitStatus({ repoAddr: addr, targetEventId, status }),\n });\n}\n\n/**\n * Read the target repo's kind:30617 and warn on stderr when the active\n * identity is NOT an authorized status author (owner ∪ declared maintainers,\n * #287). Never throws / never blocks: a relay read failure downgrades to a\n * \"could not verify\" note and the publish proceeds under the normal gate.\n */\nasync function warnIfNotMaintainer(\n deps: EventCommandDeps,\n args: {\n identity: IdentityReport;\n addr: GitRepoAddr;\n relayUrl: string | undefined;\n }\n): Promise<void> {\n const { io } = deps;\n const { identity, addr, relayUrl } = args;\n // The owner is always an implicit maintainer — no need to read the relay.\n if (identity.pubkey.toLowerCase() === addr.ownerPubkey.toLowerCase()) return;\n if (relayUrl === undefined) return;\n try {\n const remote = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: addr.ownerPubkey,\n repoId: addr.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n const authorized = authorizedStatusAuthors(\n addr.ownerPubkey,\n remote.announceEvent?.tags ?? []\n );\n if (authorized.has(identity.pubkey.toLowerCase())) return;\n io.err(\n `warning: you (${identity.pubkey.slice(0, 8)}…) are not a maintainer of ` +\n `30617:${addr.ownerPubkey.slice(0, 8)}…:${addr.repoId} — clients honoring ` +\n 'repo authority (rig, rig-web) will IGNORE this status when resolving the ' +\n \"issue/PR's state. Publishing anyway (the relay is permissionless); ask the \" +\n 'owner to `rig maintainers add` you if this should stick.'\n );\n } catch {\n io.err(\n 'warning: could not read the repo announcement to verify your maintainer ' +\n 'status — if you are not the owner or a declared maintainer, ' +\n 'authority-honoring clients will ignore this status.'\n );\n }\n}\n","/**\n * The FREE tracker views (#278): `rig issue list|show` and `rig pr list|show`.\n *\n * Pure relay reads over NIP-01 (../remote-state.ts `queryRelay` — the same\n * decoder that tolerates the devnet relay's non-canonical EVENT payload\n * encodings): kind:1621 issues / kind:1617 patches scoped to the repo by the\n * `#a` tag (`30617:<owner>:<repoId>`), kind:1630-1633 status events to derive\n * each item's state (LATEST-WINS: highest created_at, ties broken by lowest\n * id), and kind:1622 comments under `show`. No payments, no channel, no\n * identity — reads are free on TOON.\n *\n * State derivation mirrors rig-web's proven `resolvePRStatus`, upgraded to\n * latest-wins for issues too (a re-opened issue is open again).\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n ISSUE_KIND,\n PATCH_KIND,\n REPOSITORY_ANNOUNCEMENT_KIND,\n STATUS_APPLIED_KIND,\n STATUS_CLOSED_KIND,\n STATUS_DRAFT_KIND,\n STATUS_OPEN_KIND,\n} from '@toon-protocol/core/nip34';\nimport { COMMENT_KIND, authorizedStatusAuthors } from '../nip34-events.js';\nimport { ownerToHex } from '../npub.js';\nimport {\n queryRelay,\n type NostrEvent,\n type NostrFilter,\n type WebSocketFactory,\n type WebSocketLike,\n} from '../remote-state.js';\nimport {\n emitCliError,\n UnconfiguredRepoAddressError,\n InvalidRelayUrlError,\n} from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport type { ReadCommandDeps } from './read-seams.js';\nimport { resolveRelays } from './remote.js';\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\nconst READ_COMMON_FLAGS = ` --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or 64-char hex; default: git config)\n --remote <name> read via this configured git remote (default: origin)\n --relay <url> ad-hoc relay override; repeatable — reads are merged\n --json machine-readable envelope\n -h, --help show this help`;\n\nexport const ISSUE_LIST_USAGE = `Usage: rig issue list [--state open|closed|all] [options]\n\nList the repo's issues (kind:1621) with their derived state — FREE (relay\nreads only). State comes from kind:1630-1633 status events: the latest status\nwins; an issue with no status events is open.\n\nOptions:\n --state <state> open | closed | all (default: all)\n${READ_COMMON_FLAGS}`;\n\nexport const ISSUE_SHOW_USAGE = `Usage: rig issue show <event-id> [options]\n\nShow one issue (kind:1621): metadata, derived state, body, and its\nkind:1622 comments — FREE (relay reads only). <event-id> is the 64-char hex\nid \\`rig issue create\\` printed (also visible in \\`rig issue list\\`).\n\nOptions:\n${READ_COMMON_FLAGS}`;\n\nexport const PR_LIST_USAGE = `Usage: rig pr list [--state open|applied|closed|draft|all] [options]\n\nList the repo's patches/PRs (kind:1617) with their derived state — FREE\n(relay reads only). State comes from kind:1630-1633 status events: the\nlatest status wins; a patch with no status events is open.\n\nOptions:\n --state <state> open | applied | closed | draft | all (default: all)\n${READ_COMMON_FLAGS}`;\n\nexport const PR_SHOW_USAGE = `Usage: rig pr show <event-id> [options]\n\nShow one patch/PR (kind:1617): metadata, derived state, the FULL patch text\n(real \\`git format-patch\\` output — pipe it to \\`git am\\` to apply), and its\nkind:1622 comments — FREE (relay reads only).\n\nOptions:\n${READ_COMMON_FLAGS}`;\n\n// ---------------------------------------------------------------------------\n// Status derivation (latest-wins)\n// ---------------------------------------------------------------------------\n\nexport type TrackerStatus = 'open' | 'applied' | 'closed' | 'draft';\n\nconst STATUS_BY_KIND: Record<number, TrackerStatus> = {\n [STATUS_OPEN_KIND]: 'open',\n [STATUS_APPLIED_KIND]: 'applied',\n [STATUS_CLOSED_KIND]: 'closed',\n [STATUS_DRAFT_KIND]: 'draft',\n};\n\nconst STATUS_KINDS = [\n STATUS_OPEN_KIND,\n STATUS_APPLIED_KIND,\n STATUS_CLOSED_KIND,\n STATUS_DRAFT_KIND,\n];\n\nfunction tagValue(tags: string[][], name: string): string | undefined {\n return tags.find((t) => t[0] === name)?.[1];\n}\n\nfunction tagValues(tags: string[][], name: string): string[] {\n return tags.filter((t) => t[0] === name && t[1]).map((t) => t[1] as string);\n}\n\n/**\n * Derive the state of an issue/patch from its status events: consider only\n * kind:1630-1633 events whose `e` tag references the target AND whose author\n * is AUTHORIZED — the repo owner ∪ declared maintainers (#287). Among the\n * authorized events the LATEST wins (highest created_at, ties broken by lowest\n * event id — the same replaceable convention remote-state uses). Unauthorized\n * status events (any funded stranger) are IGNORED for state; they never move\n * it. No authorized status events ⇒ open.\n *\n * `authorized` is the lowercased-hex set from {@link authorizedStatusAuthors}.\n * When it is empty (the 30617 could not be resolved) NOTHING is authorized and\n * the state stays open — a safe, non-spoofable default.\n */\nexport function deriveStatus(\n targetEventId: string,\n statusEvents: Iterable<NostrEvent>,\n authorized: ReadonlySet<string>\n): TrackerStatus {\n let winner: NostrEvent | null = null;\n for (const event of statusEvents) {\n if (STATUS_BY_KIND[event.kind] === undefined) continue;\n if (!authorized.has(event.pubkey.toLowerCase())) continue;\n if (!event.tags.some((t) => t[0] === 'e' && t[1] === targetEventId))\n continue;\n if (\n winner === null ||\n event.created_at > winner.created_at ||\n (event.created_at === winner.created_at && event.id < winner.id)\n ) {\n winner = event;\n }\n }\n return winner === null\n ? 'open'\n : (STATUS_BY_KIND[winner.kind] as TrackerStatus);\n}\n\n// ---------------------------------------------------------------------------\n// Relay querying (multi-relay merge; tolerant decode via queryRelay)\n// ---------------------------------------------------------------------------\n\nconst RELAY_TIMEOUT_MS = 10000;\nconst HEX64_RE = /^[0-9a-f]{64}$/;\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\nfunction defaultWebSocketFactory(url: string): WebSocketLike {\n const ctor = (\n globalThis as { WebSocket?: new (url: string) => WebSocketLike }\n ).WebSocket;\n if (!ctor) {\n throw new Error(\n 'No global WebSocket constructor (Node >= 22 required) — pass webSocketFactory'\n );\n }\n return new ctor(url);\n}\n\n/**\n * Query every relay with every filter and merge events by id. Resolves as\n * long as at least one relay answered; throws when all fail.\n */\nasync function queryAll(\n relays: string[],\n filters: NostrFilter[],\n webSocketFactory: WebSocketFactory\n): Promise<Map<string, NostrEvent>> {\n const jobs = relays.flatMap((relay) =>\n filters.map((filter) =>\n queryRelay(relay, filter, RELAY_TIMEOUT_MS, webSocketFactory)\n )\n );\n const results = await Promise.allSettled(jobs);\n const byId = new Map<string, NostrEvent>();\n let failures = 0;\n let firstError: unknown;\n for (const result of results) {\n if (result.status === 'rejected') {\n failures += 1;\n firstError ??= result.reason;\n continue;\n }\n for (const event of result.value) {\n if (typeof event.id === 'string' && !byId.has(event.id)) {\n byId.set(event.id, event);\n }\n }\n }\n if (failures === results.length && results.length > 0) {\n throw firstError instanceof Error\n ? firstError\n : new Error(String(firstError));\n }\n return byId;\n}\n\n// ---------------------------------------------------------------------------\n// Shared context resolution (repo address + relays; NO identity, NO payment)\n// ---------------------------------------------------------------------------\n\ninterface TrackerFlags {\n json: boolean;\n help: boolean;\n state?: string;\n relay: string[];\n remote?: string;\n repoId?: string;\n owner?: string;\n}\n\nconst TRACKER_OPTIONS = {\n json: { type: 'boolean', default: false },\n state: { type: 'string' },\n relay: { type: 'string', multiple: true },\n remote: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n} as const;\n\nfunction pickTrackerFlags(values: Record<string, unknown>): TrackerFlags {\n const flags: TrackerFlags = {\n json: values['json'] === true,\n help: values['help'] === true,\n relay: Array.isArray(values['relay']) ? (values['relay'] as string[]) : [],\n };\n if (typeof values['state'] === 'string') flags.state = values['state'];\n if (typeof values['remote'] === 'string') flags.remote = values['remote'];\n if (typeof values['repo-id'] === 'string') flags.repoId = values['repo-id'];\n if (typeof values['owner'] === 'string')\n flags.owner = ownerToHex(values['owner']);\n return flags;\n}\n\ninterface TrackerContext {\n relays: string[];\n /** Set when the repo address resolved (list always has it; show may not). */\n repoAddr: { ownerPubkey: string; repoId: string } | null;\n webSocketFactory: WebSocketFactory;\n}\n\n/**\n * Resolve relays (+ repo address when `needRepoAddr`) from flags and the git\n * config, mirroring the paid commands' #249 chain — but reads may target\n * MULTIPLE relays (results are merged), and only ws/wss URLs are usable.\n */\nasync function resolveTrackerContext(\n flags: TrackerFlags,\n deps: ReadCommandDeps,\n needRepoAddr: boolean\n): Promise<TrackerContext> {\n let repoRoot: string | undefined;\n let toonConfig: { repoId?: string; owner?: string; relays: string[] } = {\n relays: [],\n };\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n toonConfig = await readToonConfig(repoRoot);\n } catch {\n // Not inside a git repo — flags must carry everything.\n }\n\n // Resolve the repo address from flags/git config. `list` REQUIRES it (throws\n // when unresolved). `show` does not, but resolves it OPPORTUNISTICALLY when\n // available so it can fall back to it for the authority set (#287) when the\n // shown item lacks a parseable `a` tag — otherwise `show` would report a\n // falsely-`open` status that `list` (which always has the address) resolves\n // correctly.\n let repoAddr: TrackerContext['repoAddr'] = null;\n const repoId = flags.repoId ?? toonConfig.repoId;\n const owner = flags.owner ?? toonConfig.owner;\n if (repoId && owner) {\n repoAddr = { ownerPubkey: owner, repoId };\n } else if (needRepoAddr) {\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n throw new UnconfiguredRepoAddressError('repository owner');\n }\n\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: flags.remote,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n const wsRelays = resolved.relays.filter((url) => WS_URL_RE.test(url));\n if (wsRelays.length === 0) {\n throw new InvalidRelayUrlError(\n resolved.relays[0] ?? '',\n 'reads need a ws:// or wss:// relay'\n );\n }\n\n return {\n relays: wsRelays,\n repoAddr,\n webSocketFactory: deps.webSocketFactory ?? defaultWebSocketFactory,\n };\n}\n\nfunction repoATag(addr: { ownerPubkey: string; repoId: string }): string {\n return `${REPOSITORY_ANNOUNCEMENT_KIND}:${addr.ownerPubkey}:${addr.repoId}`;\n}\n\n/**\n * Resolve the AUTHORIZED status authors (#287) for a repo: the owner ∪ the\n * maintainers declared on the repo's kind:30617 announcement. Reads the 30617\n * from the relay(s) — untrusted relays may over-return, so only the owner's\n * own announcement for this `d`-tag is honored. When no announcement is found\n * the set falls back to OWNER-ONLY (the owner is always an implicit\n * maintainer); this is the safe default — an unresolved 30617 can never widen\n * authority to a stranger.\n */\nasync function fetchAuthorizedAuthors(\n ctx: TrackerContext,\n ownerPubkey: string,\n repoId: string\n): Promise<Set<string>> {\n let announceTags: string[][] = [];\n try {\n const events = await queryAll(\n ctx.relays,\n [\n {\n kinds: [REPOSITORY_ANNOUNCEMENT_KIND],\n authors: [ownerPubkey],\n '#d': [repoId],\n },\n ],\n ctx.webSocketFactory\n );\n // Latest replaceable 30617 by (created_at, id) from the trusted owner.\n let latest: NostrEvent | null = null;\n for (const event of events.values()) {\n if (event.kind !== REPOSITORY_ANNOUNCEMENT_KIND) continue;\n if (event.pubkey !== ownerPubkey) continue;\n if (!event.tags.some((t) => t[0] === 'd' && t[1] === repoId)) continue;\n if (\n latest === null ||\n event.created_at > latest.created_at ||\n (event.created_at === latest.created_at && event.id < latest.id)\n ) {\n latest = event;\n }\n }\n if (latest) announceTags = latest.tags;\n } catch {\n // Relay read failed — fall back to owner-only authority.\n }\n return authorizedStatusAuthors(ownerPubkey, announceTags);\n}\n\n// ---------------------------------------------------------------------------\n// Shared list/show engines (issues and PRs differ only in kind + fields)\n// ---------------------------------------------------------------------------\n\ninterface TrackerItem {\n eventId: string;\n kind: number;\n title: string;\n status: TrackerStatus;\n authorPubkey: string;\n createdAt: number;\n labels: string[];\n content: string;\n /** kind:1617 only: `commit` tag SHAs. */\n commitShas?: string[];\n /** kind:1617 only: `branch` tag. */\n branch?: string;\n /**\n * kind:1617 only: the PR body from the `description` tag (#280). Separate\n * from `content`, which is pure `git format-patch` output for `git am`.\n */\n description?: string;\n}\n\nfunction parseTrackerItem(\n event: NostrEvent,\n status: TrackerStatus\n): TrackerItem {\n const item: TrackerItem = {\n eventId: event.id,\n kind: event.kind,\n title:\n tagValue(event.tags, 'subject') ??\n (event.content.split('\\n')[0] ?? '').slice(0, 120),\n status,\n authorPubkey: event.pubkey,\n createdAt: event.created_at,\n labels: tagValues(event.tags, 't'),\n content: event.content,\n };\n if (event.kind === PATCH_KIND) {\n item.commitShas = tagValues(event.tags, 'commit');\n const branch = tagValue(event.tags, 'branch');\n if (branch !== undefined) item.branch = branch;\n const description = tagValue(event.tags, 'description');\n if (description !== undefined) item.description = description;\n }\n return item;\n}\n\nfunction isoDate(createdAt: number): string {\n return new Date(createdAt * 1000).toISOString().slice(0, 10);\n}\n\n/** Fetch items of `kind` for the repo + their statuses; derive state. */\nasync function fetchItems(\n ctx: TrackerContext,\n kind: number\n): Promise<TrackerItem[]> {\n const addr = ctx.repoAddr as { ownerPubkey: string; repoId: string };\n const aTag = repoATag(addr);\n // Authority set (#287): owner ∪ declared maintainers from the 30617. Fetched\n // in parallel with the items — status resolution honors ONLY these authors.\n const authorizedPromise = fetchAuthorizedAuthors(\n ctx,\n addr.ownerPubkey,\n addr.repoId\n );\n const [itemEvents, aStatusEvents] = await Promise.all([\n queryAll(\n ctx.relays,\n [{ kinds: [kind], '#a': [aTag] }],\n ctx.webSocketFactory\n ),\n queryAll(\n ctx.relays,\n [{ kinds: STATUS_KINDS, '#a': [aTag] }],\n ctx.webSocketFactory\n ),\n ]);\n\n // Defense against over-returning relays: keep only the right kind + repo.\n const items = [...itemEvents.values()].filter(\n (e) => e.kind === kind && e.tags.some((t) => t[0] === 'a' && t[1] === aTag)\n );\n\n // Statuses may lack the repo `a` tag (other clients) — also query by `#e`.\n const statuses = new Map(aStatusEvents);\n if (items.length > 0) {\n const byE = await queryAll(\n ctx.relays,\n [{ kinds: STATUS_KINDS, '#e': items.map((i) => i.id) }],\n ctx.webSocketFactory\n );\n for (const [id, event] of byE)\n if (!statuses.has(id)) statuses.set(id, event);\n }\n\n const authorized = await authorizedPromise;\n return items\n .map((event) =>\n parseTrackerItem(event, deriveStatus(event.id, statuses.values(), authorized))\n )\n .sort((a, b) => b.createdAt - a.createdAt);\n}\n\ninterface ShownItem {\n item: TrackerItem;\n comments: {\n eventId: string;\n authorPubkey: string;\n createdAt: number;\n content: string;\n }[];\n repoATag: string | null;\n}\n\n/** Fetch one item by event id + its statuses and comments. */\nasync function fetchItem(\n ctx: TrackerContext,\n eventId: string,\n expectedKind: number\n): Promise<ShownItem> {\n const found = await queryAll(\n ctx.relays,\n [{ ids: [eventId] }],\n ctx.webSocketFactory\n );\n const event = found.get(eventId);\n if (!event) {\n throw new Error(`event ${eventId} not found on ${ctx.relays.join(', ')}`);\n }\n if (event.kind !== expectedKind) {\n const hint =\n event.kind === PATCH_KIND\n ? ' (it is a kind:1617 patch — use `rig pr show`)'\n : event.kind === ISSUE_KIND\n ? ' (it is a kind:1621 issue — use `rig issue show`)'\n : '';\n throw new Error(\n `event ${eventId} has kind ${event.kind}, expected ${expectedKind}${hint}`\n );\n }\n\n const [statusEvents, commentEvents] = await Promise.all([\n queryAll(\n ctx.relays,\n [{ kinds: STATUS_KINDS, '#e': [eventId] }],\n ctx.webSocketFactory\n ),\n queryAll(\n ctx.relays,\n [{ kinds: [COMMENT_KIND], '#e': [eventId] }],\n ctx.webSocketFactory\n ),\n ]);\n\n const comments = [...commentEvents.values()]\n .filter(\n (e) =>\n e.kind === COMMENT_KIND &&\n e.tags.some((t) => t[0] === 'e' && t[1] === eventId)\n )\n .sort((a, b) => a.created_at - b.created_at)\n .map((e) => ({\n eventId: e.id,\n authorPubkey: e.pubkey,\n createdAt: e.created_at,\n content: e.content,\n }));\n\n // Authority set (#287): prefer the shown item's own `a` tag\n // (30617:<owner>:<id>) and read that repo's 30617 for the maintainers. When\n // the item lacks a parseable `a` tag, fall back to the configured repo\n // address (--repo-id/--owner or git config) so `show` matches `list` instead\n // of reporting a falsely-`open` status. Only when NEITHER is available is the\n // set empty ⇒ status stays open (safe: no stranger can move it either way).\n const repoATag = tagValue(event.tags, 'a') ?? null;\n const parsedAddr = parseRepoATag(repoATag) ?? ctx.repoAddr;\n const authorized = parsedAddr\n ? await fetchAuthorizedAuthors(ctx, parsedAddr.ownerPubkey, parsedAddr.repoId)\n : new Set<string>();\n\n return {\n item: parseTrackerItem(\n event,\n deriveStatus(eventId, statusEvents.values(), authorized)\n ),\n comments,\n repoATag,\n };\n}\n\n/** Parse a NIP-34 repo `a` tag `30617:<owner-hex>:<repoId>` into its parts. */\nfunction parseRepoATag(\n aTag: string | null\n): { ownerPubkey: string; repoId: string } | null {\n if (!aTag) return null;\n const [kind, ownerPubkey, ...repoIdParts] = aTag.split(':');\n const repoId = repoIdParts.join(':');\n if (kind !== String(REPOSITORY_ANNOUNCEMENT_KIND) || !ownerPubkey || !repoId) {\n return null;\n }\n return { ownerPubkey, repoId };\n}\n\n// ---------------------------------------------------------------------------\n// list command (shared by issue/pr)\n// ---------------------------------------------------------------------------\n\ninterface ListSpec {\n command: 'issue list' | 'pr list';\n kind: number;\n usage: string;\n states: readonly TrackerStatus[];\n jsonKey: 'issues' | 'prs';\n}\n\nasync function runList(\n args: string[],\n deps: ReadCommandDeps,\n spec: ListSpec\n): Promise<number> {\n const { io } = deps;\n let flags: TrackerFlags;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: TRACKER_OPTIONS,\n allowPositionals: true,\n });\n if (positionals.length > 0) {\n throw new Error(`rig ${spec.command} takes no positional arguments`);\n }\n flags = pickTrackerFlags(values);\n if (\n flags.state !== undefined &&\n flags.state !== 'all' &&\n !spec.states.includes(flags.state as TrackerStatus)\n ) {\n throw new Error(\n `--state must be one of ${[...spec.states, 'all'].join(' | ')} (got ${JSON.stringify(flags.state)})`\n );\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(spec.usage);\n return 2;\n }\n if (flags.help) {\n io.out(spec.usage);\n return 0;\n }\n\n try {\n const ctx = await resolveTrackerContext(flags, deps, true);\n const all = await fetchItems(ctx, spec.kind);\n const state = flags.state ?? 'all';\n const items = state === 'all' ? all : all.filter((i) => i.status === state);\n\n if (flags.json) {\n io.emitJson({\n command: spec.command,\n repoAddr: ctx.repoAddr,\n relays: ctx.relays,\n state,\n count: items.length,\n [spec.jsonKey]: items,\n });\n return 0;\n }\n\n if (items.length === 0) {\n io.out(\n `no ${state === 'all' ? '' : `${state} `}${spec.jsonKey} found for ` +\n `${repoATag(ctx.repoAddr as { ownerPubkey: string; repoId: string })}`\n );\n return 0;\n }\n for (const item of items) {\n const labels =\n item.labels.length > 0 ? ` [${item.labels.join(', ')}]` : '';\n io.out(\n `${item.status.padEnd(7)} ${item.eventId.slice(0, 8)} ${item.title}` +\n ` (${item.authorPubkey.slice(0, 8)}, ${isoDate(item.createdAt)})${labels}`\n );\n }\n io.out(\n `${items.length} ${spec.jsonKey}${state === 'all' ? '' : ` (${state})`}`\n );\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, spec.command, err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// show command (shared by issue/pr)\n// ---------------------------------------------------------------------------\n\ninterface ShowSpec {\n command: 'issue show' | 'pr show';\n kind: number;\n usage: string;\n jsonKey: 'issue' | 'pr';\n /** PRs print their full patch text; issues print the body. */\n bodyLabel: string;\n}\n\nasync function runShow(\n args: string[],\n deps: ReadCommandDeps,\n spec: ShowSpec\n): Promise<number> {\n const { io } = deps;\n let flags: TrackerFlags;\n let eventId: string;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: TRACKER_OPTIONS,\n allowPositionals: true,\n });\n flags = pickTrackerFlags(values);\n if (flags.help) {\n io.out(spec.usage);\n return 0;\n }\n if (positionals.length !== 1) {\n throw new Error('expected exactly one <event-id>');\n }\n eventId = positionals[0] as string;\n if (!HEX64_RE.test(eventId)) {\n throw new Error(\n `<event-id> must be a 64-char lowercase hex id (got ${JSON.stringify(eventId)})`\n );\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(spec.usage);\n return 2;\n }\n\n try {\n const ctx = await resolveTrackerContext(flags, deps, false);\n const shown = await fetchItem(ctx, eventId, spec.kind);\n\n if (flags.json) {\n io.emitJson({\n command: spec.command,\n relays: ctx.relays,\n repoATag: shown.repoATag,\n [spec.jsonKey]: shown.item,\n comments: shown.comments,\n });\n return 0;\n }\n\n const { item } = shown;\n io.out(`${spec.jsonKey} ${item.eventId}`);\n io.out(`Title: ${item.title}`);\n io.out(`Status: ${item.status}`);\n io.out(`Author: ${item.authorPubkey}`);\n io.out(`Date: ${isoDate(item.createdAt)}`);\n if (item.labels.length > 0) io.out(`Labels: ${item.labels.join(', ')}`);\n if (item.branch !== undefined) io.out(`Branch: ${item.branch}`);\n if (item.commitShas && item.commitShas.length > 0) {\n io.out(`Commits: ${item.commitShas.join(', ')}`);\n }\n if (shown.repoATag !== null) io.out(`Repo: ${shown.repoATag}`);\n if (item.description !== undefined) {\n // The `description` tag (`rig pr create --body`): shown as its own\n // section so the patch text below stays pipeable into `git am`.\n io.out('');\n io.out('Body:');\n for (const line of item.description.split('\\n')) io.out(line);\n }\n io.out('');\n io.out(`${spec.bodyLabel}:`);\n for (const line of item.content.split('\\n')) io.out(line);\n io.out('');\n io.out(`Comments (${shown.comments.length}):`);\n for (const comment of shown.comments) {\n io.out(\n `--- ${comment.eventId.slice(0, 8)} by ${comment.authorPubkey.slice(0, 8)} ` +\n `on ${isoDate(comment.createdAt)}`\n );\n for (const line of comment.content.split('\\n')) io.out(line);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, spec.command, err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public entry points\n// ---------------------------------------------------------------------------\n\nconst ISSUE_STATES = ['open', 'closed', 'applied', 'draft'] as const;\nconst PR_STATES = ['open', 'applied', 'closed', 'draft'] as const;\n\n/** `rig issue list` */\nexport function runIssueList(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runList(args, deps, {\n command: 'issue list',\n kind: ISSUE_KIND,\n usage: ISSUE_LIST_USAGE,\n states: ISSUE_STATES,\n jsonKey: 'issues',\n });\n}\n\n/** `rig issue show <event-id>` */\nexport function runIssueShow(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runShow(args, deps, {\n command: 'issue show',\n kind: ISSUE_KIND,\n usage: ISSUE_SHOW_USAGE,\n jsonKey: 'issue',\n bodyLabel: 'Body',\n });\n}\n\n/** `rig pr list` */\nexport function runPrList(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runList(args, deps, {\n command: 'pr list',\n kind: PATCH_KIND,\n usage: PR_LIST_USAGE,\n states: PR_STATES,\n jsonKey: 'prs',\n });\n}\n\n/** `rig pr show <event-id>` */\nexport function runPrShow(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n return runShow(args, deps, {\n command: 'pr show',\n kind: PATCH_KIND,\n usage: PR_SHOW_USAGE,\n jsonKey: 'pr',\n bodyLabel: 'Patch',\n });\n}\n","/**\n * `rig entry` — name the TOON connector rig pays.\n *\n * One URL is the whole network configuration since 4.0: a connector describes\n * itself on `GET /ilp` (addresses, prices, chains, sealing key — connector ADR\n * 0050), so there is nothing else to point rig at. This command records that\n * URL as `connectorUrl` in the shared client config, optionally with the\n * free-read relay (`--relay`) the same node serves, and shows what is in\n * effect and where it came from. Free: only the local config file is touched.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport type { CliIo } from './output.js';\n\nexport const ENTRY_USAGE = `Usage: rig entry [<connector-url> | clear] [options]\n\nName the TOON connector rig pays. A connector describes itself on GET /ilp\n(its addresses, routes and prices, settlement chains), so its URL is the\nwhole configuration. Free: only the local config file is touched.\n\n rig entry show the effective connector + relay and their source\n rig entry <connector-url> record the node's client-edge URL (https://…);\n pass --relay <wss-url> to also record its free-read relay\n rig entry clear forget the recorded connector (and relay)\n\nExisting payment channels are per node: after switching, the next paid\ncommand opens or adopts a channel with the new node.\n\nNOTE for repos: the relay a repo publishes to is its git \\`origin\\` remote,\nwhich OVERRIDES the config relayUrl. After switching, point the repo too:\n\\`rig remote add origin <relay-url>\\` (or use a fresh repo).\n\nOptions:\n --relay <url> with <connector-url>: also record the relay URL (ws:// or wss://)\n --json machine-readable envelope\n -h, --help show this help`;\n\n/** What `rig entry` needs from the command environment. */\nexport interface EntryDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n}\n\n/** The slice of the shared client config `rig entry` reads/writes. */\ninterface EntryConfigFile {\n connectorUrl?: string;\n relayUrl?: string;\n /** @deprecated pre-4.0 spellings, migrated away on write. */\n proxyUrl?: string;\n btpUrl?: string;\n [key: string]: unknown;\n}\n\n/** Where an effective endpoint value came from. */\nexport type EndpointSource =\n 'env' | 'config' | 'legacy-env' | 'legacy-config' | null;\n\n/** `--json` envelope. */\ninterface EntryJson {\n command: 'entry';\n connectorUrl: string | null;\n connectorSource: EndpointSource;\n relayUrl: string | null;\n relaySource: EndpointSource;\n /** What was written to config (mutations only). */\n wrote?: { connectorUrl: string | null; relayUrl: string | null };\n configPath: string;\n warnings?: string[];\n}\n\n/** Resolve the client config directory + path (mirrors `rig chain`). */\nfunction configPathFor(env: NodeJS.ProcessEnv): string {\n const dir = env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n return join(dir, 'config.json');\n}\n\nfunction readEntryConfig(configPath: string): EntryConfigFile {\n try {\n return JSON.parse(readFileSync(configPath, 'utf8')) as EntryConfigFile;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw new Error(\n `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** Read-merge-write: preserve every other field. */\nfunction writeEntryConfig(configPath: string, file: EntryConfigFile): void {\n mkdirSync(dirname(configPath), { recursive: true });\n writeFileSync(configPath, `${JSON.stringify(file, null, 2)}\\n`, 'utf8');\n}\n\n/** The effective connector and relay, with the precedence the paid path uses. */\nexport function effectiveEntry(\n env: NodeJS.ProcessEnv,\n file: EntryConfigFile\n): {\n connectorUrl: string | null;\n connectorSource: EndpointSource;\n relayUrl: string | null;\n relaySource: EndpointSource;\n} {\n let connectorUrl: string | null = null;\n let connectorSource: EndpointSource = null;\n if (env['TOON_CONNECTOR']) {\n connectorUrl = env['TOON_CONNECTOR'];\n connectorSource = 'env';\n } else if (env['TOON_CLIENT_PROXY_URL']) {\n connectorUrl = env['TOON_CLIENT_PROXY_URL'];\n connectorSource = 'legacy-env';\n } else if (file.connectorUrl) {\n connectorUrl = file.connectorUrl;\n connectorSource = 'config';\n } else if (file.proxyUrl) {\n connectorUrl = file.proxyUrl;\n connectorSource = 'legacy-config';\n }\n const relayUrl = env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl ?? null;\n const relaySource: EndpointSource = env['TOON_CLIENT_RELAY_URL']\n ? 'env'\n : file.relayUrl\n ? 'config'\n : null;\n return { connectorUrl, connectorSource, relayUrl, relaySource };\n}\n\nconst HTTP_URL = /^https?:\\/\\/.+/i;\nconst WS_URL = /^wss?:\\/\\/.+/i;\n\n/** Run `rig entry`; returns the process exit code. */\nexport async function runEntry(\n args: string[],\n deps: EntryDeps\n): Promise<number> {\n const { io, env } = deps;\n\n let positionals: string[];\n let relayFlag: string | undefined;\n let json = false;\n try {\n const parsed = parseArgs({\n args,\n allowPositionals: true,\n options: {\n relay: { type: 'string' },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (parsed.values.help) {\n io.out(ENTRY_USAGE);\n return 0;\n }\n positionals = parsed.positionals;\n relayFlag = parsed.values.relay;\n json = parsed.values.json ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(ENTRY_USAGE);\n return 2;\n }\n\n if (positionals.length > 1) {\n io.err(\n `rig entry takes at most one argument, got ${String(positionals.length)}: ${positionals.join(' ')}`\n );\n io.err(ENTRY_USAGE);\n return 2;\n }\n const target = positionals[0];\n\n // Usage-validate the target OUTSIDE the runtime-error wrapper (exit 2).\n let mutation:\n | { kind: 'clear' }\n | { kind: 'url'; connectorUrl: string; relayUrl?: string }\n | undefined;\n if (target !== undefined) {\n if (target === 'clear') {\n if (relayFlag !== undefined) {\n io.err('--relay only applies to a <connector-url> entry');\n io.err(ENTRY_USAGE);\n return 2;\n }\n mutation = { kind: 'clear' };\n } else if (HTTP_URL.test(target)) {\n if (relayFlag !== undefined && !WS_URL.test(relayFlag)) {\n io.err(`--relay must be a ws(s) URL, got ${JSON.stringify(relayFlag)}`);\n io.err(ENTRY_USAGE);\n return 2;\n }\n mutation = {\n kind: 'url',\n connectorUrl: target.replace(/\\/+$/, ''),\n ...(relayFlag !== undefined ? { relayUrl: relayFlag } : {}),\n };\n } else if (WS_URL.test(target)) {\n io.err(\n `${JSON.stringify(target)} is a WebSocket URL — the entry is the connector's http(s) URL ` +\n '(the one whose GET /ilp describes it); pass the relay with --relay'\n );\n io.err(ENTRY_USAGE);\n return 2;\n } else {\n io.err(\n `unknown entry ${JSON.stringify(target)} — expected a connector http(s):// URL or \\`clear\\``\n );\n io.err(ENTRY_USAGE);\n return 2;\n }\n }\n\n try {\n const configPath = configPathFor(env);\n const file = readEntryConfig(configPath);\n\n const label = (source: EndpointSource): string =>\n source === 'env'\n ? 'env'\n : source === 'legacy-env'\n ? 'env (TOON_CLIENT_PROXY_URL, pre-4.0 spelling — set TOON_CONNECTOR)'\n : source === 'config'\n ? `config (${configPath})`\n : source === 'legacy-config'\n ? `config proxyUrl (${configPath}, pre-4.0 spelling)`\n : 'not configured';\n\n // ── show (no argument) ─────────────────────────────────────────────────\n if (mutation === undefined) {\n const state = effectiveEntry(env, file);\n if (json) {\n io.emitJson({\n command: 'entry',\n ...state,\n configPath,\n } satisfies EntryJson);\n return 0;\n }\n io.out(\n `Connector ${state.connectorUrl ?? '(none)'} [${label(state.connectorSource)}]`\n );\n io.out(\n `Relay ${state.relayUrl ?? '(none)'} [${label(state.relaySource)}]`\n );\n if (!state.connectorUrl) {\n io.out(\n 'Set one with `rig entry <connector-url>` (or export TOON_CONNECTOR).'\n );\n }\n return 0;\n }\n\n // ── mutations ──────────────────────────────────────────────────────────\n const warnings: string[] = [];\n const next: EntryConfigFile = { ...file };\n // The pre-4.0 spellings are retired on any write: a stale `proxyUrl`\n // would otherwise keep outranking nothing, and `btpUrl` is ignored.\n if (file.proxyUrl !== undefined || file.btpUrl !== undefined) {\n delete next.proxyUrl;\n delete next.btpUrl;\n warnings.push(\n 'removed the pre-4.0 proxyUrl/btpUrl fields (the connector URL replaces both)'\n );\n }\n if (mutation.kind === 'clear') {\n delete next.connectorUrl;\n delete next.relayUrl;\n } else {\n next.connectorUrl = mutation.connectorUrl;\n if (mutation.relayUrl !== undefined) next.relayUrl = mutation.relayUrl;\n }\n if (env['TOON_CONNECTOR'] || env['TOON_CLIENT_PROXY_URL']) {\n warnings.push(\n 'TOON_CONNECTOR / TOON_CLIENT_PROXY_URL is set in this shell and outranks the config file'\n );\n }\n writeEntryConfig(configPath, next);\n const wrote = {\n connectorUrl: next.connectorUrl ?? null,\n relayUrl: next.relayUrl ?? null,\n };\n const state = effectiveEntry(env, next);\n\n if (json) {\n io.emitJson({\n command: 'entry',\n ...state,\n wrote,\n configPath,\n ...(warnings.length > 0 ? { warnings } : {}),\n } satisfies EntryJson);\n return 0;\n }\n if (mutation.kind === 'clear') {\n io.out(`Cleared the recorded connector in ${configPath}.`);\n } else {\n io.out(`Recorded connector ${mutation.connectorUrl} in ${configPath}.`);\n if (mutation.relayUrl !== undefined)\n io.out(`Recorded relay ${mutation.relayUrl}.`);\n }\n for (const w of warnings) io.out(`warning: ${w}`);\n io.out(\n `Effective connector: ${state.connectorUrl ?? '(none)'} [${label(state.connectorSource)}]`\n );\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'entry', err);\n }\n}\n","/**\n * `rig fetch` (#278) — the clone pipeline against an EXISTING repository:\n * fetch the remote refs + sha→txId map from the relay, download only the\n * objects the local repository is missing (SHA-1 verified), and update the\n * remote-tracking refs (refs/remotes/<remote>/*; tags to refs/tags/*),\n * reporting what moved like `git fetch` does. FREE — no payments anywhere.\n *\n * No merge: integrating fetched refs is `rig merge origin/main` (the git\n * passthrough), exactly like plain git. `rig fetch` shadows `git fetch` the\n * same way `rig push` shadows `git push`; plain-git fetches stay available\n * by running `git fetch` directly.\n */\n\nimport { parseArgs } from 'node:util';\nimport {\n isSafeRefname,\n runGit,\n updateRef,\n writeGitObjects,\n} from '../materialize.js';\nimport { ownerToHex } from '../npub.js';\nimport { collectRepoObjects } from '../read-pipeline.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport {\n emitCliError,\n InvalidRelayUrlError,\n MultiUrlRemoteError,\n UnconfiguredRepoAddressError,\n UnknownRemoteError,\n} from './errors.js';\nimport {\n readToonConfig,\n getGitRemoteUrls,\n resolveRepoRoot,\n} from './git-config.js';\nimport { MissingRemoteObjectsError } from './clone.js';\nimport type { ReadCommandDeps } from './read-seams.js';\n\nexport const FETCH_USAGE = `Usage: rig fetch [remote] [options]\n\nFetch from a TOON remote — FREE (relay reads + Arweave gateway downloads; no\npayments, no identity needed). Reads the kind:30618 repository state from the\nremote's relay, downloads only the git objects this repository is missing\n(SHA-1 verified), and updates the remote-tracking refs\n(refs/remotes/<remote>/*; tags land at refs/tags/*), reporting what moved.\n\nNo merge happens: integrate with the git passthrough, e.g.\n\\`rig merge origin/main\\`. \\`rig fetch\\` is the TOON transport and shadows\n\\`git fetch\\` — plain-git fetches remain available via \\`git fetch\\` directly.\n\nThe repo address (toon.repoid/toon.owner) comes from the config \\`rig init\\`\nor \\`rig clone\\` writes; --repo-id/--owner override.\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or 64-char hex; default: git config)\n --relay <url> ad-hoc relay override — bypasses the remote's URL\n --concurrency <n> parallel gateway downloads (default 8)\n --json machine-readable result envelope\n -h, --help show this help`;\n\n/** One remote-tracking ref movement, `git fetch`-style. */\nexport interface RefUpdate {\n /** Remote refname (as announced), e.g. `refs/heads/main`. */\n refname: string;\n /** Local ref that was updated, e.g. `refs/remotes/origin/main`. */\n localRef: string;\n oldSha: string | null;\n newSha: string;\n kind: 'new' | 'fast-forward' | 'forced' | 'up-to-date';\n}\n\nconst WS_URL_RE = /^wss?:\\/\\//i;\n\n/** Map an announced refname to its local destination for `remote`. */\nfunction localRefFor(refname: string, remote: string): string | null {\n if (refname.startsWith('refs/heads/')) {\n return `refs/remotes/${remote}/${refname.slice('refs/heads/'.length)}`;\n }\n if (refname.startsWith('refs/tags/')) return refname;\n return null; // exotic namespaces are skipped\n}\n\n/** rev-parse a ref, null when it doesn't exist. */\nasync function resolveLocalRef(\n repoRoot: string,\n refname: string\n): Promise<string | null> {\n try {\n const out = await runGit(repoRoot, [\n 'rev-parse',\n '--verify',\n '--quiet',\n refname,\n ]);\n const sha = out.trim();\n return /^[0-9a-f]{40}$/.test(sha) ? sha : null;\n } catch {\n return null;\n }\n}\n\n/** Run `rig fetch …`; returns the process exit code. */\nexport async function runFetch(\n args: string[],\n deps: ReadCommandDeps\n): Promise<number> {\n const { io } = deps;\n\n let json = false;\n let remote = 'origin';\n let relayFlag: string | undefined;\n let repoIdFlag: string | undefined;\n let ownerFlag: string | undefined;\n let concurrency: number | undefined;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n relay: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n concurrency: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n if (values.help) {\n io.out(FETCH_USAGE);\n return 0;\n }\n json = values.json === true;\n if (positionals.length > 1) {\n throw new Error(\n `expected at most one [remote] argument, got ${positionals.length}`\n );\n }\n if (positionals[0] !== undefined) remote = positionals[0];\n relayFlag = values.relay;\n repoIdFlag = values['repo-id'];\n ownerFlag =\n values.owner !== undefined ? ownerToHex(values.owner) : undefined;\n if (values.concurrency !== undefined) {\n concurrency = Number.parseInt(values.concurrency, 10);\n if (!Number.isSafeInteger(concurrency) || concurrency < 1) {\n throw new Error('--concurrency must be a positive integer');\n }\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(FETCH_USAGE);\n return 2;\n }\n\n try {\n // ── Repo addressing + relay resolution ─────────────────────────────────\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = repoIdFlag ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const owner = ownerFlag ?? toonConfig.owner;\n if (!owner) throw new UnconfiguredRepoAddressError('repository owner');\n\n let relayUrl: string;\n if (relayFlag !== undefined) {\n relayUrl = relayFlag;\n } else {\n const urls = await getGitRemoteUrls(repoRoot, remote);\n if (urls.length === 0) throw new UnknownRemoteError(remote);\n if (urls.length > 1) throw new MultiUrlRemoteError(remote, urls);\n relayUrl = urls[0] as string;\n }\n if (!WS_URL_RE.test(relayUrl)) {\n throw new InvalidRelayUrlError(\n relayUrl,\n `remote ${JSON.stringify(remote)}`\n );\n }\n\n // ── Remote state ────────────────────────────────────────────────────────\n const remoteState = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: owner,\n repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n ...(deps.resolveSha ? { resolveSha: deps.resolveSha } : {}),\n });\n\n // Plan the tracking-ref updates (hostile-relay refname gate included).\n const planned: { refname: string; localRef: string; newSha: string }[] = [];\n for (const [refname, sha] of remoteState.refs) {\n if (!isSafeRefname(refname)) {\n io.err(\n `warning: skipping unsafe ref name from relay: ${JSON.stringify(refname)}`\n );\n continue;\n }\n const localRef = localRefFor(refname, remote);\n if (localRef === null) {\n io.err(\n `warning: skipping ref outside refs/heads and refs/tags: ${refname}`\n );\n continue;\n }\n planned.push({ refname, localRef, newSha: sha });\n }\n\n // ── Delta: download only what the local repository is missing ──────────\n const reader = new GitRepoReader(repoRoot);\n const tips = [...new Set(planned.map((p) => p.newSha))];\n const candidates = [...new Set([...remoteState.shaToTxId.keys(), ...tips])];\n const { missing: absent } = await reader.statObjects(candidates);\n const absentSet = new Set(absent);\n const presentLocally = new Set(\n candidates.filter((sha) => !absentSet.has(sha))\n );\n\n const collected = await collectRepoObjects({\n tips,\n shaToTxId: remoteState.shaToTxId,\n resolveMissing: (shas) => remoteState.resolveMissing(shas),\n presentLocally,\n ...(deps.fetchFn ? { fetchFn: deps.fetchFn } : {}),\n ...(concurrency !== undefined ? { concurrency } : {}),\n });\n if (collected.missing.length > 0) {\n throw new MissingRemoteObjectsError(\n collected.missing,\n `cannot fetch from ${relayUrl}`\n );\n }\n const written = await writeGitObjects(repoRoot, collected.objects.values());\n\n // ── Update tracking refs + report movements ─────────────────────────────\n const updates: RefUpdate[] = [];\n for (const { refname, localRef, newSha } of planned) {\n const oldSha = await resolveLocalRef(repoRoot, localRef);\n if (oldSha === newSha) {\n updates.push({ refname, localRef, oldSha, newSha, kind: 'up-to-date' });\n continue;\n }\n let kind: RefUpdate['kind'];\n if (oldSha === null) {\n kind = 'new';\n } else {\n kind = (await reader.isAncestor(oldSha, newSha))\n ? 'fast-forward'\n : 'forced';\n }\n await updateRef(repoRoot, localRef, newSha);\n updates.push({ refname, localRef, oldSha, newSha, kind });\n }\n\n // ── Report ──────────────────────────────────────────────────────────────\n const moved = updates.filter((u) => u.kind !== 'up-to-date');\n if (json) {\n io.emitJson({\n command: 'fetch',\n repoAddr: { ownerPubkey: owner, repoId },\n remote,\n relay: relayUrl,\n objectsDownloaded: written,\n updates,\n executed: true,\n });\n return 0;\n }\n if (moved.length === 0) {\n io.out('Already up to date.');\n return 0;\n }\n io.out(`From ${relayUrl}`);\n for (const u of moved) {\n const short = (refname: string): string =>\n refname\n .replace(/^refs\\/heads\\//, '')\n .replace(/^refs\\/tags\\//, '')\n .replace(/^refs\\/remotes\\//, '');\n const src = short(u.refname);\n const dst = short(u.localRef);\n if (u.kind === 'new') {\n const label = u.refname.startsWith('refs/tags/')\n ? '[new tag]'\n : '[new branch]';\n io.out(` * ${label.padEnd(17)} ${src.padEnd(14)} -> ${dst}`);\n } else if (u.kind === 'forced') {\n io.out(\n ` + ${(u.oldSha as string).slice(0, 7)}...${u.newSha.slice(0, 7)} ${src.padEnd(14)} -> ${dst} (forced update)`\n );\n } else {\n io.out(\n ` ${(u.oldSha as string).slice(0, 7)}..${u.newSha.slice(0, 7)} ${src.padEnd(14)} -> ${dst}`\n );\n }\n }\n io.out(`Downloaded ${written} object(s) (SHA-1 verified).`);\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'fetch', err);\n }\n}\n","/**\n * `rig fund` — drip devnet test funds to the active identity's wallet (#263).\n *\n * A FREE command: no relay, no client start, no nonce guard, no payment\n * channel — just the identity chain (RIG_MNEMONIC precedence, ./identity.ts)\n * to derive the chain address(es), and an HTTP POST per chain to the devnet\n * faucet (`@toon-protocol/client`'s `fundWallet`, which hits the USDC-ONLY\n * legs: `POST {faucet}/api/base-sepolia/request` for EVM,\n * `/api/solana/usdc-request`, `/api/mina/usdc-request` — body `{ address }`;\n * the faucet drips a FIXED amount, so there is no --amount). Each per-chain\n * drip funds ONLY the settlement token (USDC) and ASSUMES the wallet already\n * holds enough native gas to transact — the EVM leg still best-effort tops up\n * Base Sepolia gas, but Solana/Mina expect the address to already hold SOL/MINA.\n *\n * MULTI-CHAIN BY DEFAULT: with no chain argument, `rig fund` funds ALL supported\n * chains (evm + solana + mina) so the wallet matches the multi-chain\n * `rig balance` view (#299) in one run instead of three. A chain argument —\n * positional (`rig fund sol`) or `--chain <one>` — narrows to a single chain;\n * `all` is the explicit alias for the default. The drips run in PARALLEL — the\n * Mina faucet legitimately takes\n * ~75s, so serializing would cost ~150s for a run that overlaps to ~75s — and\n * each chain's result is INDEPENDENT: one chain's faucet failing never aborts\n * the others. Exit code is 0 only when every targeted chain funded; if any\n * chain failed the exit code is 1 and the per-chain breakdown is always shown.\n *\n * Faucet resolution mirrors the toon-clientd conventions\n * (client-mcp/src/daemon/config.ts — no import, keep in sync):\n * `TOON_CLIENT_FAUCET_URL` env → `faucetUrl` in the shared client config →\n * the deployed devnet faucet when the network IS (or is inferred as) devnet.\n * A configured `*.devnet.toonprotocol.dev` origin infers devnet even when\n * `network` still reads its `custom` default (#288) — that origin is BOTH a\n * devnet-looking relay/proxy/btp endpoint in env/config AND the git `origin`\n * remote `rig remote` configures (resolved the same way push/fetch resolve\n * their relay), so a fresh user who only ran `rig remote add origin\n * wss://relay-ws.devnet.toonprotocol.dev` gets the drip from a plain\n * `rig fund` with no env var. A truly FRESH install — no origin configured\n * anywhere (env, config, git `origin`) — falls back to core's committed\n * genesis seed, whose relay/btp origin names the live shared devnet, so\n * `npm i -g @toon-protocol/rig && rig fund` drips with zero config; any\n * configured origin (devnet or not) suppresses the seed, keeping the #288\n * \"explicit stays authoritative\" rule. On any other network there is no\n * faucet: the command prints the derived wallet address(es) to fund\n * externally instead of failing silently.\n *\n * The drips are awaited (a CLI has no background) but run concurrently: the\n * Mina faucet legitimately takes ~75s, so the per-chain timeout is generous\n * (daemon convention: 90s, mina 130s; `TOON_CLIENT_FAUCET_TIMEOUT_MS` /\n * config `faucetTimeoutMs` override) and a serial evm→solana→mina run would\n * stack those budgets — parallel drips overlap them.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport { resolveIdentity } from './identity.js';\nimport type { CliIo, IdentityReport } from './push.js';\nimport { renderIdentityLine } from './render.js';\nimport { resolveRelays } from './remote.js';\n\n/**\n * The deployed devnet faucet — the same edge the e2e suite drips from\n * (`client-mcp/src/e2e/devnet.ts`). Used only when the configured network is\n * `devnet` and no explicit faucet URL is set.\n */\nexport const DEVNET_FAUCET_URL = 'https://faucet.devnet.toonprotocol.dev';\n\n/** Supported faucet chains (client `FaucetChain`). */\nconst CHAINS = ['evm', 'solana'] as const;\ntype FundChain = (typeof CHAINS)[number];\n\n/**\n * Accepted chain arguments (positional `rig fund sol` or `--chain sol`), mapped\n * to the canonical selector. Short aliases (`sol`) are accepted alongside the\n * canonical names; `all` funds every supported chain (the default).\n */\nconst CHAIN_ALIASES: Record<string, FundChain | 'all'> = {\n evm: 'evm',\n eth: 'evm',\n sol: 'solana',\n solana: 'solana',\n all: 'all',\n};\n\n/** Human-readable list of accepted chain arguments (for usage/errors). */\nconst CHAIN_ARG_LIST = 'evm | sol | solana | all';\n\n/**\n * Resolve a raw chain argument (positional or `--chain`) to the canonical\n * selector, accepting short aliases. Throws a usage error on an unknown value.\n * Returns `undefined` when no chain was given (→ the all-chains default).\n */\nfunction resolveChainArg(raw: string | undefined): FundChain | 'all' | undefined {\n if (raw === undefined) return undefined;\n const canonical = CHAIN_ALIASES[raw.toLowerCase()];\n if (!canonical) {\n throw new Error(\n `chain must be one of ${CHAIN_ARG_LIST}, got ${JSON.stringify(raw)}`\n );\n }\n return canonical;\n}\n\nexport const FUND_USAGE = `Usage: rig fund [chain] [options]\n\nDrip devnet USDC to the active identity's wallet — free (the faucet pays). Each\ndrip funds ONLY the settlement token (USDC) and assumes the wallet already holds\nenough native gas to transact. By default funds ALL supported chains (evm +\nsolana + mina) so the wallet matches the multi-chain \\`rig balance\\` view in one\nrun; name a chain — positional (\\`rig fund sol\\`) or \\`--chain\\` — to narrow to\none. The per-chain drips run in parallel and are independent — one chain's\nfaucet failing does not abort the others (exit 0 only when every targeted chain\nfunded; exit 1 if any failed, with the per-chain breakdown always shown).\n\nThe identity comes from RIG_MNEMONIC (env or a project .env) or the\n~/.toon-client keystore/config; the faucet from TOON_CLIENT_FAUCET_URL, the\nfaucetUrl config field, or the deployed devnet faucet when the network is\ndevnet — including when a configured *.devnet.toonprotocol.dev origin infers\nit (a devnet relay/proxy/btp endpoint, or the git origin remote from\n\\`rig remote add origin <devnet relay>\\`). A completely fresh install with NO\norigin configured anywhere infers devnet from the built-in genesis seed, so a\nbare \\`rig fund\\` works with zero config. The faucet drips a FIXED amount per\nchain (there is no --amount). On a network without a faucet, prints the wallet\naddress(es) to fund externally instead.\n\nOptions:\n [chain] evm | sol | solana | mina | all — positional chain to\n fund (default: all supported chains)\n --chain <chain> same as the positional chain argument\n --address <address> fund this address instead of the identity's own\n (requires an explicit single chain)\n --json machine-readable envelope (per-chain results array)\n -h, --help show this help`;\n\n/** What `rig fund` needs from the command environment. */\nexport interface FundDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n /** Working directory (starts the project-local `.env` walk). */\n cwd: string;\n /** fetch used for the faucet call (tests inject; default global fetch). */\n fetchImpl?: typeof fetch;\n /**\n * Genesis-seed loader seam: consulted ONLY when nothing else — env, config,\n * or the git `origin` remote — names an origin at all (a truly fresh\n * install with no config). Defaults to the lazy standalone\n * network-bootstrap import (core's committed genesis peer); tests inject.\n */\n loadGenesisSeed?: () => Promise<\n { relayUrl?: string; btpEndpoint?: string } | undefined\n >;\n}\n\n/** The slice of the shared client config file `rig fund` consumes. */\nexport interface FundConfigFile {\n network?: string;\n faucetUrl?: string;\n faucetTimeoutMs?: number;\n relayUrl?: string;\n proxyUrl?: string;\n btpUrl?: string;\n}\n\n/** One chain's drip outcome — the parallel, independent unit of work. */\ninterface ChainDripResult {\n chain: FundChain;\n /** True when this chain's faucet drip succeeded. */\n funded: boolean;\n /** The address that was (or would have been) funded; null if none derived. */\n address: string | null;\n /** Raw faucet response body on success (shape is faucet-defined). */\n response?: unknown;\n /** Failure reason when `funded` is false. */\n error?: string;\n /** Wall-clock duration of this chain's drip in ms (present once attempted). */\n elapsedMs?: number;\n}\n\n/** `--json` envelope. */\ninterface FundJson {\n command: 'fund';\n identity: IdentityReport;\n /** True only when EVERY targeted chain funded (overall success). */\n funded: boolean;\n network: string | null;\n faucetUrl?: string;\n /** The per-chain drip results (one entry per targeted chain). */\n results?: ChainDripResult[];\n /**\n * Set when `network` was inferred as `devnet` from a\n * `*.devnet.toonprotocol.dev` origin (#288) rather than an explicit\n * `TOON_CLIENT_NETWORK`/config value — carries the origin that triggered\n * it. A fresh-install inference from the built-in genesis seed (no origin\n * configured anywhere) is marked with a ` (genesis seed)` suffix.\n */\n inferredDevnetFrom?: string;\n /** Non-devnet path: the derived wallet addresses to fund externally. */\n addresses?: { evm: string | null; solana: string | null };\n guidance?: string;\n}\n\n/** Hostname suffix of every shared-devnet edge (relay, proxy, faucet …). */\nconst SHARED_DEVNET_SUFFIX = '.devnet.toonprotocol.dev';\n\n/** `url` when its host is a shared-devnet edge (`*.devnet.toonprotocol.dev`). */\nfunction devnetHost(url: string | undefined): string | undefined {\n if (!url) return undefined;\n try {\n const { hostname } = new URL(url);\n if (\n hostname.endsWith(SHARED_DEVNET_SUFFIX) ||\n hostname === SHARED_DEVNET_SUFFIX.slice(1)\n ) {\n return url;\n }\n } catch {\n // junk URL — other commands surface that; fund only sniffs\n }\n return undefined;\n}\n\n/**\n * The first configured relay/uplink URL that points at the shared devnet\n * (`*.devnet.toonprotocol.dev`), if any. When the user's endpoints already\n * target the shared devnet but `network` still says `custom`, the fix for a\n * failed `rig fund` is `TOON_CLIENT_NETWORK=devnet` — NOT hunting for a\n * faucet URL (the #280 UX-study trap).\n *\n * The candidate endpoints are the env/config relay/proxy/btp URLs PLUS the\n * relay(s) resolved from the git `origin` remote (`originRelays`, resolved by\n * the same `rig remote`/git-config path push and fetch use — see\n * {@link resolveOriginRelays}). The git origin is the endpoint a fresh user\n * actually configures with `rig remote add origin <devnet relay>`; keying off\n * only env/config (#291) missed it, so plain `rig fund` still refused to drip\n * (#288 reopened). Exported for tests.\n */\nexport function sharedDevnetOrigin(\n env: NodeJS.ProcessEnv,\n file: FundConfigFile,\n originRelays: string[] = []\n): string | undefined {\n const candidates = [\n env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl,\n env['TOON_CLIENT_PROXY_URL'] ?? file.proxyUrl,\n env['TOON_CLIENT_BTP_URL'] ?? file.btpUrl,\n ...originRelays,\n ];\n for (const url of candidates) {\n const hit = devnetHost(url);\n if (hit) return hit;\n }\n return undefined;\n}\n\n/**\n * The relay URL(s) the git `origin` remote resolves to — the SAME resolution\n * `rig push`/`rig fetch` use (`resolveRelays` over the repo's real git\n * remotes + the deprecated `toon.relay` fallback). `rig fund` only sniffs the\n * host for the devnet suffix, so every failure mode is swallowed to `[]`: not\n * a git repo, no `origin`, a non-relay `origin` (a GitHub clone URL), or an\n * ambiguous multi-URL origin all mean \"no origin relay to infer from\" — never\n * an error out of a free command.\n */\n/**\n * Default {@link FundDeps.loadGenesisSeed}: core's committed genesis peer,\n * loaded lazily (same pattern as `rig init`'s offline relay fallback) so a\n * run that never needs it — any configured origin — never drags the\n * standalone bootstrap in. Failures mean \"no seed\", never an error out of a\n * free command.\n */\nasync function loadGenesisSeedDefault(): Promise<\n { relayUrl?: string; btpEndpoint?: string } | undefined\n> {\n // There is no built-in network seed since 4.0: a node is named (TOON_CONNECTOR\n // / `rig entry <url>`), never discovered. Nothing configured means no seed.\n return undefined;\n}\n\n/**\n * The devnet-or-not decision shared by `rig fund` and `rig name` (#288 + the\n * genesis-seed fresh-install fallback). Precedence:\n *\n * 1. An explicit non-`custom` `TOON_CLIENT_NETWORK`/config `network` is\n * authoritative — never coerced.\n * 2. Otherwise a configured `*.devnet.toonprotocol.dev` origin (env/config\n * relay/proxy/btp URL, or the git `origin` relay) infers devnet.\n * 3. Otherwise — NOTHING configured anywhere (a truly fresh install) —\n * core's committed genesis seed is consulted. Its URLs still go through\n * {@link devnetHost}: \"seed\" never hardcodes \"devnet\"; a future seed\n * pointing elsewhere simply stops inferring. Any configured origin,\n * devnet or not, suppresses the seed so a deliberately non-devnet setup\n * keeps refusing to drip.\n *\n * Exported for `rig name` (default `--via` DVM) and tests.\n */\nexport async function resolveEffectiveNetwork(opts: {\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Pre-read client config slice (callers that already loaded it). */\n file?: FundConfigFile;\n /** Genesis-seed loader seam (tests inject; default core's committed seed). */\n loadGenesisSeed?: FundDeps['loadGenesisSeed'];\n}): Promise<{\n /** The explicit env/config network value, if any. */\n network: string | undefined;\n /** `network` with devnet inference applied. */\n effectiveNetwork: string | undefined;\n /** The devnet-looking origin that drove (or could drive) inference. */\n devnetOrigin: string | undefined;\n /** True when the origin came from the built-in genesis seed. */\n seededOrigin: boolean;\n /** True when `effectiveNetwork` is an INFERRED devnet (not explicit). */\n inferredDevnet: boolean;\n}> {\n const { env, cwd } = opts;\n const file = opts.file ?? readFundConfig(env).file;\n const network = env['TOON_CLIENT_NETWORK'] ?? file.network;\n const canInfer = network === undefined || network === 'custom';\n const originRelays = canInfer ? await resolveOriginRelays(cwd) : [];\n let devnetOrigin = sharedDevnetOrigin(env, file, originRelays);\n let seededOrigin = false;\n if (devnetOrigin === undefined && canInfer) {\n const anyConfiguredOrigin = [\n env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl,\n env['TOON_CLIENT_PROXY_URL'] ?? file.proxyUrl,\n env['TOON_CLIENT_BTP_URL'] ?? file.btpUrl,\n ...originRelays,\n ].some((url) => url !== undefined);\n if (!anyConfiguredOrigin) {\n const seed = await (opts.loadGenesisSeed ?? loadGenesisSeedDefault)();\n devnetOrigin = devnetHost(seed?.relayUrl) ?? devnetHost(seed?.btpEndpoint);\n seededOrigin = devnetOrigin !== undefined;\n }\n }\n const inferredDevnet = devnetOrigin !== undefined && canInfer;\n return {\n network,\n effectiveNetwork: inferredDevnet ? 'devnet' : network,\n devnetOrigin,\n seededOrigin,\n inferredDevnet,\n };\n}\n\nexport async function resolveOriginRelays(cwd: string): Promise<string[]> {\n let repoRoot: string;\n try {\n repoRoot = await resolveRepoRoot(cwd);\n } catch {\n return [];\n }\n try {\n const toonConfig = await readToonConfig(repoRoot);\n const resolved = await resolveRelays({\n relayFlags: [],\n remoteName: undefined,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n return resolved.relays;\n } catch {\n return [];\n }\n}\n\n/**\n * Remediation for `rig fund` on a network without a faucet. Orders the\n * suggestions by likelihood (#280): the network preset FIRST — a fresh\n * config defaults to `custom`, and on the shared devnet the whole fix is\n * `TOON_CLIENT_NETWORK=devnet` — then the faucet-URL override for\n * self-hosted networks, then external funding. Exported for tests.\n */\nexport function noFaucetGuidance(\n network: string | undefined,\n devnetOrigin: string | undefined\n): string {\n const head = `no faucet is configured for network ${JSON.stringify(network ?? 'custom')}`;\n const external =\n 'To fund the wallet externally instead, send the settlement token plus ' +\n 'native gas to the address below for the chain your channels settle on.';\n if (devnetOrigin !== undefined) {\n return (\n `${head} — but your configured origin (${devnetOrigin}) looks like ` +\n 'the shared devnet. Set TOON_CLIENT_NETWORK=devnet (or \"network\": ' +\n '\"devnet\" in the client config) and re-run `rig fund` — no faucet ' +\n `URL is needed there. ${external}`\n );\n }\n return (\n `${head}. If you meant the shared devnet, set TOON_CLIENT_NETWORK=devnet ` +\n 'and re-run `rig fund` — no faucet URL is needed there. If this is a ' +\n 'self-hosted network with its own faucet, set TOON_CLIENT_FAUCET_URL ' +\n `(or the faucetUrl config field). ${external}`\n );\n}\n\nfunction readFundConfig(env: NodeJS.ProcessEnv): {\n file: FundConfigFile;\n configPath: string;\n} {\n const dir = env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n const configPath = join(dir, 'config.json');\n try {\n return {\n file: JSON.parse(readFileSync(configPath, 'utf8')) as FundConfigFile,\n configPath,\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return { file: {}, configPath };\n }\n throw new Error(\n `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** Run `rig fund`; returns the process exit code. */\nexport async function runFund(args: string[], deps: FundDeps): Promise<number> {\n const { io, env } = deps;\n\n let resolvedChain: FundChain | 'all' | undefined;\n let addressFlag: string | undefined;\n let json = false;\n try {\n const { values, positionals } = parseArgs({\n args,\n allowPositionals: true,\n options: {\n chain: { type: 'string' },\n address: { type: 'string' },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n io.out(FUND_USAGE);\n return 0;\n }\n // The chain can be given positionally (`rig fund sol`) OR with `--chain`,\n // but not both, and at most one positional is accepted.\n if (positionals.length > 1) {\n throw new Error(\n `rig fund takes at most one chain argument, got ${positionals.length}: ${positionals.join(' ')}`\n );\n }\n const positionalChain = positionals[0];\n if (positionalChain !== undefined && values.chain !== undefined) {\n throw new Error(\n 'give the chain as a positional argument (`rig fund sol`) OR with --chain, not both'\n );\n }\n resolvedChain = resolveChainArg(positionalChain ?? values.chain);\n addressFlag = values.address;\n json = values.json ?? false;\n // A per-chain address (`--address`) is meaningless across chains — an EVM\n // 0x address cannot fund Solana or Mina. Require an explicit single chain.\n if (addressFlag !== undefined && (resolvedChain === undefined || resolvedChain === 'all')) {\n throw new Error(\n `--address requires an explicit single chain (${CHAIN_ARG_LIST}) — ` +\n 'a single address cannot fund every chain'\n );\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(FUND_USAGE);\n return 2;\n }\n\n try {\n const { file } = readFundConfig(env);\n // MULTI-CHAIN BY DEFAULT (#299 parity): no chain argument (or `all`) funds\n // every supported chain; a specific chain narrows to one. The env/config\n // `chain` settlement preference no longer narrows `rig fund` — funding all\n // chains is a strict superset and matches `rig balance`.\n const targetChains: FundChain[] =\n resolvedChain === undefined || resolvedChain === 'all'\n ? [...CHAINS]\n : [resolvedChain];\n const network = env['TOON_CLIENT_NETWORK'] ?? file.network;\n // A configured `*.devnet.toonprotocol.dev` origin means the shared devnet\n // even when `network` still reads its `custom` default (#288): the host\n // already encodes it, so infer devnet and let the faucet \"just work\"\n // instead of making the user also export TOON_CLIENT_NETWORK=devnet. The\n // origin can be an env/config relay/proxy/btp endpoint OR the git `origin`\n // remote `rig remote add origin …` configured (resolved like push/fetch);\n // a fresh user who only ran that must still get the drip. An EXPLICIT\n // non-`custom` network stays authoritative — it is never coerced.\n //\n // Only an unset/`custom` network can be inferred to devnet; when the\n // network is explicit and non-`custom` the inference is a no-op, so skip\n // the git-origin resolution (several `git` subprocesses) entirely.\n const { devnetOrigin, seededOrigin, inferredDevnet, effectiveNetwork } =\n await resolveEffectiveNetwork({\n env,\n cwd: deps.cwd,\n file,\n ...(deps.loadGenesisSeed\n ? { loadGenesisSeed: deps.loadGenesisSeed }\n : {}),\n });\n const faucetUrl =\n env['TOON_CLIENT_FAUCET_URL'] ??\n file.faucetUrl ??\n (effectiveNetwork === 'devnet' ? DEVNET_FAUCET_URL : undefined);\n\n // ── Identity chain → wallet addresses (never the phrase) ────────────────\n const resolved = await resolveIdentity({\n env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n });\n const identity: IdentityReport = {\n pubkey: resolved.pubkey,\n source: resolved.source,\n sourceLabel: resolved.sourceLabel,\n };\n // Dynamic import: `@toon-protocol/client` is heavy; runs that fail\n // earlier (usage errors) never pay its startup cost.\n const client = await import('@toon-protocol/client');\n const derived = client.deriveFullIdentity(resolved.mnemonic, {\n accountIndex: resolved.accountIndex,\n scheme: 'legacy',\n });\n const addresses = {\n evm: derived.evm.address || null,\n solana: derived.solana.publicKey || null,\n };\n\n // ── No faucet on this network: name the ACTUAL knob first (#280) ────────\n if (!faucetUrl) {\n const guidance = noFaucetGuidance(network, devnetOrigin);\n if (json) {\n io.emitJson({\n command: 'fund',\n identity,\n funded: false,\n network: network ?? null,\n addresses,\n guidance,\n } satisfies FundJson);\n return 0;\n }\n io.out(renderIdentityLine(identity));\n io.out(guidance);\n io.out('Wallet addresses:');\n io.out(` evm ${addresses.evm ?? '(no key derived)'}`);\n io.out(` solana ${addresses.solana ?? '(no key derived)'}`);\n return 0;\n }\n\n // ── Devnet faucet drips (parallel, independent per chain) ───────────────\n // Env/config override applies uniformly to every chain's drip.\n const timeoutEnv = env['TOON_CLIENT_FAUCET_TIMEOUT_MS'];\n const timeoutFor = (): number => {\n if (timeoutEnv && Number.isFinite(Number(timeoutEnv))) return Number(timeoutEnv);\n if (file.faucetTimeoutMs !== undefined) return file.faucetTimeoutMs;\n return 90_000;\n };\n\n if (!json && inferredDevnet) {\n io.out(\n seededOrigin\n ? `Inferred network 'devnet' from the built-in genesis seed ` +\n `${devnetOrigin} (nothing configured — fresh install). ` +\n 'Set TOON_CLIENT_NETWORK explicitly to override.'\n : `Inferred network 'devnet' from the configured origin ${devnetOrigin} ` +\n `(network was ${JSON.stringify(network ?? 'custom')}). ` +\n 'Set TOON_CLIENT_NETWORK explicitly to override.'\n );\n }\n if (!json) {\n const list = targetChains.join(', ');\n io.out(\n `Requesting ${targetChains.length === 1 ? '' : 'parallel '}USDC drip${targetChains.length === 1 ? '' : 's'} ` +\n `from ${faucetUrl} for ${list} …`\n );\n }\n\n // Each chain is an INDEPENDENT unit: derive-or-fail and drip-or-fail are\n // both captured into a ChainDripResult so one chain's failure never\n // rejects the batch. Kicking every drip off before awaiting makes them\n // genuinely concurrent (the Mina ~75s overlaps evm/solana, not stacks).\n const singleChain = targetChains.length === 1;\n const drips = targetChains.map(async (chain): Promise<ChainDripResult> => {\n const address = (singleChain ? addressFlag : undefined) ?? addresses[chain];\n if (!address) {\n return {\n chain,\n funded: false,\n address: null,\n error: `no ${chain} address could be derived for this identity`,\n };\n }\n const started = Date.now();\n try {\n const { response } = await client.fundWallet(faucetUrl, address, chain, {\n timeout: timeoutFor(),\n ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}),\n });\n return {\n chain,\n funded: true,\n address,\n response,\n elapsedMs: Date.now() - started,\n };\n } catch (err) {\n return {\n chain,\n funded: false,\n address,\n error: err instanceof Error ? err.message : String(err),\n elapsedMs: Date.now() - started,\n };\n }\n });\n const results = await Promise.all(drips);\n const allFunded = results.every((r) => r.funded);\n\n if (json) {\n io.emitJson({\n command: 'fund',\n identity,\n funded: allFunded,\n network: effectiveNetwork ?? null,\n faucetUrl,\n results,\n ...(inferredDevnet\n ? {\n inferredDevnetFrom: seededOrigin\n ? `${devnetOrigin} (genesis seed)`\n : devnetOrigin,\n }\n : {}),\n } satisfies FundJson);\n return allFunded ? 0 : 1;\n }\n\n for (const r of results) {\n const label = r.chain.padEnd(6);\n // Always echo the funded (or attempted) address so a human can confirm\n // WHERE the funds went — essential when `--address` targets an arbitrary,\n // non-derived address a typo could misdirect (only shown via --json\n // otherwise).\n const addr = r.address ? ` → ${r.address}` : '';\n if (r.funded) {\n // The faucet drips USDC only (gas is assumed); annotate the token, and\n // the wall time for slow chains (mina) so a >1-minute wait reads as normal.\n const slow = r.elapsedMs !== undefined && r.elapsedMs >= 5_000;\n const time = slow ? ` (${Math.round((r.elapsedMs as number) / 1000)}s)` : '';\n io.out(` ${label} ✓ funded (USDC)${addr}${time}`);\n } else {\n io.out(` ${label} ✗${addr} — ${r.error ?? 'failed'}`);\n }\n }\n io.out(renderIdentityLine(identity));\n io.out('Re-check with `rig balance` (a drip can take a few blocks to land).');\n return allFunded ? 0 : 1;\n } catch (err) {\n return emitCliError(io, json, 'fund', err);\n }\n}\n","/**\n * Git passthrough (#250): any subcommand `rig` does not own is executed as\n * `git <argv...>` verbatim — `rig status`, `rig add -p`, `rig commit`,\n * `rig log --oneline`, `rig rebase -i`, everything.\n *\n * The child git runs with `stdio: 'inherit'` so interactive commands, pagers,\n * colors, and prompts behave exactly as if the user had typed `git` (no\n * capture, no buffering). The child's exit code is propagated verbatim; a\n * child killed by a signal maps to the shell convention 128+N. While the\n * child runs, rig ignores-and-forwards SIGINT/SIGTERM/SIGHUP so git (not\n * rig) decides the outcome of a Ctrl-C — e.g. `rebase -i` gets to clean up —\n * and rig then reports git's exit.\n */\n\nimport { spawn } from 'node:child_process';\nimport { constants as osConstants } from 'node:os';\n\nexport interface GitPassthroughOptions {\n /** Working directory for the git child (default: the rig process cwd). */\n cwd?: string;\n /** Environment for the git child (default: the rig process env). */\n env?: NodeJS.ProcessEnv;\n /** Write one line to stderr (missing-git error); default: process.stderr. */\n err?: (line: string) => void;\n}\n\n/** The passthrough seam `dispatch` uses; tests inject a fake. */\nexport type GitRunner = (\n argv: string[],\n options?: GitPassthroughOptions\n) => Promise<number>;\n\n/** Exit code when the system git binary cannot be found (shell convention). */\nexport const GIT_NOT_FOUND_EXIT = 127;\n\n/** Signals relayed to the git child while it runs. */\nconst RELAYED_SIGNALS: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGHUP'];\n\n/** Shell-convention exit code for a child terminated by `signal`. */\nfunction signalExitCode(signal: NodeJS.Signals): number {\n const num = osConstants.signals[signal];\n return num === undefined ? 1 : 128 + num;\n}\n\n/**\n * Run system `git` with the exact argv tail, inheriting rig's stdio.\n * Resolves to the exit code rig should exit with; never rejects.\n */\nexport const runGitPassthrough: GitRunner = (argv, options = {}) => {\n const err =\n options.err ?? ((line: string) => process.stderr.write(`${line}\\n`));\n\n return new Promise<number>((resolve) => {\n const child = spawn('git', argv, {\n stdio: 'inherit',\n ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n env: options.env ?? process.env,\n });\n\n // Terminal-generated signals (Ctrl-C) already reach the child through the\n // shared foreground process group; the handlers stop rig's default\n // die-on-signal so the child controls the outcome, and forward the signal\n // for the cases where only rig was targeted (`kill <rig-pid>`).\n const relay = new Map<NodeJS.Signals, () => void>();\n for (const signal of RELAYED_SIGNALS) {\n const handler = (): void => {\n child.kill(signal);\n };\n relay.set(signal, handler);\n process.on(signal, handler);\n }\n const restoreSignals = (): void => {\n for (const [signal, handler] of relay) process.removeListener(signal, handler);\n };\n\n child.on('error', (spawnErr: NodeJS.ErrnoException) => {\n restoreSignals();\n if (spawnErr.code === 'ENOENT') {\n err(\n `rig: git not found — \\`rig ${argv[0] ?? ''}\\` is not a rig command, so it is ` +\n 'passed through to the system `git`, which is not on your PATH. ' +\n 'Install git (https://git-scm.com) or fix your PATH.'\n );\n resolve(GIT_NOT_FOUND_EXIT);\n return;\n }\n err(`rig: failed to run git: ${spawnErr.message}`);\n resolve(1);\n });\n\n child.on('close', (code, signal) => {\n restoreSignals();\n resolve(signal !== null ? signalExitCode(signal) : (code ?? 1));\n });\n });\n};\n","/**\n * `rig identity` — the cold-start identity command group (#294).\n *\n * rig resolves a signing identity along a precedence chain (./identity.ts) but,\n * before this command, it never MINTED one: a brand-new user hit\n * {@link MissingIdentityError} and had to hand-mint a BIP-39 phrase out of band\n * before anything ran. `rig identity` closes that gap while keeping rig's\n * deliberate security invariants intact:\n *\n * - `rig identity create` — generate a fresh BIP-39 mnemonic (via the\n * client's existing generator — no hand-rolled bip39/crypto), display it\n * ONCE with a prominent backup warning, and persist it to the ENCRYPTED\n * keystore under `TOON_CLIENT_HOME` (reusing the client/daemon keystore\n * write path + the auto-password convention). This is the ONLY command\n * that ever surfaces a phrase, and `--json` is the ONE sanctioned path\n * that emits the phrase in machine output (a scripting/agent need).\n * - `rig identity show` — report the active identity's SOURCE + derived\n * pubkey; NEVER the phrase, in any mode.\n * - `rig identity import` — read an existing phrase from stdin/prompt (NEVER\n * argv — that leaks to shell history / `ps`) and write it to the keystore.\n *\n * The phrase is written ONLY to the encrypted keystore (or shown once / emitted\n * in the sanctioned `create --json` envelope) — never to git config, never to a\n * repo file, never to plaintext outside the keystore. Persistence is gated on\n * the command being explicitly invoked (and refuses to clobber an existing\n * identity without `--force`).\n */\n\nimport { existsSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport { parseArgs } from 'node:util';\nimport { emitCliError } from './errors.js';\nimport {\n clientConfigPath,\n clientKeystorePath,\n DEFAULT_KEYSTORE_PASSWORD,\n linkKeystoreInClientConfig,\n MissingIdentityError,\n readClientConfigFile,\n resolveAccountIndex,\n resolveIdentity,\n type ResolvedIdentity,\n} from './identity.js';\nimport type { CliIo } from './output.js';\nimport { renderIdentityLine } from './render.js';\nimport { deriveNostrKeyFromMnemonic } from '../standalone/nostr-identity.js';\n\n// ---------------------------------------------------------------------------\n// Deps + client-key seam\n// ---------------------------------------------------------------------------\n\n/** The `@toon-protocol/client` key operations `rig identity` reuses. */\nexport interface IdentityKeyOps {\n /** Generate a fresh mnemonic, encrypt it, and write the keystore to `path`. */\n generateKeystore(path: string, password: string): { mnemonic: string };\n /** Validate + encrypt an existing mnemonic and write the keystore to `path`. */\n importKeystore(path: string, mnemonic: string, password: string): unknown;\n /** Derive the Nostr pubkey (hex) for a mnemonic at a BIP-44 account index. */\n deriveNostrKeyFromMnemonic(\n mnemonic: string,\n accountIndex?: number\n ): { pubkey: string };\n}\n\n/** Default key-ops loader: the real client, dynamically imported (see below). */\nasync function loadKeyOps(): Promise<IdentityKeyOps> {\n const { generateKeystore, importKeystore } = await import(\n '@toon-protocol/client'\n );\n return { generateKeystore, importKeystore, deriveNostrKeyFromMnemonic };\n}\n\n/** Deps `rig identity` needs; the seams default to the real implementations. */\nexport interface IdentityDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Identity resolver seam (tests); defaults to the real chain. */\n resolveIdentityImpl?: typeof resolveIdentity;\n /** Client key-ops seam (tests); defaults to `@toon-protocol/client`. */\n loadKeyOps?: () => Promise<IdentityKeyOps>;\n /**\n * Read one line of secret input for `rig identity import` (tests). Defaults\n * to a stdin read (prompt on stderr when interactive). NEVER argv.\n */\n readSecretLine?: (prompt: string, isInteractive: boolean) => Promise<string>;\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/** Refused: an identity already resolves and `--force` was not given. */\nexport class IdentityExistsError extends Error {\n constructor(\n public readonly pubkey: string,\n public readonly sourceLabel: string\n ) {\n super(\n `an identity already resolves (${pubkey}, from ${sourceLabel}) — rig ` +\n 'will not overwrite it. Inspect it with `rig identity show`, or pass ' +\n '`--force` to replace the keystore with a brand-new identity (the old ' +\n 'phrase becomes unrecoverable unless you backed it up).'\n );\n this.name = 'IdentityExistsError';\n }\n}\n\n/** Refused: a keystore file already sits at the target path (unlinked). */\nexport class KeystoreFileExistsError extends Error {\n constructor(public readonly keystorePath: string) {\n super(\n `a keystore file already exists at ${keystorePath} — rig will not ` +\n 'overwrite it. Link it via the client config, or pass `--force` to ' +\n 'replace it with a new identity.'\n );\n this.name = 'KeystoreFileExistsError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core: generate / import → encrypted keystore\n// ---------------------------------------------------------------------------\n\n/** A newly minted (or imported) identity — the phrase is present ONLY here. */\nexport interface CreatedIdentity {\n /** The BIP-39 phrase. Surfaced only by `create` (once / `--json`). */\n mnemonic: string;\n pubkey: string;\n keystorePath: string;\n configPath: string;\n /** True when rig chose the default keystore password (no user password). */\n autoPassword: boolean;\n accountIndex: number;\n /**\n * Set only when a HIGHER-precedence source (env / .env) still shadows the\n * new keystore identity — possible only under `--force`.\n */\n shadowedBy?: { sourceLabel: string; pubkey: string };\n}\n\n/** Inputs shared by `create` and `import` (IO-free core). */\nexport interface MintIdentityInput {\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Overwrite an existing identity / keystore file. */\n force: boolean;\n warn(line: string): void;\n resolveIdentityImpl?: typeof resolveIdentity;\n loadKeyOps?: () => Promise<IdentityKeyOps>;\n}\n\ninterface KeystoreTarget {\n keystorePath: string;\n password: string;\n autoPassword: boolean;\n /** An identity that already resolved (guards + shadow reporting). */\n existing?: ResolvedIdentity;\n keyOps: IdentityKeyOps;\n}\n\n/** Guard against clobbering, resolve the keystore path + password. */\nasync function prepareKeystoreTarget(\n input: MintIdentityInput\n): Promise<KeystoreTarget> {\n const keyOps = await (input.loadKeyOps ?? loadKeyOps)();\n const resolveImpl = input.resolveIdentityImpl ?? resolveIdentity;\n\n let existing: ResolvedIdentity | undefined;\n try {\n existing = await resolveImpl({\n env: input.env,\n cwd: input.cwd,\n warn: input.warn,\n });\n } catch (err) {\n if (!(err instanceof MissingIdentityError)) throw err;\n }\n if (existing && !input.force) {\n throw new IdentityExistsError(existing.pubkey, existing.sourceLabel);\n }\n\n const keystorePath = clientKeystorePath(input.env);\n if (existsSync(keystorePath) && !input.force) {\n throw new KeystoreFileExistsError(keystorePath);\n }\n\n // The keystore password comes ONLY from TOON_CLIENT_KEYSTORE_PASSWORD (env),\n // never a CLI flag: a `--password` argv would leak the value that decrypts\n // the keystore to shell history / `ps` / `/proc` — the exact exposure this\n // command deliberately avoids for the seed phrase itself. No env var → the\n // default password, so the identity reloads with no configuration.\n const envPassword = input.env['TOON_CLIENT_KEYSTORE_PASSWORD']?.trim() || undefined;\n const autoPassword = envPassword === undefined;\n const password = envPassword ?? DEFAULT_KEYSTORE_PASSWORD;\n\n mkdirSync(dirname(keystorePath), { recursive: true });\n return { keystorePath, password, autoPassword, existing, keyOps };\n}\n\n/** BIP-44 account index exactly as {@link resolveIdentity} will pick it for\n * the keystore this command mints (`RIG_ACCOUNT_INDEX` env > shared config >\n * 0), so the reported pubkey matches subsequent runs. */\nfunction readAccountIndex(env: NodeJS.ProcessEnv): number {\n const file = readClientConfigFile(clientConfigPath(env));\n return resolveAccountIndex(env, 'keystore', file);\n}\n\n/** Assemble the {@link CreatedIdentity} once a phrase is on disk. */\nfunction finishMint(\n input: MintIdentityInput,\n target: KeystoreTarget,\n mnemonic: string\n): CreatedIdentity {\n const configPath = linkKeystoreInClientConfig(\n input.env,\n target.keystorePath,\n target.autoPassword\n );\n const accountIndex = readAccountIndex(input.env);\n const { pubkey } = target.keyOps.deriveNostrKeyFromMnemonic(\n mnemonic,\n accountIndex\n );\n const result: CreatedIdentity = {\n mnemonic,\n pubkey,\n keystorePath: target.keystorePath,\n configPath,\n autoPassword: target.autoPassword,\n accountIndex,\n };\n if (target.existing && target.existing.pubkey !== pubkey) {\n result.shadowedBy = {\n sourceLabel: target.existing.sourceLabel,\n pubkey: target.existing.pubkey,\n };\n }\n return result;\n}\n\n/** Generate a fresh identity into the encrypted keystore. */\nexport async function createIdentity(\n input: MintIdentityInput\n): Promise<CreatedIdentity> {\n const target = await prepareKeystoreTarget(input);\n const { mnemonic } = target.keyOps.generateKeystore(\n target.keystorePath,\n target.password\n );\n return finishMint(input, target, mnemonic);\n}\n\n/** Import an existing phrase into the encrypted keystore (validated). */\nexport async function importIdentity(\n input: MintIdentityInput & { mnemonic: string }\n): Promise<CreatedIdentity> {\n const target = await prepareKeystoreTarget(input);\n // importKeystore validates the BIP-39 phrase before writing anything.\n target.keyOps.importKeystore(\n target.keystorePath,\n input.mnemonic,\n target.password\n );\n return finishMint(input, target, input.mnemonic);\n}\n\n// ---------------------------------------------------------------------------\n// Human display (the one-time backup banner)\n// ---------------------------------------------------------------------------\n\n/** The one-time seed-phrase backup banner (human, non-`--json`). */\nexport function createdIdentityBanner(result: CreatedIdentity): string[] {\n return [\n '',\n '════════════════════════════════════════════════════════════════',\n ' rig: generated a new identity',\n '════════════════════════════════════════════════════════════════',\n ` Nostr pubkey : ${result.pubkey}`,\n '',\n ' Seed phrase — this phrase CONTROLS YOUR FUNDS. Write it down and',\n ' store it safely. It is shown ONCE and CANNOT be recovered:',\n '',\n ` ${result.mnemonic}`,\n '',\n ` Encrypted keystore: ${result.keystorePath}`,\n result.autoPassword\n ? ' Encrypted with the default password, so the identity reloads with no\\n' +\n ' env var. To use your own password: set TOON_CLIENT_KEYSTORE_PASSWORD\\n' +\n ' and re-import with `rig identity import`.'\n : ' Encrypted with your TOON_CLIENT_KEYSTORE_PASSWORD.',\n '════════════════════════════════════════════════════════════════',\n '',\n ];\n}\n\n/** The stderr note fired after a fresh mint, when a higher tier shadows it. */\nexport function shadowNote(shadowedBy: {\n sourceLabel: string;\n pubkey: string;\n}): string {\n return (\n `note: a higher-precedence identity (${shadowedBy.pubkey}, from ` +\n `${shadowedBy.sourceLabel}) still shadows the new keystore — rig keeps ` +\n 'using it until you remove that source (unset the env var / edit .env).'\n );\n}\n\n// ---------------------------------------------------------------------------\n// Command dispatch\n// ---------------------------------------------------------------------------\n\nexport const IDENTITY_USAGE = `Usage: rig identity <command> [options]\n\nManage the BIP-39 signing identity rig uses to sign and pay:\n\n create generate a fresh identity into the encrypted keystore under\n TOON_CLIENT_HOME. The seed phrase is shown ONCE — back it up.\n Refuses to overwrite an existing identity without --force.\n show report the ACTIVE identity's source + derived pubkey (never the\n phrase); errors with the resolution remediation when none exists.\n import read an EXISTING phrase from stdin (never a CLI argument) and write\n it to the encrypted keystore.\n\nOptions:\n --force (create/import) replace an existing identity/keystore\n --json machine-readable output. NOTE: \\`identity create --json\\`\n DELIBERATELY emits the seed phrase in a \\`mnemonic\\`\n field — treat that output as SECRET. \\`identity show\\`\n and \\`identity import\\` never emit the phrase.\n -h, --help show this help\n\nThe keystore is encrypted with TOON_CLIENT_KEYSTORE_PASSWORD when that env var\nis set, else a default password so the identity reloads with no configuration.\nrig deliberately does NOT accept the keystore password as a CLI flag — that\nwould leak the value that decrypts your keys to shell history and \\`ps\\`.`;\n\n/** Route `rig identity <sub>`; returns the process exit code. */\nexport async function runIdentity(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const [sub, ...rest] = args;\n switch (sub) {\n case 'create':\n return runIdentityCreate(rest, deps);\n case 'show':\n return runIdentityShow(rest, deps);\n case 'import':\n return runIdentityImport(rest, deps);\n case 'help':\n case '--help':\n case '-h':\n deps.io.out(IDENTITY_USAGE);\n return 0;\n case undefined:\n deps.io.err('rig identity needs a subcommand: create | show | import');\n deps.io.err(IDENTITY_USAGE);\n return 2;\n default:\n deps.io.err(`unknown rig identity subcommand: ${sub}`);\n deps.io.err(IDENTITY_USAGE);\n return 2;\n }\n}\n\ninterface MintFlags {\n force: boolean;\n json: boolean;\n help: boolean;\n}\n\nfunction parseMintArgs(args: string[], verb: string): MintFlags {\n // No `--password` option on purpose: an unknown `--password` therefore\n // errors out (caught → usage exit) rather than silently accepting a secret\n // on the command line. The keystore password comes from the env var only.\n const { values, positionals } = parseArgs({\n args,\n options: {\n force: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: false,\n });\n if (positionals.length > 0) {\n throw new Error(`rig identity ${verb} takes no positional arguments`);\n }\n return {\n force: values.force ?? false,\n json: values.json ?? false,\n help: values.help ?? false,\n };\n}\n\nasync function runIdentityCreate(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const { io } = deps;\n let flags: MintFlags;\n try {\n flags = parseMintArgs(args, 'create');\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(IDENTITY_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(IDENTITY_USAGE);\n return 0;\n }\n\n try {\n const result = await createIdentity({\n env: deps.env,\n cwd: deps.cwd,\n force: flags.force,\n warn: (line) => io.err(line),\n ...(deps.resolveIdentityImpl\n ? { resolveIdentityImpl: deps.resolveIdentityImpl }\n : {}),\n ...(deps.loadKeyOps ? { loadKeyOps: deps.loadKeyOps } : {}),\n });\n emitCreated(io, flags.json, 'identity create', result);\n return 0;\n } catch (err) {\n return emitMintError(io, flags.json, 'identity create', err);\n }\n}\n\nasync function runIdentityImport(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const { io } = deps;\n let flags: MintFlags;\n try {\n flags = parseMintArgs(args, 'import');\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(IDENTITY_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(IDENTITY_USAGE);\n return 0;\n }\n\n try {\n const read = deps.readSecretLine ?? defaultReadSecretLine;\n const phrase = (\n await read(\n 'Paste your BIP-39 seed phrase (read from stdin, not the terminal ' +\n 'history): ',\n io.isInteractive\n )\n ).trim();\n if (phrase === '') {\n throw new Error(\n 'no seed phrase provided on stdin — pipe it in or type it at the ' +\n 'prompt (never pass a phrase as a CLI argument; it leaks to shell ' +\n 'history and `ps`).'\n );\n }\n const result = await importIdentity({\n env: deps.env,\n cwd: deps.cwd,\n force: flags.force,\n mnemonic: phrase,\n warn: (line) => io.err(line),\n ...(deps.resolveIdentityImpl\n ? { resolveIdentityImpl: deps.resolveIdentityImpl }\n : {}),\n ...(deps.loadKeyOps ? { loadKeyOps: deps.loadKeyOps } : {}),\n });\n // Import NEVER echoes the phrase back (unlike create) — only the pubkey.\n if (flags.json) {\n io.emitJson({\n command: 'identity import',\n imported: true,\n pubkey: result.pubkey,\n keystorePath: result.keystorePath,\n autoPassword: result.autoPassword,\n ...(result.shadowedBy ? { shadowedBy: result.shadowedBy } : {}),\n });\n } else {\n io.out(`Imported identity ${result.pubkey}`);\n io.out(` Encrypted keystore: ${result.keystorePath}`);\n }\n if (result.shadowedBy) io.err(shadowNote(result.shadowedBy));\n return 0;\n } catch (err) {\n return emitMintError(io, flags.json, 'identity import', err);\n }\n}\n\nasync function runIdentityShow(\n args: string[],\n deps: IdentityDeps\n): Promise<number> {\n const { io } = deps;\n let json = false;\n let help = false;\n try {\n const parsed = parseArgs({\n args,\n options: {\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: false,\n });\n json = parsed.values.json ?? false;\n help = parsed.values.help ?? false;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(IDENTITY_USAGE);\n return 2;\n }\n if (help) {\n io.out(IDENTITY_USAGE);\n return 0;\n }\n\n try {\n const identity = await (deps.resolveIdentityImpl ?? resolveIdentity)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n });\n // NEVER the phrase — source + derived pubkey only.\n if (json) {\n io.emitJson({\n command: 'identity show',\n source: identity.source,\n sourceLabel: identity.sourceLabel,\n pubkey: identity.pubkey,\n accountIndex: identity.accountIndex,\n });\n } else {\n io.out(renderIdentityLine(identity));\n io.out(` source : ${identity.source} (${identity.sourceLabel})`);\n io.out(` pubkey : ${identity.pubkey}`);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, json, 'identity show', err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Shared emitters\n// ---------------------------------------------------------------------------\n\n/**\n * Emit a freshly created identity. `--json` is the ONE sanctioned path that\n * carries the phrase (the `mnemonic` field) — a scripting/agent need — as the\n * single stdout document; human mode prints the one-time backup banner.\n */\nexport function emitCreated(\n io: CliIo,\n json: boolean,\n command: string,\n result: CreatedIdentity\n): void {\n if (json) {\n io.emitJson({\n command,\n created: true,\n pubkey: result.pubkey,\n keystorePath: result.keystorePath,\n autoPassword: result.autoPassword,\n // DELIBERATE, documented exception to \"never print the phrase\": the\n // scripting/agent path needs the generated phrase to back it up.\n mnemonic: result.mnemonic,\n ...(result.shadowedBy ? { shadowedBy: result.shadowedBy } : {}),\n });\n io.err(\n 'rig: `--json` emitted your seed phrase in the `mnemonic` field — this ' +\n 'output is SECRET; store it safely and do not log or share it.'\n );\n } else {\n for (const line of createdIdentityBanner(result)) io.out(line);\n }\n if (result.shadowedBy) io.err(shadowNote(result.shadowedBy));\n}\n\n/** Map the mint-path errors to output; refusals get their own stable codes. */\nfunction emitMintError(\n io: CliIo,\n json: boolean,\n command: string,\n err: unknown\n): 1 {\n if (err instanceof IdentityExistsError) {\n if (json) {\n io.emitJson({\n command,\n error: 'identity_exists',\n pubkey: err.pubkey,\n detail: err.message,\n });\n }\n for (const line of err.message.split('\\n')) io.err(line);\n return 1;\n }\n if (err instanceof KeystoreFileExistsError) {\n if (json) {\n io.emitJson({\n command,\n error: 'keystore_exists',\n keystorePath: err.keystorePath,\n detail: err.message,\n });\n }\n for (const line of err.message.split('\\n')) io.err(line);\n return 1;\n }\n return emitCliError(io, json, command, err);\n}\n\n/**\n * Default secret reader: one line from stdin. When a human types the phrase at\n * a TTY, the terminal echo is SUPPRESSED — the phrase is the most sensitive\n * value this CLI handles (\"CONTROLS YOUR FUNDS\"), so it must never land in\n * cleartext on screen, scrollback, or a session recording. We write the prompt\n * to stderr ourselves, then mute readline's echo of the typed characters (like\n * a conventional password prompt). Piped, non-interactive input has no echo to\n * mask, so it is read verbatim with no prompt.\n */\nasync function defaultReadSecretLine(\n prompt: string,\n isInteractive: boolean\n): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n if (isInteractive) {\n process.stderr.write(prompt);\n // Suppress echo of the typed secret. readline routes every keystroke\n // through `_writeToOutput`; replacing it with a no-op masks the input\n // while still capturing the line.\n (rl as unknown as { _writeToOutput: (s: string) => void })._writeToOutput =\n () => {\n /* mask: swallow every echoed keystroke so the phrase never prints */\n };\n }\n try {\n const answer = await rl.question('');\n // The muted Enter left the cursor on the hidden prompt line; advance it.\n if (isInteractive) process.stderr.write('\\n');\n return answer;\n } finally {\n rl.close();\n }\n}\n","/**\n * `rig init` — one-shot, idempotent repo setup (#248).\n *\n * Replaces the old \"config written as a side effect of the first push\":\n *\n * 1. ensures the working directory is inside a git repository — when it is\n * not, it OFFERS to `git init` for you (a TTY `[y/N]` prompt, or the\n * non-interactive `--git-init` flag), mirroring how it offers to mint an\n * identity on a cold start; a refusal keeps the old `git init` hint;\n * 2. resolves the signing identity via the RIG_MNEMONIC precedence chain\n * (./identity.ts) and reports the SOURCE + derived pubkey (never the\n * phrase); a chain miss errors with all three remediation options;\n * 3. writes `toon.repoid` (default: repo directory basename; existing\n * value kept on re-runs; `--repo-id` overrides) and `toon.owner` (the\n * derived pubkey) to the repository's LOCAL git config — the mnemonic\n * itself is never written to git config or any repo file;\n * 4. reports the relay setup (#249): when the deprecated v0.1\n * `git config toon.relay` is set and no `origin` remote exists, it\n * MIGRATES the value to a real `origin` git remote (the old key stays\n * readable as a fallback and is removed in v0.3); when nothing is\n * configured it suggests `rig remote add origin <relay-url>` as the\n * follow-up step.\n *\n * Re-running updates and reports instead of erroring. `--json` emits a\n * machine-readable report. Free — nothing is published or paid.\n */\n\nimport { basename } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { emitCliError, NotAGitRepositoryError } from './errors.js';\nimport {\n resolveGitAuthor,\n profileTimeoutFromEnv,\n type GitAuthor,\n} from './git-author.js';\nimport {\n addGitRemote,\n initGitRepository,\n listGitRemotes,\n readToonConfig,\n resolveRepoRoot,\n setGitAuthor,\n writeToonConfig,\n type GitRemoteInfo,\n} from './git-config.js';\nimport {\n createIdentity,\n createdIdentityBanner,\n shadowNote,\n type CreatedIdentity,\n} from './identity-cmd.js';\nimport {\n MissingIdentityError,\n resolveIdentity,\n type ResolvedIdentity,\n} from './identity.js';\nimport type { CliIo } from './push.js';\nimport { isRelayUrl } from './remote.js';\nimport { renderIdentityLine } from './render.js';\n\nexport const INIT_USAGE = `Usage: rig init [options]\n\nSet up the current git repository for rig (one-shot, idempotent, free):\nresolves your identity (RIG_MNEMONIC env → project .env → ~/.toon-client\nkeystore/config), then writes toon.repoid and toon.owner to the repo's\nLOCAL git config. Re-running updates and reports; it never errors on an\nalready-initialized repo. The seed phrase is never written anywhere.\n\nIt also sets the repo's LOCAL git commit-author from your nostr identity\n(never --global) so \\`rig commit\\`/\\`git commit\\` work out of the box and every\ncommit is attributed to the signer: user.email = <npub>@nostr, user.name =\nyour kind:0 profile display name when published (read best-effort from a\nrelay, latest-wins) else the npub. Re-running refreshes the name from a\nnow-readable profile.\n\nThe follow-up step is adding a relay: \\`rig remote add origin <relay-url>\\`\n(a real git remote — \\`git remote -v\\` shows it). A deprecated v0.1\n\\`git config toon.relay\\` is migrated to the origin remote automatically\nwhen no origin exists (the old key stays readable and is removed in v0.3).\n\nWhen the directory is NOT inside a git repository, init does not dead-end: in\na terminal it offers to create one (\\`Initialize a git repository here?\n[y/N]\\`), and \\`--git-init\\` does it non-interactively. Likewise, when NO\nidentity resolves it offers to generate one (\\`Create a new identity now?\n[y/N]\\`), and \\`--generate-identity\\` does it non-interactively (equivalent to\n\\`rig identity create\\` — the phrase is shown once to back up). Nothing — repo\nor identity — is ever created without your yes. \\`--git-init\n--generate-identity\\` is a fully non-interactive fresh setup.\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: the existing\n toon.repoid, then the repo directory basename)\n --git-init when the cwd is not a git repo, run \\`git init\\` here\n first, then proceed (no prompt)\n --relay <url> relay to read your kind:0 profile from for the git\n author name (default: origin/toon.relay, then the\n genesis seed; skipped if none is resolvable)\n --generate-identity when no identity resolves, mint a fresh one (no prompt)\n --json machine-readable report\n -h, --help show this help`;\n\n/** Deps subset `rig init` needs (no publisher — init is free). */\nexport interface InitDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Identity resolver seam (tests); defaults to the real chain. */\n resolveIdentityImpl?: typeof resolveIdentity;\n /** Identity generator seam (tests); defaults to the real mint. */\n createIdentityImpl?: typeof createIdentity;\n /** Git-author resolver seam (tests); defaults to the real kind:0 read. */\n resolveGitAuthorImpl?: typeof resolveGitAuthor;\n}\n\ninterface InitFlags {\n repoId?: string;\n gitInit: boolean;\n relay?: string;\n generateIdentity: boolean;\n json: boolean;\n help: boolean;\n}\n\nfunction parseInitArgs(args: string[]): InitFlags {\n const { values, positionals } = parseArgs({\n args,\n options: {\n 'repo-id': { type: 'string' },\n 'git-init': { type: 'boolean', default: false },\n relay: { type: 'string' },\n 'generate-identity': { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: false,\n });\n if (positionals.length > 0) {\n throw new Error(`rig init takes no positional arguments`);\n }\n const flags: InitFlags = {\n gitInit: values['git-init'] ?? false,\n generateIdentity: values['generate-identity'] ?? false,\n json: values.json ?? false,\n help: values.help ?? false,\n };\n const repoId = values['repo-id'];\n if (repoId !== undefined) {\n if (repoId.trim() === '') throw new Error('--repo-id must not be empty');\n flags.repoId = repoId;\n }\n const relay = values.relay;\n if (relay !== undefined) {\n if (relay.trim() === '') throw new Error('--relay must not be empty');\n flags.relay = relay.trim();\n }\n return flags;\n}\n\n/** True for a WebSocket-scheme URL (the kind:0 profile read speaks only ws(s)). */\nfunction isWebSocketRelay(url: string): boolean {\n return /^wss?:\\/\\//i.test(url);\n}\n\n/**\n * Resolve the relay to read the identity's kind:0 profile from, at init time —\n * BEFORE `rig remote add origin` may have run. Precedence: `--relay` flag →\n * the `origin` remote → the deprecated `toon.relay` → the #264 genesis seed.\n * Only ws(s) URLs qualify (the read is a WebSocket REQ); returns undefined when\n * none resolves, in which case the git author falls back to the npub.\n */\nasync function resolveProfileRelay(\n flagRelay: string | undefined,\n originRelay: string | undefined,\n toonRelays: string[]\n): Promise<string | undefined> {\n const candidates = [\n flagRelay,\n originRelay,\n ...toonRelays,\n ].filter((u): u is string => u !== undefined && isWebSocketRelay(u));\n if (candidates[0] !== undefined) return candidates[0];\n // No relay anywhere: the author falls back to the npub. (There is no\n // built-in network seed since 4.0 — a node is named, never discovered.)\n return undefined;\n}\n\n/** JSON envelope emitted by `rig init --json`. */\ninterface InitJsonOutput {\n command: 'init';\n repoRoot: string;\n /** True when THIS run created the git repository (`--git-init` or a TTY yes). */\n initializedGitRepo: boolean;\n repoId: string;\n /** `toon.owner` — the derived pubkey of the active identity. */\n owner: string;\n identity: {\n source: ResolvedIdentity['source'];\n sourceLabel: string;\n pubkey: string;\n };\n /** Deprecated `git config toon.relay` values (kept readable until v0.3). */\n relays: string[];\n /** True when any relay source is configured (origin remote or toon.relay). */\n relayConfigured: boolean;\n /** Configured git remotes (post-migration). */\n remotes: GitRemoteInfo[];\n /** The single relay URL of the `origin` remote, when it is one. */\n origin: string | null;\n /** True when this run migrated toon.relay to a new `origin` remote. */\n migratedToonRelay: boolean;\n /**\n * The repo-local git commit-author derived from the nostr identity (#302):\n * `user.name` (kind:0 display name when published, else the npub) and\n * `user.email` = `<npub>@nostr`. Always set so `rig commit` works out of the\n * box; `source` records whether the name came from the profile or the npub.\n */\n gitAuthor: { name: string; email: string; source: GitAuthor['source'] };\n /** What this run changed in git config (false = already up to date). */\n changed: { repoId: boolean; owner: boolean };\n /**\n * Present only when THIS run generated the identity (`--generate-identity`\n * or a TTY yes). Like `rig identity create --json`, it carries the seed\n * phrase in `mnemonic` for the scripted path — treat as SECRET.\n */\n generatedIdentity?: {\n mnemonic: string;\n pubkey: string;\n keystorePath: string;\n autoPassword: boolean;\n };\n}\n\n/**\n * Resolve the git worktree root; when the cwd is not inside a repo, create one\n * instead of dead-ending — but ONLY with consent (`--git-init` or an\n * interactive `[y/N]` yes), mirroring the identity generate-on-first-run flow.\n * A refusal (non-interactive, or a prompt no) throws {@link\n * NotAGitRepositoryError}, whose remediation now leads with `rig init\n * --git-init`. `git init` runs in the cwd only (never a parent).\n */\nasync function resolveOrInitGitRepo(\n deps: InitDeps,\n flags: InitFlags\n): Promise<{ repoRoot: string; initialized: boolean }> {\n const { io } = deps;\n try {\n return { repoRoot: await resolveRepoRoot(deps.cwd), initialized: false };\n } catch {\n let doInit = flags.gitInit;\n if (!doInit && io.isInteractive && !flags.json) {\n io.err('Not a git repository — rig keeps its config and objects in one.');\n doInit = await io.confirm('Initialize a git repository here? [y/N] ');\n }\n if (!doInit) throw new NotAGitRepositoryError(deps.cwd);\n\n await initGitRepository(deps.cwd);\n // git init succeeded, so this must now resolve.\n return { repoRoot: await resolveRepoRoot(deps.cwd), initialized: true };\n }\n}\n\n/**\n * Resolve the signing identity; when nothing resolves, generate one instead of\n * dead-ending — but ONLY with consent (`--generate-identity` or an interactive\n * yes). A refusal (non-interactive, or a `[y/N]` no) rethrows the original\n * {@link MissingIdentityError}, whose remediation now leads with\n * `rig identity create`.\n */\nasync function resolveOrGenerateIdentity(\n deps: InitDeps,\n flags: InitFlags\n): Promise<{ identity: ResolvedIdentity; generated?: CreatedIdentity }> {\n const { io, env } = deps;\n const resolve = deps.resolveIdentityImpl ?? resolveIdentity;\n try {\n return { identity: await resolve({ env, cwd: deps.cwd, warn: io.err }) };\n } catch (err) {\n if (!(err instanceof MissingIdentityError)) throw err;\n\n let generate = flags.generateIdentity;\n if (!generate && io.isInteractive && !flags.json) {\n io.err('No identity found — rig needs one to sign and pay.');\n generate = await io.confirm('Create a new identity now? [y/N] ');\n }\n if (!generate) throw err;\n\n const created = await (deps.createIdentityImpl ?? createIdentity)({\n env,\n cwd: deps.cwd,\n force: false,\n warn: io.err,\n ...(deps.resolveIdentityImpl\n ? { resolveIdentityImpl: deps.resolveIdentityImpl }\n : {}),\n });\n // Build the ResolvedIdentity from the fresh mint directly (rather than\n // re-resolving) so a custom-password keystore needs no env var to link.\n const identity: ResolvedIdentity = {\n mnemonic: created.mnemonic,\n accountIndex: created.accountIndex,\n source: 'keystore',\n sourceLabel: created.keystorePath,\n pubkey: created.pubkey,\n };\n return { identity, generated: created };\n }\n}\n\n/** Run `rig init`; returns the process exit code. */\nexport async function runInit(args: string[], deps: InitDeps): Promise<number> {\n const { io } = deps;\n\n let flags: InitFlags;\n try {\n flags = parseInitArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(INIT_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(INIT_USAGE);\n return 0;\n }\n\n try {\n // ── (a) Git repository — create one (consent-gated) when there is none ──\n // A cold start (`mkdir x && rig init`) is no longer a dead end: with\n // consent init runs `git init` here first (prompt, or `--git-init`).\n const { repoRoot, initialized: initializedGitRepo } =\n await resolveOrInitGitRepo(deps, flags);\n\n // ── (b) Identity chain: source + derived pubkey (never the phrase) ──────\n // A chain miss no longer dead-ends: offer or honor identity generation.\n const { identity, generated } = await resolveOrGenerateIdentity(deps, flags);\n\n // ── (c) Write toon.repoid / toon.owner to LOCAL git config ──────────────\n const existing = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? existing.repoId ?? basename(repoRoot);\n const changed = {\n repoId: existing.repoId !== repoId,\n owner: existing.owner !== identity.pubkey,\n };\n await writeToonConfig(repoRoot, { repoId, owner: identity.pubkey });\n\n // ── (d) Relay setup (#249): migrate toon.relay → origin remote ──────────\n // toon.relay is the deprecated v0.1 key. When it is set, single-valued,\n // relay-shaped, and no `origin` remote exists, adopt it as a real git\n // remote. The old key stays readable (paid commands still fall back to\n // it, with a nudge) and is removed in v0.3.\n let remotes = await listGitRemotes(repoRoot);\n let migratedToonRelay = false;\n const legacyRelay = existing.relays[0];\n if (\n !remotes.some((r) => r.name === 'origin') &&\n existing.relays.length === 1 &&\n legacyRelay !== undefined &&\n isRelayUrl(legacyRelay)\n ) {\n await addGitRemote(repoRoot, 'origin', legacyRelay);\n migratedToonRelay = true;\n remotes = await listGitRemotes(repoRoot);\n }\n const origin = remotes.find((r) => r.name === 'origin');\n const originRelay =\n origin !== undefined &&\n origin.urls.length === 1 &&\n isRelayUrl(origin.urls[0] as string)\n ? (origin.urls[0] as string)\n : undefined;\n\n // ── (e) Git commit-author from the nostr identity (#302) ────────────────\n // On a rig repo the nostr key IS the identity: set the repo's LOCAL git\n // author (never --global) so `rig commit` (a git passthrough) stops\n // dead-ending on \"empty ident name not allowed\" and every commit is\n // attributed to the signer. user.name = the kind:0 display name when\n // published (best-effort, latest-wins), else the npub; email `<npub>@nostr`.\n // Re-running refreshes user.name from a now-readable profile.\n const profileRelay = await resolveProfileRelay(\n flags.relay,\n originRelay,\n existing.relays\n );\n const resolveAuthor = deps.resolveGitAuthorImpl ?? resolveGitAuthor;\n const gitAuthor = await resolveAuthor({\n pubkey: identity.pubkey,\n relayUrl: profileRelay,\n ...(profileTimeoutFromEnv(deps.env) !== undefined\n ? { timeoutMs: profileTimeoutFromEnv(deps.env) as number }\n : {}),\n });\n await setGitAuthor(repoRoot, {\n name: gitAuthor.name,\n email: gitAuthor.email,\n });\n\n // ── (f) Report ───────────────────────────────────────────────────────────\n if (flags.json) {\n const output: InitJsonOutput = {\n command: 'init',\n repoRoot,\n initializedGitRepo,\n repoId,\n owner: identity.pubkey,\n identity: {\n source: identity.source,\n sourceLabel: identity.sourceLabel,\n pubkey: identity.pubkey,\n },\n relays: existing.relays,\n relayConfigured: originRelay !== undefined || existing.relays.length > 0,\n remotes,\n origin: originRelay ?? null,\n migratedToonRelay,\n gitAuthor: {\n name: gitAuthor.name,\n email: gitAuthor.email,\n source: gitAuthor.source,\n },\n changed,\n ...(generated\n ? {\n generatedIdentity: {\n mnemonic: generated.mnemonic,\n pubkey: generated.pubkey,\n keystorePath: generated.keystorePath,\n autoPassword: generated.autoPassword,\n },\n }\n : {}),\n };\n io.emitJson(output);\n if (generated) {\n io.err(\n 'rig: `--json` emitted your new seed phrase in ' +\n '`generatedIdentity.mnemonic` — this output is SECRET; store it ' +\n 'safely and do not log or share it.'\n );\n if (generated.shadowedBy) io.err(shadowNote(generated.shadowedBy));\n }\n return 0;\n }\n\n // A freshly minted identity gets its one-time backup banner FIRST, before\n // the init report, so the phrase is the thing the user sees.\n if (generated) {\n for (const line of createdIdentityBanner(generated)) io.out(line);\n if (generated.shadowedBy) io.err(shadowNote(generated.shadowedBy));\n }\n if (initializedGitRepo) io.out(`Created a git repository at ${repoRoot}`);\n io.out(`Initialized rig for ${repoRoot}`);\n io.out(renderIdentityLine(identity));\n io.out(\n ` toon.repoid = ${repoId}` +\n (changed.repoId ? '' : ' (unchanged)') +\n (existing.repoId && changed.repoId ? ` (was ${existing.repoId})` : '')\n );\n io.out(\n ` toon.owner = ${identity.pubkey}` +\n (changed.owner ? '' : ' (unchanged)') +\n (existing.owner && changed.owner ? ` (was ${existing.owner})` : '')\n );\n io.out(\n `Git author: ${gitAuthor.name} <${gitAuthor.email}> ` +\n `(from ${gitAuthor.source === 'profile' ? 'nostr profile' : 'npub'})`\n );\n if (originRelay !== undefined) {\n io.out(\n ` origin = ${originRelay}` +\n (migratedToonRelay ? ' (migrated from git config toon.relay)' : '')\n );\n if (migratedToonRelay) {\n io.out(\n 'note: toon.relay is deprecated — it stays readable as a fallback ' +\n 'and is removed in v0.3; drop it now with ' +\n '`git config --unset-all toon.relay`.'\n );\n }\n io.out('Ready: `rig push` publishes this repo via remote \"origin\".');\n } else if (existing.relays.length > 0) {\n // toon.relay is set but could not be migrated (multi-valued, junk URL,\n // or a non-relay `origin` remote already occupies the name).\n io.out(` toon.relay = ${existing.relays.join(', ')} (deprecated)`);\n io.out(\n origin !== undefined\n ? `The \"origin\" remote (${origin.urls.join(', ')}) is not a single ` +\n 'relay URL, so toon.relay stays the fallback — add the relay ' +\n 'under another name (`rig remote add toon <relay-url>`) and ' +\n 'push with `rig push toon`.'\n : existing.relays.length > 1\n ? `toon.relay has ${existing.relays.length} values and rig ` +\n 'publishes to one relay — migrate the right one: ' +\n '`rig remote add origin <relay-url>`.'\n : 'This value is not a relay URL (ws://, wss://, http://, or ' +\n 'https://) — set a real one: `rig remote add origin <relay-url>`.'\n );\n } else if (origin !== undefined) {\n // The origin name is occupied by a non-relay remote (e.g. a GitHub\n // clone) and no legacy toon.relay exists.\n io.out(\n `No relay configured yet — \"origin\" (${origin.urls.join(', ')}) is ` +\n 'not a relay URL, so add the relay under another name: ' +\n '`rig remote add toon <relay-url>`, then `rig push toon`.'\n );\n } else {\n io.out(\n 'No relay configured yet — add one as the follow-up step: ' +\n '`rig remote add origin <relay-url>` (a real git remote; ' +\n '`git remote -v` shows it). One-off pushes can pass --relay <url>.'\n );\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'init', err);\n }\n}\n","/**\n * Git commit-author from the nostr identity (#302).\n *\n * On a rig repo the nostr key IS the identity, so `rig init` sets the repo's\n * LOCAL git author fields from it — the commit author == the push signer ==\n * the nostr identity, a coherent authorship chain baked permanently into the\n * git objects that land on Arweave. Without this, `rig commit` (a git\n * passthrough, #250) dead-ends on git's \"Author identity unknown / empty ident\n * name not allowed\" for anyone who never set a global git identity.\n *\n * user.email = `<npub>@nostr` — npub is bech32, lowercase-alphanumeric, a\n * valid email local part; `@nostr` is a stable\n * non-routable marker domain.\n * user.name = the identity's kind:0 profile DISPLAY NAME when published\n * (prefer `display_name`, else `name` from the content JSON),\n * read latest-wins (highest created_at) from a resolvable relay,\n * BEST-EFFORT; falls back to the npub when there is no profile,\n * no resolvable relay, or the read fails.\n *\n * The kind:0 read reuses the tolerant NIP-01 machinery from `../remote-state`\n * (double-JSON-encoded EVENT payloads and all). It never throws and never\n * blocks init: a short timeout, and any failure falls back to the npub.\n */\n\nimport { hexToNpub } from '../npub.js';\nimport { queryRelay, type WebSocketFactory } from '../remote-state.js';\n\n/** Nostr metadata event kind (profile). */\nexport const PROFILE_KIND = 0;\n\n/** Default bounded wait for the kind:0 profile read (env-overridable). */\nexport const DEFAULT_PROFILE_TIMEOUT_MS = 3000;\n\n/** Env var overriding the kind:0 read timeout (milliseconds). */\nexport const PROFILE_TIMEOUT_ENV = 'RIG_PROFILE_TIMEOUT_MS';\n\n/** Where `user.name` came from: the nostr profile, or the npub fallback. */\nexport type GitAuthorSource = 'profile' | 'npub';\n\n/** A resolved git commit-author derived from the nostr identity. */\nexport interface GitAuthor {\n /** `user.name`: the kind:0 display name, else the npub. */\n name: string;\n /** `user.email`: `<npub>@nostr`. */\n email: string;\n /** The npub of the identity (bech32). */\n npub: string;\n source: GitAuthorSource;\n}\n\nexport interface ResolveGitAuthorOptions {\n /** Identity pubkey (64-char hex). */\n pubkey: string;\n /**\n * Relay to read the kind:0 profile from (resolved at init time). When\n * undefined or not a ws(s) URL, the profile read is skipped and the npub is\n * used — init must not depend on a relay being reachable.\n */\n relayUrl?: string | undefined;\n /** Bounded wait for the kind:0 read (default {@link DEFAULT_PROFILE_TIMEOUT_MS}). */\n timeoutMs?: number;\n /** WebSocket factory override (defaults to the global WebSocket). */\n webSocketFactory?: WebSocketFactory;\n /** Relay-query seam (tests); defaults to {@link queryRelay}. */\n queryRelayImpl?: typeof queryRelay;\n}\n\n/** True for a WebSocket-scheme URL (the only scheme the kind:0 read speaks). */\nfunction isWebSocketRelay(url: string): boolean {\n return /^wss?:\\/\\//i.test(url);\n}\n\n/**\n * Extract a display name from a kind:0 event's content JSON: prefer\n * `display_name`, then `name`. Returns undefined when neither is a non-empty\n * string or the content is not parseable — the caller then keeps the npub.\n */\nexport function displayNameFromKind0(content: string): string | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n const fields = parsed as Record<string, unknown>;\n for (const key of ['display_name', 'name'] as const) {\n const value = fields[key];\n if (typeof value === 'string' && value.trim() !== '') return value.trim();\n }\n return undefined;\n}\n\n/**\n * Resolve the git commit-author for the identity `pubkey`: `<npub>@nostr` email\n * plus a `user.name` of the published kind:0 display name (latest-wins) or, on\n * any miss, the npub. Best-effort and non-throwing — a relay that is missing,\n * unreachable, slow, or serves no/garbage profile just yields the npub.\n */\nexport async function resolveGitAuthor(\n options: ResolveGitAuthorOptions\n): Promise<GitAuthor> {\n const npub = hexToNpub(options.pubkey);\n const email = `${npub}@nostr`;\n const fallback: GitAuthor = { name: npub, email, npub, source: 'npub' };\n\n const { relayUrl } = options;\n if (relayUrl === undefined || !isWebSocketRelay(relayUrl)) {\n return fallback;\n }\n\n const query = options.queryRelayImpl ?? queryRelay;\n const timeoutMs = options.timeoutMs ?? DEFAULT_PROFILE_TIMEOUT_MS;\n const factory = options.webSocketFactory ?? defaultWebSocketFactory;\n\n try {\n const events = await query(\n relayUrl,\n { kinds: [PROFILE_KIND], authors: [options.pubkey], limit: 20 },\n timeoutMs,\n factory\n );\n // Latest-wins over the whole buffer — a relay may serve a stale kind:0\n // ahead of the newest (issue #157), so never trust first-in-buffer.\n let latest: { created_at: number; content: string } | undefined;\n for (const event of events) {\n if (event.kind !== PROFILE_KIND) continue;\n if (event.pubkey !== options.pubkey) continue;\n if (!latest || event.created_at > latest.created_at) {\n latest = { created_at: event.created_at, content: event.content };\n }\n }\n if (latest) {\n const name = displayNameFromKind0(latest.content);\n if (name !== undefined) {\n return { name, email, npub, source: 'profile' };\n }\n }\n } catch {\n // Best-effort: any failure keeps the npub fallback (init never blocks).\n }\n return fallback;\n}\n\n/** Read {@link PROFILE_TIMEOUT_ENV} as a positive integer, else undefined. */\nexport function profileTimeoutFromEnv(\n env: NodeJS.ProcessEnv\n): number | undefined {\n const raw = env[PROFILE_TIMEOUT_ENV]?.trim();\n if (!raw) return undefined;\n const ms = Number.parseInt(raw, 10);\n return Number.isFinite(ms) && ms > 0 ? ms : undefined;\n}\n\nfunction defaultWebSocketFactory(url: string): ReturnType<WebSocketFactory> {\n const ctor = (\n globalThis as {\n WebSocket?: new (url: string) => ReturnType<WebSocketFactory>;\n }\n ).WebSocket;\n if (!ctor) {\n throw new Error(\n 'No global WebSocket constructor (Node >= 22 required) for the kind:0 read'\n );\n }\n return new ctor(url);\n}\n","/**\n * `rig maintainers list|add|remove <pubkey>` (#287) — manage the declared\n * maintainer set on a repo's kind:30617 announcement.\n *\n * Status authority is CONSUMER-side: rig and rig-web resolve an issue/PR's\n * state ONLY from kind:1630-1633 events signed by the repo owner ∪ its\n * declared maintainers. The owner is ALWAYS an implicit maintainer; this\n * command edits the EXPLICIT set carried by the `[\"maintainers\", …]` tag.\n *\n * list FREE relay read — print owner + declared maintainers\n * add <pubkey> PAID — republish the 30617 with <pubkey> added\n * remove <pubkey> PAID — republish the 30617 with <pubkey> removed\n *\n * add/remove republish the WHOLE announcement (a replaceable event keyed by\n * author + `d` tag), so they preserve the existing name/description and only\n * mutate the maintainers list. Because the 30617 is addressed by its author,\n * only the OWNER's republish is authoritative — running add/remove under a\n * non-owner identity writes that identity's own (irrelevant) announcement, so\n * we refuse it. The daemon has no announcement route, so this always runs the\n * embedded standalone publisher; the confirm gate matches every other paid\n * write (`--yes` skips; a non-TTY without it refuses; `--json` without `--yes`\n * is a pure estimate).\n */\n\nimport { parseArgs } from 'node:util';\nimport { buildRepoAnnouncement, parseMaintainers } from '../nip34-events.js';\nimport { ownerToHex } from '../npub.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport {\n serializeEventReceipt,\n type GitEventResponse,\n} from '../routes.js';\nimport type { EventCommandDeps } from './events.js';\nimport { emitCliError, InvalidRelayUrlError } from './errors.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type IdentityReport,\n} from './push.js';\nimport { feeLabel } from './render.js';\nimport { singleRelayRefusal } from './remote.js';\nimport {\n pickRepoCommandFlags,\n REPO_COMMAND_OPTIONS,\n resolveRepoContext,\n WS_URL_RE,\n type RepoCommandFlags,\n} from './repo-command.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\nconst HEX64_RE = /^[0-9a-f]{64}$/;\n\nexport const MAINTAINERS_USAGE = `Usage: rig maintainers <list|add|remove> [<pubkey>] [options]\n\nManage a repo's declared maintainers (#287). Status authority is consumer-side:\nrig and rig-web honor an issue/PR status (kind:1630-1633) ONLY when its author\nis the repo owner or a declared maintainer. The owner is always an implicit\nmaintainer; this command edits the explicit set on the kind:30617 announcement.\n\nSubcommands:\n list show the owner + declared maintainers — FREE (relay read)\n add <pubkey> add a maintainer (npub or 64-char hex) — PAID: republishes\n the kind:30617 (permanent, non-refundable)\n remove <pubkey> remove a maintainer — PAID: republishes the kind:30617\n\nadd/remove must run under the repo OWNER's identity (only the owner's\nannouncement is authoritative).\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or hex; default: git config)\n --remote <name> publish/read via this configured git remote (default: origin)\n --relay <url> ad-hoc relay override (exactly one for add/remove)\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable envelope\n -h, --help show this help`;\n\n/** Run `rig maintainers …`; returns the process exit code. */\nexport async function runMaintainers(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'list':\n return runList(rest, deps);\n case 'add':\n return runMutate('add', rest, deps);\n case 'remove':\n return runMutate('remove', rest, deps);\n case '--help':\n case '-h':\n case 'help':\n io.out(MAINTAINERS_USAGE);\n return 0;\n default:\n io.err(\n sub === undefined\n ? 'missing subcommand: rig maintainers <list|add|remove>'\n : `unknown rig maintainers subcommand: ${sub}`\n );\n io.err(MAINTAINERS_USAGE);\n return 2;\n }\n}\n\n// ---------------------------------------------------------------------------\n// list (FREE)\n// ---------------------------------------------------------------------------\n\nasync function runList(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n let flags: RepoCommandFlags;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: REPO_COMMAND_OPTIONS,\n allowPositionals: true,\n });\n if (positionals.length > 0) {\n throw new Error('rig maintainers list takes no positional arguments');\n }\n flags = pickRepoCommandFlags(values);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(MAINTAINERS_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(MAINTAINERS_USAGE);\n return 0;\n }\n\n try {\n const ctx = await resolveRepoContext(flags, deps);\n const wsRelays = ctx.relays.filter((url) => WS_URL_RE.test(url));\n if (wsRelays.length === 0) {\n throw new InvalidRelayUrlError(\n ctx.relays[0] ?? '',\n 'reads need a ws:// or wss:// relay'\n );\n }\n const remote = await fetchRemoteState({\n relayUrls: wsRelays,\n ownerPubkey: ctx.owner,\n repoId: ctx.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n const maintainers = remote.maintainers;\n if (flags.json) {\n io.emitJson({\n command: 'maintainers list',\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n announced: remote.announced,\n owner: ctx.owner,\n maintainers,\n });\n return 0;\n }\n io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);\n io.out(`Owner: ${ctx.owner} (implicit maintainer)`);\n if (!remote.announced) {\n io.out('No kind:30617 announcement found — owner-only authority.');\n return 0;\n }\n if (maintainers.length === 0) {\n io.out('Maintainers: (none declared — owner-only authority)');\n } else {\n io.out(`Maintainers (${maintainers.length}):`);\n for (const m of maintainers) io.out(` ${m}`);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'maintainers list', err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// add / remove (PAID — republish the 30617 under the owner's identity)\n// ---------------------------------------------------------------------------\n\ninterface MaintJsonOutput {\n command: 'maintainers add' | 'maintainers remove';\n repoAddr: { ownerPubkey: string; repoId: string };\n identity: IdentityReport;\n executed: boolean;\n feeEstimate: string | null;\n maintainers: string[];\n result?: GitEventResponse;\n hint?: string;\n}\n\nasync function runMutate(\n op: 'add' | 'remove',\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const command = `maintainers ${op}` as\n | 'maintainers add'\n | 'maintainers remove';\n\n let flags: RepoCommandFlags;\n let pubkey: string;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: REPO_COMMAND_OPTIONS,\n allowPositionals: true,\n });\n flags = pickRepoCommandFlags(values);\n if (flags.help) {\n io.out(MAINTAINERS_USAGE);\n return 0;\n }\n if (positionals.length !== 1) {\n throw new Error(`expected exactly one <pubkey> to ${op}`);\n }\n pubkey = ownerToHex(positionals[0] as string).toLowerCase();\n if (!HEX64_RE.test(pubkey)) {\n throw new Error(`<pubkey> must resolve to 64-char hex (got ${JSON.stringify(positionals[0])})`);\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(MAINTAINERS_USAGE);\n return 2;\n }\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n const ctx = await resolveRepoContext(flags, deps);\n // A single relay for a paid publish (mirror push/events guard).\n if (ctx.relays.length > 1) {\n io.err(singleRelayRefusal(ctx.resolved, 'Nothing was published or paid.'));\n return 1;\n }\n const relayUrl = ctx.relays[0];\n if (relayUrl === undefined || !WS_URL_RE.test(relayUrl)) {\n throw new InvalidRelayUrlError(\n relayUrl ?? '',\n 'a paid publish needs a ws:// or wss:// relay'\n );\n }\n\n // Standalone only: the daemon has no announcement route.\n const load = deps.loadStandalone ?? defaultLoadStandalone;\n standaloneCtx = await load({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n relayUrl,\n });\n const identity = identityReport(standaloneCtx);\n\n // Only the owner's 30617 is authoritative — refuse a non-owner republish.\n if (identity.pubkey.toLowerCase() !== ctx.owner.toLowerCase()) {\n io.err(\n `rig: only the repo owner (${ctx.owner.slice(0, 8)}…) can change the ` +\n `maintainer set — the active identity is ${identity.pubkey.slice(0, 8)}…. ` +\n 'A non-owner republish would write your own (ignored) announcement. ' +\n 'Nothing was published or paid.'\n );\n return 1;\n }\n\n // Read the current announcement to preserve name/description + base set.\n const remote = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: ctx.owner,\n repoId: ctx.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n // Refuse on an unannounced repo: republishing here would MINT a phantom\n // kind:30617 with a placeholder name (= repoId) and empty description, for\n // real money. Worse, `rig push` only announces when the repo is NOT already\n // announced (see push.ts), so that placeholder would permanently shadow the\n // real name/description the first push intended, with no way to fix it.\n // Managing maintainers presupposes the repo exists — announce it first.\n if (!remote.announced) {\n io.err(\n `rig: 30617:${ctx.owner.slice(0, 8)}…:${ctx.repoId} has no announcement ` +\n 'yet — run `rig push` to publish the repo (with its real ' +\n 'name/description) before managing maintainers. Nothing was published ' +\n 'or paid.'\n );\n return 1;\n }\n const current = remote.announceEvent\n ? parseMaintainers(remote.announceEvent.tags)\n : [];\n const currentSet = new Set(current);\n if (op === 'add' && currentSet.has(pubkey)) {\n io.err(\n `rig: ${pubkey.slice(0, 8)}… is already a maintainer — nothing to do (not published).`\n );\n return 0;\n }\n if (op === 'remove' && !currentSet.has(pubkey)) {\n io.err(\n `rig: ${pubkey.slice(0, 8)}… is not a declared maintainer — nothing to do (not published).`\n );\n return 0;\n }\n const next =\n op === 'add'\n ? [...current, pubkey]\n : current.filter((m) => m !== pubkey);\n\n const name = remote.name ?? ctx.repoId;\n const description = remote.description ?? '';\n // Preserve the payout pointer (rig#92) — this republish must not\n // silently wipe it out from under `rig payout`.\n const event = buildRepoAnnouncement(\n ctx.repoId,\n name,\n description,\n next,\n remote.payout\n );\n const fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();\n const action = `kind:30617 maintainers ${op} ${pubkey.slice(0, 8)}…`;\n\n // ── Confirm gate ────────────────────────────────────────────────────────\n if (!flags.json) {\n io.out(`Republish ${action}`);\n io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);\n io.out(`Maintainers after: ${next.length === 0 ? '(none)' : next.join(', ')}`);\n io.out(`Fee: ${feeLabel(fee)}. Writes are permanent and non-refundable.`);\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n identity,\n executed: false,\n feeEstimate: fee,\n maintainers: next,\n hint: 'estimate only — re-run with --yes to publish (permanent, non-refundable)',\n } satisfies MaintJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid republish (${feeLabel(fee)})? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was published.');\n return 1;\n }\n }\n\n // ── Execute ───────────────────────────────────────────────────────────────\n const receipt = await standaloneCtx.publisher.publishEvent(event, [\n relayUrl,\n ]);\n const result = serializeEventReceipt(event.kind, receipt);\n\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n identity,\n executed: true,\n feeEstimate: fee,\n maintainers: next,\n result,\n } satisfies MaintJsonOutput);\n } else {\n io.out(\n `Published ${action}: ${result.eventId} paid ${result.feePaid} base units`\n );\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, command, err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * Shared scaffolding for the rig-owned commands that read or republish a\n * repo's kind:30617 announcement (`rig maintainers`, `rig payout`): the\n * common flag set (`--repo-id/--owner/--remote/--relay/--yes/--json`), and\n * the resolution of the repo address + relays from those flags plus the\n * repo's `toon.*` git config.\n *\n * These commands are deliberately identical at the edges — same flags, same\n * repo-address resolution, same relay rules — and differ only in WHICH tag of\n * the announcement they touch. Keeping the edges in one place is what makes\n * that sameness real rather than aspirational.\n */\n\nimport { ownerToHex } from '../npub.js';\nimport type { EventCommandDeps } from './events.js';\nimport { UnconfiguredRepoAddressError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport {\n resolveRelays,\n type ResolvedRelays,\n} from './remote.js';\n\n/** Relay URLs rig can actually talk to (reads and paid publishes alike). */\nexport const WS_URL_RE = /^wss?:\\/\\//i;\n\n/** The flags every kind:30617 command accepts. */\nexport interface RepoCommandFlags {\n json: boolean;\n yes: boolean;\n help: boolean;\n relay: string[];\n remote?: string;\n repoId?: string;\n owner?: string;\n}\n\n/** `parseArgs` option spec matching {@link RepoCommandFlags}. */\nexport const REPO_COMMAND_OPTIONS = {\n json: { type: 'boolean', default: false },\n yes: { type: 'boolean', default: false },\n relay: { type: 'string', multiple: true },\n remote: { type: 'string' },\n 'repo-id': { type: 'string' },\n owner: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n} as const;\n\n/** Narrow `parseArgs` values into {@link RepoCommandFlags} (`--owner` → hex). */\nexport function pickRepoCommandFlags(\n values: Record<string, unknown>\n): RepoCommandFlags {\n const flags: RepoCommandFlags = {\n json: values['json'] === true,\n yes: values['yes'] === true,\n help: values['help'] === true,\n relay: Array.isArray(values['relay']) ? (values['relay'] as string[]) : [],\n };\n if (typeof values['remote'] === 'string') flags.remote = values['remote'];\n if (typeof values['repo-id'] === 'string') flags.repoId = values['repo-id'];\n if (typeof values['owner'] === 'string')\n flags.owner = ownerToHex(values['owner']);\n return flags;\n}\n\nexport interface RepoContext {\n repoId: string;\n owner: string;\n relays: string[];\n /** The full relay resolution (source/nudge) — for the single-relay refusal. */\n resolved: ResolvedRelays;\n repoRoot?: string;\n}\n\n/** Resolve repo address (repoId + owner) and relays from flags + git config. */\nexport async function resolveRepoContext(\n flags: RepoCommandFlags,\n deps: EventCommandDeps\n): Promise<RepoContext> {\n let repoRoot: string | undefined;\n let toonConfig: { repoId?: string; owner?: string; relays: string[] } = {\n relays: [],\n };\n try {\n repoRoot = await resolveRepoRoot(deps.cwd);\n toonConfig = await readToonConfig(repoRoot);\n } catch {\n // Not inside a git repo — flags must carry everything.\n }\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const owner = flags.owner ?? toonConfig.owner;\n if (!owner) throw new UnconfiguredRepoAddressError('repository owner');\n\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: flags.remote,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) deps.io.err(resolved.nudge);\n return {\n repoId,\n owner,\n relays: resolved.relays,\n resolved,\n ...(repoRoot !== undefined ? { repoRoot } : {}),\n };\n}\n","/**\n * `rig name` — ArNS naming verbs (#367): buy / set / status, owned and paid\n * by the rig mnemonic's Solana key.\n *\n * ArNS is the missing NAMING layer over everything Rig serves from Arweave.\n * Since ar.io's Solana migration, ArNS names are owned and managed by Solana\n * wallets, and `@ar.io/sdk` is Solana-native with prices denominated in mARIO.\n * The rig identity ALREADY has the required key: `@toon-protocol/client`\n * derives a Solana Ed25519 keypair from the same mnemonic that pays for pushes\n * (`m/44'/501'/{index}'/0'`, SLIP-0010 — see packages/client/src/keys) and\n * `rig fund --chain solana` funds it. So the same phrase can own ArNS names and\n * pay for them, with ZERO new key material or config.\n *\n * PAYMENT MODEL — the load-bearing distinction (see {@link MARIO_PAYMENT_NOTE}):\n * `rig name buy` spends **mARIO from the identity's Solana wallet, charged\n * on-chain by the ar.io registry program**. It does NOT move value through the\n * TOON ILP payment channels that `rig push` uses — a name purchase is a\n * Solana-settled registry transaction, not a pay-to-write relay claim.\n *\n * Same discipline as every paid rig command: estimate → confirm → execute,\n * strict `--json` contract, `--yes` for non-TTY. `buy` and `set` are the\n * money/state-moving paths (gated); `status` is FREE (a registry read, like\n * `rig balance`).\n *\n * DEPENDENCY HYGIENE (#367 open question, decided): `@ar.io/sdk` is an\n * OPTIONAL, lazily-imported dependency — it is `import()`ed only inside the\n * command path (via the {@link LoadArns} seam), so the base `rig` install stays\n * lean and runs that never touch names never pay its startup cost. When it is\n * not installed, the command fails with a clean, actionable error\n * ({@link ArnsSdkUnavailableError}) instead of a module-resolution stack trace.\n *\n * SDK WIRING (#376): `@ar.io/sdk` >= 4.0.3 is Solana-native. There is no\n * `SolanaSigner` class and no AO registry process id, and `ARIO.init()` builds\n * NO default rpc — the caller constructs everything from `@solana/kit`:\n * `createSolanaRpc` (all calls), plus `createSolanaRpcSubscriptions` and a\n * `createKeyPairSignerFromBytes` signer for writes only. The FREE read path\n * (`status`) therefore runs signerless ({@link LoadArnsOptions.mode}) — reads\n * being free is the rig discipline everywhere else. This surface is pinned by\n * a live smoke test against the published SDK\n * (`src/__integration__/arns-live-read.integration.test.ts`), because both\n * #376 bugs came from coding against an API no released version exports.\n *\n * DEVNET (#367 open question, revised by #376): post-migration, registry\n * selection is a Solana CLUSTER, not an AO process id — `--network\n * mainnet|devnet` (or `RIG_ARIO_NETWORK`) picks the cluster (devnet applies\n * the SDK's `DEVNET_PROGRAM_IDS`); ar.io deploys nothing on Solana's testnet\n * cluster, so `testnet` is rejected up front. `--process-id <id>` (or\n * `RIG_ARIO_PROCESS_ID`) overrides the ArNS registry program id outright.\n * Defaults to mainnet.\n */\n\nimport { deriveNostrKeyFromMnemonic } from '../standalone/nostr-identity.js';\nimport { randomUUID } from 'node:crypto';\nimport { parseArgs } from 'node:util';\nimport { formatUnits } from './balance.js';\nimport { emitCliError } from './errors.js';\nimport { resolveEffectiveNetwork } from './fund.js';\nimport { resolveIdentity } from './identity.js';\nimport type { CliIo } from './output.js';\nimport type { IdentityReport } from './push.js';\nimport { defaultLoadStandalone } from './push.js';\nimport type { StoreJobRequest, StoreJobResponse } from '../publisher.js';\nimport type { LoadStandalone } from './standalone-context.js';\nimport { renderIdentityLine } from './render.js';\n\n// ---------------------------------------------------------------------------\n// mARIO / ARIO\n// ---------------------------------------------------------------------------\n\n/**\n * $ARIO token decimals: 1 ARIO = 1_000_000 mARIO (mARIO is the base unit\n * `@ar.io/sdk` quotes in). Used only to render a human ARIO figure alongside\n * the exact mARIO amount — the mARIO integer is always the authoritative value.\n */\nexport const ARIO_DECIMALS = 6;\n\n/** Render a mARIO base-unit amount as `<mARIO> mARIO (~<ARIO> ARIO)`. */\nexport function renderMario(mario: bigint): string {\n return `${mario.toString()} mARIO (~${formatUnits(mario.toString(), ARIO_DECIMALS)} ARIO)`;\n}\n\n/**\n * THE load-bearing note (#367): a name purchase spends mARIO on Solana via the\n * ar.io registry program — NOT through TOON ILP payment channels. Exported so\n * the buy human output, the `--json` hint, and the tests all pin one string.\n */\nexport const MARIO_PAYMENT_NOTE =\n \"Payment is mARIO from this identity's Solana wallet, charged on-chain by \" +\n 'the ar.io registry program — NOT through TOON ILP payment channels. Fund ' +\n 'this wallet with `rig fund --chain solana` (or send $ARIO to the Solana ' +\n 'address above).';\n\n/**\n * The brokered (\"buyfor\") counterpart of {@link MARIO_PAYMENT_NOTE}: with\n * `--via <dvm>`, a store DVM pays the mARIO name price from ITS wallet by\n * executing the kind:5095 ArNS-buy job — this identity never holds $ARIO.\n * The client still OWNS the name from inception, because the job carries the\n * processId of an ANT this identity spawned and owns (`ANT.spawn` costs only\n * dust SOL). Exported so the buy output and the tests pin one string.\n */\nexport const DVM_PAYMENT_NOTE =\n 'Brokered buy (--via): the DVM pays the mARIO name price from ITS Solana ' +\n 'wallet via the kind:5095 job; this wallet needs only dust SOL to spawn ' +\n 'the ANT it owns. On the paid path the job fee is enforced by the ' +\n 'connector payment proxy in front of the DVM; when --via targets the DVM ' +\n 'backend directly the job payment is STUBBED (dev/e2e only). The ArNS ' +\n 'purchase itself is real either way, and the name is owned by YOUR ANT ' +\n 'from inception.';\n\n// ---------------------------------------------------------------------------\n// The ar.io SDK seam (lazily imported; tests inject a stub — NEVER the live net)\n// ---------------------------------------------------------------------------\n\n/** A name registration kind: a time-boxed lease or a one-time permabuy. */\nexport type NameType = 'lease' | 'permabuy';\n\n/**\n * The Solana clusters ar.io deploys its programs to; mainnet is the default.\n * (No `testnet`: ar.io has no deployment on Solana's testnet cluster — #376.)\n */\nexport type ArioNetwork = 'mainnet' | 'devnet';\n\n/** One name's current registry record (the free `status` read). */\nexport interface ArnsRecordView {\n /**\n * ANT (Arweave Name Token) process id that owns/serves the name, or `null`\n * when no ANT is attached. The registry's all-ones placeholder\n * ({@link ARNS_NULL_PROCESS_ID}) is normalized to `null` at this seam — a\n * non-null value here always means a real ANT (#79).\n */\n processId: string | null;\n /** `lease` or `permabuy`, when known. */\n type: NameType | null;\n /** Lease/registration start (ms epoch), when known. */\n startTimestamp?: number;\n /** Lease expiry (ms epoch); absent/undefined for a permabuy. */\n endTimestamp?: number;\n /** Included undername slots (ArNS ships 10 per name). */\n undernameLimit?: number;\n}\n\n/** One ANT record target (base name or an undername). */\nexport interface AntRecordTarget {\n /** Arweave txId the record points at (typically a path manifest). */\n transactionId: string;\n /** Record TTL in seconds (gateway cache hint). */\n ttlSeconds: number;\n}\n\n/**\n * A handle on one name's ANT process — used by `set` (write) and `status`\n * (read). The base name record is conventionally the `@` undername.\n */\nexport interface ArnsAnt {\n /** All current record targets, keyed by undername (`@` = the base name). */\n getRecords(): Promise<Record<string, AntRecordTarget>>;\n /** Point the base name at an Arweave txId. */\n setBaseNameRecord(args: {\n transactionId: string;\n ttlSeconds: number;\n }): Promise<{ id: string }>;\n /** Point an undername (`<sub>_<name>`) at an Arweave txId. */\n setUndernameRecord(args: {\n undername: string;\n transactionId: string;\n ttlSeconds: number;\n }): Promise<{ id: string }>;\n}\n\n/**\n * The slice of `@ar.io/sdk` `rig name` uses, behind our own seam so tests can\n * inject a stub and NEVER reach the live ar.io registry (the hard safety rule:\n * no real $ARIO is ever spent, no real registry call is ever made in code we\n * run or in tests).\n */\nexport interface ArnsSdk {\n /** Quote the mARIO cost of an intent (here always `Buy-Name`). */\n getTokenCost(args: {\n intent: 'Buy-Name';\n name: string;\n type: NameType;\n years?: number;\n }): Promise<bigint>;\n /**\n * Register (buy) a name. `processId`, when supplied, binds the purchase to\n * an ANT the caller already owns (both `rig name` buy paths spawn their\n * own ANT first and pass its id here — #79 — so the name is never\n * registered against the registry's placeholder). Returns the settling\n * registry transaction id and, when the SDK echoes it back, the ANT\n * process id actually bound; absent that echo, callers trust the\n * `processId` they requested.\n */\n buyRecord(args: {\n name: string;\n type: NameType;\n years?: number;\n processId?: string;\n }): Promise<{ id: string; processId?: string }>;\n /**\n * Spawn a fresh ANT owned by THIS identity's Solana key (`ANT.spawn` —\n * mints the MPL Core asset + initializes the ario-ant PDAs; costs only\n * rent/fee dust, no $ARIO). The returned `processId` (the asset pubkey) is\n * what a brokered `--via` buy hands the DVM so the client owns the bought\n * name from inception. Write mode only — a signerless SDK must throw.\n */\n spawnAnt(args: {\n name: string;\n }): Promise<{ processId: string; signature: string }>;\n /**\n * Build (do NOT send) a partially-signed ANT record-set transaction for\n * the gas-station path (toon-meta#163): feePayer = the DVM's advertised\n * gas wallet, lifetime = the quoted blockhash, caller = THIS identity's\n * Solana key, which partial-signs. Returns the base64 wire transaction\n * ready for a kind:5096 execute job. Write mode only.\n */\n buildSetRecordTransaction(args: {\n antProcessId: string;\n /** `@` for the base name. */\n undername: string;\n transactionId: string;\n ttlSeconds: number;\n feePayer: string;\n recentBlockhash: string;\n }): Promise<string>;\n /** Read a name's current registry record (free). */\n getArNSRecord(args: { name: string }): Promise<ArnsRecordView | null>;\n /** Bind an ANT handle for a name's process id (for `set` / `status`). */\n ant(processId: string): Promise<ArnsAnt>;\n}\n\n/** What the {@link LoadArns} seam needs to build a targeted SDK. */\nexport interface LoadArnsOptions {\n /**\n * Which capability the caller needs (#376). `read` builds a SIGNERLESS,\n * read-only client — the FREE lookups (`status`, cost quotes) must never\n * require write plumbing. `write` additionally derives a `@solana/kit`\n * signer from `solanaSecretKey` and wires the rpc-subscriptions client that\n * transaction confirmation requires.\n */\n mode: 'read' | 'write';\n /**\n * 64-byte Ed25519 Solana keypair (secretKey ‖ publicKey) that owns and\n * pays — consumed only in `write` mode (readers never touch it).\n */\n solanaSecretKey: Uint8Array;\n /** Solana public key (base58) — for the signer + human messaging. */\n solanaPublicKey: string;\n /** Which cluster's ar.io deployment to target. */\n network: ArioNetwork;\n /** Explicit ArNS registry program id override (wins over `network`). */\n processId?: string;\n}\n\n/** Build a network-targeted {@link ArnsSdk} (tests inject a stub). */\nexport type LoadArns = (options: LoadArnsOptions) => Promise<ArnsSdk>;\n\n/**\n * The Solana System Program id (32 base58 \"1\"s) — the ar.io registry writes\n * this into a record's `processId` when no ANT is actually attached. It is a\n * real, valid program id (not a null the SDK invented), so a buy that never\n * attaches an ANT looks superficially like it worked unless this exact\n * string is checked for wherever an ANT process id is accepted or reported\n * (#79 — a direct buy silently registering against this placeholder is the\n * bug this constant exists to make impossible to miss).\n */\nexport const ARNS_NULL_PROCESS_ID = '11111111111111111111111111111111';\n\n/**\n * Normalize an ANT process id: the real id, or `null` when no ANT is attached\n * (absent, or the registry's all-ones placeholder). Every command that accepts\n * or reports an ANT process id goes through this, so the placeholder can never\n * be mistaken for a working attachment (#79 AC4).\n */\nfunction antProcessIdOf(id: string | null | undefined): string | null {\n if (id === null || id === undefined || id === ARNS_NULL_PROCESS_ID) {\n return null;\n }\n return id;\n}\n\n/**\n * The minimum `@ar.io/sdk` release `rig name` is built against: the first\n * Solana-native surface verified to expose the clients the default loader\n * wires (`ARIO.init`/`ANT.init` over a caller-built `@solana/kit` rpc, signer\n * optional). Mirrored by the `optionalDependencies` pin in package.json.\n */\nexport const MIN_ARIO_SDK_VERSION = '4.0.3';\n\n/**\n * An optional module (`@ar.io/sdk`, or its `@solana/kit` companion) is not\n * installed. Optional-dependency by design (#367): surface a clean,\n * actionable message instead of a module-resolution stack trace. Distinct\n * from {@link ArnsSdkIncompatibleError} — \"not installed\" and \"installed but\n * the wrong API surface\" need different remediations (#376).\n */\nexport class ArnsSdkUnavailableError extends Error {\n constructor(cause?: unknown, module = '@ar.io/sdk') {\n super(\n `\\`rig name\\` needs the optional \\`${module}\\` dependency, which is not ` +\n 'installed. It is intentionally NOT a base `rig` dependency (keeps the ' +\n 'install lean). Add it to use ArNS naming:\\n' +\n ` npm i @ar.io/sdk@^${MIN_ARIO_SDK_VERSION} # or: pnpm add @ar.io/sdk@^${MIN_ARIO_SDK_VERSION}\\n` +\n '(`@solana/kit` installs alongside it) then re-run your `rig name` ' +\n 'command.' +\n (cause instanceof Error ? `\\n(underlying error: ${cause.message})` : '')\n );\n this.name = 'ArnsSdkUnavailableError';\n }\n}\n\n/**\n * `@ar.io/sdk` (or `@solana/kit`) IS installed but exposes an API surface\n * `rig name` cannot drive — e.g. a pre-Solana-migration build. Kept separate\n * from {@link ArnsSdkUnavailableError} so users are never told to install a\n * package they already have (#376: the old message sent users chasing an\n * upgrade that did not exist).\n */\nexport class ArnsSdkIncompatibleError extends Error {\n constructor(detail: string) {\n super(\n `the installed @ar.io/sdk is incompatible with \\`rig name\\`: ${detail}.\\n` +\n `\\`rig name\\` requires @ar.io/sdk >= ${MIN_ARIO_SDK_VERSION} (the ` +\n 'Solana-native release driven via a `@solana/kit` rpc + signer). ' +\n 'Upgrade with:\\n' +\n ' npm i @ar.io/sdk@latest # or: pnpm add @ar.io/sdk@latest'\n );\n this.name = 'ArnsSdkIncompatibleError';\n }\n}\n\n/** Public Solana RPC endpoints (fallbacks when the SDK exports none). */\nconst SOLANA_MAINNET_RPC_URL = 'https://api.mainnet-beta.solana.com';\nconst SOLANA_DEVNET_RPC_URL = 'https://api.devnet.solana.com';\n\n/**\n * The untyped shape of the pieces of `@ar.io/sdk` the default loader reaches\n * for (verified against the published 4.0.3). Kept local (the package is\n * optional and its types are not a build dep) and cast through `unknown` —\n * never `any`, so eslint's no-explicit-any holds.\n */\ninterface RawArioModule {\n ARIO?: {\n init?: (config: unknown) => RawArioInstance;\n };\n ANT?: {\n /** 4.x resolves the ANT program from the asset, hence async. */\n init?: (config: unknown) => Promise<RawAntInstance>;\n /** 4.x Solana `ANT.spawn` — mints the MPL Core asset (write only). */\n spawn?: (\n params: unknown\n ) => Promise<{ processId: string; signature: string }>;\n };\n DEFAULT_SOLANA_RPC_URL?: string;\n MAINNET_RPC_URL?: string;\n DEVNET_RPC_URL?: string;\n /** Devnet (staging) program-id overrides — required off mainnet. */\n DEVNET_PROGRAM_IDS?: {\n core?: string;\n gar?: string;\n arns?: string;\n ant?: string;\n };\n /** Root-exported PDA helper: (mint, undername, antProgramId?) → [pda]. */\n getAntRecordPDA?: (\n mint: unknown,\n undername: string,\n programId?: unknown\n ) => Promise<readonly unknown[]>;\n}\ninterface RawArioInstance {\n getTokenCost: (args: unknown) => Promise<unknown>;\n /** Present only on the writeable (signer-built) client. */\n buyRecord?: (args: unknown) => Promise<unknown>;\n getArNSRecord: (args: unknown) => Promise<unknown>;\n}\ninterface RawAntInstance {\n getRecords: () => Promise<\n Record<string, { transactionId: string; ttlSeconds: number }>\n >;\n /** Present only on the writeable (signer-built) client. */\n setBaseNameRecord?: (args: unknown) => Promise<{ id: string }>;\n setUndernameRecord?: (args: unknown) => Promise<{ id: string }>;\n}\n/** The three `@solana/kit` factories the Solana-native SDK is driven with. */\ninterface RawSolanaKitModule {\n createSolanaRpc?: (url: string) => unknown;\n createSolanaRpcSubscriptions?: (url: string) => unknown;\n createKeyPairSignerFromBytes?: (bytes: Uint8Array) => Promise<unknown>;\n // ── extras the gas-station tx builder uses (all loose-typed on purpose:\n // the optional module's types are not a build dep) ──\n createKeyPairFromBytes?: (bytes: Uint8Array) => Promise<unknown>;\n createNoopSigner?: (addr: unknown) => unknown;\n address?: (s: string) => unknown;\n blockhash?: (s: string) => unknown;\n createTransactionMessage?: (o: { version: number }) => unknown;\n setTransactionMessageFeePayer?: (a: unknown, m: unknown) => unknown;\n setTransactionMessageLifetimeUsingBlockhash?: (\n l: unknown,\n m: unknown\n ) => unknown;\n appendTransactionMessageInstructions?: (ix: unknown[], m: unknown) => unknown;\n compileTransaction?: (m: unknown) => unknown;\n partiallySignTransaction?: (kps: unknown[], tx: unknown) => Promise<unknown>;\n getBase64EncodedWireTransaction?: (tx: unknown) => string;\n}\n/** The `@ar.io/solana-contracts/ant` slice the record-set builder uses. */\ninterface RawAntContractsModule {\n getSetRecordInstructionAsync?: (\n input: Record<string, unknown>,\n config?: { programAddress?: unknown }\n ) => Promise<unknown>;\n}\n\n/**\n * Default {@link LoadArns}: lazily `import('@ar.io/sdk')` + `@solana/kit` and\n * adapt them to our seam. Specifiers are stored in `string`-typed variables so\n * TypeScript does not try to resolve the optional modules at build time; a\n * missing package surfaces as {@link ArnsSdkUnavailableError}, a wrong API\n * surface as {@link ArnsSdkIncompatibleError}.\n *\n * THE #376 LESSON, load-bearing: the SDK provides NO defaults. Bare\n * `ARIO.init()` throws and `ARIO.init({})` produces a client whose every read\n * fails — the caller must build the rpc (`createSolanaRpc`) explicitly, and\n * for writes also `rpcSubscriptions` + a `createKeyPairSignerFromBytes`\n * signer. Read mode constructs NO signer at all, so free lookups need zero\n * key material at the SDK layer.\n *\n * NOTE: no test drives this adapter against the live registry except the\n * env-gated smoke test (`__integration__/arns-live-read.integration.test.ts`,\n * FREE reads only) — every money-moving path runs ONLY against injected\n * stubs, and no real $ARIO is ever spent by code we run.\n */\nexport const defaultLoadArns: LoadArns = async (options) => {\n // Cast to `string` (not a literal type) so TypeScript does not try to\n // resolve the OPTIONAL modules at build time — a missing package must\n // surface as a clean runtime error, not a compile failure.\n const sdkSpecifier = '@ar.io/sdk' as string;\n let mod: RawArioModule;\n try {\n mod = (await import(sdkSpecifier)) as unknown as RawArioModule;\n } catch (err) {\n throw new ArnsSdkUnavailableError(err);\n }\n // `@solana/kit` carries the rpc/signer factories the Solana-native SDK is\n // driven with. It is a dependency of `@ar.io/sdk` AND declared in rig's own\n // optionalDependencies so strict (pnpm-style) layouts resolve it here too.\n const kitSpecifier = '@solana/kit' as string;\n let kit: RawSolanaKitModule;\n try {\n kit = (await import(kitSpecifier)) as unknown as RawSolanaKitModule;\n } catch (err) {\n throw new ArnsSdkUnavailableError(err, '@solana/kit');\n }\n\n const arioInit = mod.ARIO?.init;\n const antInit = mod.ANT?.init;\n if (!arioInit || !antInit) {\n throw new ArnsSdkIncompatibleError('it exposes no ARIO.init / ANT.init');\n }\n const {\n createSolanaRpc,\n createSolanaRpcSubscriptions,\n createKeyPairSignerFromBytes,\n } = kit;\n if (\n !createSolanaRpc ||\n !createSolanaRpcSubscriptions ||\n !createKeyPairSignerFromBytes\n ) {\n throw new ArnsSdkIncompatibleError(\n 'the resolved @solana/kit exposes no createSolanaRpc / ' +\n 'createSolanaRpcSubscriptions / createKeyPairSignerFromBytes'\n );\n }\n\n // Cluster targeting: rpc endpoint + (off mainnet) program-id overrides.\n const rpcUrl =\n options.network === 'devnet'\n ? (mod.DEVNET_RPC_URL ?? SOLANA_DEVNET_RPC_URL)\n : (mod.DEFAULT_SOLANA_RPC_URL ??\n mod.MAINNET_RPC_URL ??\n SOLANA_MAINNET_RPC_URL);\n const devnetIds =\n options.network === 'devnet' ? mod.DEVNET_PROGRAM_IDS : undefined;\n if (options.network === 'devnet' && devnetIds === undefined) {\n throw new ArnsSdkIncompatibleError(\n 'it exposes no DEVNET_PROGRAM_IDS — devnet targeting needs the ' +\n \"SDK's staging program ids\"\n );\n }\n const antProgramId = devnetIds?.ant;\n const programOverrides = {\n ...(devnetIds?.core !== undefined ? { coreProgramId: devnetIds.core } : {}),\n ...(devnetIds?.gar !== undefined ? { garProgramId: devnetIds.gar } : {}),\n ...(devnetIds?.arns !== undefined ? { arnsProgramId: devnetIds.arns } : {}),\n ...(antProgramId !== undefined ? { antProgramId } : {}),\n // --process-id / RIG_ARIO_PROCESS_ID: explicit ArNS registry program\n // override (wins over the cluster default).\n ...(options.processId !== undefined\n ? { arnsProgramId: options.processId }\n : {}),\n };\n\n // Build the transport(s) explicitly — see the #376 lesson above. Write mode\n // alone derives the signer (from the identity's 64-byte Ed25519 keypair)\n // and the ws subscriptions client that transaction confirmation needs.\n const rpc = createSolanaRpc(rpcUrl);\n const writeExtras =\n options.mode === 'write'\n ? {\n signer: await createKeyPairSignerFromBytes(options.solanaSecretKey),\n rpcSubscriptions: createSolanaRpcSubscriptions(\n rpcUrl.replace(/^http/, 'ws')\n ),\n }\n : {};\n const ario = arioInit({ rpc, ...writeExtras, ...programOverrides });\n\n return {\n getTokenCost: async (args) => BigInt(String(await ario.getTokenCost(args))),\n buyRecord: async (args) => {\n if (typeof ario.buyRecord !== 'function') {\n throw new ArnsSdkIncompatibleError(\n 'the signed ARIO client exposes no buyRecord'\n );\n }\n return (await ario.buyRecord(args)) as { id: string; processId?: string };\n },\n spawnAnt: async (args) => {\n const spawn = mod.ANT?.spawn;\n if (typeof spawn !== 'function') {\n throw new ArnsSdkIncompatibleError('it exposes no ANT.spawn');\n }\n if (options.mode !== 'write') {\n // Mirrors the SDK's own contract: spawning signs a transaction, so a\n // signerless (read) client must never attempt it.\n throw new ArnsSdkIncompatibleError(\n 'ANT.spawn requires the write-mode SDK (a signer) — this client ' +\n 'was built signerless'\n );\n }\n const result = await spawn({\n rpc,\n ...writeExtras,\n state: { name: args.name },\n ...(antProgramId !== undefined ? { antProgramId } : {}),\n });\n return { processId: result.processId, signature: result.signature };\n },\n buildSetRecordTransaction: async (args) => {\n if (options.mode !== 'write') {\n throw new ArnsSdkIncompatibleError(\n 'buildSetRecordTransaction requires the write-mode SDK (a client ' +\n 'partial-signature) — this client was built signerless'\n );\n }\n const contractsSpecifier = '@ar.io/solana-contracts/ant' as string;\n let contracts: RawAntContractsModule;\n try {\n contracts = (await import(\n contractsSpecifier\n )) as unknown as RawAntContractsModule;\n } catch (err) {\n throw new ArnsSdkUnavailableError(err, '@ar.io/solana-contracts');\n }\n const getSetRecordInstructionAsync =\n contracts.getSetRecordInstructionAsync;\n const getAntRecordPDA = mod.getAntRecordPDA;\n const {\n createKeyPairFromBytes,\n createNoopSigner,\n address: toAddr,\n blockhash: toBlockhash,\n createTransactionMessage,\n setTransactionMessageFeePayer,\n setTransactionMessageLifetimeUsingBlockhash,\n appendTransactionMessageInstructions,\n compileTransaction,\n partiallySignTransaction,\n getBase64EncodedWireTransaction,\n } = kit;\n if (\n !getSetRecordInstructionAsync ||\n !getAntRecordPDA ||\n !createKeyPairFromBytes ||\n !createNoopSigner ||\n !toAddr ||\n !toBlockhash ||\n !createTransactionMessage ||\n !setTransactionMessageFeePayer ||\n !setTransactionMessageLifetimeUsingBlockhash ||\n !appendTransactionMessageInstructions ||\n !compileTransaction ||\n !partiallySignTransaction ||\n !getBase64EncodedWireTransaction\n ) {\n throw new ArnsSdkIncompatibleError(\n 'the installed @ar.io/sdk / @ar.io/solana-contracts / @solana/kit ' +\n 'do not expose the record-set transaction builder surface'\n );\n }\n\n const asset = toAddr(args.antProcessId);\n const antProgram =\n antProgramId !== undefined ? toAddr(antProgramId) : undefined;\n const [recordPda] = await getAntRecordPDA(\n asset,\n args.undername,\n antProgram\n );\n // The client is the record CALLER (authority) — a noop signer here so\n // the compiled account meta is marked signer; the real signature comes\n // from partiallySignTransaction below. The DVM's gas wallet is ONLY\n // the fee payer.\n const ix = await getSetRecordInstructionAsync(\n {\n asset,\n record: recordPda,\n caller: createNoopSigner(toAddr(options.solanaPublicKey)),\n undername: args.undername,\n target: args.transactionId,\n targetProtocol: 0,\n ttlSeconds: args.ttlSeconds,\n priority: null,\n recordOwner: null,\n },\n antProgram !== undefined ? { programAddress: antProgram } : undefined\n );\n\n let message = createTransactionMessage({ version: 0 });\n message = setTransactionMessageFeePayer(toAddr(args.feePayer), message);\n message = setTransactionMessageLifetimeUsingBlockhash(\n {\n blockhash: toBlockhash(args.recentBlockhash),\n lastValidBlockHeight: 0n,\n },\n message\n );\n message = appendTransactionMessageInstructions([ix], message);\n\n const keyPair = await createKeyPairFromBytes(options.solanaSecretKey);\n const signed = await partiallySignTransaction(\n [keyPair],\n compileTransaction(message)\n );\n return getBase64EncodedWireTransaction(signed);\n },\n getArNSRecord: async (args) => {\n // 4.x throws on an unregistered name; our seam reports `null` so\n // `status` can render \"available\" instead of an error.\n let raw: {\n processId?: string;\n type?: NameType;\n startTimestamp?: number;\n endTimestamp?: number;\n undernameLimit?: number;\n };\n try {\n raw = (await ario.getArNSRecord(args)) as typeof raw;\n } catch (err) {\n if (err instanceof Error && /not found/i.test(err.message)) return null;\n throw err;\n }\n // Solana-native records carry cluster unix timestamps in SECONDS; the\n // seam contract (and the human expiry render) is ms epoch.\n return {\n // #79 AC4: the registry writes the all-ones placeholder when no ANT\n // is attached. The seam contract is \"a process id or null\", so the\n // placeholder is normalized to null right here — every caller then\n // sees \"no ANT\" instead of a valid-looking System Program address.\n processId: antProcessIdOf(raw.processId),\n type: raw.type ?? null,\n ...(raw.startTimestamp !== undefined\n ? { startTimestamp: raw.startTimestamp * 1000 }\n : {}),\n ...(raw.endTimestamp !== undefined\n ? { endTimestamp: raw.endTimestamp * 1000 }\n : {}),\n ...(raw.undernameLimit !== undefined\n ? { undernameLimit: raw.undernameLimit }\n : {}),\n };\n },\n ant: async (pid) => {\n const ant = await antInit({\n processId: pid,\n rpc,\n ...writeExtras,\n ...(antProgramId !== undefined ? { antProgramId } : {}),\n });\n return {\n getRecords: async () => {\n // Pin the seam shape: 4.x records carry extra fields (index,\n // targetProtocol, …) that must not leak into the `--json` contract.\n const records = await ant.getRecords();\n const targets: Record<string, AntRecordTarget> = {};\n for (const [undername, record] of Object.entries(records)) {\n targets[undername] = {\n transactionId: record.transactionId,\n ttlSeconds: record.ttlSeconds,\n };\n }\n return targets;\n },\n setBaseNameRecord: async (a) => {\n if (typeof ant.setBaseNameRecord !== 'function') {\n throw new ArnsSdkIncompatibleError(\n 'the signed ANT client exposes no setBaseNameRecord'\n );\n }\n return ant.setBaseNameRecord(a);\n },\n setUndernameRecord: async (a) => {\n if (typeof ant.setUndernameRecord !== 'function') {\n throw new ArnsSdkIncompatibleError(\n 'the signed ANT client exposes no setUndernameRecord'\n );\n }\n return ant.setUndernameRecord(a);\n },\n };\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// The brokered-buy DVM job seam (#buyfor)\n// ---------------------------------------------------------------------------\n\n/**\n * The NIP-90 job kind for a brokered ArNS name purchase — mirrors the store\n * repo's `ARNS_BUY_KIND` (the DVM registers this next to its kind:5094\n * Arweave storage job).\n */\nexport const ARNS_BUY_JOB_KIND = 5095;\n\n/**\n * Paid transport for one NIP-90 job to a store node's DVM (#101).\n *\n * This is {@link Publisher.submitStoreJob} narrowed to a function, so the two\n * job seams below depend on the capability rather than on a whole publisher.\n */\nexport type SubmitStoreJob = (\n request: StoreJobRequest\n) => Promise<StoreJobResponse>;\n\n/** One brokered buy job, ready to submit to a DVM. */\nexport interface DvmBuyJobRequest {\n /**\n * The store node's ILP destination that `--via` resolved. Carried for error\n * messages only — the paid transport is {@link DvmBuyJobRequest.submit},\n * which is already bound to this destination.\n */\n destination: string;\n name: string;\n type: NameType;\n /** Lease years; null for a permabuy. */\n years: number | null;\n /** The CLIENT's freshly-spawned ANT (asset pubkey) — the owner-to-be. */\n processId: string;\n /**\n * Paid transport to that node's DVM. The job event is signed by the\n * publisher's own identity, exactly as a kind:5094 store write is, so no\n * key material travels through this seam.\n */\n submit: SubmitStoreJob;\n}\n\n/** What the DVM reports back for an executed buy job. */\nexport interface DvmBuyJobReceipt {\n /** Registry transaction signature of the DVM-paid buy. */\n registryTxId: string;\n /** The mARIO the DVM quoted/paid, when reported. */\n quotedMario: string | null;\n /** The permissionless `syncAttributes` reconcile tx, when it succeeded. */\n syncAttributesTxId: string | null;\n}\n\n/** Submit one kind:5095 job (tests inject a stub — NEVER the live net). */\nexport type SubmitDvmBuyJob = (\n request: DvmBuyJobRequest\n) => Promise<DvmBuyJobReceipt>;\n\n/** A DVM refused or failed a brokered buy job. */\nexport class DvmBuyJobError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DvmBuyJobError';\n }\n}\n\n/**\n * Default {@link SubmitDvmBuyJob}: carry the kind:5095 job to the store node's\n * DVM over the PAID path (#101).\n *\n * This used to `fetch(${viaUrl}/store)` directly. No connector serves `/store`\n * and none should: the store sits behind the connector's payment termination,\n * so a publicly reachable one would be an anonymous free gateway to a paid\n * handler — exactly the failure ADR 0020 exists to close. The job now travels\n * as a kind:5094 store write does, inside a paid ILP packet with `/store` as\n * the envelope target beneath the route's handler path.\n *\n * The job's `param` tags are unchanged, so the handler sees the identical\n * event either way.\n */\nexport const defaultSubmitDvmBuyJob: SubmitDvmBuyJob = async (request) => {\n let answer;\n try {\n answer = await request.submit({\n kind: ARNS_BUY_JOB_KIND,\n params: [\n ['name', request.name],\n ['type', request.type],\n ...(request.years !== null\n ? ([['years', String(request.years)]] as [string, string][])\n : []),\n ['processId', request.processId],\n ],\n });\n } catch (err) {\n throw new DvmBuyJobError(\n `could not reach the DVM at ${request.destination}: ` +\n `${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n if (!answer.accept) {\n throw new DvmBuyJobError(\n `the DVM at ${request.destination} rejected the kind:${ARNS_BUY_JOB_KIND} ` +\n `buy job (HTTP ${answer.status}${answer.code ? `, ${answer.code}` : ''})` +\n `${answer.message ? `: ${answer.message}` : ''}`\n );\n }\n const registryTxId = answer.result?.['registryTxId'];\n if (typeof registryTxId !== 'string' || registryTxId.length === 0) {\n throw new DvmBuyJobError(\n `the DVM accepted the job but returned no registryTxId — response: ` +\n JSON.stringify(answer.result ?? null)\n );\n }\n const quotedMario = answer.result?.['quotedMario'];\n const syncAttributesTxId = answer.result?.['syncAttributesTxId'];\n return {\n registryTxId,\n quotedMario: typeof quotedMario === 'string' ? quotedMario : null,\n syncAttributesTxId:\n typeof syncAttributesTxId === 'string' ? syncAttributesTxId : null,\n };\n};\n\n// ---------------------------------------------------------------------------\n// The gas-station job seam (kind:5096 — toon-meta#163)\n// ---------------------------------------------------------------------------\n\n/** The NIP-90 job kind for a gas-station (fee-payer-as-a-service) job. */\nexport const GAS_STATION_JOB_KIND = 5096;\n\n/** A kind:5096 quote — the merged quote/blockhash deadline contract. */\nexport interface GasStationQuote {\n quoteId: string;\n /** The DVM's advertised fee-payer address — set as the tx feePayer. */\n feePayer: string;\n /** The delta cap the DVM will enforce (lamports, base-10 string). */\n maxLamports: string;\n /** Build + partial-sign against exactly this blockhash. */\n recentBlockhash: string;\n /** ms epoch — submit before this or re-quote. */\n expiresAt: number;\n}\n\n/** A landed kind:5096 execute result. */\nexport interface GasStationExecuteResult {\n signature: string;\n slot: string | null;\n feeLamportsActual: string | null;\n replayed?: boolean;\n}\n\n/** The DVM refused or failed a gas-station job (machine-readable reason). */\nexport class GasStationJobError extends Error {\n constructor(\n public readonly reason: string,\n message: string\n ) {\n super(message);\n this.name = 'GasStationJobError';\n }\n}\n\n/** kind:5096 client seam (tests inject a stub — NEVER the live net). */\nexport interface GasStationClient {\n quote(args: {\n /** Store node's ILP destination, for error messages. */\n destination: string;\n /** Optional draft wire tx for an accurate (rent-aware) maxLamports. */\n transaction?: string;\n /** Paid transport to that node's DVM. */\n submit: SubmitStoreJob;\n }): Promise<GasStationQuote>;\n execute(args: {\n destination: string;\n transaction: string;\n quoteId: string;\n idempotencyKey: string;\n submit: SubmitStoreJob;\n }): Promise<GasStationExecuteResult>;\n}\n\n/**\n * Carry one kind:5096 job to the DVM over the PAID path (#101).\n *\n * Same change as the buy job above, and for the same reason: `/store` is an\n * envelope target beneath the route's handler, not a public URL path.\n */\nasync function submitGasStationJob(\n destination: string,\n params: [string, string][],\n submit: SubmitStoreJob\n): Promise<Record<string, unknown>> {\n let answer;\n try {\n answer = await submit({ kind: GAS_STATION_JOB_KIND, params });\n } catch (err) {\n throw new GasStationJobError(\n 'unreachable',\n `could not reach the DVM at ${destination}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (!answer.accept || !answer.result) {\n throw new GasStationJobError(\n String(answer.code ?? 'rejected'),\n `the DVM at ${destination} rejected the kind:${GAS_STATION_JOB_KIND} job (HTTP ${answer.status}${answer.code ? `, ${answer.code}` : ''})${answer.message ? `: ${answer.message}` : ''}`\n );\n }\n const result = answer.result;\n if (result['status'] === 'failed') {\n throw new GasStationJobError(\n String(result['reason'] ?? 'failed'),\n `gas-station job failed: ${String(result['reason'] ?? 'unknown')} — ${String(result['detail'] ?? '')}`\n );\n }\n return result;\n}\n\n/**\n * Default {@link GasStationClient}: signed kind:5096 events POSTed to the\n * DVM's payment-oblivious `/store` backend — the identical HTTP request the\n * connector payment proxy replays on the paid path (RouteTermination).\n */\nexport const defaultGasStationClient: GasStationClient = {\n quote: async (args) => {\n const result = await submitGasStationJob(\n args.destination,\n [\n ['phase', 'quote'],\n ...(args.transaction !== undefined\n ? ([['transaction', args.transaction]] as [string, string][])\n : []),\n ],\n args.submit\n );\n const { quoteId, feePayer, maxLamports, recentBlockhash, expiresAt } =\n result as Partial<GasStationQuote>;\n if (\n typeof quoteId !== 'string' ||\n typeof feePayer !== 'string' ||\n typeof maxLamports !== 'string' ||\n typeof recentBlockhash !== 'string' ||\n typeof expiresAt !== 'number'\n ) {\n throw new GasStationJobError(\n 'bad_response',\n `the DVM quote is missing fields: ${JSON.stringify(result)}`\n );\n }\n return { quoteId, feePayer, maxLamports, recentBlockhash, expiresAt };\n },\n execute: async (args) => {\n const result = await submitGasStationJob(\n args.destination,\n [\n ['phase', 'execute'],\n ['transaction', args.transaction],\n ['quoteId', args.quoteId],\n ['idempotencyKey', args.idempotencyKey],\n ],\n args.submit\n );\n const signature = result['signature'];\n if (typeof signature !== 'string' || signature.length === 0) {\n throw new GasStationJobError(\n 'bad_response',\n `the DVM execute result carries no signature: ${JSON.stringify(result)}`\n );\n }\n return {\n signature,\n slot: typeof result['slot'] === 'string' ? result['slot'] : null,\n feeLamportsActual:\n typeof result['feeLamportsActual'] === 'string'\n ? result['feeLamportsActual']\n : null,\n ...(result['replayed'] === true ? { replayed: true } : {}),\n };\n },\n};\n\n// ---------------------------------------------------------------------------\n// Deps + usage\n// ---------------------------------------------------------------------------\n\n/** What `rig name` needs from the command environment. */\nexport interface NameDeps {\n io: CliIo;\n env: NodeJS.ProcessEnv;\n /** Working directory (project-local `.env` walk for the identity). */\n cwd: string;\n /** ar.io SDK loader seam; defaults to the lazy `@ar.io/sdk` import. */\n loadArns?: LoadArns;\n /** kind:5095 job submitter seam; defaults to the paid ILP submission. */\n submitDvmBuyJob?: SubmitDvmBuyJob;\n /** kind:5096 gas-station client seam; defaults to the paid ILP submission. */\n gasStation?: GasStationClient;\n /**\n * Standalone-session factory for the `--via` paid path (#101); defaults to\n * `rig push`'s. Tests inject a fake so no session is ever opened and no\n * packet is ever paid for.\n */\n loadStandalone?: LoadStandalone;\n /**\n * TOON-network resolution seam for the default `--via` DVM (defaults to\n * `rig fund`'s {@link resolveEffectiveNetwork}; tests inject). The devnet\n * DVM is only defaulted when the TOON side ALSO resolves to devnet.\n */\n resolveToonNetwork?: typeof resolveEffectiveNetwork;\n}\n\n/**\n * The deployed devnet store DVM — defaulted as `--via` for buy/set when BOTH\n * the ArNS `--network` and the TOON network resolve to devnet and the user\n * neither named a DVM (`--via`/`RIG_ARNS_DVM_DESTINATION`) nor opted out\n * (`--direct`).\n */\nexport const DEVNET_DVM_DESTINATION = 'g.toon.ario';\n\n/**\n * @deprecated `--via` names an ILP destination, not an HTTP endpoint (#101).\n * Kept as an alias so an importer of the old name still compiles; it now holds\n * the same destination as {@link DEVNET_DVM_DESTINATION}.\n */\nexport const DEVNET_DVM_URL = DEVNET_DVM_DESTINATION;\n\nexport const NAME_USAGE = `Usage: rig name <buy|set|status> <name> [options]\n\nArNS naming for Arweave-served artifacts. A name registered on the ar.io\nregistry resolves at every ar.io gateway (https://<name>.<gateway>/), pointing\nat whatever Arweave txId its ANT record targets (10 undernames included).\n\nNames are OWNED and PAID FOR by this rig identity's Solana key — the same\nmnemonic that pays for pushes (derived at m/44'/501'/0'/0'). Fund it with\n\\`rig fund --chain solana\\`. Purchases spend mARIO on Solana via the ar.io\nregistry program — NOT through TOON ILP payment channels.\n\nCommands:\n name buy <name> [--years n | --permabuy] [--via <destination>]\n quote (mARIO) → confirm → register. The spawned ANT is\n owned by this identity's Solana key. Default: 1-year\n lease. PAID — spends mARIO from the Solana wallet.\n With --via: BROKERED — this identity spawns and owns\n the ANT (dust SOL only), then a store DVM executes the\n kind:5095 buy job and pays the mARIO from ITS wallet;\n the name is owned by your ANT from inception.\n name set <name> <txId> [--undername <sub>] [--ttl <seconds>] [--via <destination>]\n point the name (or an undername) at an Arweave txId\n (typically a deployed path manifest). Signs an ANT\n record update with the Solana key. With --via: the\n gas-station path (kind:5096) — you author and\n partial-sign, the DVM co-signs as fee payer and pays\n the lamports; needs ZERO SOL in this wallet.\n <txId> may instead be given via --tx-id <id> — use\n that instead of the positional when the txId leads\n with '-' or '_' (Arweave txids are base64url). For a\n leading '-' write --tx-id=<id> (the '=' form), since\n \"--tx-id -XYZ...\" is itself ambiguous to the parser.\n name status <name> FREE: registry record (lease/permabuy, expiry), ANT\n process id, current target txId(s), TTL, undernames.\n\nOptions:\n --years <n> lease length in years (buy; default 1; mutually\n exclusive with --permabuy)\n --permabuy permanent registration instead of a lease (buy)\n --undername <sub> target the undername <sub>_<name> instead of the base\n name (set)\n --ttl <seconds> record TTL in seconds (set; default 3600)\n --tx-id <id> set only: the Arweave txId to point at, as an\n explicit option instead of the positional (mutually\n exclusive with the positional <txId>). For a value\n leading with '-' use --tx-id=<id>.\n --network <net> cluster: mainnet | devnet (default mainnet; or\n RIG_ARIO_NETWORK). ar.io has no Solana-testnet\n deployment. Non-mainnet gateway resolution is\n unverified.\n --process-id <id> explicit ArNS registry program id — a Solana program\n address (overrides --network; or RIG_ARIO_PROCESS_ID)\n --via <destination> broker buy/set through a store node's DVM, naming its\n ILP DESTINATION (or RIG_ARNS_DVM_DESTINATION), e.g.\n --via ${DEVNET_DVM_DESTINATION}. The DVM pays the mARIO;\n you own the name via your spawned ANT.\n The job travels as a PAID packet, exactly as a git-object\n store write does — the store sits behind the connector's\n payment termination, so there is no unpaid endpoint to\n aim at. That node's ingress, route price and payment\n channel are all discovered from its own announce, so the\n destination is the only thing you supply.\n Costs one store-route packet per job (two for set:\n quote + execute).\n DEVNET DEFAULT: with --network devnet and the TOON\n network on devnet too, buy/set default to the deployed\n devnet store DVM (${DEVNET_DVM_DESTINATION})\n unless --direct opts out.\n --direct force the direct wallet-paid path: never default (or\n read RIG_ARNS_DVM_DESTINATION as) a --via DVM. Mutually\n exclusive with an explicit --via.\n --yes skip the confirmation (required when not a TTY) for\n buy/set\n --json machine-readable envelope; for buy/set without --yes it\n is a pure estimate (nothing is bought or written)\n -h, --help show this help`;\n\n// ---------------------------------------------------------------------------\n// Shared setup: identity → Solana key → SDK\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 3600;\nconst DEFAULT_LEASE_YEARS = 1;\nconst NETWORKS: readonly ArioNetwork[] = ['mainnet', 'devnet'];\n\n/** Resolved wallet context shared by every `rig name` action. */\ninterface NameContext {\n identity: IdentityReport;\n solanaAddress: string;\n network: ArioNetwork;\n processId: string | undefined;\n sdk: ArnsSdk;\n /** Nostr secret key of the identity — signs brokered kind:5095 jobs. */\n nostrSecretKey: Uint8Array;\n}\n\n/**\n * Resolve the rig identity, derive its Solana key (the owner/payer), and build\n * the (stub-injected in tests) ArNS SDK targeted at the chosen registry.\n * `mode` decides whether the SDK gets write plumbing: every FREE lookup —\n * `status`, the buy quote, the set preview — runs `read` (signerless, #376);\n * `buy`/`set` escalate to `write` only at execute time, after the confirm\n * gate.\n */\n/**\n * Open a paid session against the store node `--via` names, and hand back its\n * job seam plus the teardown the caller must run (#101).\n *\n * `storeDestination` is the whole configuration this needs. From it, the\n * machinery `rig push` already uses discovers that node's BTP ingress from its\n * own kind:10032 announce, opens (or resumes) a payment channel against its\n * settlement address, and reads its route price to floor the claim — the same\n * store leg #98 built, pointed somewhere chosen per invocation.\n *\n * ⚠️ The caller owns the returned `stop`. A session left open holds the\n * identity lock and an started embedded client.\n */\nasync function openStoreJobSession(\n deps: NameDeps,\n destination: string\n): Promise<{ submit: SubmitStoreJob; stop: () => Promise<void> }> {\n const ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => deps.io.err(line),\n storeDestination: destination,\n });\n const submitStoreJob = ctx.publisher.submitStoreJob;\n if (!submitStoreJob) {\n await ctx.stop();\n throw new Error(\n 'the active publisher cannot submit a store job (submitStoreJob ' +\n 'unavailable) — `rig name --via` requires the standalone publisher'\n );\n }\n return {\n submit: (request) => submitStoreJob.call(ctx.publisher, request),\n stop: () => ctx.stop(),\n };\n}\n\nasync function resolveNameContext(\n deps: NameDeps,\n network: ArioNetwork,\n processId: string | undefined,\n mode: 'read' | 'write'\n): Promise<NameContext> {\n const { io, env } = deps;\n const resolved = await resolveIdentity({\n env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n });\n const identity: IdentityReport = {\n pubkey: resolved.pubkey,\n source: resolved.source,\n sourceLabel: resolved.sourceLabel,\n };\n // Dynamic import: `@toon-protocol/client` is heavy — the same lazy load\n // `rig fund`/`rig balance` use to derive the multi-chain identity.\n const client = await import('@toon-protocol/client');\n const derived = client.deriveFullIdentity(resolved.mnemonic, {\n accountIndex: resolved.accountIndex,\n scheme: 'legacy',\n });\n const solanaAddress = derived.solana.publicKey;\n if (!solanaAddress) {\n throw new Error(\n 'no Solana key could be derived for this identity — ArNS names are ' +\n \"owned by the Solana key (m/44'/501'/0'/0'). Ensure the optional \" +\n 'Solana derivation deps are installed.'\n );\n }\n const sdk = await (deps.loadArns ?? defaultLoadArns)({\n mode,\n solanaSecretKey: derived.solana.secretKey,\n solanaPublicKey: solanaAddress,\n network,\n ...(processId !== undefined ? { processId } : {}),\n });\n const nostrSecretKey = deriveNostrKeyFromMnemonic(\n resolved.mnemonic,\n resolved.accountIndex\n ).secretKey;\n return { identity, solanaAddress, network, processId, sdk, nostrSecretKey };\n}\n\n// ---------------------------------------------------------------------------\n// Parsed flags\n// ---------------------------------------------------------------------------\n\ninterface NameFlags {\n years?: number;\n permabuy: boolean;\n undername?: string;\n ttl: number;\n network: ArioNetwork;\n processId?: string;\n /** Brokered buy: the DVM endpoint to submit the kind:5095 job to. */\n via?: string;\n /**\n * Opt out of the devnet default `--via` DVM: force the direct wallet-paid\n * path even when both networks resolve to devnet.\n */\n direct: boolean;\n /**\n * `set` only: the Arweave txId as an explicit option, so it never has to\n * sit in the hyphen-ambiguous positional slot — Arweave txids are\n * base64url and roughly 1 in 32 lead with `-` or `_`, which Node's\n * `parseArgs` (strict by default) misreads as an unknown flag (#399).\n */\n txId?: string;\n yes: boolean;\n json: boolean;\n}\n\nfunction parseNameFlags(\n args: string[],\n env: NodeJS.ProcessEnv\n): {\n positionals: string[];\n flags: NameFlags;\n} {\n const { values, positionals } = parseArgs({\n args,\n allowPositionals: true,\n options: {\n years: { type: 'string' },\n permabuy: { type: 'boolean', default: false },\n undername: { type: 'string' },\n ttl: { type: 'string' },\n network: { type: 'string' },\n 'process-id': { type: 'string' },\n via: { type: 'string' },\n direct: { type: 'boolean', default: false },\n 'tx-id': { type: 'string' },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n if (values.help) {\n return {\n positionals: ['--help'],\n flags: {\n permabuy: false,\n ttl: 0,\n network: 'mainnet',\n direct: false,\n yes: false,\n json: false,\n },\n };\n }\n\n let years: number | undefined;\n if (values.years !== undefined) {\n years = Number(values.years);\n if (!Number.isInteger(years) || years <= 0) {\n throw new Error(\n `--years must be a positive integer, got ${JSON.stringify(values.years)}`\n );\n }\n }\n if (years !== undefined && values.permabuy) {\n throw new Error('--years and --permabuy are mutually exclusive');\n }\n\n let ttl = DEFAULT_TTL_SECONDS;\n if (values.ttl !== undefined) {\n ttl = Number(values.ttl);\n if (!Number.isInteger(ttl) || ttl <= 0) {\n throw new Error(\n `--ttl must be a positive integer number of seconds, got ${JSON.stringify(values.ttl)}`\n );\n }\n }\n\n const networkRaw = values.network ?? env['RIG_ARIO_NETWORK'] ?? 'mainnet';\n if (!NETWORKS.includes(networkRaw as ArioNetwork)) {\n throw new Error(\n `--network must be one of ${NETWORKS.join(' | ')}, got ${JSON.stringify(networkRaw)}`\n );\n }\n const processId = values['process-id'] ?? env['RIG_ARIO_PROCESS_ID'];\n\n if (values.direct && values.via !== undefined) {\n throw new Error(\n '--direct and --via are mutually exclusive: --direct forces the ' +\n 'wallet-paid path, --via brokers through a DVM'\n );\n }\n // --direct beats the ambient env var too (explicit opt-out).\n // `RIG_ARNS_DVM_URL` is the pre-#101 spelling, still read so an existing\n // environment keeps working, but it now carries a destination.\n const viaRaw = values.direct\n ? undefined\n : (values.via ??\n env['RIG_ARNS_DVM_DESTINATION'] ??\n env['RIG_ARNS_DVM_URL']);\n let via: string | undefined;\n if (viaRaw !== undefined) {\n // #101: `--via` names an ILP DESTINATION, not an HTTP endpoint. The store\n // sits behind the connector's payment termination and no connector serves\n // a public `/store`, so a URL here is a leftover from the broken direct\n // path rather than a usable value — reject it with the fix rather than\n // letting it fail later as an unroutable address.\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(viaRaw)) {\n throw new Error(\n `--via names an ILP destination, not a URL (got ${JSON.stringify(viaRaw)}). ` +\n `Brokered ArNS jobs travel as paid packets to a store node, e.g. ` +\n `--via ${DEVNET_DVM_DESTINATION}. The node's endpoint, price and ` +\n `payment channel are discovered from its own announce.`\n );\n }\n if (!/^g\\.[a-z0-9]+(\\.[a-z0-9-]+)*$/i.test(viaRaw)) {\n throw new Error(\n `--via must be an ILP destination like ${DEVNET_DVM_DESTINATION}, ` +\n `got ${JSON.stringify(viaRaw)}`\n );\n }\n via = viaRaw;\n }\n\n return {\n positionals,\n flags: {\n ...(years !== undefined ? { years } : {}),\n permabuy: values.permabuy ?? false,\n ...(values.undername !== undefined\n ? { undername: values.undername }\n : {}),\n ttl,\n network: networkRaw as ArioNetwork,\n ...(processId !== undefined ? { processId } : {}),\n ...(via !== undefined ? { via } : {}),\n direct: values.direct ?? false,\n ...(values['tx-id'] !== undefined ? { txId: values['tx-id'] } : {}),\n yes: values.yes ?? false,\n json: values.json ?? false,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// buy\n// ---------------------------------------------------------------------------\n\ninterface NameBuyJson {\n command: 'name';\n action: 'buy';\n name: string;\n type: NameType;\n years: number | null;\n network: ArioNetwork;\n processId: string | null;\n /** Brokered buy: the DVM endpoint the kind:5095 job goes to (else null). */\n via: string | null;\n identity: IdentityReport;\n solanaAddress: string;\n /** The mARIO quote (base units, string) + a human ARIO figure. */\n quote: { mARIO: string; ARIO: string };\n /** How the purchase settles — always Solana/registry, never ILP. */\n payment: string;\n executed: boolean;\n hint?: string;\n /**\n * The ANT this identity spawned and owns (execute only) — both the\n * brokered and direct paths spawn one (#79).\n */\n spawn?: { processId: string; signature: string };\n result?: {\n registryTxId: string;\n antProcessId: string | null;\n /** Brokered buy: the DVM's permissionless trait reconcile tx, if any. */\n syncAttributesTxId?: string | null;\n /** Brokered buy: the mARIO the DVM reported paying, if any. */\n dvmQuotedMario?: string | null;\n };\n}\n\nasync function runBuy(\n name: string,\n flags: NameFlags,\n deps: NameDeps\n): Promise<number> {\n const { io } = deps;\n const type: NameType = flags.permabuy ? 'permabuy' : 'lease';\n const years = type === 'lease' ? (flags.years ?? DEFAULT_LEASE_YEARS) : null;\n\n // Signerless context: the quote is a FREE read (#376); write plumbing is\n // built only after the confirm gate, right before money moves.\n const ctx = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'read'\n );\n\n // ── Estimate (quote the mARIO cost) ──────────────────────────────────────\n const mario = await ctx.sdk.getTokenCost({\n intent: 'Buy-Name',\n name,\n type,\n ...(years !== null ? { years } : {}),\n });\n const quote = {\n mARIO: mario.toString(),\n ARIO: formatUnits(mario.toString(), ARIO_DECIMALS),\n };\n\n const via = flags.via ?? null;\n const paymentNote = via === null ? MARIO_PAYMENT_NOTE : DVM_PAYMENT_NOTE;\n\n const buildJson = (\n executed: boolean,\n extra: Partial<NameBuyJson> = {}\n ): NameBuyJson => ({\n command: 'name',\n action: 'buy',\n name,\n type,\n years,\n network: ctx.network,\n processId: ctx.processId ?? null,\n via,\n identity: ctx.identity,\n solanaAddress: ctx.solanaAddress,\n quote,\n payment: paymentNote,\n executed,\n ...extra,\n });\n\n // ── Human estimate table ─────────────────────────────────────────────────\n if (!flags.json) {\n io.out(\n `Buy ArNS name \"${name}\" — ${type}` +\n (years !== null ? ` (${years} year${years === 1 ? '' : 's'})` : '') +\n ` on ${ctx.network}` +\n (via !== null ? ` — brokered via DVM ${via}` : '')\n );\n io.out(\n via === null\n ? ` Cost: ${renderMario(mario)}`\n : ` Name cost (paid by the DVM): ${renderMario(mario)}`\n );\n io.out(` Solana wallet: ${ctx.solanaAddress}`);\n io.out(` ${paymentNote}`);\n io.out(renderIdentityLine(ctx.identity));\n }\n\n // ── Confirm gate ─────────────────────────────────────────────────────────\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson(\n buildJson(false, {\n hint:\n via === null\n ? 'estimate only — re-run with --yes to buy (spends mARIO on Solana, non-refundable)'\n : 'estimate only — re-run with --yes to spawn your ANT and submit the kind:5095 buy job to the DVM',\n })\n );\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n via === null\n ? 'refusing to spend mARIO without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for a pure estimate)'\n : 'refusing to spawn an ANT and submit a paid DVM job without ' +\n 'confirmation in a non-interactive session — re-run with --yes ' +\n '(or use --json for a pure estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n via === null\n ? `Proceed — buy \"${name}\" for ${renderMario(mario)} from your Solana wallet? [y/N] `\n : `Proceed — spawn your ANT and have the DVM at ${via} buy \"${name}\" ` +\n `for ${renderMario(mario)} from ITS wallet? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was bought or paid.');\n return 1;\n }\n }\n\n // ── Execute — build the signed SDK (write mode) only now, confirmed ──────\n const signed = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'write'\n );\n\n if (via !== null) {\n // ── Brokered (\"buyfor\"): spawn OUR ANT, then the DVM buys for it ───────\n // 1. ANT.spawn with this identity's Solana key — the client owns the ANT\n // (and therefore the name, from inception). Costs dust SOL, no $ARIO.\n const spawn = await signed.sdk.spawnAnt({ name });\n if (!flags.json) {\n io.out(`Spawned ANT ${spawn.processId} (tx ${spawn.signature})`);\n }\n // 2. Submit the kind:5095 job carrying OUR processId; the DVM executes\n // buyRecord with ITS funded signer. The job rides a PAID ILP packet to\n // the store node `--via` names (#101), so a session is opened for it and\n // closed whatever happens — it holds the identity lock.\n const submit = deps.submitDvmBuyJob ?? defaultSubmitDvmBuyJob;\n const session = await openStoreJobSession(deps, via);\n let receipt;\n try {\n receipt = await submit({\n destination: via,\n name,\n type,\n years,\n processId: spawn.processId,\n submit: session.submit,\n });\n } finally {\n await session.stop();\n }\n const result = {\n registryTxId: receipt.registryTxId,\n antProcessId: spawn.processId,\n syncAttributesTxId: receipt.syncAttributesTxId,\n dvmQuotedMario: receipt.quotedMario,\n };\n\n if (flags.json) {\n io.emitJson(\n buildJson(true, {\n spawn: { processId: spawn.processId, signature: spawn.signature },\n result,\n })\n );\n } else {\n io.out(\n `Registered \"${name}\" via the DVM — registry tx ${result.registryTxId}`\n );\n io.out(` ANT process (owned by YOU): ${spawn.processId}`);\n if (receipt.syncAttributesTxId) {\n io.out(` Trait sync: ${receipt.syncAttributesTxId}`);\n } else {\n // Proven on devnet: the deployed ario-ant program gates SyncAttributes\n // to the NFT holder, so the DVM cannot reconcile the traits — you can.\n io.out(\n ' Trait sync: not run by the DVM (holder-gated on this ' +\n 'deployment) — as the ANT holder you can reconcile with ' +\n 'syncAttributes later; resolution works regardless.'\n );\n }\n io.out(\n `Point it at content with \\`rig name set ${name} <txId>\\`, then it ` +\n `resolves at https://${name}.<gateway>/`\n );\n }\n return 0;\n }\n\n // ── Direct: register with our own funded wallet (the #367 path) ──────────\n // #79: this identity spawns ITS OWN ANT first (dust SOL, same as the\n // brokered path) and passes its processId into buyRecord, so the name is\n // bound to a real ANT from inception instead of collapsing to the\n // registry's all-ones placeholder.\n const spawn = await signed.sdk.spawnAnt({ name });\n if (!flags.json) {\n io.out(`Spawned ANT ${spawn.processId} (tx ${spawn.signature})`);\n }\n const receipt = await signed.sdk.buyRecord({\n name,\n type,\n ...(years !== null ? { years } : {}),\n processId: spawn.processId,\n });\n // The ANT actually bound: the SDK's echo when it returns one, otherwise the\n // id we asked it to attach (4.0.3's Solana `buyRecord` resolves to `{ id }`\n // alone, so in practice this is the ANT we just spawned). Normalized like\n // every other ANT id, so the placeholder reads as \"no ANT\" here too.\n const antProcessId = antProcessIdOf(receipt.processId ?? spawn.processId);\n const result = { registryTxId: receipt.id, antProcessId };\n const spawnInfo = { processId: spawn.processId, signature: spawn.signature };\n\n if (antProcessId === null) {\n // The purchase went through — the spend is real and on-chain — but no\n // ANT is attached, so the name cannot resolve. Exit non-zero and surface\n // the registry tx either way: never exit 0 on a null ANT (#79), and\n // never lose the tx that makes the spend recoverable.\n const hint =\n `bought \"${name}\" (registry tx ${result.registryTxId}) but no ANT is ` +\n 'attached — the spend is on-chain and recoverable, but the name ' +\n 'cannot resolve until an ANT is attached to it';\n if (flags.json) {\n io.emitJson(buildJson(true, { spawn: spawnInfo, result, hint }));\n } else {\n io.err(hint);\n }\n return 1;\n }\n\n if (flags.json) {\n io.emitJson(buildJson(true, { spawn: spawnInfo, result }));\n } else {\n io.out(`Registered \"${name}\" — registry tx ${result.registryTxId}`);\n io.out(` ANT process: ${result.antProcessId}`);\n io.out(\n `Point it at content with \\`rig name set ${name} <txId>\\`, then it ` +\n `resolves at https://${name}.<gateway>/`\n );\n }\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// set\n// ---------------------------------------------------------------------------\n\ninterface NameSetJson {\n command: 'name';\n action: 'set';\n name: string;\n undername: string | null;\n txId: string;\n ttl: number;\n network: ArioNetwork;\n processId: string | null;\n /** Gas-station path: the DVM endpoint the kind:5096 job goes to. */\n via: string | null;\n identity: IdentityReport;\n solanaAddress: string;\n antProcessId: string;\n executed: boolean;\n hint?: string;\n /** Gas-station path: the quote the DVM enforced. */\n gasStation?: {\n quoteId: string;\n feePayer: string;\n maxLamports: string;\n expiresAt: number;\n feeLamportsActual: string | null;\n };\n result?: { messageId: string };\n}\n\nasync function runSet(\n name: string,\n txId: string,\n flags: NameFlags,\n deps: NameDeps\n): Promise<number> {\n const { io } = deps;\n // Signerless context: the record lookup / preview is a FREE read (#376);\n // write plumbing is built only after the confirm gate.\n const ctx = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'read'\n );\n\n const record = await ctx.sdk.getArNSRecord({ name });\n if (!record) {\n throw new Error(\n `no ArNS record for \"${name}\" on ${ctx.network} — buy it first with ` +\n `\\`rig name buy ${name}\\` (or check \\`rig name status ${name}\\`)`\n );\n }\n const antProcessId = antProcessIdOf(record.processId);\n if (antProcessId === null) {\n // #79 AC4: the placeholder is \"no ANT\", not a process id. Signing a\n // record update against it would target the Solana System Program and\n // cannot succeed, so refuse here rather than build and sign a doomed tx.\n throw new Error(\n `\"${name}\" is registered on ${ctx.network} but has NO ANT attached ` +\n `(the registry placeholder ${ARNS_NULL_PROCESS_ID}) — \\`rig name set\\` ` +\n `needs a real ANT process, so there is nothing to write to. Check ` +\n `\\`rig name status ${name}\\`; the name has to be re-bound to an ANT ` +\n `before it can resolve.`\n );\n }\n const undername = flags.undername ?? null;\n const via = flags.via ?? null;\n\n const buildJson = (\n executed: boolean,\n extra: Partial<NameSetJson> = {}\n ): NameSetJson => ({\n command: 'name',\n action: 'set',\n name,\n undername,\n txId,\n ttl: flags.ttl,\n network: ctx.network,\n processId: ctx.processId ?? null,\n via,\n identity: ctx.identity,\n solanaAddress: ctx.solanaAddress,\n antProcessId,\n executed,\n ...extra,\n });\n\n const targetLabel = undername\n ? `undername \"${undername}_${name}\"`\n : `base name \"${name}\"`;\n\n if (!flags.json) {\n io.out(\n `Set ${targetLabel} → txId ${txId} (ttl ${flags.ttl}s) on ${ctx.network}` +\n (via !== null ? ` — gas paid by the DVM at ${via} (kind:5096)` : '')\n );\n io.out(` ANT process: ${antProcessId}`);\n io.out(` Signed by the identity's Solana key (${ctx.solanaAddress}).`);\n if (via !== null) {\n io.out(\n ' Gas station: you author + partial-sign the record update; the ' +\n 'DVM co-signs as fee payer and pays the lamports (toon-meta#163). ' +\n 'Direct backend targeting stubs the job payment (dev/e2e).'\n );\n }\n io.out(renderIdentityLine(ctx.identity));\n }\n\n // ── Confirm gate (a signed ANT record update) ────────────────────────────\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson(\n buildJson(false, {\n hint:\n via === null\n ? 'estimate only — re-run with --yes to write the ANT record'\n : 'estimate only — re-run with --yes to quote the gas-station and write the ANT record (DVM pays the gas)',\n })\n );\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to write an ANT record without confirmation in a ' +\n 'non-interactive session — re-run with --yes (or --json to preview)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed — point ${targetLabel} at ${txId}?` +\n (via !== null ? ' (the DVM pays the gas)' : '') +\n ' [y/N] '\n );\n if (!proceed) {\n io.err('aborted — the ANT record was not changed.');\n return 1;\n }\n }\n\n // ── Execute (sign + submit the ANT record update) ────────────────────────\n // Only now — confirmed — build the signed SDK (write mode).\n const signed = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'write'\n );\n\n if (via !== null) {\n // ── Gas-station path (toon-meta#163): author + partial-sign locally,\n // the DVM co-signs as fee payer and broadcasts. ────────────────────\n const gas = deps.gasStation ?? defaultGasStationClient;\n // Both phases ride PAID ILP packets to the store node `--via` names\n // (#101). One session covers the pair: the quote's blockhash deadline\n // makes re-opening between them a way to expire your own quote.\n const session = await openStoreJobSession(deps, via);\n let quote: GasStationQuote;\n let executed: GasStationExecuteResult;\n try {\n // Quote: learn the fee payer + the quoted blockhash (merged deadline).\n quote = await gas.quote({\n destination: via,\n submit: session.submit,\n });\n // Build + partial-sign against exactly the quoted blockhash.\n const wireTx = await signed.sdk.buildSetRecordTransaction({\n antProcessId,\n undername: undername ?? '@',\n transactionId: txId,\n ttlSeconds: flags.ttl,\n feePayer: quote.feePayer,\n recentBlockhash: quote.recentBlockhash,\n });\n executed = await gas.execute({\n destination: via,\n transaction: wireTx,\n quoteId: quote.quoteId,\n idempotencyKey: randomUUID(),\n submit: session.submit,\n });\n } finally {\n await session.stop();\n }\n const gasStation = {\n quoteId: quote.quoteId,\n feePayer: quote.feePayer,\n maxLamports: quote.maxLamports,\n expiresAt: quote.expiresAt,\n feeLamportsActual: executed.feeLamportsActual,\n };\n const result = { messageId: executed.signature };\n\n if (flags.json) {\n io.emitJson(buildJson(true, { gasStation, result }));\n } else {\n io.out(\n `Updated — record-set tx ${executed.signature} (gas paid by ${quote.feePayer})`\n );\n const host = undername ? `${undername}_${name}` : name;\n io.out(\n ` Resolves at https://${host}.<gateway>/ (allow for gateway cache/TTL).`\n );\n }\n return 0;\n }\n\n const ant = await signed.sdk.ant(antProcessId);\n const receipt = undername\n ? await ant.setUndernameRecord({\n undername,\n transactionId: txId,\n ttlSeconds: flags.ttl,\n })\n : await ant.setBaseNameRecord({\n transactionId: txId,\n ttlSeconds: flags.ttl,\n });\n const result = { messageId: receipt.id };\n\n if (flags.json) {\n io.emitJson(buildJson(true, { result }));\n } else {\n io.out(`Updated — ANT message ${result.messageId}`);\n const host = undername ? `${undername}_${name}` : name;\n io.out(\n ` Resolves at https://${host}.<gateway>/ (allow for gateway cache/TTL).`\n );\n }\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// status (FREE)\n// ---------------------------------------------------------------------------\n\ninterface NameStatusJson {\n command: 'name';\n action: 'status';\n name: string;\n network: ArioNetwork;\n processId: string | null;\n registered: boolean;\n /**\n * #79 AC4: the name is registered but no ANT is attached (the registry's\n * all-ones placeholder) — it cannot resolve, and `rig name set` cannot fix\n * it. Never reported as success: status also exits non-zero in this case.\n */\n antMissing: boolean;\n identity: IdentityReport;\n solanaAddress: string;\n record: {\n antProcessId: string | null;\n type: NameType | null;\n startTimestamp: number | null;\n endTimestamp: number | null;\n undernameLimit: number | null;\n } | null;\n /** ANT record targets keyed by undername (`@` = base name). */\n targets: Record<string, AntRecordTarget> | null;\n /** Set when the status is not a clean bill of health (`antMissing`). */\n hint?: string;\n}\n\nasync function runStatus(\n name: string,\n flags: NameFlags,\n deps: NameDeps\n): Promise<number> {\n const { io } = deps;\n // FREE read: signerless SDK — a status lookup must never need write plumbing.\n const ctx = await resolveNameContext(\n deps,\n flags.network,\n flags.processId,\n 'read'\n );\n\n const record = await ctx.sdk.getArNSRecord({ name });\n // #79 AC4: never report the registry's placeholder as the name's ANT. A\n // registered name with no ANT attached cannot resolve, so it is a failure\n // to be diagnosed — not a healthy registration.\n const antProcessId = antProcessIdOf(record?.processId);\n const antMissing = record !== null && antProcessId === null;\n const antMissingHint =\n `\"${name}\" is registered on ${ctx.network} but has NO ANT attached ` +\n `(the registry placeholder ${ARNS_NULL_PROCESS_ID}) — it cannot resolve, ` +\n `and \\`rig name set\\` cannot write records against it. The name has to be ` +\n `re-bound to an ANT.`;\n let targets: Record<string, AntRecordTarget> | null = null;\n if (antProcessId !== null) {\n const ant = await ctx.sdk.ant(antProcessId);\n targets = await ant.getRecords();\n }\n\n if (flags.json) {\n io.emitJson({\n command: 'name',\n action: 'status',\n name,\n network: ctx.network,\n processId: ctx.processId ?? null,\n registered: record !== null,\n antMissing,\n identity: ctx.identity,\n solanaAddress: ctx.solanaAddress,\n record: record\n ? {\n antProcessId,\n type: record.type,\n startTimestamp: record.startTimestamp ?? null,\n endTimestamp: record.endTimestamp ?? null,\n undernameLimit: record.undernameLimit ?? null,\n }\n : null,\n targets,\n ...(antMissing ? { hint: antMissingHint } : {}),\n } satisfies NameStatusJson);\n return antMissing ? 1 : 0;\n }\n\n io.out(`ArNS name \"${name}\" on ${ctx.network}:`);\n if (!record) {\n io.out(' not registered — available to `rig name buy`.');\n io.out(renderIdentityLine(ctx.identity));\n return 0;\n }\n io.out(` ANT process: ${antProcessId ?? 'NONE — no ANT is attached'}`);\n io.out(` Type: ${record.type ?? '(unknown)'}`);\n if (record.type === 'permabuy') {\n io.out(' Expiry: never (permabuy)');\n } else if (record.endTimestamp !== undefined) {\n io.out(` Expiry: ${new Date(record.endTimestamp).toISOString()}`);\n }\n if (record.undernameLimit !== undefined) {\n io.out(` Undernames included: ${record.undernameLimit}`);\n }\n if (targets && Object.keys(targets).length > 0) {\n io.out(' Records:');\n for (const [under, target] of Object.entries(targets)) {\n const label = under === '@' ? '(base)' : `${under}_${name}`;\n io.out(\n ` ${label} → ${target.transactionId} (ttl ${target.ttlSeconds}s)`\n );\n }\n } else if (antMissing) {\n io.out(' Records: none — there is no ANT to hold them.');\n } else {\n io.out(' Records: none set — point one with `rig name set`.');\n }\n io.out(renderIdentityLine(ctx.identity));\n if (antMissing) {\n io.err(antMissingHint);\n return 1;\n }\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// Dispatch\n// ---------------------------------------------------------------------------\n\n/** Run `rig name <sub> …`; returns the process exit code. */\nexport async function runName(args: string[], deps: NameDeps): Promise<number> {\n const { io } = deps;\n const sub = args[0];\n\n if (sub === undefined) {\n // Usage error → stderr + exit 2 (matches every other rig-owned command).\n io.err(NAME_USAGE);\n return 2;\n }\n if (sub === '--help' || sub === '-h' || sub === 'help') {\n io.out(NAME_USAGE);\n return 0;\n }\n if (!['buy', 'set', 'status'].includes(sub)) {\n io.err(`unknown \\`rig name\\` subcommand: ${JSON.stringify(sub)}`);\n io.err(NAME_USAGE);\n return 2;\n }\n\n let positionals: string[];\n let flags: NameFlags;\n try {\n const parsed = parseNameFlags(args.slice(1), deps.env);\n positionals = parsed.positionals;\n flags = parsed.flags;\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(NAME_USAGE);\n return 2;\n }\n if (positionals[0] === '--help') {\n io.out(NAME_USAGE);\n return 0;\n }\n\n const name = positionals[0];\n if (name === undefined) {\n io.err(`\\`rig name ${sub}\\` needs a <name>`);\n io.err(NAME_USAGE);\n return 2;\n }\n\n // Default `--via` DVM on the shared devnet (#demo): buy/set broker through\n // the deployed store DVM when the user neither named a DVM (--via /\n // RIG_ARNS_DVM_URL) nor opted out (--direct). Hard-gated BOTH ways: the\n // ArNS `--network` must be devnet (a mainnet purchase must never silently\n // switch payment paths) AND the TOON network must resolve to devnet (same\n // inference `rig fund` drips on — explicit config, devnet origin, or the\n // genesis-seed fresh install).\n if (\n (sub === 'buy' || sub === 'set') &&\n !flags.direct &&\n flags.via === undefined &&\n flags.network === 'devnet'\n ) {\n let toonDevnet = false;\n try {\n const resolved = await (\n deps.resolveToonNetwork ?? resolveEffectiveNetwork\n )({ env: deps.env, cwd: deps.cwd });\n toonDevnet = resolved.effectiveNetwork === 'devnet';\n } catch {\n // Unreadable client config — leave the wallet-paid path untouched.\n }\n if (toonDevnet) {\n flags = { ...flags, via: DEVNET_DVM_DESTINATION };\n io.err(\n `Brokering via the devnet store DVM ${DEVNET_DVM_DESTINATION} ` +\n `(no --via given; pass --direct for a wallet-paid ${sub}).`\n );\n }\n }\n\n try {\n if (sub === 'buy') return await runBuy(name, flags, deps);\n if (sub === 'status') return await runStatus(name, flags, deps);\n // set: `rig name set <name> <txId>` — or `rig name set <name> --tx-id\n // <id>` (#399: a positional txId leading with `-`/`_` is hyphen-\n // ambiguous with Node's strict `parseArgs`).\n if (flags.txId !== undefined && positionals[1] !== undefined) {\n io.err('`--tx-id` and a positional <txId> are mutually exclusive');\n io.err(NAME_USAGE);\n return 2;\n }\n const txId = flags.txId ?? positionals[1];\n if (txId === undefined) {\n io.err(\n '`rig name set` needs a <txId> (the Arweave transaction to point at) ' +\n '— as a positional or via --tx-id'\n );\n io.err(NAME_USAGE);\n return 2;\n }\n return await runSet(name, txId, flags, deps);\n } catch (err) {\n return emitCliError(io, flags.json, 'name', err);\n }\n}\n","/**\n * `rig payout set|clear|show` (rig#92, part of the payout epic\n * toon-protocol/toon-meta#391) — manage the declared payout pointer on a\n * repo's kind:30617 announcement.\n *\n * The payout pointer is the ONLY thing that turns on a serving node's\n * node-declared `ownerFeeShare` split on repo-scoped paid writes\n * (toon-meta#391 decision 2): no pointer on the announcement → no split, the\n * node keeps 100%. v1 accepts exactly one chain, `evm` — the payout accrual\n * ledger is EVM-only today (`crates/connector-client-edge/src/btp.rs:270-272`)\n * — but the tag shape (`['payout', '<chain>', '<address>']`) carries the\n * chain label so nothing re-shapes later.\n *\n * show FREE relay read — print the pointer or \"none\"\n * set <address> PAID — republish the 30617 with the payout tag set to\n * `evm <checksummed address>`\n * clear PAID — republish the 30617 with the payout tag removed\n *\n * set/clear republish the WHOLE announcement (a replaceable event keyed by\n * author + `d` tag), so they preserve the existing name/description/\n * maintainers and only mutate the payout pointer — mirrors `rig maintainers`\n * exactly (`./maintainers.ts:1-23`). Because the 30617 is addressed by its\n * author, only the OWNER's republish is authoritative, so a non-owner\n * republish is refused (same shape as maintainers.ts:344-351), as is a\n * republish on an unannounced repo (maintainers.ts:369-377). The daemon has\n * no announcement route, so this always runs the embedded standalone\n * publisher; the confirm gate matches every other paid write (`--yes` skips;\n * a non-TTY without it refuses; `--json` without `--yes` is a pure\n * estimate).\n */\n\nimport { parseArgs } from 'node:util';\nimport { getAddress } from 'viem';\nimport {\n buildRepoAnnouncement,\n isValidEvmPayoutAddress,\n type PayoutPointer,\n} from '../nip34-events.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport { serializeEventReceipt, type GitEventResponse } from '../routes.js';\nimport type { EventCommandDeps } from './events.js';\nimport { emitCliError, InvalidRelayUrlError } from './errors.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n type IdentityReport,\n} from './push.js';\nimport { feeLabel } from './render.js';\nimport { singleRelayRefusal } from './remote.js';\nimport {\n pickRepoCommandFlags,\n REPO_COMMAND_OPTIONS,\n resolveRepoContext,\n WS_URL_RE,\n type RepoCommandFlags,\n} from './repo-command.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\nexport const PAYOUT_USAGE = `Usage: rig payout <set|clear|show> [<address>] [options]\n\nManage a repo's declared payout pointer (rig#92, part of the payout epic\ntoon-protocol/toon-meta#391). No pointer on the kind:30617 announcement means\na serving node keeps 100% of repo-scoped write fees; a pointer opts the repo\ninto that node's declared ownerFeeShare split.\n\nSubcommands:\n show show the declared payout pointer — FREE (relay read)\n set <address> declare the payout pointer (EVM address, EIP-55\n checksummed or all-lowercase) — PAID: republishes the\n kind:30617 (permanent, non-refundable). v1 accepts evm\n addresses only.\n clear remove the payout pointer — PAID: republishes the\n kind:30617\n\nset/clear must run under the repo OWNER's identity (only the owner's\nannouncement is authoritative).\n\nOptions:\n --repo-id <id> repository id / NIP-34 d-tag (default: git config)\n --owner <pubkey> repository owner (npub or hex; default: git config)\n --remote <name> publish/read via this configured git remote (default: origin)\n --relay <url> ad-hoc relay override (exactly one for set/clear)\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable envelope\n -h, --help show this help`;\n\n/** Run `rig payout …`; returns the process exit code. */\nexport async function runPayout(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n switch (sub) {\n case 'show':\n return runShow(rest, deps);\n case 'set':\n return runMutate('set', rest, deps);\n case 'clear':\n return runMutate('clear', rest, deps);\n case '--help':\n case '-h':\n case 'help':\n io.out(PAYOUT_USAGE);\n return 0;\n default:\n io.err(\n sub === undefined\n ? 'missing subcommand: rig payout <set|clear|show>'\n : `unknown rig payout subcommand: ${sub}`\n );\n io.err(PAYOUT_USAGE);\n return 2;\n }\n}\n\n// ---------------------------------------------------------------------------\n// show (FREE)\n// ---------------------------------------------------------------------------\n\nasync function runShow(\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n let flags: RepoCommandFlags;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: REPO_COMMAND_OPTIONS,\n allowPositionals: true,\n });\n if (positionals.length > 0) {\n throw new Error('rig payout show takes no positional arguments');\n }\n flags = pickRepoCommandFlags(values);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PAYOUT_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(PAYOUT_USAGE);\n return 0;\n }\n\n try {\n const ctx = await resolveRepoContext(flags, deps);\n const wsRelays = ctx.relays.filter((url) => WS_URL_RE.test(url));\n if (wsRelays.length === 0) {\n throw new InvalidRelayUrlError(\n ctx.relays[0] ?? '',\n 'reads need a ws:// or wss:// relay'\n );\n }\n const remote = await fetchRemoteState({\n relayUrls: wsRelays,\n ownerPubkey: ctx.owner,\n repoId: ctx.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n const payout = remote.payout;\n if (flags.json) {\n io.emitJson({\n command: 'payout show',\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n announced: remote.announced,\n payout,\n });\n return 0;\n }\n io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);\n if (!remote.announced) {\n io.out('No kind:30617 announcement found — no payout pointer.');\n return 0;\n }\n io.out(\n payout === null\n ? 'Payout: none (the serving node keeps 100% of repo-scoped write fees)'\n : `Payout: ${payout.chain} ${payout.address}`\n );\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'payout show', err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// set / clear (PAID — republish the 30617 under the owner's identity)\n// ---------------------------------------------------------------------------\n\ninterface PayoutJsonOutput {\n command: 'payout set' | 'payout clear';\n repoAddr: { ownerPubkey: string; repoId: string };\n identity: IdentityReport;\n executed: boolean;\n feeEstimate: string | null;\n payout: PayoutPointer | null;\n result?: GitEventResponse;\n hint?: string;\n}\n\nasync function runMutate(\n op: 'set' | 'clear',\n args: string[],\n deps: EventCommandDeps\n): Promise<number> {\n const { io } = deps;\n const command = `payout ${op}` as 'payout set' | 'payout clear';\n\n let flags: RepoCommandFlags;\n /** The pointer this run publishes: validated for `set`, `null` for `clear`. */\n let nextPayout: PayoutPointer | null = null;\n try {\n const { values, positionals } = parseArgs({\n args,\n options: REPO_COMMAND_OPTIONS,\n allowPositionals: true,\n });\n flags = pickRepoCommandFlags(values);\n if (flags.help) {\n io.out(PAYOUT_USAGE);\n return 0;\n }\n if (op === 'set') {\n if (positionals.length !== 1) {\n throw new Error('expected exactly one <address> to set');\n }\n const raw = positionals[0] as string;\n if (!isValidEvmPayoutAddress(raw)) {\n throw new Error(\n `<address> must be a valid EVM address (0x + 40 hex chars, ` +\n `correctly EIP-55 checksummed if mixed-case) — got ` +\n `${JSON.stringify(raw)}. See toon-meta#391 (payout epic): v1 ` +\n 'accepts evm addresses only.'\n );\n }\n nextPayout = { chain: 'evm', address: getAddress(raw) };\n } else if (positionals.length !== 0) {\n throw new Error('rig payout clear takes no positional arguments');\n }\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(PAYOUT_USAGE);\n return 2;\n }\n\n let standaloneCtx: StandaloneContext | undefined;\n try {\n const ctx = await resolveRepoContext(flags, deps);\n // A single relay for a paid publish (mirror push/events guard).\n if (ctx.relays.length > 1) {\n io.err(singleRelayRefusal(ctx.resolved, 'Nothing was published or paid.'));\n return 1;\n }\n const relayUrl = ctx.relays[0];\n if (relayUrl === undefined || !WS_URL_RE.test(relayUrl)) {\n throw new InvalidRelayUrlError(\n relayUrl ?? '',\n 'a paid publish needs a ws:// or wss:// relay'\n );\n }\n\n // Standalone only: the daemon has no announcement route.\n const load = deps.loadStandalone ?? defaultLoadStandalone;\n standaloneCtx = await load({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n relayUrl,\n });\n const identity = identityReport(standaloneCtx);\n\n // Only the owner's 30617 is authoritative — refuse a non-owner republish.\n if (identity.pubkey.toLowerCase() !== ctx.owner.toLowerCase()) {\n io.err(\n `rig: only the repo owner (${ctx.owner.slice(0, 8)}…) can change the ` +\n `payout pointer — the active identity is ${identity.pubkey.slice(0, 8)}…. ` +\n 'A non-owner republish would write your own (ignored) announcement. ' +\n 'Nothing was published or paid.'\n );\n return 1;\n }\n\n // Read the current announcement to preserve name/description/maintainers.\n const remote = await fetchRemoteState({\n relayUrls: [relayUrl],\n ownerPubkey: ctx.owner,\n repoId: ctx.repoId,\n ...(deps.webSocketFactory\n ? { webSocketFactory: deps.webSocketFactory }\n : {}),\n });\n // Refuse on an unannounced repo: republishing here would MINT a phantom\n // kind:30617 with a placeholder name (= repoId) and empty description, for\n // real money (mirrors rig maintainers, maintainers.ts:363-377).\n if (!remote.announced) {\n io.err(\n `rig: 30617:${ctx.owner.slice(0, 8)}…:${ctx.repoId} has no announcement ` +\n 'yet — run `rig push` to publish the repo (with its real ' +\n 'name/description) before managing the payout pointer. Nothing was ' +\n 'published or paid.'\n );\n return 1;\n }\n\n const current = remote.payout;\n if (\n nextPayout !== null &&\n current !== null &&\n current.chain === nextPayout.chain &&\n current.address === nextPayout.address\n ) {\n io.err(\n `rig: payout is already set to ${current.chain} ${current.address} — nothing to do (not published).`\n );\n return 0;\n }\n if (op === 'clear' && current === null) {\n io.err('rig: no payout pointer is set — nothing to do (not published).');\n return 0;\n }\n\n const name = remote.name ?? ctx.repoId;\n const description = remote.description ?? '';\n const event = buildRepoAnnouncement(\n ctx.repoId,\n name,\n description,\n remote.maintainers,\n nextPayout\n );\n const fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();\n const action = nextPayout\n ? `kind:30617 payout set ${nextPayout.chain} ${nextPayout.address}`\n : 'kind:30617 payout clear';\n\n // ── Confirm gate ────────────────────────────────────────────────────────\n if (!flags.json) {\n io.out(`Republish ${action}`);\n io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);\n io.out(\n `Payout after: ${nextPayout ? `${nextPayout.chain} ${nextPayout.address}` : '(none)'}`\n );\n io.out(`Fee: ${feeLabel(fee)}. Writes are permanent and non-refundable.`);\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n identity,\n executed: false,\n feeEstimate: fee,\n payout: nextPayout,\n hint: 'estimate only — re-run with --yes to publish (permanent, non-refundable)',\n } satisfies PayoutJsonOutput);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid republish (${feeLabel(fee)})? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was published.');\n return 1;\n }\n }\n\n // ── Execute ───────────────────────────────────────────────────────────────\n const receipt = await standaloneCtx.publisher.publishEvent(event, [\n relayUrl,\n ]);\n const result = serializeEventReceipt(event.kind, receipt);\n\n if (flags.json) {\n io.emitJson({\n command,\n repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },\n identity,\n executed: true,\n feeEstimate: fee,\n payout: nextPayout,\n result,\n } satisfies PayoutJsonOutput);\n } else {\n io.out(\n `Published ${action}: ${result.eventId} paid ${result.feePaid} base units`\n );\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, command, err);\n } finally {\n if (standaloneCtx) {\n try {\n await standaloneCtx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n","/**\n * `rig site publish [ref]` + `rig site url [ref]` — a pushed repo as a\n * permaweb site (#368).\n *\n * Every `rig push` already stores a repo's raw blob bytes on Arweave and, with\n * #368's per-file Content-Type, a gateway serves each blob as its real media\n * type. `rig site publish` adds the last piece: it walks a ref's root tree,\n * joins each file path to the Arweave txId the cumulative kind:30618 `arweave`\n * map already records for that blob (no GraphQL, no re-upload), builds the\n * ar.io path manifest, and uploads THAT as one paid store write. The manifest\n * txId is the site's canonical URL: `https://<gateway>/<txid>/`. Point an ArNS\n * name at it (#367, `rig name set`) for a stable, human name.\n *\n * PAID DISCIPLINE (mirrors `rig push`): estimate → confirm → execute, strict\n * `--json` (one document on stdout), `--yes` required to spend in a non-TTY.\n * Without `--yes`, `--json` is a pure estimate (nothing uploaded, exit 0).\n *\n * `--force-reupload` re-pays to upload the ref's blobs THROUGH the #368\n * mime-typed path before building the manifest, for repos pushed before\n * per-file Content-Type existed (whose blobs would otherwise serve as\n * `application/octet-stream`). Content-addressed dedupe means a plain re-push\n * would skip them, so this is the explicit escape hatch.\n *\n * `rig site url [ref]` is FREE: it reads the manifest txId the last publish\n * recorded locally (../cli/site-record.ts) and prints the URL — no client\n * start, no relay query, no payment.\n */\n\nimport { uploadChargeFor } from '../publisher.js';\nimport { PREFERRED_GATEWAY } from '../gateway-preference.js';\nimport { parseArgs } from 'node:util';\nimport {\n buildArweaveManifest,\n type ManifestEntry,\n} from '../arweave-manifest.js';\nimport { resolveConflictingPath } from '../mime.js';\nimport { GitRepoReader } from '../repo-reader.js';\nimport type { RemoteState } from '../remote-state.js';\nimport {\n defaultLoadStandalone,\n identityReport,\n selectRefspecs,\n type IdentityReport,\n type PushDeps,\n} from './push.js';\nimport { emitCliError, UnconfiguredRepoAddressError } from './errors.js';\nimport { readToonConfig, resolveRepoRoot } from './git-config.js';\nimport { renderIdentityLine } from './render.js';\nimport { resolveRelays, singleRelayRefusal } from './remote.js';\nimport { readSiteRecord, writeSiteRecord } from './site-record.js';\nimport type { StandaloneContext } from './standalone-context.js';\n\n/** The ar.io path-manifest media type (spec-mandated `output` tag value). */\nexport const MANIFEST_CONTENT_TYPE = 'application/x.arweave-manifest+json';\n\n/**\n * Default Arweave/ar.io gateway the printed site URL uses: the shared list's\n * first MAINNET gateway ({@link PREFERRED_GATEWAY}), so this and `rig push`\n * cannot drift apart. A site is ONE manifest txid, so only the primary is\n * printed here — pass `--gateway` (or `RIG_ARWEAVE_GATEWAY`) to re-print\n * against another when one is down.\n */\nexport const DEFAULT_GATEWAY = PREFERRED_GATEWAY;\n\nexport const SITE_USAGE = `Usage: rig site <publish|url> [ref] [options]\n\nServe a pushed repo as a permanent, path-routed website. \\`rig push\\` already\nstored the file bytes on Arweave; \\`rig site publish\\` builds the ar.io path\nmanifest (paths → Arweave txids, index → index.html) and uploads it as ONE\npaid store write, printing the site URL. \\`rig site url\\` re-prints the URL of\nthe last publish for free.\n\nThe repo must be set up with \\`rig init\\`; the relay is the \"origin\" remote\n(\\`rig push\\` reads the same). \\`ref\\` defaults to the current branch.\n\nCommands:\n publish [ref] build + upload the path manifest (paid); prints the URL and\n a \\`rig name set\\` suggestion (#367)\n url [ref] print the last-published site URL for a ref (free)\n\nOptions (publish):\n --index <path> path served at / (default: index.html)\n --spa single-page app: serve index for any unknown path\n (sets the manifest \\`fallback\\` to the index txid)\n --fallback <path> explicit fallback path for unknown routes (overrides\n --spa); must be one of the site's files\n --force-reupload re-pay to re-upload the ref's blobs with #368 per-file\n Content-Type before building the manifest — for repos\n pushed before mime-typing existed (else they serve as\n application/octet-stream)\n --gateway <url> gateway base for the printed URL (default: ${DEFAULT_GATEWAY};\n env RIG_ARWEAVE_GATEWAY also sets it)\n --relay <url> ad-hoc relay override (bypasses configured remotes)\n --repo-id <id> repository id (default: git config toon.repoid)\n --yes skip the fee confirmation (required when not a TTY)\n --json machine-readable envelope; without --yes it is a pure\n estimate (nothing uploaded)\n -h, --help show this help`;\n\n/** Deps for `rig site` — the same seam `rig push` uses (tests inject fakes). */\nexport type SiteDeps = PushDeps;\n\n// ---------------------------------------------------------------------------\n// Arg parsing\n// ---------------------------------------------------------------------------\n\ninterface SiteFlags {\n index: string;\n spa: boolean;\n fallback?: string;\n forceReupload: boolean;\n gateway?: string;\n relay: string[];\n repoId?: string;\n yes: boolean;\n json: boolean;\n help: boolean;\n positionals: string[];\n}\n\nfunction parseSiteArgs(args: string[]): SiteFlags {\n const { values, positionals } = parseArgs({\n args,\n options: {\n index: { type: 'string' },\n spa: { type: 'boolean', default: false },\n fallback: { type: 'string' },\n 'force-reupload': { type: 'boolean', default: false },\n gateway: { type: 'string' },\n relay: { type: 'string', multiple: true },\n 'repo-id': { type: 'string' },\n yes: { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n allowPositionals: true,\n });\n const flags: SiteFlags = {\n index: values.index ?? 'index.html',\n spa: values.spa ?? false,\n forceReupload: values['force-reupload'] ?? false,\n relay: values.relay ?? [],\n yes: values.yes ?? false,\n json: values.json ?? false,\n help: values.help ?? false,\n positionals,\n };\n if (values.fallback !== undefined) flags.fallback = values.fallback;\n if (values.gateway !== undefined) flags.gateway = values.gateway;\n if (values['repo-id'] !== undefined) flags.repoId = values['repo-id'];\n return flags;\n}\n\n// ---------------------------------------------------------------------------\n// JSON envelopes\n// ---------------------------------------------------------------------------\n\ninterface SitePublishJson {\n command: 'site publish';\n repoId: string;\n ref: string;\n identity: IdentityReport;\n executed: boolean;\n forceReupload: boolean;\n /** Number of files the manifest routes. */\n fileCount: number;\n index: string;\n fallback?: string;\n estimate: {\n manifestBytes: number;\n reuploadBytes: number;\n /** Total fee to spend, base units (string — bigint is not JSON-safe). */\n totalFee: string;\n };\n manifest?: { txId: string; url: string };\n nameHint?: string;\n hint?: string;\n}\n\ninterface SiteUrlJson {\n command: 'site url';\n repoId: string;\n ref: string;\n found: boolean;\n manifestTxId?: string;\n url?: string;\n updatedAt?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction normalizeGateway(gateway: string): string {\n return gateway.replace(/\\/+$/, '');\n}\n\nfunction siteUrl(gateway: string, manifestTxId: string): string {\n return `${normalizeGateway(gateway)}/${manifestTxId}/`;\n}\n\n/** A 43-char placeholder txId for accurate manifest-size estimation. */\nconst PLACEHOLDER_TX = 'A'.repeat(43);\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\n/** Route `rig site <sub>`; returns the process exit code. */\nexport async function runSite(args: string[], deps: SiteDeps): Promise<number> {\n const { io } = deps;\n const [sub, ...rest] = args;\n\n if (sub === 'publish') return runSitePublish(rest, deps);\n if (sub === 'url') return runSiteUrl(rest, deps);\n if (sub === undefined || sub === '-h' || sub === '--help' || sub === 'help') {\n io.out(SITE_USAGE);\n return sub === undefined ? 2 : 0;\n }\n io.err(`unknown site subcommand ${JSON.stringify(sub)}`);\n io.err(SITE_USAGE);\n return 2;\n}\n\n// ---------------------------------------------------------------------------\n// site publish\n// ---------------------------------------------------------------------------\n\nasync function runSitePublish(args: string[], deps: SiteDeps): Promise<number> {\n const { io } = deps;\n\n let flags: SiteFlags;\n try {\n flags = parseSiteArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(SITE_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(SITE_USAGE);\n return 0;\n }\n\n let ctx: StandaloneContext | undefined;\n try {\n // ── Repo + config ──────────────────────────────────────────────────────\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const reader = new GitRepoReader(repoRoot);\n\n // ── Ref selection (single ref; default current branch) ─────────────────\n const selected = await selectRefspecs(\n reader,\n flags.positionals,\n false,\n false\n );\n if (selected.length !== 1) {\n throw new Error(\n `rig site publish builds ONE ref into a site — got ${selected.length} ` +\n `(${selected.join(', ')}); pass a single branch or tag`\n );\n }\n const ref = selected[0] as string;\n\n // ── Relay resolution (origin default; same path as push) ───────────────\n const resolved = await resolveRelays({\n relayFlags: flags.relay,\n remoteName: undefined,\n repoRoot,\n toonRelays: toonConfig.relays,\n });\n if (resolved.nudge !== undefined) io.err(resolved.nudge);\n const relaysUsed = resolved.relays;\n if (relaysUsed.length > 1) {\n io.err(singleRelayRefusal(resolved, 'Nothing was uploaded or paid.'));\n return 1;\n }\n\n // ── Standalone session (identity + publisher) ──────────────────────────\n ctx = await (deps.loadStandalone ?? defaultLoadStandalone)({\n env: deps.env,\n cwd: deps.cwd,\n warn: (line) => io.err(line),\n ...(relaysUsed[0] !== undefined ? { relayUrl: relaysUsed[0] } : {}),\n });\n const identity = identityReport(ctx);\n if (!ctx.publisher.uploadBlob) {\n throw new Error(\n 'the active publisher cannot upload a raw manifest blob ' +\n '(uploadBlob unavailable) — `rig site` requires the standalone publisher'\n );\n }\n\n // ── Files + the known sha→txId map from the cumulative refs event ──────\n const blobs = await reader.listBlobs(ref);\n if (blobs.length === 0) {\n throw new Error(`ref ${JSON.stringify(ref)} has no files to serve`);\n }\n const shaToPaths = new Map<string, string[]>();\n for (const { path, sha } of blobs) {\n const paths = shaToPaths.get(sha) ?? [];\n paths.push(path);\n shaToPaths.set(sha, paths);\n }\n const uniqueShas = [...shaToPaths.keys()];\n\n const remoteState: RemoteState = await ctx.fetchRemote({\n ownerPubkey: ctx.ownerPubkey,\n repoId,\n relayUrls: relaysUsed,\n });\n const known = new Map(remoteState.shaToTxId);\n // Resolve any sha the refs event didn't carry (GraphQL fallback) — free.\n const gaps = uniqueShas.filter((sha) => !known.has(sha));\n if (gaps.length > 0) {\n const found = await remoteState.resolveMissing(gaps);\n for (const [sha, txId] of found) known.set(sha, txId);\n }\n\n // ── Fallback (SPA) path resolution ─────────────────────────────────────\n const fallbackPath =\n flags.fallback ?? (flags.spa ? flags.index : undefined);\n const pathSet = new Set(blobs.map((b) => b.path));\n if (fallbackPath !== undefined && !pathSet.has(fallbackPath)) {\n throw new Error(\n `fallback path ${JSON.stringify(fallbackPath)} is not one of the ` +\n \"site's files — pick an existing path (or the --index file for --spa)\"\n );\n }\n if (!pathSet.has(flags.index)) {\n io.err(\n `warning: no ${JSON.stringify(flags.index)} in this ref — the site ` +\n 'will 404 at / until you add one (or pass --index <path>)'\n );\n }\n\n // ── Without --force-reupload every file must already be on Arweave ──────\n if (!flags.forceReupload) {\n const unpublished = uniqueShas.filter((sha) => !known.has(sha));\n if (unpublished.length > 0) {\n const paths = unpublished\n .flatMap((sha) => shaToPaths.get(sha) ?? [])\n .slice(0, 10);\n throw new Error(\n `${unpublished.length} file(s) in ${ref} are not on Arweave yet ` +\n `(e.g. ${paths.join(', ')}) — run \\`rig push\\` first, or ` +\n '`rig site publish --force-reupload` to upload them now (paid).'\n );\n }\n }\n\n // ── Fee estimate ───────────────────────────────────────────────────────\n // An upload costs the store route's schedule for its size (ADR 0065) —\n // the same rule the publisher's claim follows.\n const feeRates = await ctx.publisher.getFeeRates();\n // Preview manifest with known/placeholder 43-char txids: byte-accurate for\n // the fee (every txid is 43 chars, so the real manifest is the same size).\n const previewEntries: ManifestEntry[] = blobs.map((b) => ({\n path: b.path,\n txId: known.get(b.sha) ?? PLACEHOLDER_TX,\n }));\n const previewManifest = buildArweaveManifest(\n previewEntries,\n flags.index,\n fallbackPath ? PLACEHOLDER_TX : undefined\n );\n const manifestBytes = Buffer.byteLength(JSON.stringify(previewManifest));\n\n let reuploadBytes = 0;\n let reuploadFee = 0n;\n if (flags.forceReupload) {\n const { objects } = await reader.statObjects(uniqueShas);\n reuploadBytes = objects.reduce((sum, o) => sum + o.size, 0);\n reuploadFee = objects.reduce(\n (sum, o) => sum + uploadChargeFor(feeRates, o.size),\n 0n\n );\n }\n const manifestFee = uploadChargeFor(feeRates, manifestBytes);\n const totalFee = manifestFee + reuploadFee;\n\n const gateway =\n flags.gateway ?? deps.env['RIG_ARWEAVE_GATEWAY'] ?? DEFAULT_GATEWAY;\n\n const baseJson = (): Omit<SitePublishJson, 'executed'> => ({\n command: 'site publish',\n repoId,\n ref,\n identity,\n forceReupload: flags.forceReupload,\n fileCount: blobs.length,\n index: flags.index,\n ...(fallbackPath ? { fallback: fallbackPath } : {}),\n estimate: {\n manifestBytes,\n reuploadBytes,\n totalFee: totalFee.toString(),\n },\n });\n\n // ── Confirm gate ───────────────────────────────────────────────────────\n if (!flags.json) {\n io.out(`Site publish plan for ${ref} (repo ${repoId}):`);\n io.out(` files: ${blobs.length}`);\n io.out(\n ` index: ${flags.index}${pathSet.has(flags.index) ? '' : ' (missing!)'}`\n );\n if (fallbackPath) io.out(` fallback: ${fallbackPath}`);\n if (flags.forceReupload) {\n io.out(\n ` re-upload ${uniqueShas.length} blob(s), ${reuploadBytes} bytes (paid)`\n );\n }\n io.out(` manifest: ${manifestBytes} bytes`);\n io.out(` total fee: ${totalFee} base units`);\n io.out(renderIdentityLine(identity));\n }\n if (!flags.yes) {\n if (flags.json) {\n io.emitJson({\n ...baseJson(),\n executed: false,\n hint: 'estimate only — re-run with --yes to upload the manifest (permanent, non-refundable)',\n } satisfies SitePublishJson);\n return 0;\n }\n if (!io.isInteractive) {\n io.err(\n 'refusing to spend channel funds without confirmation in a non-interactive ' +\n 'session — re-run with --yes (or use --json for an estimate)'\n );\n return 1;\n }\n const proceed = await io.confirm(\n `Proceed with paid site publish (total ${totalFee} base units)? [y/N] `\n );\n if (!proceed) {\n io.err('aborted — nothing was uploaded.');\n return 1;\n }\n }\n\n // ── Execute ────────────────────────────────────────────────────────────\n // #368 force-reupload: re-pay to upload each blob THROUGH the mime-typed\n // git-object path so the store tags it with the right Content-Type; the\n // returned (fresh) txids feed the manifest.\n if (flags.forceReupload) {\n const { objects, missing } = await reader.readObjects(uniqueShas);\n if (missing.length > 0) {\n throw new Error(\n `objects vanished from the local repository: ${missing.join(', ')}`\n );\n }\n const bodyBySha = new Map(objects.map((o) => [o.sha, o.body]));\n for (const sha of uniqueShas) {\n const body = bodyBySha.get(sha);\n if (!body) throw new Error(`internal: no body for ${sha}`);\n // A blob reached by conflicting-extension paths uploads as\n // octet-stream (deterministic, no arbitrary favoring); otherwise its\n // single content type.\n const uploadPath = resolveConflictingPath(shaToPaths.get(sha) ?? []);\n const receipt = await ctx.publisher.uploadGitObject({\n sha,\n type: 'blob',\n body,\n repoId,\n ...(uploadPath ? { path: uploadPath } : {}),\n });\n known.set(sha, receipt.txId);\n }\n }\n\n const entries: ManifestEntry[] = blobs.map((b) => {\n const txId = known.get(b.sha);\n if (!txId) {\n throw new Error(`internal: no Arweave txid for ${b.path} (${b.sha})`);\n }\n return { path: b.path, txId };\n });\n const fallbackTxId =\n fallbackPath !== undefined\n ? entries.find((e) => e.path === fallbackPath)?.txId\n : undefined;\n const manifest = buildArweaveManifest(entries, flags.index, fallbackTxId);\n const manifestBody = Buffer.from(JSON.stringify(manifest), 'utf8');\n\n const receipt = await ctx.publisher.uploadBlob({\n body: manifestBody,\n contentType: MANIFEST_CONTENT_TYPE,\n repoId,\n });\n const url = siteUrl(gateway, receipt.txId);\n writeSiteRecord(deps.env, {\n repoId,\n ref,\n owner: ctx.ownerPubkey,\n manifestTxId: receipt.txId,\n gateway: normalizeGateway(gateway),\n updatedAt: Date.now(),\n });\n\n const nameHint = `Point a name at it (see #367): rig name set <name> ${receipt.txId}`;\n if (flags.json) {\n io.emitJson({\n ...baseJson(),\n executed: true,\n manifest: { txId: receipt.txId, url },\n nameHint,\n } satisfies SitePublishJson);\n } else {\n io.out(`Site published: ${url}`);\n io.out(nameHint);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'site publish', err);\n } finally {\n if (ctx) {\n try {\n await ctx.stop();\n } catch {\n // best-effort teardown\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// site url (free)\n// ---------------------------------------------------------------------------\n\nasync function runSiteUrl(args: string[], deps: SiteDeps): Promise<number> {\n const { io } = deps;\n\n let flags: SiteFlags;\n try {\n flags = parseSiteArgs(args);\n } catch (err) {\n io.err(err instanceof Error ? err.message : String(err));\n io.err(SITE_USAGE);\n return 2;\n }\n if (flags.help) {\n io.out(SITE_USAGE);\n return 0;\n }\n\n try {\n const repoRoot = await resolveRepoRoot(deps.cwd);\n const toonConfig = await readToonConfig(repoRoot);\n const repoId = flags.repoId ?? toonConfig.repoId;\n if (!repoId) throw new UnconfiguredRepoAddressError('repository id');\n const reader = new GitRepoReader(repoRoot);\n\n const selected = await selectRefspecs(\n reader,\n flags.positionals,\n false,\n false\n );\n if (selected.length !== 1) {\n throw new Error(\n `rig site url takes ONE ref — got ${selected.length} (${selected.join(', ')})`\n );\n }\n const ref = selected[0] as string;\n\n const record = readSiteRecord(deps.env, repoId, ref);\n if (!record) {\n const detail =\n `no site published for ${ref} (repo ${repoId}) yet — run ` +\n '`rig site publish` first (the manifest txid is only known after a paid publish)';\n if (flags.json) {\n io.emitJson({\n command: 'site url',\n repoId,\n ref,\n found: false,\n } satisfies SiteUrlJson);\n }\n io.err(detail);\n return 1;\n }\n\n const url = siteUrl(record.gateway, record.manifestTxId);\n if (flags.json) {\n io.emitJson({\n command: 'site url',\n repoId,\n ref,\n found: true,\n manifestTxId: record.manifestTxId,\n url,\n updatedAt: record.updatedAt,\n } satisfies SiteUrlJson);\n } else {\n io.out(url);\n }\n return 0;\n } catch (err) {\n return emitCliError(io, flags.json, 'site url', err);\n }\n}\n","/**\n * Arweave path manifest builder for `rig site` permaweb deploys (#368).\n *\n * MIRROR of `@toon-protocol/rig-web`'s\n * `packages/rig-web/src/web/deploy-manifest.ts` — copied rather than imported\n * because `rig` (a CLI) must not take a runtime dependency on `rig-web` (a\n * browser-only frontend). The two are intentionally kept in sync; this copy\n * additionally supports the manifest spec's optional `fallback` field (SPA\n * routing), which the site verb needs but the rig-web deploy script does not.\n *\n * Generates the JSON manifest ar.io gateways use to serve a multi-file\n * Arweave deployment as a virtual path-routed site: one manifest transaction\n * whose id becomes the site's canonical `https://<gateway>/<txid>/` URL.\n *\n * spec: https://specs.ar.io/arweave-standards/ao/index-1/manifest\n */\n\nexport interface ArweaveManifest {\n manifest: 'arweave/paths';\n version: '0.2.0';\n /**\n * Omitted when `indexPath` isn't one of the manifest's `paths` — an `index`\n * pointing at a path the manifest doesn't carry makes gateways 404 the site\n * root (indistinguishable from ArNS propagation lag; see #398).\n */\n index?: { path: string };\n /**\n * Optional SPA fallback: the transaction served for any path not present in\n * `paths` (e.g. client-routed `/about` on a single-page app). Omitted for a\n * plain static site.\n */\n fallback?: { id: string };\n paths: Record<string, { id: string }>;\n}\n\nexport interface ManifestEntry {\n /** Relative URL path, e.g. `index.html` or `assets/main.js`. */\n path: string;\n /** Arweave transaction id the file's bytes are stored under. */\n txId: string;\n}\n\nconst DEFAULT_INDEX = 'index.html';\n\n/**\n * Build an Arweave path manifest from a list of uploaded files.\n *\n * Each entry maps a relative URL path to the Arweave transaction id where\n * that file was uploaded. The resulting manifest is uploaded as its own\n * Arweave transaction; its id becomes the canonical URL for the deployment.\n *\n * @param entries path → txId for every file the site serves.\n * @param indexPath the path served at `/` (default `index.html`).\n * @param fallbackTxId optional SPA fallback transaction id (spec `fallback`).\n */\nexport function buildArweaveManifest(\n entries: ManifestEntry[],\n indexPath = DEFAULT_INDEX,\n fallbackTxId?: string\n): ArweaveManifest {\n const paths: Record<string, { id: string }> = {};\n for (const { path, txId } of entries) {\n paths[path] = { id: txId };\n }\n return {\n manifest: 'arweave/paths',\n version: '0.2.0',\n ...(Object.hasOwn(paths, indexPath) ? { index: { path: indexPath } } : {}),\n ...(fallbackTxId ? { fallback: { id: fallbackTxId } } : {}),\n paths,\n };\n}\n","/**\n * Local record of the last-published site manifest per (repo, ref) — the\n * lookup `rig site url` reads for FREE (#368).\n *\n * A site manifest's txId is only knowable AFTER the paid manifest upload (it\n * is the hash of the signed Arweave data item), and it changes every publish.\n * There is no free network lookup for \"the current manifest of this repo\"\n * until an ArNS name points at it (#367). So `rig site publish` records what\n * it just published here, and `rig site url` reads it back — no client start,\n * no relay query, no payment.\n *\n * Stored under `TOON_CLIENT_HOME` (default `~/.toon-client`) as\n * `site-manifests.json`, keyed by `<repoId>\\0<ref>` (local, single-user\n * scope — the owner pubkey is stored as a field, not part of the key). A\n * corrupt/unreadable file is treated as empty for reads and overwritten on\n * write, never fatal to a free lookup.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const SITE_MANIFEST_FILENAME = 'site-manifests.json';\n\n/** One recorded site publish. */\nexport interface SiteManifestRecord {\n repoId: string;\n /** Full refname the site was built from, e.g. `refs/heads/main`. */\n ref: string;\n /** Owner pubkey (hex) the manifest was published under. */\n owner: string;\n /** The manifest transaction id (43-char base64url). */\n manifestTxId: string;\n /** Gateway base the printed URL used, e.g. `https://arweave.net`. */\n gateway: string;\n /** Unix milliseconds of the publish. */\n updatedAt: number;\n}\n\ntype SiteManifestFile = Record<string, SiteManifestRecord>;\n\nfunction storeDir(env: NodeJS.ProcessEnv): string {\n return env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n}\n\nfunction storePath(env: NodeJS.ProcessEnv): string {\n return join(storeDir(env), SITE_MANIFEST_FILENAME);\n}\n\nfunction keyOf(repoId: string, ref: string): string {\n return `${repoId}\\0${ref}`;\n}\n\nfunction readFile(env: NodeJS.ProcessEnv): SiteManifestFile {\n try {\n const parsed = JSON.parse(readFileSync(storePath(env), 'utf8')) as unknown;\n if (parsed && typeof parsed === 'object') return parsed as SiteManifestFile;\n return {};\n } catch {\n // Missing or corrupt → empty (a free lookup must never throw on this).\n return {};\n }\n}\n\n/** The recorded manifest for (repoId, ref), or `undefined` if none. */\nexport function readSiteRecord(\n env: NodeJS.ProcessEnv,\n repoId: string,\n ref: string\n): SiteManifestRecord | undefined {\n return readFile(env)[keyOf(repoId, ref)];\n}\n\n/** Record (or overwrite) the manifest just published for (repoId, ref). */\nexport function writeSiteRecord(\n env: NodeJS.ProcessEnv,\n record: SiteManifestRecord\n): void {\n const dir = storeDir(env);\n mkdirSync(dir, { recursive: true });\n const file = readFile(env);\n file[keyOf(record.repoId, record.ref)] = record;\n writeFileSync(storePath(env), `${JSON.stringify(file, null, 2)}\\n`, 'utf8');\n}\n","/**\n * The rig CLI output layer (#265): the strict `--json` stdout guarantee.\n *\n * CONTRACT — when `--json` is set on a rig-owned command, stdout carries\n * EXACTLY ONE parseable JSON document and nothing else. Agents consume this\n * stream (`rig … --json | jq`), so any stray banner, progress line, warning,\n * deprecation nudge, or third-party `console.log` on stdout breaks pipelines\n * (the #260 addendum: `[Bootstrap] …` logs from the embedded client's core\n * polluted `rig push --json`). Everything human-facing goes to stderr.\n *\n * Three layers enforce the contract (composed in ./rig.ts; the enforcement\n * matrix in ./strict-json.test.ts mirrors that composition):\n *\n * 1. {@link makeCliIo} — the ONLY output surface commands use. In JSON mode\n * `out()` (human lines) reroutes to stderr and `emitJson()` is the sole\n * writer that reaches the real stdout.\n * 2. {@link redirectStdoutToStderr} — a process-level guard for code the io\n * seam cannot reach: dependencies that `console.log` directly (the\n * embedded `@toon-protocol/client`'s core bootstrap does). Installed\n * before any command code runs, it reroutes EVERY `process.stdout.write`\n * to stderr; only the writer it returns (wired into `emitJson`) still\n * reaches the real stdout.\n * 3. {@link RigIo.ensureSingleJsonDoc} — the backstop for paths that bail\n * out before emitting an envelope (usage errors, pre-payment refusals):\n * after dispatch it emits one error envelope built from the collected\n * stderr lines, so stdout is never empty in JSON mode.\n *\n * GIT PASSTHROUGH IS EXEMPT: `--json` is a per-subcommand flag on rig-owned\n * verbs, not a global rig flag. Any verb rig does not own goes to system git\n * with the EXACT argv tail and inherited stdio — `rig status --json` runs\n * `git status --json` (git rejects it), and flags BEFORE the subcommand\n * (`rig --json status`) are not rig's either: the whole argv passes through\n * to git verbatim. {@link isJsonInvocation} implements exactly that boundary.\n */\n\n// ---------------------------------------------------------------------------\n// The io seam\n// ---------------------------------------------------------------------------\n\n/** Terminal I/O seam — every rig-owned command writes ONLY through this. */\nexport interface CliIo {\n /**\n * One HUMAN-facing line: stdout normally, stderr when `--json` is active\n * (chatter must never pollute the machine stream).\n */\n out(line: string): void;\n /** One human-facing line to stderr (warnings, nudges, errors). */\n err(line: string): void;\n /**\n * THE machine-readable JSON document of a `--json` run — serialized here\n * (2-space indent) and written to the REAL stdout. Must be a command's\n * single stdout emission; call it at most once per invocation.\n */\n emitJson(payload: unknown): void;\n /** True when stdin+stdout are TTYs (interactive confirm possible). */\n isInteractive: boolean;\n /** Ask a y/N question; resolves true on explicit yes. */\n confirm(question: string): Promise<boolean>;\n}\n\n/** {@link CliIo} plus the JSON-mode bookkeeping the entrypoint needs. */\nexport interface RigIo extends CliIo {\n /** True when this invocation runs in `--json` mode. */\n readonly jsonMode: boolean;\n /** True once `emitJson` has written the machine document. */\n readonly emittedJson: boolean;\n /**\n * The #265 backstop: called once after dispatch (see ./rig.ts). In JSON\n * mode, when NO machine document was emitted (usage error, pre-payment\n * refusal, unexpected crash), emits one error envelope carrying the\n * human-facing lines the run wrote to stderr — so `--json` stdout always\n * parses. No-op outside JSON mode or after a real emission.\n */\n ensureSingleJsonDoc(exitCode: number): void;\n}\n\n/** Sinks + terminal facts {@link makeCliIo} builds a {@link RigIo} from. */\nexport interface CliIoOptions {\n /** Whether this invocation is a rig-owned command with `--json`. */\n jsonMode: boolean;\n /**\n * Write to the REAL stdout (in JSON mode: the pre-guard writer returned by\n * {@link redirectStdoutToStderr}). Receives full text including newlines.\n */\n writeStdout(text: string): void;\n /** Write to stderr. Receives full text including newlines. */\n writeStderr(text: string): void;\n isInteractive: boolean;\n confirm(question: string): Promise<boolean>;\n}\n\n/**\n * Build the {@link RigIo} for one invocation. Centralizes the #265 routing:\n * human lines → stderr in JSON mode, and `emitJson` as the only stdout path.\n */\nexport function makeCliIo(options: CliIoOptions): RigIo {\n const { jsonMode, writeStdout, writeStderr } = options;\n let emittedJson = false;\n /** Human lines collected in JSON mode — the backstop envelope's detail. */\n const humanLines: string[] = [];\n\n const toStderr = (line: string): void => {\n if (jsonMode) humanLines.push(line);\n writeStderr(`${line}\\n`);\n };\n\n return {\n jsonMode,\n get emittedJson() {\n return emittedJson;\n },\n out: (line) => {\n if (jsonMode) {\n toStderr(line);\n } else {\n writeStdout(`${line}\\n`);\n }\n },\n err: toStderr,\n emitJson: (payload) => {\n emittedJson = true;\n writeStdout(`${JSON.stringify(payload, null, 2)}\\n`);\n },\n isInteractive: options.isInteractive,\n confirm: options.confirm,\n ensureSingleJsonDoc(exitCode: number): void {\n if (!jsonMode || emittedJson) return;\n const detail =\n humanLines.join('\\n') ||\n (exitCode === 0\n ? 'the command produced no machine output'\n : 'the command failed before emitting machine output — see stderr');\n this.emitJson(\n exitCode === 0\n ? { error: null, exitCode, detail }\n : { error: 'error', exitCode, detail }\n );\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// JSON-mode detection (and the git-passthrough exemption)\n// ---------------------------------------------------------------------------\n\n/**\n * The verbs rig owns — everything else is `git <argv…>` verbatim. Must match\n * the ./dispatch.ts switch (dispatch.test.ts pins both directions).\n */\nexport const RIG_OWNED_VERBS: ReadonlySet<string> = new Set([\n 'init',\n 'identity',\n 'remote',\n 'clone',\n 'fetch',\n 'push',\n 'site',\n 'issue',\n 'comment',\n 'pr',\n 'maintainers',\n 'payout',\n 'channel',\n 'channels',\n 'fund',\n 'balance',\n 'chain',\n 'entry',\n 'name',\n]);\n\n/**\n * True when this argv is a rig-owned command run with `--json` — the strict\n * stdout contract applies. Deliberately NOT true for:\n *\n * - non-owned verbs (`rig status --json` IS `git status --json`: inherited\n * stdio, git's own semantics, rig adds nothing);\n * - flags before the subcommand (`rig --json status`): rig has no global\n * flags besides help/--version, so the argv passes to git verbatim;\n * - `--json` after a bare `--` (parseArgs treats those tokens as\n * positionals, so rig's flag parsers never see it as a flag either).\n *\n * Mirrors a plain token scan rather than each command's full parseArgs\n * config: the one divergence is `--json` consumed as a STRING option's value\n * (e.g. `rig push --relay --json`) — a pathological invocation that ends up\n * with chatter on stderr and a backstop envelope on stdout, which still\n * honors the parse guarantee.\n */\nexport function isJsonInvocation(argv: string[]): boolean {\n const [verb, ...rest] = argv;\n if (verb === undefined || !RIG_OWNED_VERBS.has(verb)) return false;\n for (const arg of rest) {\n if (arg === '--') return false;\n if (arg === '--json') return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Process-level stdout guard (third-party console.log defense)\n// ---------------------------------------------------------------------------\n\n/** Handle on an installed stdout guard. */\nexport interface StdoutGuard {\n /** Write to the REAL stdout (bypasses the redirection). */\n write(text: string): void;\n /** Undo the patch (tests; the one-shot CLI process never needs it). */\n restore(): void;\n}\n\n/**\n * Reroute every `process.stdout.write` — including `console.log` from\n * dependencies rig cannot re-route at the io seam, like the embedded\n * client's `[Bootstrap] …` logs (#260) — to stderr. Returns the ONLY writer\n * that still reaches the real stdout; ./rig.ts wires it into\n * {@link makeCliIo}'s `writeStdout` so `emitJson` output is the single\n * survivor on the machine stream.\n *\n * @param realWrite Override the saved real-stdout writer (tests capture it);\n * defaults to the unpatched `process.stdout.write`.\n */\n// ---------------------------------------------------------------------------\n// Process-level stderr calmer (third-party bootstrap noise defense, #280)\n// ---------------------------------------------------------------------------\n\n/** Handle on an installed stderr calmer. */\nexport interface StderrCalmer {\n /** Undo the patch (tests; the one-shot CLI process never needs it). */\n restore(): void;\n}\n\n/** The embedded client's core self-announce failure log line. */\nconst ANNOUNCE_FAILED_RE = /\\[Bootstrap\\] Announce failed/;\n/** … specifically the EXPECTED pre-payment 402 refusal (x402 challenge). */\nconst ANNOUNCE_402_RE = /402|payment required/i;\n\n/**\n * The calm reframe of the announce-402: what happened, why it is expected,\n * and that the command is unaffected — instead of a full x402 challenge JSON\n * dump. Exported so tests pin the exact line.\n */\nexport const ANNOUNCE_402_INFO =\n 'rig: skipped the optional identity self-announce — the payment peer ' +\n 'charges for announces and this identity has not paid for one (expected ' +\n 'on a fresh or unfunded identity); harmless, the command continues.\\n';\n\n/**\n * Reframe the embedded client's scary-but-harmless bootstrap announce noise\n * (#280). The core's bootstrap tries a PAID self-announce and `console.warn`s\n * the refusal — `[Bootstrap] Announce failed …: … (402 Payment Required):\n * {…x402…}` — straight to stderr, which rig's io seam cannot reach. A\n * first-run user reads that as their (succeeding!) push having failed.\n *\n * This process-level guard patches `process.stderr.write`:\n *\n * - an announce-402 line becomes {@link ANNOUNCE_402_INFO} once per\n * process (repeats are dropped — one calm line, not one per peer);\n * - announce failures that are NOT the expected 402 (network errors, peer\n * misconfig) pass through untouched — those ARE signal;\n * - everything else passes through untouched.\n *\n * Installed unconditionally in ./rig.ts before dispatch. Composes with\n * {@link redirectStdoutToStderr}: that guard forwards to `process.stderr.write`\n * via a dynamic property lookup, so rerouted stdout noise is calmed too.\n */\nexport function calmBootstrapNoise(): StderrCalmer {\n const original = process.stderr.write;\n let reframed = false;\n const patched = ((\n chunk: Uint8Array | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void\n ): boolean => {\n let text = chunk;\n if (typeof chunk === 'string' && ANNOUNCE_FAILED_RE.test(chunk)) {\n if (ANNOUNCE_402_RE.test(chunk)) {\n text = reframed ? '' : ANNOUNCE_402_INFO;\n reframed = true;\n }\n }\n if (typeof encodingOrCb === 'function') {\n // `original` is `typeof process.stderr.write`, an overloaded function\n // type; `.call()` on it only resolves against the LAST overload\n // (chunk, encoding, cb), so the 2-arg (chunk, cb) call needs an\n // explicit narrow to the matching overload signature.\n const writeWithCallback = original as (\n chunk: Uint8Array | string,\n cb?: (err?: Error | null) => void\n ) => boolean;\n return writeWithCallback.call(process.stderr, text, encodingOrCb);\n }\n return original.call(process.stderr, text, encodingOrCb, cb);\n }) as typeof process.stderr.write;\n process.stderr.write = patched;\n return {\n restore: () => {\n if (process.stderr.write === patched) process.stderr.write = original;\n },\n };\n}\n\nexport function redirectStdoutToStderr(\n realWrite?: (text: string) => void\n): StdoutGuard {\n const original = process.stdout.write;\n const real = realWrite ?? original.bind(process.stdout);\n const patched = ((\n chunk: Uint8Array | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void\n ): boolean =>\n typeof encodingOrCb === 'function'\n ? process.stderr.write(chunk, encodingOrCb)\n : process.stderr.write(\n chunk,\n encodingOrCb,\n cb\n )) as typeof process.stdout.write;\n process.stdout.write = patched;\n return {\n write: (text) => {\n real(text);\n },\n restore: () => {\n if (process.stdout.write === patched) process.stdout.write = original;\n },\n };\n}\n"],"mappings":"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","names":["createInterface","parseArgs","ctx","io","parseArgs","io","parseArgs","io","rigPage","io","parseArgs","mkdirSync","readFileSync","writeFileSync","homedir","join","parseArgs","join","homedir","readFileSync","mkdirSync","writeFileSync","io","parseArgs","parseArgs","io","parseArgs","result","dirname","join","parseArgs","parseArgs","io","dirname","join","parseArgs","REPOSITORY_ANNOUNCEMENT_KIND","STATUS_APPLIED_KIND","STATUS_CLOSED_KIND","STATUS_DRAFT_KIND","STATUS_OPEN_KIND","parseArgs","WS_URL_RE","repoATag","io","parseArgs","HEX64_RE","io","parseArgs","STATUS_OPEN_KIND","STATUS_APPLIED_KIND","STATUS_CLOSED_KIND","STATUS_DRAFT_KIND","REPOSITORY_ANNOUNCEMENT_KIND","args","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","parseArgs","configPathFor","join","homedir","readFileSync","mkdirSync","dirname","writeFileSync","io","parseArgs","state","parseArgs","WS_URL_RE","io","parseArgs","readFileSync","homedir","join","parseArgs","CHAIN_ARG_LIST","join","homedir","readFileSync","io","parseArgs","argv","resolve","mkdirSync","dirname","parseArgs","mkdirSync","dirname","parseArgs","io","basename","parseArgs","defaultWebSocketFactory","parseArgs","isWebSocketRelay","io","resolve","basename","parseArgs","WS_URL_RE","HEX64_RE","io","runList","parseArgs","WS_URL_RE","parseArgs","spawn","io","parseArgs","spawn","receipt","result","parseArgs","io","runShow","runMutate","parseArgs","WS_URL_RE","parseArgs","mkdirSync","readFileSync","writeFileSync","homedir","join","storeDir","storePath","readFile","parseArgs","io","receipt","require","argv","io","argv","createInterface"]}