shinjuku-shield 0.3.87 → 0.3.89

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 CHANGED
@@ -6,13 +6,13 @@ answers privately, in a terminal chat or for your agent app. Its `mcp`
6
6
  command runs a local MCP server (stdio) for your agent. Your keys never
7
7
  leave your machine.
8
8
 
9
- This is version 0.3.87. The npm packages `shinjuku-shield` and
9
+ This is version 0.3.89. The npm packages `shinjuku-shield` and
10
10
  `shinjuku-shielded` hold the same files; `shinjuku` is the short command.
11
11
 
12
12
  ## Set up
13
13
 
14
14
  ```sh
15
- npx -y --no-audit --no-fund shinjuku-shield@0.3.87 setup
15
+ npx -y --no-audit --no-fund shinjuku-shield@0.3.89 setup
16
16
  ```
17
17
 
18
18
  Setup makes the wallet on this machine, a private passphrase file, and the
@@ -24,7 +24,7 @@ server to that host's config.
24
24
  ## The `shinjuku` command
25
25
 
26
26
  ```sh
27
- npm install -g shinjuku@0.3.87
27
+ npm install -g shinjuku@0.3.89
28
28
  shinjuku help
29
29
  ```
30
30
 
@@ -36,13 +36,13 @@ Every wallet command works after `shinjuku`, for example `shinjuku balance`,
36
36
  Claude Code:
37
37
 
38
38
  ```sh
39
- claude mcp add --scope user shinjuku-shielded -- npx -y --no-audit --no-fund shinjuku-shield@0.3.87 mcp
39
+ claude mcp add --scope user shinjuku-shielded -- npx -y --no-audit --no-fund shinjuku-shield@0.3.89 mcp
40
40
  ```
41
41
 
42
42
  Claude Desktop (`claude_desktop_config.json`) or Cursor (`~/.cursor/mcp.json`):
43
43
 
44
44
  ```json
45
- { "mcpServers": { "shinjuku-shielded": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.87", "mcp"] } } }
45
+ { "mcpServers": { "shinjuku-shielded": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.89", "mcp"] } } }
46
46
  ```
47
47
 
48
48
  On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
package/manifest.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schema": "carbon-shielded-wallet/bundle-manifest/v1",
3
3
  "file": "shinjuku-wallet.mjs",
4
- "sha256": "c0b0b77bafa0cc4e15bd9c01e207c73b8188102f8ed1c9fe5e74e67c7bde008b",
5
- "bytes": 12523149,
6
- "sourceCommit": "d3e53e8aee2580ccfe7aee5fd957aea96457dc73",
4
+ "sha256": "9af59797297cdea3750a86cc8bc6287cab8952e4a8fc5da4bdb8d3e48ab2bd67",
5
+ "bytes": 12528864,
6
+ "sourceCommit": "5a32786bd0096a2a45135944a10dd1944ee4012d",
7
7
  "sourceDirty": false,
8
8
  "installRecordMatchesLockfile": true,
9
9
  "releaseRule": "valid only when two fresh npm ci --ignore-scripts builds on different OSes give the same sha256; installRecordMatchesLockfile true means every entry npm installed equals its package-lock.json entry and every entry not marked optional, devOptional included, is installed: an optional entry (a package for another platform) may be absent",
@@ -1282,5 +1282,5 @@
1282
1282
  "version": "1.8.0"
1283
1283
  }
1284
1284
  ],
1285
- "publishedAt": "2026-10-23T23:09:24.273Z"
1285
+ "publishedAt": "2026-10-24T00:07:43.778Z"
1286
1286
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shield",
3
- "version": "0.3.87",
3
+ "version": "0.3.89",
4
4
  "mcpName": "io.github.ShinjukuStaition/shinjuku-mcp",
5
5
  "description": "Shinjuku Shielded, the private x402 facilitator on Solana: the self-custody wallet CLI and its MCP server. Shield, pay, and unshield USDC from any MCP agent, under caps you set.",
6
- "shinjukuRelease": "c0b0b77b",
7
- "shinjukuSha256": "c0b0b77bafa0cc4e15bd9c01e207c73b8188102f8ed1c9fe5e74e67c7bde008b",
6
+ "shinjukuRelease": "9af59797",
7
+ "shinjukuSha256": "9af59797297cdea3750a86cc8bc6287cab8952e4a8fc5da4bdb8d3e48ab2bd67",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-mcp#readme",
@@ -47011,6 +47011,14 @@ async function proveProxy(mode, proxy) {
47011
47011
  throw new Error(`proxy_not_answering: ${address5} did not carry a request to ${TOR_CHECK}, so nothing was sent. Check the proxy and rerun`);
47012
47012
  }
47013
47013
  }
