@toon-protocol/rig 4.5.0 → 4.7.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.
- package/README.md +101 -8
- package/dist/{chunk-S2BMLXAD.js → chunk-3IVO2MSZ.js} +584 -20
- package/dist/chunk-3IVO2MSZ.js.map +1 -0
- package/dist/{chunk-UZZ2JKEC.js → chunk-J6Y3U645.js} +522 -204
- package/dist/chunk-J6Y3U645.js.map +1 -0
- package/dist/{chunk-HMED76GU.js → chunk-S3KKQ4IC.js} +104 -56
- package/dist/chunk-S3KKQ4IC.js.map +1 -0
- package/dist/chunk-XQ2AWNHQ.js +0 -0
- package/dist/chunk-XQ2AWNHQ.js.map +1 -0
- package/dist/{ci-serve-PYEHIBN7.js → ci-serve-T33FCQVT.js} +154 -39
- package/dist/ci-serve-T33FCQVT.js.map +1 -0
- package/dist/cli/rig.js +5 -3
- package/dist/cli/rig.js.map +1 -1
- package/dist/index.d.ts +478 -23
- package/dist/index.js +531 -7
- package/dist/index.js.map +1 -1
- package/dist/{publisher-Cf6tKnZ3.d.ts → publisher-DgbfziOm.d.ts} +152 -26
- package/dist/standalone/index.d.ts +1 -1
- package/dist/{standalone-mode-W3ZEKC6M.js → standalone-mode-FY3XVQQK.js} +16 -4
- package/dist/standalone-mode-FY3XVQQK.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-HMED76GU.js.map +0 -1
- package/dist/chunk-S2BMLXAD.js.map +0 -1
- package/dist/chunk-UZZ2JKEC.js.map +0 -1
- package/dist/ci-serve-PYEHIBN7.js.map +0 -1
- package/dist/standalone-mode-W3ZEKC6M.js.map +0 -1
package/dist/cli/rig.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/rig.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 * 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 'ci',\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":["argv"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/rig.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 * 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 'refresh',\n 'channel',\n 'channels',\n 'fund',\n 'balance',\n 'chain',\n 'entry',\n 'name',\n 'ci',\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":";;;;;;;;;;;AA2BA,SAAS,uBAAuB;;;ACoEzB,SAAS,UAAU,SAA8B;AACtD,QAAM,EAAE,UAAU,aAAa,YAAY,IAAI;AAC/C,MAAI,cAAc;AAElB,QAAM,aAAuB,CAAC;AAE9B,QAAM,WAAW,CAAC,SAAuB;AACvC,QAAI,SAAU,YAAW,KAAK,IAAI;AAClC,gBAAY,GAAG,IAAI;AAAA,CAAI;AAAA,EACzB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAAA,IACA,KAAK,CAAC,SAAS;AACb,UAAI,UAAU;AACZ,iBAAS,IAAI;AAAA,MACf,OAAO;AACL,oBAAY,GAAG,IAAI;AAAA,CAAI;AAAA,MACzB;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,UAAU,CAAC,YAAY;AACrB,oBAAc;AACd,kBAAY,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,IACrD;AAAA,IACA,eAAe,QAAQ;AAAA,IACvB,SAAS,QAAQ;AAAA,IACjB,oBAAoB,UAAwB;AAC1C,UAAI,CAAC,YAAY,YAAa;AAC9B,YAAM,SACJ,WAAW,KAAK,IAAI,MACnB,aAAa,IACV,2CACA;AACN,WAAK;AAAA,QACH,aAAa,IACT,EAAE,OAAO,MAAM,UAAU,OAAO,IAChC,EAAE,OAAO,SAAS,UAAU,OAAO;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;AAUO,IAAM,kBAAuC,oBAAI,IAAI;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAmBM,SAAS,iBAAiBA,OAAyB;AACxD,QAAM,CAAC,MAAM,GAAG,IAAI,IAAIA;AACxB,MAAI,SAAS,UAAa,CAAC,gBAAgB,IAAI,IAAI,EAAG,QAAO;AAC7D,aAAW,OAAO,MAAM;AACtB,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,QAAQ,SAAU,QAAO;AAAA,EAC/B;AACA,SAAO;AACT;AAoCA,IAAM,qBAAqB;AAE3B,IAAM,kBAAkB;AAOjB,IAAM,oBACX;AAuBK,SAAS,qBAAmC;AACjD,QAAM,WAAW,QAAQ,OAAO;AAChC,MAAI,WAAW;AACf,QAAM,WAAW,CACf,OACA,cACA,OACY;AACZ,QAAI,OAAO;AACX,QAAI,OAAO,UAAU,YAAY,mBAAmB,KAAK,KAAK,GAAG;AAC/D,UAAI,gBAAgB,KAAK,KAAK,GAAG;AAC/B,eAAO,WAAW,KAAK;AACvB,mBAAW;AAAA,MACb;AAAA,IACF;AACA,QAAI,OAAO,iBAAiB,YAAY;AAKtC,YAAM,oBAAoB;AAI1B,aAAO,kBAAkB,KAAK,QAAQ,QAAQ,MAAM,YAAY;AAAA,IAClE;AACA,WAAO,SAAS,KAAK,QAAQ,QAAQ,MAAM,cAAc,EAAE;AAAA,EAC7D;AACA,UAAQ,OAAO,QAAQ;AACvB,SAAO;AAAA,IACL,SAAS,MAAM;AACb,UAAI,QAAQ,OAAO,UAAU,QAAS,SAAQ,OAAO,QAAQ;AAAA,IAC/D;AAAA,EACF;AACF;AAEO,SAAS,uBACd,WACa;AACb,QAAM,WAAW,QAAQ,OAAO;AAChC,QAAM,OAAO,aAAa,SAAS,KAAK,QAAQ,MAAM;AACtD,QAAM,WAAW,CACf,OACA,cACA,OAEA,OAAO,iBAAiB,aACpB,QAAQ,OAAO,MAAM,OAAO,YAAY,IACxC,QAAQ,OAAO;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACN,UAAQ,OAAO,QAAQ;AACvB,SAAO;AAAA,IACL,OAAO,CAAC,SAAS;AACf,WAAK,IAAI;AAAA,IACX;AAAA,IACA,SAAS,MAAM;AACb,UAAI,QAAQ,OAAO,UAAU,QAAS,SAAQ,OAAO,QAAQ;AAAA,IAC/D;AAAA,EACF;AACF;;;ADnSA,SAAS,OAAO,UAA0B;AAGxC,qBAAmB;AAInB,QAAM,QAAQ,WAAW,uBAAuB,IAAI;AACpD,SAAO,UAAU;AAAA,IACf;AAAA,IACA,aAAa,QACT,MAAM,QACN,CAAC,SAAS;AACR,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,IACJ,aAAa,CAAC,SAAS;AACrB,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,IACA,eAAe,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,KAAK;AAAA,IAClE,SAAS,OAAO,aAAa;AAC3B,YAAM,KAAK,gBAAgB;AAAA,QACzB,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,MAClB,CAAC;AACD,UAAI;AACF,cAAM,UAAU,MAAM,GAAG,SAAS,QAAQ,GAAG,KAAK,EAAE,YAAY;AAChE,eAAO,WAAW,OAAO,WAAW;AAAA,MACtC,UAAE;AACA,WAAG,MAAM;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAYA,SAAS,gBAAgB,MAAoB;AAC3C,UAAQ,WAAW;AACnB,MAAI,UAAU;AACd,QAAM,OAAO,MAAY;AACvB,eAAW;AACX,QAAI,YAAY,EAAG,SAAQ,KAAK,IAAI;AAAA,EACtC;AACA,UAAQ,OAAO,MAAM,IAAI,IAAI;AAC7B,UAAQ,OAAO,MAAM,IAAI,IAAI;AAC/B;AAEA,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,KAAK,OAAO,iBAAiB,IAAI,CAAC;AAExC,SAAS,MAAM;AAAA,EACb;AAAA,EACA,KAAK,QAAQ;AAAA,EACb,KAAK,QAAQ,IAAI;AACnB,CAAC,EAAE;AAAA,EACD,CAAC,SAAS;AACR,OAAG,oBAAoB,IAAI;AAC3B,oBAAgB,IAAI;AAAA,EACtB;AAAA,EACA,CAAC,QAAiB;AAChB,YAAQ,OAAO;AAAA,MACb,0BAA0B,eAAe,QAAS,IAAI,SAAS,IAAI,UAAW,OAAO,GAAG,CAAC;AAAA;AAAA,IAC3F;AACA,OAAG,oBAAoB,CAAC;AACxB,oBAAgB,CAAC;AAAA,EACnB;AACF;","names":["argv"]}
|