47014
+ function plainTorTrouble(text3, said = TOR_TROUBLE_SAID) {
47015
+ const line = String(text3).replace(/\r?\n$/, "");
47016
+ if (!/^(?:tor|rpc|history|memo service): /.test(line) || !TOR_TROUBLE_LINE.test(line) || /\bWARNING\b/.test(line)) return void 0;
47017
+ const plain = TOR_TROUBLE_PLAIN.find(([kind]) => kind.test(line))?.[1] ?? TOR_WAIT_PLAIN;
47018
+ if (said.has(plain)) return "";
47019
+ said.add(plain);
47020
+ return plain;
47021
+ }
47014
47022
  function childRunProxy(env = process.env) {
47015
47023
  const marked = String(env[MARK] ?? "");
47016
47024
  if (!marked) return { args: [], env: { ...env } };
@@ -47306,7 +47314,7 @@ async function proxyEntry(argv2, run5, { err = (text3) => process.stderr.write(t
47306
47314
  }
47307
47315
  return reexec(options.args, options.mode, options.proxy);
47308
47316
  }
47309
- var TOR_HTTP_TUNNEL, TOR_CHECK, PROOF_TIMEOUT_MS, LOCAL_PROOF_TIMEOUT_MS, LOCAL_PROOF_MAX_BYTES, torProvenAt, proxyProvenAt, MARK, TOR_RUN_STARTED_ENV, ownProxyRefused, ONION_V3, RETRY_AFTER_CAP_MS, RETRY_AFTER_FLOOR_MS, RETRY_AFTER_DEFAULT_MS, RPC_NO_ANSWER_LIMIT_MS, RPC_PACING_CAP_MS, PACING_NOTICE_EVERY_MS, PACING_RATE_WINDOW_MS, TOR_MAX_ROTATIONS, runStartedAt, rpcNotBefore, pacingWaiters, pacingSince, pacedMs, rpcAnswered, lastAnswerAt, readSteps, pacingNoticeAt, pacingSamples, torMoves, torCircuitId, torMovesRefused, pendingMove, inTorRun, runNetworkMode, isOnionOrigin, ProxyUsageError, isOnionHost, TOR_EXPERT_BUNDLE, TUNNEL_LINE, TOR_INSTALL, OS_NAMES, osKey, torNotRunningMessage, NOTICE, QUIET_RUN_MARK, QUIET_NOTICE, quietRun, TOR_TROUBLE_LINE, quietTorErr, withRunTag, proxyEnv, pacedSoFar, RESENDABLE_METHOD, torCircuit, GLOBAL_DISPATCHER2, laneDispatchers, paymentWarmStop, PROXY_WARNING_FLAG, proxiedExecArgv, proxiedNodeOptions, TOR_FROM_CONFIG_ENV, TOR_FROM_CONFIG_HINT;
47317
+ var TOR_HTTP_TUNNEL, TOR_CHECK, PROOF_TIMEOUT_MS, LOCAL_PROOF_TIMEOUT_MS, LOCAL_PROOF_MAX_BYTES, torProvenAt, proxyProvenAt, MARK, TOR_RUN_STARTED_ENV, ownProxyRefused, ONION_V3, RETRY_AFTER_CAP_MS, RETRY_AFTER_FLOOR_MS, RETRY_AFTER_DEFAULT_MS, RPC_NO_ANSWER_LIMIT_MS, RPC_PACING_CAP_MS, PACING_NOTICE_EVERY_MS, PACING_RATE_WINDOW_MS, TOR_MAX_ROTATIONS, runStartedAt, rpcNotBefore, pacingWaiters, pacingSince, pacedMs, rpcAnswered, lastAnswerAt, readSteps, pacingNoticeAt, pacingSamples, torMoves, torCircuitId, torMovesRefused, pendingMove, inTorRun, runNetworkMode, isOnionOrigin, ProxyUsageError, isOnionHost, TOR_EXPERT_BUNDLE, TUNNEL_LINE, TOR_INSTALL, OS_NAMES, osKey, torNotRunningMessage, NOTICE, QUIET_RUN_MARK, QUIET_NOTICE, QUIET_TERMINAL_COMMANDS, INFER_SUBCOMMANDS, quietRun, TOR_TROUBLE_LINE, TOR_WAIT_PLAIN, TOR_TROUBLE_PLAIN, TOR_TROUBLE_SAID, quietTorErr, withRunTag, proxyEnv, pacedSoFar, RESENDABLE_METHOD, torCircuit, GLOBAL_DISPATCHER2, laneDispatchers, paymentWarmStop, PROXY_WARNING_FLAG, proxiedExecArgv, proxiedNodeOptions, TOR_FROM_CONFIG_ENV, TOR_FROM_CONFIG_HINT;
47310
47318
  var init_proxy = __esm({
47311
47319
  "wallet/src/net/proxy.mjs"() {
47312
47320
  "use strict";
@@ -47371,14 +47379,31 @@ var init_proxy = __esm({
47371
47379
  chat: { tor: "Private: this chat goes through Tor.", proxy: "Private: this chat goes through your proxy." },
47372
47380
  funds: { tor: "Private: every request of this run goes through Tor.", proxy: "Private: every request of this run goes through your proxy." }
47373
47381
  };
47382
+ QUIET_TERMINAL_COMMANDS = /* @__PURE__ */ new Set(["add-funds", "funds-status", "balance", "unshield"]);
47383
+ INFER_SUBCOMMANDS = /* @__PURE__ */ new Set(["models", "serve", "start", "status", "stop"]);
47374
47384
  quietRun = (args) => {
47375
47385
  if (args.includes("--verbose")) return void 0;
47376
47386
  if (args[0] === "chat") return "chat";
47377
- return ["add-funds", "funds-status"].includes(args[0]) && process.stdout.isTTY && !args.includes("--json") ? "funds" : void 0;
47387
+ const quietCommand = QUIET_TERMINAL_COMMANDS.has(args[0]) || args[0] === "infer" && !INFER_SUBCOMMANDS.has(args[1]);
47388
+ return quietCommand && process.stdout.isTTY && !args.includes("--json") ? "funds" : void 0;
47378
47389
  };
47379
47390
  TOR_TROUBLE_LINE = /\bno (?:other )?(?:history-proxy )?onion\b|\bgave no answer\b|\bstalled\b|\bHTTP 429\b|\bcannot move\b/;
47391
+ TOR_WAIT_PLAIN = "Tor is slow right now, so the wallet waits for it and tries again. This can take longer than usual.";
47392
+ TOR_TROUBLE_PLAIN = [
47393
+ [/\bpublishes no onion\b/, "One server of this run has no Tor-only address, so the last Tor relay sees that server's name, but not what the wallet sends."],
47394
+ [/\bHTTP 429\b/, "A server asked the wallet to slow down, so the wallet waits as the server asks. This can add some time."],
47395
+ [/\bkeeps its circuit\b|\bcannot move\b|\bretries there\b|\bwait for (?:it|them)\b|\bno (?:other )?(?:history-proxy )?onion\b/, TOR_WAIT_PLAIN],
47396
+ [/\bmoved to a new Tor circuit\b|\bgave no answer\b/, "Tor was slow, so the wallet switched to another Tor route. This can add a few seconds."]
47397
+ ];
47398
+ TOR_TROUBLE_SAID = /* @__PURE__ */ new Set();
47380
47399
  quietTorErr = (err) => (text3) => {
47381
- if (/^tor: /.test(text3) && !TOR_TROUBLE_LINE.test(text3) && !/\bWARNING\b/.test(text3)) return;
47400
+ const plain = plainTorTrouble(text3);
47401
+ if (plain !== void 0) {
47402
+ if (plain) err(`${plain}
47403
+ `);
47404
+ return;
47405
+ }
47406
+ if (/^tor: /.test(text3) && !/\bWARNING\b/.test(text3)) return;
47382
47407
  err(text3);
47383
47408
  };
47384
47409
  withRunTag = (mode, proxy) => {
@@ -103417,7 +103442,9 @@ async function createSellerAdapter({
103417
103442
  }
103418
103443
  syncDirectory2();
103419
103444
  }
103420
- console.log(`SELLER_STORE layout=${OFFERS_LAYOUT} offers=${Object.keys(state.offers).length} migrated=${migrated ? "yes" : "no"} ms=${Date.now() - storeStarted}`);
103445
+ if (receiptVerification === "chain") {
103446
+ console.log(`SELLER_STORE layout=${OFFERS_LAYOUT} offers=${Object.keys(state.offers).length} migrated=${migrated ? "yes" : "no"} ms=${Date.now() - storeStarted}`);
103447
+ }
103421
103448
  let dirty = false;
103422
103449
  let snapshotting = false;
103423
103450
  let generation = 0;
@@ -107367,6 +107394,18 @@ var init_family = __esm({
107367
107394
  }
107368
107395
  });
107369
107396
 
107397
+ // wallet/src/caps/launchCaps.mjs
107398
+ function capFlagFromLaunchLine(flag3, argv2 = process.argv) {
107399
+ const at = argv2.indexOf("mcp");
107400
+ if (at < 0) return false;
107401
+ return argv2.slice(at + 1).some((arg) => arg === flag3 || arg.startsWith(`${flag3}=`));
107402
+ }
107403
+ var init_launchCaps = __esm({
107404
+ "wallet/src/caps/launchCaps.mjs"() {
107405
+ "use strict";
107406
+ }
107407
+ });
107408
+
107370
107409
  // wallet/src/mcp/sendRunner.mjs
107371
107410
  import { spawn as spawn4 } from "node:child_process";
107372
107411
  import { dirname as dirname22, join as join24 } from "node:path";
@@ -109872,9 +109911,9 @@ function refusalSay(a, tool, again, npmVersion) {
109872
109911
  const minutes = minutesText(REFUND_MINUTES);
109873
109912
  const ask = typeof a.requestId === "string" && a.requestId ? `Ask again with request_id ${a.requestId}.` : "Ask again with the same request_id.";
109874
109913
  return [
109875
- `${head} ${again} If the seller never takes it, the money returns in about ${minutes}.`,
109876
- `${head} ${ask} If the seller never takes it, the money returns in about ${minutes}.`,
109877
- `${head} ${ask} Otherwise the money returns in about ${minutes}.`
109914
+ `${head} ${again} If the seller never takes it, the money returns within about ${minutes}.`,
109915
+ `${head} ${ask} If the seller never takes it, the money returns within about ${minutes}.`,
109916
+ `${head} ${ask} Otherwise the money returns within about ${minutes}.`
109878
109917
  ].find((line) => words(line) <= SAY_MAX_WORDS) ?? `${head} ${again}`;
109879
109918
  }
109880
109919
  if (/_retry_same_request$/.test(code2)) {
@@ -109973,7 +110012,7 @@ function refusalSay(a, tool, again, npmVersion) {
109973
110012
  const total = usdcText(a.totalAtomic ?? a.neededAtomic ?? a.amountAtomic);
109974
110013
  const cap = usdcText(a.capAtomic ?? a.limitAtomic);
109975
110014
  if (a.capKind === "call" && total && cap) return `Nothing was paid: it costs ${total} USDC, over this request's ${cap} USDC cap. Allow ${total} USDC to pay it.`;
109976
- return total && cap ? `Nothing was paid: ${total} USDC is over your ${cap} USDC limit. ${raiseLine("--max-payment", npmVersion)}` : `Nothing was paid: this is above your per-payment limit. ${raiseLine("--max-payment", npmVersion)}`;
110015
+ return total && cap ? raiseLine("--max-payment", npmVersion, `Nothing was paid: ${total} USDC is over your ${cap} USDC limit.`) : raiseLine("--max-payment", npmVersion, "Nothing was paid: this is above your per-payment limit.");
109977
110016
  }
109978
110017
  if (MOVE_CAP_CODES.has(code2)) {
109979
110018
  const total = usdcText(a.totalAtomic ?? a.neededAtomic ?? a.amountAtomic);
@@ -109991,10 +110030,10 @@ function refusalSay(a, tool, again, npmVersion) {
109991
110030
  return `Nothing was paid: this request's ${usdcText(a.capAtomic)} USDC cap is below the ${usdcText(a.ceilingAtomic)} USDC ceiling. ${allow}`;
109992
110031
  }
109993
110032
  if ((code2 === "inference_ceiling_over_cap" || code2 === "p03_float_over_maximum") && usdcText(a.totalAtomic) && usdcText(a.capAtomic)) {
109994
- return `Nothing was paid: up to ${usdcText(a.totalAtomic)} USDC is over your ${usdcText(a.capAtomic)} USDC limit. ${raiseLine("--max-payment", npmVersion)}`;
110033
+ return raiseLine("--max-payment", npmVersion, `Nothing was paid: up to ${usdcText(a.totalAtomic)} USDC is over your ${usdcText(a.capAtomic)} USDC limit.`);
109995
110034
  }
109996
110035
  if (code2 === "mcp_session_cap_exceeded" && usdcText(a.capAtomic)) {
109997
- return `Nothing was paid: over your 24-hour limit of ${usdcText(a.capAtomic)} USDC. ${raiseLine("--max-session", npmVersion)}`;
110036
+ return raiseLine("--max-session", npmVersion, `Nothing was paid: over your 24-hour limit of ${usdcText(a.capAtomic)} USDC.`);
109998
110037
  }
109999
110038
  if (OWNER_LIMIT_CODES.has(code2)) return "Nothing was paid. This is above a spending limit set for this wallet.";
110000
110039
  if (code2 === "spend_host_not_allowed") return "Nothing was paid. This wallet's settings do not allow payments to this site.";
@@ -110260,9 +110299,12 @@ function previewReason(a, npmVersion) {
110260
110299
  if (PAY_CAP_CODES.has(code2)) {
110261
110300
  const total = usdcText(a.totalAtomic ?? a.priceAtomic);
110262
110301
  const cap = usdcText(a.capAtomic);
110263
- return total && cap ? `${total} USDC is over your ${cap} USDC limit. ${raiseLine("--max-payment", npmVersion)}` : `it is above your per-payment limit. ${raiseLine("--max-payment", npmVersion)}`;
110302
+ const room = SAY_MAX_WORDS - 3;
110303
+ return total && cap ? raiseLine("--max-payment", npmVersion, `${total} USDC is over your ${cap} USDC limit.`, room) : raiseLine("--max-payment", npmVersion, "it is above your per-payment limit.", room);
110304
+ }
110305
+ if (code2 === "mcp_session_cap_exceeded" && usdcText(a.capAtomic)) {
110306
+ return raiseLine("--max-session", npmVersion, `over your 24-hour limit of ${usdcText(a.capAtomic)} USDC.`, SAY_MAX_WORDS - 3);
110264
110307
  }
110265
- if (code2 === "mcp_session_cap_exceeded" && usdcText(a.capAtomic)) return `over your 24-hour limit of ${usdcText(a.capAtomic)} USDC. ${raiseLine("--max-session", npmVersion)}`;
110266
110308
  if (OWNER_LIMIT_CODES.has(code2)) return "it is above a spending limit set for this wallet.";
110267
110309
  if (BUSY.test(code2)) return "the payment service is busy; try again in a minute.";
110268
110310
  if (code2 === "mcp_wallet_unreadable" || code2 === "p03_float_config_unreadable") return "the price could not be checked just now; try again in a minute.";
@@ -110505,6 +110547,7 @@ var init_say = __esm({
110505
110547
  "use strict";
110506
110548
  init_amounts();
110507
110549
  init_config2();
110550
+ init_launchCaps();
110508
110551
  SAY_MAX_WORDS = 25;
110509
110552
  DECIMALS = 6;
110510
110553
  ATOMIC3 = /^[0-9]{1,31}$/;
@@ -110519,7 +110562,13 @@ var init_say = __esm({
110519
110562
  MOVING_ROLES = /* @__PURE__ */ new Set(["draining", "old pool (switching)"]);
110520
110563
  CLOSE_LATER = "Cannot close yet: the seller could still take this payment. Ask again in about 2 minutes; if unpaid, it closes and the money comes back.";
110521
110564
  PAY_CAP_CODES = /* @__PURE__ */ new Set(["spend_payment_cap_exceeded", "mcp_cap_argument_above_launch_cap"]);
110522
- raiseLine = (flag3, npmVersion) => `Raise it: ${oneTimeCommandLine(`setup --yes ${flag3} <usdc>`, npmVersion)}, then restart this app.`;
110565
+ raiseLine = (flag3, npmVersion, head, room = SAY_MAX_WORDS) => {
110566
+ const lines = capFlagFromLaunchLine(flag3) ? [`Raise ${flag3} in this app's shinjuku-shielded entry, then restart this app.`] : [
110567
+ `Raise it: ${oneTimeCommandLine(`setup --yes ${flag3} <usdc>`, npmVersion)}, then restart this app.`,
110568
+ `Raise ${flag3} with setup in a terminal, then restart this app.`
110569
+ ];
110570
+ return lines.map((line) => `${head} ${line}`).find((line) => words(line) <= room) ?? `${head} ${lines.at(-1)}`;
110571
+ };
110523
110572
  MOVE_CAP_CODES = /* @__PURE__ */ new Set(["mcp_shield_cap_exceeded", "mcp_unshield_cap_exceeded"]);
110524
110573
  OWNER_LIMIT_CODES = /* @__PURE__ */ new Set([
110525
110574
  "mcp_session_cap_exceeded",
@@ -123332,7 +123381,7 @@ ${canonical5}`;
123332
123381
  } catch {
123333
123382
  }
123334
123383
  const sessionLeft = sessionLeftShown(policy, countStore);
123335
- const sessionSummary = `Spending limits: ${capWords(policy.limits.maxPaymentAtomic)} per payment and ${capWords(policy.limits.maxSessionAtomic)} in any 24 hours, for this wallet (every MCP process counts; a pool upgrade starts a new 24-hour count)${sessionLeft === null ? "" : ` (${usdcText2(sessionLeft)} USDC left now)`}; ${usdcText2(policy.sessionSpentAtomic) ?? "0"} USDC paid in the last 24 hours. They come from this MCP server's launch line in the host (--max-payment and --max-session, in USDC like 0.05), else from the limits setup recorded. To change them, edit those flags in the host's MCP entry, or run ${terminalCommand("setup --yes --max-payment <usdc> --max-session <usdc>")} in a terminal; then restart the host. The wallet file also holds its own limits (--max-payment, and --max-cumulative for all payments together): ${terminalCommand("limits")} shows and changes them`;
123384
+ const sessionSummary = `Spending limits: ${capWords(policy.limits.maxPaymentAtomic)} per payment and ${capWords(policy.limits.maxSessionAtomic)} in any 24 hours, for this wallet (every MCP process counts; a pool upgrade starts a new 24-hour count)${sessionLeft === null ? "" : ` (${usdcText2(sessionLeft)} USDC left now)`}; ${usdcText2(policy.sessionSpentAtomic) ?? "0"} USDC paid in the last 24 hours. --max-payment comes from ${capPlaceWords("--max-payment")}, and --max-session from ${capPlaceWords("--max-session")}. To change one from the host's entry, edit that flag (in USDC, like 0.05) in the host's entry for shinjuku-shielded; to change one from setup, run ${terminalCommand("setup --yes --max-payment <usdc> --max-session <usdc>")} in a terminal; then restart the host. The wallet file also holds its own limits (--max-payment, and --max-cumulative for all payments together): ${terminalCommand("limits")} shows and changes them`;
123336
123385
  return json3({
123337
123386
  ok: true,
123338
123387
  ...reportPublic,
@@ -128920,7 +128969,7 @@ function createSetupTools({
128920
128969
  };
128921
128970
  return { tools: [setupTool, statusTool, ...MCP_TOOL_NAMES.map((name) => name === "x402_discover" ? discoverTool(discoverCacheDir) : notSetUp(name))], doneTool };
128922
128971
  }
128923
- var import_web3133, shownCaps, RELEASE_RETRY_MS, STAGE_WORDS, stageWords, INTERNAL_BALANCE_DETAIL, shownBreakdown, sessionLeftShown, TOKEN_UNIT_TOOLS, RESOURCE_PAYMENT_WAL_PREFIX2, POOL_LAYOUT_CODE, POOL_LAYOUT_UPDATE, USEPOD_VIA_INFERENCE_CHAT, SEND_RUNS_ON, DEPOSIT_RUNS_ON, CLI_FUNDS_PLAN_PREFIX, CLI_FUNDS_SCHEMA, SELF_PAY_ORIGIN3, REQUEST_ID4, POSITIVE_ATOMIC6, PRIVATE_HOST3, FORBIDDEN_HEADERS3, MAX_BODY_BYTES2, PREVIEW_TIMEOUT_MS, PREVIEW_SELLER_READ_MS, CALL_BUDGET_MS, budgetLeft, MONEY_FIRST_ANSWER_MS, BALANCE_AFTER_LANDING_MS, JOIN_CALL_MAX_MS, JOIN_NUDGE_QUIET_MS, JOIN_STEP_MS, sleep2, PROGRESS_EVERY_MS2, READ_BUDGET_MS, UNPAID_TOR_TRY_MS, UNPAID_CLEAR_MS, READ_BUDGET_TOOLS, FLOAT_BUSY_CODES, RETRY_MARGIN_MS, ASK_PAY_CODES, runningNpmVersion, terminalCommand, capRaiseText, cheaperSellerText, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, FLOAT_ID, ANSWERED_EXIT_RETRY_MS, ANSWERED_EXIT_UNCONFIRMED_MS, ANSWERED_EXIT_RETRY_WINDOW_MS, ANSWERED_EXIT_CLOSED, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, MCP_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json3, answerResult, discoverTool, refuse12, publicOffer, FLOAT_PAID_CODES, FLOAT_PRIVATE_LEG, floatStillSettling, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, PUBLIC_READ_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, OWN_TOKENS_GRACE_MS, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, ageWords2, DEPOSIT_SENT_STATES, depositLanded, usdcText2, walkWalletHistory, REFRESH_LEASE_WALK_MS, HOME_MARKS_SETTLED_MS2, AUTO_BACKUPS_KEPT, AUTO_BACKUP_NAME, AUTO_BACKUP_VERIFIED, FRONTED_SETTLE_MARGIN_SLOTS, BALANCE_REFRESH_WAIT_MS, BALANCE_REFRESH_GRACE_MS, BALANCE_REFRESH_LONG_MS, INBOUND_REFRESH_AGE_MS, CAP_BALANCE_WAIT_MS, CAP_BALANCE_RETRY_MS, REFRESH_RETRY_MS, FINALITY_POLL_MS, FINALITY_WAIT_MS, FINALITY_REFRESH_LIMIT_MS, POOL_WATCH_MS, POOL_WATCH_POLL_MS, EARLY_BALANCE_DELAY_MS, FINALITY_SETTLE_WINDOW_SLOTS, PUBLIC_READ_ANSWER_MS, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS3, TRANSFER_CHANGE_READ_MS, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, setupTerminalNext, SETUP_POLL_NEXT, PRIVATE_INFERENCE_WHY, PRIVATE_INFERENCE_NEXT;
128972
+ var import_web3133, shownCaps, RELEASE_RETRY_MS, STAGE_WORDS, stageWords, INTERNAL_BALANCE_DETAIL, shownBreakdown, sessionLeftShown, TOKEN_UNIT_TOOLS, RESOURCE_PAYMENT_WAL_PREFIX2, POOL_LAYOUT_CODE, POOL_LAYOUT_UPDATE, USEPOD_VIA_INFERENCE_CHAT, SEND_RUNS_ON, DEPOSIT_RUNS_ON, CLI_FUNDS_PLAN_PREFIX, CLI_FUNDS_SCHEMA, SELF_PAY_ORIGIN3, REQUEST_ID4, POSITIVE_ATOMIC6, PRIVATE_HOST3, FORBIDDEN_HEADERS3, MAX_BODY_BYTES2, PREVIEW_TIMEOUT_MS, PREVIEW_SELLER_READ_MS, CALL_BUDGET_MS, budgetLeft, MONEY_FIRST_ANSWER_MS, BALANCE_AFTER_LANDING_MS, JOIN_CALL_MAX_MS, JOIN_NUDGE_QUIET_MS, JOIN_STEP_MS, sleep2, PROGRESS_EVERY_MS2, READ_BUDGET_MS, UNPAID_TOR_TRY_MS, UNPAID_CLEAR_MS, READ_BUDGET_TOOLS, FLOAT_BUSY_CODES, RETRY_MARGIN_MS, ASK_PAY_CODES, runningNpmVersion, terminalCommand, capPlaceWords, capRaiseText, cheaperSellerText, limitNext, SAFE_TEXT, MCP_TOOL_ALIASES, POOL_SWITCH_WHY, POOL_SWITCH_NEXT, SWITCH_STATES, quietSwitch, switchKey, ATOMIC_TEXT, FLOAT_ID, ANSWERED_EXIT_RETRY_MS, ANSWERED_EXIT_UNCONFIRMED_MS, ANSWERED_EXIT_RETRY_WINDOW_MS, ANSWERED_EXIT_CLOSED, switchAmount, switchEta, switchRows, OWNER_CAP_CODES, JOIN_END_MCP, JOIN_END_TERMINAL_LIBRARY, JOIN_RETRY_BACKOFF_MS, WALLET_CAP_FIX, MCP_CAP_FIX, capFix, ownerOnlyNext, mcpNext, CONFIDENTIAL_RETIRED, json3, answerResult, discoverTool, refuse12, publicOffer, FLOAT_PAID_CODES, FLOAT_PRIVATE_LEG, floatStillSettling, MONEY_ID2, toRecordId, linkKindOf, moneyId, REFUSED_CODES, refusedCodeOf, PLAIN_REASONS, plainReason, KEPT_SEND_TRIES, shownId, isSplitSend, sendPartId, PROMISED_NEXT, PUBLIC_READ_TIMEOUT_MS, withTimeout, ownKey, readFailure, OWN_KEY_TOKENS_MAX, OWN_TOKENS_GRACE_MS, tokenAmountText, elsewhereId, AGENT_ID_SCHEMA, agentIdName, minutesText2, ageWords2, DEPOSIT_SENT_STATES, depositLanded, usdcText2, walkWalletHistory, REFRESH_LEASE_WALK_MS, HOME_MARKS_SETTLED_MS2, AUTO_BACKUPS_KEPT, AUTO_BACKUP_NAME, AUTO_BACKUP_VERIFIED, FRONTED_SETTLE_MARGIN_SLOTS, BALANCE_REFRESH_WAIT_MS, BALANCE_REFRESH_GRACE_MS, BALANCE_REFRESH_LONG_MS, INBOUND_REFRESH_AGE_MS, CAP_BALANCE_WAIT_MS, CAP_BALANCE_RETRY_MS, REFRESH_RETRY_MS, FINALITY_POLL_MS, FINALITY_WAIT_MS, FINALITY_REFRESH_LIMIT_MS, POOL_WATCH_MS, POOL_WATCH_POLL_MS, EARLY_BALANCE_DELAY_MS, FINALITY_SETTLE_WINDOW_SLOTS, PUBLIC_READ_ANSWER_MS, SWITCH_WAIT_MS, UNSHIELD_TO_NO_USDC_DETAIL, UNSHIELD_TO_INVALID_NEXT, INFERENCE_MIN_MAX_TOKENS, ELICIT_TIMEOUT_MS, ELICIT_UNSHOWN_MS, elicitUnshown, POLL_SECONDS3, TRANSFER_CHANGE_READ_MS, TEMP_CLEAN_DELAY_MS, KEPT_ON_DISK, MAX_SHIELDED_BALANCE_ATOMIC, receiveGenerator, MCP_TOOL_NAMES, MCP_HIDDEN_TOOL_NAMES, setupTerminalNext, SETUP_POLL_NEXT, PRIVATE_INFERENCE_WHY, PRIVATE_INFERENCE_NEXT;
128924
128973
  var init_tools = __esm({
128925
128974
  "wallet/src/mcp/tools.mjs"() {
128926
128975
  "use strict";
@@ -128948,6 +128997,7 @@ var init_tools = __esm({
128948
128997
  init_book();
128949
128998
  init_errorLine();
128950
128999
  init_spendPolicy();
129000
+ init_launchCaps();
128951
129001
  import_web3133 = __toESM(require_index_cjs(), 1);
128952
129002
  init_esm2();
128953
129003
  init_deposit();
@@ -129051,9 +129101,14 @@ var init_tools = __esm({
129051
129101
  RETRY_MARGIN_MS = 15e3;
129052
129102
  ASK_PAY_CODES = /* @__PURE__ */ new Set(["spend_payment_cap_exceeded", "mcp_cap_argument_above_launch_cap"]);
129053
129103
  terminalCommand = (words2) => oneTimeCommandLine(words2, runningNpmVersion);
129104
+ capPlaceWords = (flag3) => capFlagFromLaunchLine(flag3) ? `the host's entry (${flag3} in its args)` : "setup (config.json in the wallet folder)";
129054
129105
  capRaiseText = (flag3) => {
129106
+ if (capFlagFromLaunchLine(flag3)) {
129107
+ const both2 = flag3 === "--max-payment" ? " (raise --max-session there too when it is below the new amount: the server refuses to start with it lower)" : "";
129108
+ return `This limit comes from the host's entry for shinjuku-shielded: its args hold ${flag3}. To raise it, the user changes that value there${both2}, with amounts in USDC like 0.5, then restarts the agent host (Claude Desktop: claude_desktop_config.json; Cursor: ~/.cursor/mcp.json; Claude Code: claude mcp get shinjuku-shielded shows the entry, then claude mcp remove shinjuku-shielded and claude mcp add it again with the new value; Hermes: config.yaml). Running setup does not change this limit: the entry's ${flag3} wins over the limit setup records.`;
129109
+ }
129055
129110
  const both = flag3 === "--max-payment" ? " (add --max-session <usdc> too when the 24-hour limit is below the new amount: setup refuses it lower)" : "";
129056
- return `To raise it, the user runs this in a terminal: ${terminalCommand(`setup --yes ${flag3} <usdc>`)}${both}, with amounts in USDC like 0.5, then restarts the agent host. setup keeps the wallet and saves the limit in config.json in the wallet folder (~/.carbon-shielded-wallet, or SHIELDED_WALLET_HOME when it is set). If the host's entry for shinjuku-shielded has ${flag3} in its args, that value wins: change it there instead (Claude Desktop: claude_desktop_config.json; Cursor: ~/.cursor/mcp.json; Claude Code: claude mcp get shinjuku-shielded shows the entry; Hermes: config.yaml).`;
129111
+ return `This limit comes from setup (the host's entry has no ${flag3}). To raise it, the user runs this in a terminal: ${terminalCommand(`setup --yes ${flag3} <usdc>`)}${both}, with amounts in USDC like 0.5, then restarts the agent host. setup keeps the wallet and saves the limit in config.json in the wallet folder (~/.carbon-shielded-wallet, or SHIELDED_WALLET_HOME when it is set).`;
129057
129112
  };
129058
129113
  cheaperSellerText = "Or call x402_discover to look for a cheaper seller of the same data.";
129059
129114
  limitNext = ({ totalAtomic, capAtomic } = {}, { flag: flag3 = "--max-payment", verb = "paid", noun = "costs" } = {}) => `${totalAtomic && capAtomic ? `Nothing was ${verb}. Tell the user: this ${noun} ${usdcText2(totalAtomic)} USDC and the limit (${flag3}) is ${usdcText2(capAtomic)} USDC.` : `Nothing was ${verb}. Tell the user this is above the limit (${flag3}).`} ${capRaiseText(flag3)}${verb === "paid" ? ` ${cheaperSellerText}` : ""}`;
@@ -130531,9 +130586,16 @@ function readConfig(env) {
130531
130586
  }
130532
130587
  function hideProgressLines(stream = process.stderr) {
130533
130588
  const original = stream.write;
130589
+ const shown = (line) => {
130590
+ if (!line.endsWith("\n")) return line;
130591
+ const plain = plainTorTrouble(line);
130592
+ if (plain !== void 0) return plain ? `${plain}
130593
+ ` : "";
130594
+ return isProgressLine(line) ? "" : line;
130595
+ };
130534
130596
  stream.write = function write(chunk, encoding, callback) {
130535
130597
  const text3 = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString(typeof encoding === "string" ? encoding : "utf8");
130536
- const kept = text3.split(/(?<=\n)/).filter((line) => !(line.endsWith("\n") && isProgressLine(line))).join("");
130598
+ const kept = text3.split(/(?<=\n)/).map(shown).join("");
130537
130599
  if (kept === text3) return original.call(stream, chunk, encoding, callback);
130538
130600
  const done = typeof encoding === "function" ? encoding : callback;
130539
130601
  if (kept) return original.call(stream, kept, done);
@@ -130820,7 +130882,7 @@ var init_chat = __esm({
130820
130882
  NO_ANSWER_CODES = /^inference_(upstream_failed|response_invalid)$/;
130821
130883
  NOTHING_PAID = /\bnothing was (?:sent or )?paid\b|\bnothing was paid or signed\b/i;
130822
130884
  CAP_FROM = { line: "from this command line", setup: "set in setup", default: "the default" };
130823
- PROGRESS_LINE = /^(?:tor|rpc|history|memo service): |^reading \d+ memos? from the memo service/;
130885
+ PROGRESS_LINE = /^(?:tor|rpc|history|memo service): |^reading \d+ memos? from the memo service|^reading your private balance again\b|^merge \S+: self-paying\b/;
130824
130886
  SHOWN_PROGRESS = /\bWARNING\b|\bminutes?\b/;
130825
130887
  isProgressLine = (line) => PROGRESS_LINE.test(line) && !SHOWN_PROGRESS.test(line) && !TOR_TROUBLE_LINE.test(line);
130826
130888
  fail46 = (deps, message) => typeof deps.publicFailure === "function" ? deps.publicFailure(message) : new Error(message);
@@ -157384,6 +157446,7 @@ function withProofToolsRefresh(options, fromConfig) {
157384
157446
  return { ...options, proofToolsRefresh: { home: fromConfig.home } };
157385
157447
  }
157386
157448
  var inProxiedRun = (env) => childRunProxy(env).args.length > 0;
157449
+ var terminalQuiet = (values, deps) => deps.stdoutIsTTY?.() === true && !values.has("--json") && !values.has("--verbose");
157387
157450
  var TOR_RUN_STARTED_ENV2 = "SHINJUKU_WALLET_TOR_RUN_STARTED_FILE";
157388
157451
  var TOR_DOWN_DETAIL = "Your private connection (Tor) is not running, so no payment was made. Start Tor, then restart this MCP server in your agent host and try again.";
157389
157452
  var recordedTunnelHost = (configPath2) => {
@@ -158468,7 +158531,8 @@ var COMMANDS = [
158468
158531
  bool2("--refresh", "run the same chain walk as recover first (network)"),
158469
158532
  // --digests narrows recover's printed output; a balance needs the whole history.
158470
158533
  ...recoverFlags({ refreshOnly: true }).filter((entry) => entry.name !== "--digests"),
158471
- bool2("--json", "print the whole report as JSON in a terminal too (a file or a program gets JSON without this flag)")
158534
+ bool2("--json", "print the whole report as JSON in a terminal too (a file or a program gets JSON without this flag)"),
158535
+ bool2("--verbose", "in a terminal, also show the wallet's own progress lines (Tor, the RPC relay, the pool history, the memo reads); without it a terminal shows only the result")
158472
158536
  ],
158473
158537
  examples: [
158474
158538
  `${CLI2} balance --pool ${GUIDE.pool}`,
@@ -158479,7 +158543,7 @@ var COMMANDS = [
158479
158543
  "shinjukuShielded is what you can spend: unspent accounts and notes minus the ones in-flight payments or unshields will use.",
158480
158544
  "Without --refresh, balance reads only local files: the last walk (recover or balance --refresh) and the wallet log. It makes no network call.",
158481
158545
  "shinjukuShielded is null when the last walk is missing, stale, or incomplete. reasons says why; next shows the command to run.",
158482
- "In a terminal it prints one plain line: the private balance in USDC, and a short reason when it is not current (then the command to run). A program, or --json, gets the whole report as JSON (total, shinjukuShielded, status, reasons, next, detail).",
158546
+ "In a terminal it prints one plain line: the private balance in USDC, and a short reason when it is not current (then the command to run). The wallet's own progress lines (Tor, the RPC relay, the pool history walk, the memo reads) show only with --verbose; warnings and failures always show. A program, or --json, gets the whole report as JSON (total, shinjukuShielded, status, reasons, next, detail).",
158483
158547
  "Payments that others send to this wallet appear only after a refresh.",
158484
158548
  "With --refresh it also reads the one-time deposit addresses of this home's earlier pools (one address per request). USDC found there goes into this pool by itself (the facilitator pays the fee), and earlierDeposits lists each one with a notice.",
158485
158549
  "paymentsWithoutWaiting (and detail.fundedAccounts): your funded accounts that no in-flight work holds. A payment spends one account, and its change pays only after the next pool anchor (up to 5 minutes; about 30 s on some pools), so this many payments can run before the next anchor without waiting (an account made since the last anchor, such as a change, waits for the next one). add-funds --split makes more of them."
@@ -158493,10 +158557,12 @@ var COMMANDS = [
158493
158557
  }
158494
158558
  return;
158495
158559
  }
158496
- const extra = [...values.keys()].find((name) => name !== "--pool" && name !== "--json");
158560
+ const extra = [...values.keys()].find((name) => !["--pool", "--json", "--verbose"].includes(name));
158497
158561
  if (extra) throw new UsageError(`${extra} is used only with --refresh`);
158498
158562
  },
158499
158563
  rpcWhen: (values) => values.has("--refresh"),
158564
+ // In a terminal its progress lines show only with --verbose (inference/chat.mjs hideProgressLines; fault 6 of the pin 0.3.86).
158565
+ quietProgress: (values, deps) => terminalQuiet(values, deps),
158500
158566
  run: (args, values, deps, io) => runBalance(args, values, deps, io)
158501
158567
  },
158502
158568
  {
@@ -158586,6 +158652,7 @@ var COMMANDS = [
158586
158652
  flag2("--max-session", "<usdc>", "the most this run may pay in total, in USDC; at least --max-payment. Default: the cap setup recorded, else 1", { check: "atomic", usdc: true }),
158587
158653
  flag2("--request-id", "<id>", "your stable name for this request; default infer-<random>, printed on stderr before any payment. Rerun with the same id to resume a stopped run: it never pays twice"),
158588
158654
  bool2("--json", "print one JSON line (answer, model, usage, paidAtomic, requestId, receipt) instead of the answer text"),
158655
+ bool2("--verbose", "in a terminal, also show the wallet's own progress lines (Tor, the RPC relay, the pool history, the memo reads); without it a terminal shows only the cost line, the answer, and what it paid"),
158589
158656
  // After setup config.json gives every wallet flag; they stay for a wallet in another place.
158590
158657
  ...payerSessionFlags().map((spec) => ({ ...spec, required: false }))
158591
158658
  ],
@@ -158599,7 +158666,7 @@ var COMMANDS = [
158599
158666
  `Private form (recommended): pipe the prompt in and write - in its place, so it is not in the process list or your shell history: ${INFER_STDIN_EXAMPLE}. stdin is read until it ends (UTF-8, at most 1 MiB); an empty one is refused before anything is paid.`,
158600
158667
  "It runs only through Tor (or --proxy <url>), never a direct connection: usePod would see your IP address next to your prompt, so the command refuses before anything is sent.",
158601
158668
  `${INFER_COST_LINE}. stderr says this before the payment, with the most the request can cost.`,
158602
- "stdout holds the answer; stderr says paid <amount> USDC request-id <id>. An answer cut short by --max-tokens says so.",
158669
+ "stdout holds the answer; stderr says paid <amount> USDC request-id <id>. An answer cut short by --max-tokens says so. In a terminal the wallet's own progress lines (Tor, the RPC relay, the pool history walk, the memo reads) show only with --verbose; warnings and failures always show.",
158603
158670
  "Exit codes: 0 answered; 1 refused or failed (one line says why, and a hint says what works); 2 the command line is wrong."
158604
158671
  ],
158605
158672
  next: `chat in this terminal: ${CLI2} chat; the local AI address for an agent app: ${CLI2} infer start; the models and prices: ${CLI2} infer models`,
@@ -158609,6 +158676,8 @@ var COMMANDS = [
158609
158676
  // Outside a Tor run (or without a wallet) infer runs again behind Tor or refuses: it reads nothing itself (as chat).
158610
158677
  skipFamilyRoots: (values, env) => !inferPaysHere(values, env),
158611
158678
  rpcWhen: (values, env) => inferPaysHere(values, env),
158679
+ // The Tor run, the one that pays, in a terminal: its progress lines show only with --verbose (as chat; fault 6 of the pin 0.3.86).
158680
+ quietProgress: (values, deps) => inProxiedRun(deps.env) && terminalQuiet(values, deps),
158612
158681
  run: (args, values, deps, io) => deps.inferMain(values, { ...deps, io })
158613
158682
  },
158614
158683
  {
@@ -158943,7 +159012,8 @@ var COMMANDS = [
158943
159012
  HISTORY_RPC_FLAG,
158944
159013
  flag2("--parts", "<1-8>", "optional, default 1: send the amount as this many separate exits of unequal size (a private send); each part carries at least 0.01 USDC; above 1 it needs --max-delay-minutes 1-60, and --unshield-id may then be at most 45 characters", { check: "count" }),
158945
159014
  flag2("--max-delay-minutes", "<0-60>", "optional, default 0: each part, part 1 included, is sent after a random wait of up to this many minutes; a part that is late (the command was stopped) waits a new random time", { check: "count" }),
158946
- bool2("--json", "end with the result as JSON in a terminal too (a file or a program gets JSON without this flag)")
159015
+ bool2("--json", "end with the result as JSON in a terminal too (a file or a program gets JSON without this flag)"),
159016
+ bool2("--verbose", "in a terminal, also show the wallet's own progress lines (Tor, the RPC relay, the pool history, the memo reads, the join's steps); without it a terminal shows only the steps you act on and the result")
158947
159017
  ],
158948
159018
  // T9 (live run 2026-10-23 18:44 UTC, npm 0.3.83): the old two examples looked the same and neither had --amount or a
158949
159019
  // plain --to; after setup these two work as typed (config.json gives every file flag).
@@ -158954,12 +159024,14 @@ var COMMANDS = [
158954
159024
  "The recipient must already hold USDC (a Solana address with a USDC account, for example a Phantom address that received USDC); the command checks it first and sends nothing to an address without one. It refuses this wallet's own address: an exit there would show on chain that the money is yours. Best: an address that never sent USDC into this wallet.",
158955
159025
  "--amount all sends the whole private balance. When the balance is in more than one part, the same command joins the parts first (a private move inside this wallet, no fee; nothing leaves it; about 2 minutes per extra part, after a random wait of up to 60 s), then sends all of it. Ctrl+C stops it; the same command again goes on and never sends twice.",
158956
159026
  "The command prints the unshield id first. If it stops, run the same command with --unshield-id <that id> added: it finishes that unshield and never sends twice.",
158957
- "In a terminal it ends with one plain line (what was sent, to whom, the exit transaction) and the new private balance: after an exit the wallet reads the balance again itself (the same walk as balance --refresh, over the same connection; Tor when setup recorded it). A program, or --json, gets the result as JSON.",
159027
+ "In a terminal it ends with one plain line (what was sent, to whom, the exit transaction) and the new private balance: after an exit the wallet reads the balance again itself (the same walk as balance --refresh, over the same connection; Tor when setup recorded it). A program, or --json, gets the result as JSON. The wallet's own progress lines (Tor, the RPC relay, the pool history walk, the memo reads, the join's steps) show only with --verbose; warnings and failures always show.",
158958
159028
  `--parts and --max-delay-minutes make a private send (${CLI2} unshield --amount 3 --parts 3 --max-delay-minutes 20 --to <your wallet address>): the plan (part sizes, part ids <unshield-id>-p1.., earliest times) is saved in the wallet before part 1, each part is one unshield, and a stopped run continues at the first part not yet exited when the same command with its --unshield-id runs again. The wallet is free for other commands while a part waits. Keep the command running until it prints its result.`,
158959
159029
  `Stop the parts of a private send not sent yet: ${CLI2} unshield-cancel --unshield-id <id>.`,
158960
159030
  "Privacy limit of a private send: every part goes to the same --to, so anyone who adds up that account's incoming transfers sees the total. The parts hide the time and the single amount of the exit, not the sum the account received."
158961
159031
  ],
158962
159032
  next: `back up the wallet (${CLI2} help backup-export); ${CLI2} balance shows the private balance`,
159033
+ // In a terminal its progress lines show only with --verbose (inference/chat.mjs hideProgressLines; fault 6 of the pin 0.3.86).
159034
+ quietProgress: (values, deps) => terminalQuiet(values, deps),
158963
159035
  run: (args, values, deps, io) => runUnshieldCommand(args, values, deps, io)
158964
159036
  },
158965
159037
  {
@@ -159749,7 +159821,7 @@ async function recipientHoldsUsdc({ connection, mint, owner }) {
159749
159821
  }
159750
159822
  async function runUnshieldCommand(args, values, deps, io) {
159751
159823
  const terminal = deps.stdoutIsTTY?.() === true && !values.has("--json");
159752
- let callArgs = args.filter((word) => word !== "--json");
159824
+ let callArgs = args.filter((word) => word !== "--json" && word !== "--verbose");
159753
159825
  const setArg = (name, value) => {
159754
159826
  const at = callArgs.indexOf(name);
159755
159827
  callArgs = at >= 0 ? callArgs.map((word, index) => index === at + 1 ? value : word) : [...callArgs, name, value];
@@ -159807,6 +159879,7 @@ async function runUnshieldCommand(args, values, deps, io) {
159807
159879
  if (values.get("--amount") === "all") setArg("--amount", await sendAllAtomic(values, deps, io, openStore, ensureId));
159808
159880
  ensureId();
159809
159881
  const gated = await spendGate(callArgs, values, deps, io, { amountAtomic: values.get("--amount"), again: ` with --unshield-id ${id}` });
159882
+ if (terminal && isSingleSend(values.get("--parts") ?? 1, values.get("--max-delay-minutes") ?? 0)) io.err("sending privately now; this takes about a minute\n");
159810
159883
  let answer;
159811
159884
  const returned = await deps.unshieldMain(gated, { output: (result) => {
159812
159885
  answer = result;
@@ -160534,7 +160607,7 @@ async function runBalance(args, values, deps, io) {
160534
160607
  let store;
160535
160608
  let earlierDeposits = [];
160536
160609
  if (values.has("--refresh")) {
160537
- const refreshed = await refreshSnapshot(args.filter((word) => word !== "--json"), values, deps);
160610
+ const refreshed = await refreshSnapshot(args.filter((word) => word !== "--json" && word !== "--verbose"), values, deps);
160538
160611
  warnUnsavedSync(refreshed.result, io);
160539
160612
  refreshed.save();
160540
160613
  await refreshed.prune();