shinjuku-shielded 0.3.169 → 0.3.170

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,19 +6,18 @@ 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.169. The npm packages `shinjuku-shield` and
9
+ This is version 0.3.170. The npm packages `shinjuku-shield` and
10
10
  `shinjuku-shielded` hold the same files. The command is `shinjuku`.
11
11
 
12
12
  ## Set up
13
13
 
14
14
  ```sh
15
- npm install -g shinjuku@0.3.169
16
- shinjuku setup
15
+ npx -y shinjuku@0.3.170 setup
17
16
  ```
18
17
 
19
- Type the two lines as they are. `npx install shinjuku` does not work: npx
20
- reads `install` as the name of another npm package. To set up without
21
- installing, type `npx shinjuku@0.3.169 setup`.
18
+ Setup offers to install the `shinjuku` command and, on Windows, adds npm's
19
+ folder to your PATH when it is missing: open a new window after setup to
20
+ type `shinjuku`.
22
21
 
23
22
  Setup makes the wallet on this machine, a private passphrase file, and the
24
23
  checked proof tools (about 191 MB), and writes `config.json`. It also writes
@@ -36,13 +35,13 @@ Every wallet command works after `shinjuku`, for example `shinjuku balance`,
36
35
  Claude Code:
37
36
 
38
37
  ```sh
39
- claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.169 mcp
38
+ claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.170 mcp
40
39
  ```
41
40
 
42
41
  Claude Desktop (`claude_desktop_config.json`) or Cursor (`~/.cursor/mcp.json`):
43
42
 
44
43
  ```json
45
- { "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.169", "mcp"] } } }
44
+ { "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.170", "mcp"] } } }
46
45
  ```
47
46
 
48
47
  On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
@@ -55,7 +54,7 @@ Codex (the Codex app and Codex CLI read the same file, `~/.codex/config.toml`):
55
54
  ```toml
56
55
  [mcp_servers.shinjuku]
57
56
  command = "npx"
58
- args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.169", "mcp"]
57
+ args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.170", "mcp"]
59
58
  startup_timeout_sec = 120
60
59
  tool_timeout_sec = 300
61
60
  ```
@@ -98,8 +97,8 @@ which wallet paid. The wallet keeps no copy of a conversation.
98
97
  ## Needs
99
98
 
100
99
  - Node.js 22.21 or later, or Node.js 24 or later (`node --version` shows yours; a `--tor` run needs `NODE_USE_ENV_PROXY`, which Node.js 23 does not have).
101
- - Linux, or Windows with WSL. macOS is not supported: the provers are Linux
102
- programs.
100
+ - Windows x64 or Linux. macOS is not supported yet: setup says so before it
101
+ asks anything.
103
102
  - Tor, for private AI (and for `--tor`).
104
103
 
105
104
  The package has no install scripts. `node_modules/.bin` and the global npm
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": "9ade26e6a05c6891180751fdd695d76a8fef6376a8636b2c975b622192ac0002",
5
- "bytes": 9313549,
6
- "sourceCommit": "050b7443c989e9dcbd17e5a4037d6e9df3b07fb9",
4
+ "sha256": "1011ea8eb912d2b6cdb1c8b5696e9c9c284ac665033663e9f9d4bf553c7843b1",
5
+ "bytes": 9317658,
6
+ "sourceCommit": "dbf0f5375e0c89869b50535309c9f6dfe90c32d4",
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",
@@ -1038,5 +1038,5 @@
1038
1038
  "version": "1.8.0"
1039
1039
  }
1040
1040
  ],
1041
- "publishedAt": "2026-11-05T05:54:41.608Z"
1041
+ "publishedAt": "2026-11-05T08:02:09.127Z"
1042
1042
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "shinjuku-shielded",
3
- "version": "0.3.169",
3
+ "version": "0.3.170",
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": "9ade26e6",
7
- "shinjukuSha256": "9ade26e6a05c6891180751fdd695d76a8fef6376a8636b2c975b622192ac0002",
6
+ "shinjukuRelease": "1011ea8e",
7
+ "shinjukuSha256": "1011ea8eb912d2b6cdb1c8b5696e9c9c284ac665033663e9f9d4bf553c7843b1",
8
8
  "license": "SEE LICENSE IN LICENSE.txt",
9
9
  "author": "Shinjuku Shielded",
10
10
  "homepage": "https://github.com/ShinjukuStaition/shinjuku-shield#readme",
@@ -54100,7 +54100,7 @@ try {
54100
54100
  });
54101
54101
 
54102
54102
  // wallet/src/setup/config.mjs
54103
- import { execFileSync as execFileSync2 } from "node:child_process";
54103
+ import { execFileSync as execFileSync2, spawnSync as spawnSync3 } from "node:child_process";
54104
54104
  import { randomBytes as randomBytes7 } from "node:crypto";
54105
54105
  import { homedir } from "node:os";
54106
54106
  import { dirname as dirname6, isAbsolute as isAbsolute2, join as join9, resolve as resolve6 } from "node:path";
@@ -54488,7 +54488,7 @@ function hostShellWord(word, platform = process.platform) {
54488
54488
  if (WINDOWS_SHELL_CODE.test(word)) throw new Error("setup_path_unsafe_for_shell: a word holds a character a Windows shell reads as code");
54489
54489
  return `"${word}"`;
54490
54490
  }
54491
- function hostConfigFile(target, { platform = process.platform, env = process.env, home = homedir() } = {}) {
54491
+ function hostConfigFile(target, { platform = process.platform, env = process.env, home = homedir(), claudeRunning = claudeDataDirs } = {}) {
54492
54492
  const set = (name) => typeof env[name] === "string" && env[name].trim() ? env[name].trim() : void 0;
54493
54493
  if (target === "cursor") return join9(home, ".cursor", "mcp.json");
54494
54494
  if (target === "codex") return join9(env.CODEX_HOME || join9(home, ".codex"), "config.toml");
@@ -54506,28 +54506,56 @@ function hostConfigFile(target, { platform = process.platform, env = process.env
54506
54506
  if (target === "gemini") return join9(set("GEMINI_CLI_HOME") ?? home, ".gemini", "settings.json");
54507
54507
  if (target === "antigravity") return join9(home, ".gemini", "config", "mcp_config.json");
54508
54508
  if (target === "claude-desktop") {
54509
- if (platform === "win32") return packagedClaudeDesktopFile(env, home) ?? join9(env.APPDATA || join9(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
54509
+ if (platform === "win32") return windowsClaudeDesktopFile(env, home, claudeRunning);
54510
54510
  if (platform === "darwin") return join9(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
54511
54511
  return join9(env.XDG_CONFIG_HOME || join9(home, ".config"), "Claude", "claude_desktop_config.json");
54512
54512
  }
54513
54513
  return void 0;
54514
54514
  }
54515
- function packagedClaudeDesktopFile(env, home) {
54515
+ function windowsClaudeDesktopFile(env, home, runningDirs) {
54516
+ const roaming = join9(env.APPDATA || join9(home, "AppData", "Roaming"), "Claude", CLAUDE_DESKTOP_FILE);
54517
+ const ambiguous = (files, openApp) => Object.assign(new Error(`setup_host_config_ambiguous: this computer has ${files.length} Claude Desktop settings files (${files.join("; ")}), so the wallet did not pick one`), { files, openApp });
54518
+ const running = runningDirs(env);
54519
+ if (running.length === 1) return join9(running[0], CLAUDE_DESKTOP_FILE);
54520
+ if (running.length > 1) throw ambiguous(running.map((dir) => join9(dir, CLAUDE_DESKTOP_FILE)), false);
54521
+ const dataRoot = join9(env.LOCALAPPDATA || join9(home, "AppData", "Local"), "Claude-Data");
54522
+ let dataDirs = [];
54523
+ try {
54524
+ dataDirs = readdirSync(dataRoot, { withFileTypes: true }).filter((each) => each.isDirectory() && /^claude_[a-z0-9]+$/i.test(each.name)).map((each) => join9(dataRoot, each.name));
54525
+ } catch {
54526
+ dataDirs = [];
54527
+ }
54516
54528
  const packages = join9(env.LOCALAPPDATA || join9(home, "AppData", "Local"), "Packages");
54517
- let names;
54529
+ let packaged = [];
54518
54530
  try {
54519
- names = readdirSync(packages);
54531
+ packaged = readdirSync(packages).filter((each) => /^Claude_[a-z0-9]+$/i.test(each)).map((name) => join9(packages, name, "LocalCache", "Roaming", "Claude", CLAUDE_DESKTOP_FILE));
54520
54532
  } catch {
54521
- return void 0;
54533
+ packaged = [];
54522
54534
  }
54523
- const files = names.filter((each) => /^Claude_[a-z0-9]+$/i.test(each)).map((name) => join9(packages, name, "LocalCache", "Roaming", "Claude", "claude_desktop_config.json")).filter((file) => existsSync(file));
54524
- if (files.length > 1) {
54525
- throw Object.assign(
54526
- new Error(`setup_host_config_ambiguous: this computer has ${files.length} Claude Desktop settings files (${files.join("; ")}), so the wallet did not pick one`),
54527
- { files }
54528
- );
54535
+ const existing = [...dataDirs.map((dir) => join9(dir, CLAUDE_DESKTOP_FILE)), ...packaged, roaming].filter((file) => existsSync(file));
54536
+ if (existing.length === 1) return existing[0];
54537
+ if (existing.length > 1) throw ambiguous(existing, true);
54538
+ if (dataDirs.length > 1) throw ambiguous(dataDirs.map((dir) => join9(dir, CLAUDE_DESKTOP_FILE)), true);
54539
+ return dataDirs.length === 1 ? join9(dataDirs[0], CLAUDE_DESKTOP_FILE) : roaming;
54540
+ }
54541
+ function claudeDataDirs(env) {
54542
+ if (claudeDataDirsCache) return claudeDataDirsCache;
54543
+ const shell = join9(env.SystemRoot || env.SYSTEMROOT || "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
54544
+ const query = `Get-CimInstance Win32_Process -Filter "Name='claude.exe'" | ForEach-Object { $_.CommandLine }`;
54545
+ let text3 = "";
54546
+ try {
54547
+ const result = spawnSync3(shell, ["-NoProfile", "-NonInteractive", "-Command", query], { encoding: "utf8", timeout: 6e3, windowsHide: true });
54548
+ text3 = result.status === 0 ? String(result.stdout ?? "") : "";
54549
+ } catch {
54550
+ text3 = "";
54529
54551
  }
54530
- return files[0];
54552
+ const dirs = /* @__PURE__ */ new Map();
54553
+ for (const match of text3.matchAll(/--user-data-dir=(?:"([^"]+)"|(\S+))/g)) {
54554
+ const dir = resolve6(match[1] ?? match[2]);
54555
+ dirs.set(dir.toLowerCase(), dir);
54556
+ }
54557
+ claudeDataDirsCache = [...dirs.values()];
54558
+ return claudeDataDirsCache;
54531
54559
  }
54532
54560
  function hostConfigText({ home, env = process.env, platform = process.platform, npmVersion, skip = /* @__PURE__ */ new Set(), userHome = homedir() } = {}) {
54533
54561
  const entry = mcpServerEntry({ home, platform, npmVersion });
@@ -55148,7 +55176,7 @@ function changeFileOnce(file, change, { now, platform, restrict, codec = JSON_CO
55148
55176
  }
55149
55177
  return { changed: true, ...backup ? { backup } : {} };
55150
55178
  }
55151
- var import_web396, CONFIG_SCHEMA, CONFIG_FILE, NPM_PACKAGE_NAMES, COMMAND_PACKAGE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, OLD_MCP_SERVER_NAMES, P03_BINDING, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC, HOME_FOLDER, OLDER_HOME_FOLDER, defaultHomeWords, configPath, homeWalletPath, invalid, isPubkey, MAX_OWN_ADDRESSES, isOwnAddressText, salvagePath, clearConfigSalvage, HOST_TARGETS, HOST_NAMES, hostServersKey, hostEntry, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RECOVERY_WORDS, NPX_WALLET_LINE, RELEASES_URL, npmStartEnvironment, NPM_START_KEYS, defaultWalletHome, CMD_UNSAFE, programOf, claudeLineDiffers, WINDOWS_SHELL_CODE, CONTINUE_HEADER, tomlString, tomlKey, codexEntryOf, isPlainObject, sameJson, claudeCodeEntry, READ_ONLY_TOOL_NAMES, claudeCodeAllowRules, claudeCodeSettingsFile, UNREADABLE_JSON, JSON_CODEC, indentAt, TEXT_CODEC, RACED;
55179
+ var import_web396, CONFIG_SCHEMA, CONFIG_FILE, NPM_PACKAGE_NAMES, COMMAND_PACKAGE, NPX_PACKAGE, NPX_INSTALL_FLAGS, MCP_SERVER_NAME, OLD_MCP_SERVER_NAMES, P03_BINDING, PRODUCTION, RETIRED_POOLS, NO_LIMIT_ATOMIC, DEFAULT_CAPS, OLD_DEFAULT_SETUP_CAPS, OLD_DEFAULT_WALLET_BUDGETS, capText, POSITIVE_ATOMIC, HOME_FOLDER, OLDER_HOME_FOLDER, defaultHomeWords, configPath, homeWalletPath, invalid, isPubkey, MAX_OWN_ADDRESSES, isOwnAddressText, salvagePath, clearConfigSalvage, HOST_TARGETS, HOST_NAMES, hostServersKey, hostEntry, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RECOVERY_WORDS, NPX_WALLET_LINE, RELEASES_URL, npmStartEnvironment, NPM_START_KEYS, defaultWalletHome, CMD_UNSAFE, programOf, claudeLineDiffers, WINDOWS_SHELL_CODE, CLAUDE_DESKTOP_FILE, claudeDataDirsCache, CONTINUE_HEADER, tomlString, tomlKey, codexEntryOf, isPlainObject, sameJson, claudeCodeEntry, READ_ONLY_TOOL_NAMES, claudeCodeAllowRules, claudeCodeSettingsFile, UNREADABLE_JSON, JSON_CODEC, indentAt, TEXT_CODEC, RACED;
55152
55180
  var init_config = __esm({
55153
55181
  "wallet/src/setup/config.mjs"() {
55154
55182
  "use strict";
@@ -55240,6 +55268,7 @@ var init_config = __esm({
55240
55268
  programOf = (options) => "claudeProgram" in options ? options.claudeProgram : claudeCodeProgram(options);
55241
55269
  claudeLineDiffers = (options) => claudeProgramWord(programOf(options), "win32", "cmd") !== claudeProgramWord(programOf(options), "win32", "powershell");
55242
55270
  WINDOWS_SHELL_CODE = /[%$`"\r\n]/;
55271
+ CLAUDE_DESKTOP_FILE = "claude_desktop_config.json";
55243
55272
  CONTINUE_HEADER = Object.freeze(["name: Shinjuku Shield", "version: 0.0.1", "schema: v1", "mcpServers:"]);
55244
55273
  tomlString = (value2) => `"${String(value2).replace(/[\\"]/g, (c) => `\\${c}`).replace(/[\u0000-\u001f\u007f]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`)}"`;
55245
55274
  tomlKey = (key) => /^[A-Za-z0-9_-]+$/.test(key) ? key : tomlString(key);
@@ -78320,7 +78349,7 @@ var init_secretFile = __esm({
78320
78349
  });
78321
78350
 
78322
78351
  // wallet/src/cli/commandName.mjs
78323
- import { spawnSync as spawnSync3 } from "node:child_process";
78352
+ import { spawnSync as spawnSync4 } from "node:child_process";
78324
78353
  import { basename as basename4, dirname as dirname15, join as join17 } from "node:path";
78325
78354
  function setCommandVersionSource(source) {
78326
78355
  if (typeof source === "function") versionSource = source;
@@ -78388,9 +78417,9 @@ function terminalUseLinesHere(npmVersion, options = {}) {
78388
78417
  ` ${oneTimeCommandLine("balance", npmVersion)}`
78389
78418
  ];
78390
78419
  }
78391
- function powerShellBlocksScripts({ platform = process.platform, run: run2 = spawnSync3 } = {}) {
78420
+ function powerShellBlocksScripts({ platform = process.platform, run: run2 = spawnSync4 } = {}) {
78392
78421
  if (platform !== "win32") return false;
78393
- if (scriptsBlocked !== null && run2 === spawnSync3) return scriptsBlocked;
78422
+ if (scriptsBlocked !== null && run2 === spawnSync4) return scriptsBlocked;
78394
78423
  let blocked = true;
78395
78424
  try {
78396
78425
  const result = run2(
@@ -78403,7 +78432,7 @@ function powerShellBlocksScripts({ platform = process.platform, run: run2 = spaw
78403
78432
  } catch {
78404
78433
  blocked = true;
78405
78434
  }
78406
- if (run2 === spawnSync3) scriptsBlocked = blocked;
78435
+ if (run2 === spawnSync4) scriptsBlocked = blocked;
78407
78436
  return blocked;
78408
78437
  }
78409
78438
  function powerShellLines(options = {}) {
@@ -105488,6 +105517,19 @@ async function payViaFloat({
105488
105517
  ...verdict?.state === "landed" ? { transferLanded: true } : {}
105489
105518
  });
105490
105519
  }
105520
+ async function finalAfterLanded() {
105521
+ const deadline = Date.now() + FINAL_AFTER_202_MS;
105522
+ const watched = watch.verdict();
105523
+ let state = ["final", "dead", "cancelled", "landed"].includes(watched?.state) ? watched : await readFloatTransferState(record, fetchImpl, Math.min(FLOAT_STATUS_TIMEOUT_MS, FINAL_AFTER_202_MS));
105524
+ while (state?.state === "landed" && Date.now() < deadline) {
105525
+ await sleep5(Math.min(1e3, Math.max(0, deadline - Date.now())));
105526
+ const left = deadline - Date.now();
105527
+ if (left <= 0) break;
105528
+ const next = await readFloatTransferState(record, fetchImpl, Math.min(FLOAT_STATUS_TIMEOUT_MS, left));
105529
+ if (next && !next.unserved) state = next;
105530
+ }
105531
+ return state;
105532
+ }
105491
105533
  async function sellerLeg() {
105492
105534
  let response;
105493
105535
  let accepted;
@@ -105531,7 +105573,7 @@ async function payViaFloat({
105531
105573
  if (stopResends()) break;
105532
105574
  mark(`seller-resend-fee-payer-${resend + 1}`);
105533
105575
  }
105534
- if (response.ok && response.status !== 202) {
105576
+ const paidAnswer = async ({ paidKnown = false, knownTransaction } = {}) => {
105535
105577
  let settled;
105536
105578
  try {
105537
105579
  const encoded = response.headers.get("PAYMENT-RESPONSE") ?? response.headers.get("X-PAYMENT-RESPONSE");
@@ -105543,14 +105585,15 @@ async function payViaFloat({
105543
105585
  try {
105544
105586
  resultBase64 = await readResult(response);
105545
105587
  } catch (error) {
105546
- if (error?.message === "result_too_large_retry_same_request") throw error;
105547
- unanswered2(error);
105588
+ if (paidKnown) {
105589
+ mark("seller-202-body-unread");
105590
+ resultBase64 = "";
105591
+ } else {
105592
+ if (error?.message === "result_too_large_retry_same_request") throw error;
105593
+ unanswered2(error);
105594
+ }
105548
105595
  }
105549
- const receipt = {
105550
- success: true,
105551
- transaction: isSolanaSignature(settled?.transaction) ? settled.transaction : null,
105552
- network: record.requirement.network
105553
- };
105596
+ const receipt = { success: true, transaction: isSolanaSignature(settled?.transaction) ? settled.transaction : isSolanaSignature(knownTransaction) ? knownTransaction : null, network: record.requirement.network };
105554
105597
  const sellerHeaders = keptSellerHeaders(response.headers);
105555
105598
  record = {
105556
105599
  ...record,
@@ -105563,6 +105606,15 @@ async function payViaFloat({
105563
105606
  store.writeWal(walName2, record);
105564
105607
  mark("float-receipt");
105565
105608
  return answered(store, walName2, record, resultBase64, sellerHeaders);
105609
+ };
105610
+ if (response.ok && response.status !== 202) return paidAnswer();
105611
+ let state202;
105612
+ if (response.status === 202) {
105613
+ state202 = await finalAfterLanded();
105614
+ if (state202?.state === "final" || state202?.state === "landed") {
105615
+ mark(`seller-202-${state202.state}`);
105616
+ return paidAnswer({ paidKnown: true, knownTransaction: state202.transaction });
105617
+ }
105566
105618
  }
105567
105619
  const sellerReason = await sellerAnswerText(response);
105568
105620
  if (wasKept) keptAgain(response.status, sellerReason);
@@ -105572,7 +105624,7 @@ async function payViaFloat({
105572
105624
  store.writeWal(walName2, record);
105573
105625
  }
105574
105626
  const watchedNow = watch.verdict();
105575
- const state = ["final", "dead", "cancelled"].includes(watchedNow?.state) ? watchedNow : await readFloatTransferState(record, fetchImpl);
105627
+ const state = response.status === 202 ? state202 : ["final", "dead", "cancelled"].includes(watchedNow?.state) ? watchedNow : await readFloatTransferState(record, fetchImpl);
105576
105628
  if (state?.state === "cancelled") {
105577
105629
  byVerdict(state, {}, { httpStatus: response.status, ...sellerReason ? { sellerReason } : {} });
105578
105630
  }
@@ -105940,7 +105992,7 @@ function paidResult(record, replayed) {
105940
105992
  float: { floatId: record.floatId }
105941
105993
  };
105942
105994
  }
105943
- var import_web3115, FLOAT_PAYMENT_SCHEMA2, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX2, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, FLOAT_MEMO_PATH, FLOAT_STATUS_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_READ_EARLY_MS, REFUND_ETA_MAX_SECONDS, refundDueOf, REFUND_SETTLED_AFTER_MS, REFUND_OUTCOME_NEWS_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, FLOAT_STATUS_START_MS, FLOAT_STATUS_POLL_MS, FLOAT_STATUS_TIMEOUT_MS, FLOAT_TRANSFER_DEAD, FLOAT_PAYMENT_REVERTED, VERDICT_POLL_MS, SELLER_ANSWER_VERDICT_MS, TRANSFER_MIN_BLOCKS_LEFT, TRANSFER_FRESH_MS, BLOCK_HEIGHT_TIMEOUT_MS, CONFIG_TIMEOUT_MS, MEMO_UPLOAD_TIMEOUT_MS, CONFIG_CACHE_MS, FLOAT_POOL_WARM_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash7, fail21, GENERIC_REASON, SELLER_REASON_MAX, SELLER_REASON_READ_BYTES, FEE_PAYER_RESENDS, FEE_PAYER_RESEND_MS, GLOBAL_DISPATCHER4, sortedJson, MODEL_ID, floatPaymentWalName, floatRecordName, FLOAT_KEEP_BYTES_MS, memoryOnlyNeedsScrub, FLOAT_KEEP_OPEN_REQUEST_MS, configCache, configGeneration, configReadSequence, configReads, configRefreshes, SPECULATED_MAX_AGE_MS, speculatedQuotes, poolDomains, FLOAT_FACTS_SCHEMA, floatFacts, floatFactsKey, floatFactsMac, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText, BROADCAST_REFUSED, BROADCAST_REFUSED_STANDARD, BROADCAST_DEAD, TRANSFER_LANDING_WINDOW_MS, PROOF_DELIVERY_MS, SELF_BROADCAST_LEG1_LEFT_MS, BROADCAST_UNSIGNED, BROADCAST_NO_LOOKUP, BROADCAST_LANDED, BROADCAST_LIMIT_MS, BROADCAST_QUOTE_MARGIN_MS, SELF_BROADCAST_RESEND_MS, SELF_BROADCAST_UNANSWERED_RESEND_MS, SELLER_HEADERS_MAX_COUNT, SELLER_HEADERS_MAX_BYTES, SELLER_HEADERS_KEPT;
105995
+ var import_web3115, FLOAT_PAYMENT_SCHEMA2, REGENERATE_CODES, FLOAT_PAYMENT_WAL_PREFIX2, FLOAT_CONFIG_SCHEMA, FLOAT_PAY_PATH, FLOAT_MEMO_PATH, FLOAT_STATUS_PATH, MAX_BODY_BYTES, FLOAT_REFUND_ETA_SECONDS, REFUND_READ_EARLY_MS, REFUND_ETA_MAX_SECONDS, refundDueOf, REFUND_SETTLED_AFTER_MS, REFUND_OUTCOME_NEWS_MS, FINISHING_POLL_MS, FINISHING_LIMIT_MS, SELLER_TIMEOUT_MS, FLOAT_STATUS_START_MS, FLOAT_STATUS_POLL_MS, FLOAT_STATUS_TIMEOUT_MS, FLOAT_TRANSFER_DEAD, FLOAT_PAYMENT_REVERTED, VERDICT_POLL_MS, SELLER_ANSWER_VERDICT_MS, TRANSFER_MIN_BLOCKS_LEFT, TRANSFER_FRESH_MS, BLOCK_HEIGHT_TIMEOUT_MS, CONFIG_TIMEOUT_MS, MEMO_UPLOAD_TIMEOUT_MS, CONFIG_CACHE_MS, FLOAT_POOL_WARM_MS, DECIMAL3, POSITIVE, PENDING_CODES, FLOAT_FRONT_HEADER, hash7, fail21, GENERIC_REASON, SELLER_REASON_MAX, SELLER_REASON_READ_BYTES, FEE_PAYER_RESENDS, FEE_PAYER_RESEND_MS, GLOBAL_DISPATCHER4, sortedJson, MODEL_ID, floatPaymentWalName, floatRecordName, FLOAT_KEEP_BYTES_MS, memoryOnlyNeedsScrub, FLOAT_KEEP_OPEN_REQUEST_MS, configCache, configGeneration, configReadSequence, configReads, configRefreshes, SPECULATED_MAX_AGE_MS, speculatedQuotes, poolDomains, FLOAT_FACTS_SCHEMA, floatFacts, floatFactsKey, floatFactsMac, poolDomainReads, poolDomainWarmFailedAt, WARM_RETRY_MS, payerGenerator, etaEntry, loadPayerGenerator, plainText, BROADCAST_REFUSED, BROADCAST_REFUSED_STANDARD, BROADCAST_DEAD, TRANSFER_LANDING_WINDOW_MS, PROOF_DELIVERY_MS, SELF_BROADCAST_LEG1_LEFT_MS, BROADCAST_UNSIGNED, BROADCAST_NO_LOOKUP, BROADCAST_LANDED, BROADCAST_LIMIT_MS, BROADCAST_QUOTE_MARGIN_MS, SELF_BROADCAST_RESEND_MS, SELF_BROADCAST_UNANSWERED_RESEND_MS, SELLER_HEADERS_MAX_COUNT, SELLER_HEADERS_MAX_BYTES, FINAL_AFTER_202_MS, SELLER_HEADERS_KEPT;
105944
105996
  var init_floatPay = __esm({
105945
105997
  "wallet/src/pay/floatPay.mjs"() {
105946
105998
  "use strict";
@@ -106075,7 +106127,8 @@ var init_floatPay = __esm({
106075
106127
  SELF_BROADCAST_UNANSWERED_RESEND_MS = [2e3, 3e3, 5e3, 1e4, 15e3, 25e3];
106076
106128
  SELLER_HEADERS_MAX_COUNT = 32;
106077
106129
  SELLER_HEADERS_MAX_BYTES = 8 * 1024;
106078
- SELLER_HEADERS_KEPT = /* @__PURE__ */ new Set(["content-type", "content-language", "cache-control", "retry-after", "x-pod-route"]);
106130
+ FINAL_AFTER_202_MS = 2e4;
106131
+ SELLER_HEADERS_KEPT = /* @__PURE__ */ new Set(["content-type", "content-language", "cache-control", "retry-after", "x-pod-route", "location", "content-location"]);
106079
106132
  }
106080
106133
  });
106081
106134
 
@@ -112429,7 +112482,11 @@ async function paidCall({ session, target, method, headers, body, cap, maxPrice,
112429
112482
  replayed: result.replayed === true,
112430
112483
  receiptFinality: result.receiptFinality ?? null
112431
112484
  };
112432
- return new Response(bytes2, { status: 200, headers: paidResponseHeaders(result.sellerHeaders, sniffContentType(bytes2), payment) });
112485
+ const status = Number.isInteger(result.status) && result.status >= 200 && result.status <= 299 ? result.status : 200;
112486
+ return new Response(
112487
+ status === 204 || status === 205 ? null : bytes2,
112488
+ { status, headers: paidResponseHeaders(result.sellerHeaders, sniffContentType(bytes2), payment) }
112489
+ );
112433
112490
  } catch (error) {
112434
112491
  const failure3 = error !== null && typeof error === "object" ? error : Object.assign(new Error(String(error)), { cause: error });
112435
112492
  try {
@@ -125992,7 +126049,7 @@ var init_addFunds = __esm({
125992
126049
  });
125993
126050
 
125994
126051
  // wallet/src/setup/backup.mjs
125995
- import { execFileSync as execFileSync3, spawnSync as spawnSync4 } from "node:child_process";
126052
+ import { execFileSync as execFileSync3, spawnSync as spawnSync5 } from "node:child_process";
125996
126053
  import { createHash as createHash28, randomBytes as randomBytes24, randomInt as randomInt6 } from "node:crypto";
125997
126054
  import { homedir as homedir2, userInfo } from "node:os";
125998
126055
  import { basename as basename7, dirname as dirname28, extname, isAbsolute as isAbsolute7, join as join30, posix, resolve as resolve25 } from "node:path";
@@ -126042,7 +126099,7 @@ function backupPlaces({ platform = process.platform, env = process.env } = {}) {
126042
126099
  const places = [];
126043
126100
  if (platform === "win32") {
126044
126101
  try {
126045
- const result = spawnSync4(
126102
+ const result = spawnSync5(
126046
126103
  "powershell.exe",
126047
126104
  [
126048
126105
  "-NoProfile",
@@ -126127,7 +126184,7 @@ function cloudRoots({ platform = process.platform, env = process.env, home = hom
126127
126184
  for (const name of ["OneDrive", "OneDriveConsumer", "OneDriveCommercial"]) add2(env[name], "OneDrive");
126128
126185
  add2(join30(env.USERPROFILE ?? home, "OneDrive"), "OneDrive");
126129
126186
  try {
126130
- const result = spawnSync4(
126187
+ const result = spawnSync5(
126131
126188
  "reg.exe",
126132
126189
  ["query", "HKCU\\Software\\Microsoft\\OneDrive\\Accounts", "/s", "/v", "UserFolder"],
126133
126190
  { windowsHide: true, encoding: "utf8", timeout: 1e4 }
@@ -126393,7 +126450,7 @@ function systemLink(path, stat2, platform) {
126393
126450
  }
126394
126451
  function windowsDriveType(letter) {
126395
126452
  try {
126396
- const result = spawnSync4(
126453
+ const result = spawnSync5(
126397
126454
  "powershell.exe",
126398
126455
  ["-NoProfile", "-NonInteractive", "-Command", "([System.IO.DriveInfo]::new($env:SHINJUKU_DRIVE + ':\\')).DriveType.ToString()"],
126399
126456
  { windowsHide: true, encoding: "utf8", timeout: 1e4, env: { ...process.env, SHINJUKU_DRIVE: letter } }
@@ -126426,9 +126483,9 @@ function restrictFolderToOwner(folder, platform) {
126426
126483
  const line = String(execFileSync3(join30(system32, "whoami.exe"), ["/user", "/fo", "csv", "/nh"], { encoding: "utf8", windowsHide: true }));
126427
126484
  const sid = line.match(/"(S-1-[0-9-]+)"/)?.[1];
126428
126485
  if (!sid) return "open";
126429
- const result = spawnSync4(join30(system32, "icacls.exe"), [folder, "/inheritance:r", "/grant:r", `*${sid}:(OI)(CI)F`], { windowsHide: true, encoding: "utf8" });
126486
+ const result = spawnSync5(join30(system32, "icacls.exe"), [folder, "/inheritance:r", "/grant:r", `*${sid}:(OI)(CI)F`], { windowsHide: true, encoding: "utf8" });
126430
126487
  if (result.status !== 0) return "open";
126431
- const read = spawnSync4(
126488
+ const read = spawnSync5(
126432
126489
  join30(system32, "WindowsPowerShell", "v1.0", "powershell.exe"),
126433
126490
  [
126434
126491
  "-NoProfile",
@@ -131281,7 +131338,7 @@ function floatRefusal(error, overLimit, tool = "x402_pay") {
131281
131338
  overLimit,
131282
131339
  ...inference ? { ai: {
131283
131340
  // After "if it is refused again, " too (floatWords lowercases it there), so the condition comes last.
131284
- other: "Try again later, or pass a different model (inference_chat with no prompt lists them), if the user still wants an answer",
131341
+ other: "Try again later, or pass a different model (inference_models lists them), if the user still wants an answer",
131285
131342
  setup: `tell the user to run ${terminalCommand2("setup")} once in a terminal, then reconnect the wallet (${RESTART_STEPS})`
131286
131343
  } } : {}
131287
131344
  });
@@ -134671,7 +134728,7 @@ ${canonical5}`;
134671
134728
  return refuse12(
134672
134729
  code2,
134673
134730
  `${payee} asks a price of zero or less, which is not a payment, so this wallet does not pay it; nothing was paid`,
134674
- inference ? `Nothing was paid. Tell the user the AI provider asked a price of zero or less, which this wallet does not pay. Do not call ${tool} again unchanged; ask again later, or pick another model (inference_chat with no prompt lists them)` : "Nothing was paid. Tell the user this seller asks a price of zero or less, which this wallet does not pay. Do not retry this URL unchanged; x402_discover finds sellers this wallet can pay",
134731
+ inference ? `Nothing was paid. Tell the user the AI provider asked a price of zero or less, which this wallet does not pay. Do not call ${tool} again unchanged; ask again later, or pick another model (inference_models lists them)` : "Nothing was paid. Tell the user this seller asks a price of zero or less, which this wallet does not pay. Do not retry this URL unchanged; x402_discover finds sellers this wallet can pay",
134675
134732
  { requestId, paid: false }
134676
134733
  );
134677
134734
  } else if (code2 === "fetch_seller_unreachable") {
@@ -140803,8 +140860,12 @@ ${canonical5}`;
140803
140860
  title: "List the private inference models and prices",
140804
140861
  description: "Read only, free, moves nothing: the AI models inference_chat can call (through the AI provider, paid privately from the private balance), each with its price per 1M input and output tokens in USDC atomic units (1000000 = $1). Models today include claude-opus-5, deepseek-v4-1-flash, and qwen3-8-flash; use the ids this tool returns. " + INFERENCE_COST_WORDS + `. The answer also says whether this server can call inference_chat now (it needs Tor or the wallet's own proxy). Call it before inference_chat to choose a model and a max_tokens (the answer's length limit; at least ${INFERENCE_MIN_MAX_TOKENS}).`,
140805
140862
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
140806
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
140807
- hidden: true,
140863
+ // openWorldHint true (Codex round 1 on c4adc23c): the list reads the AI provider's own model list (inference/liveModels.mjs
140864
+ // servedModels, api.usepod.ai over this server's Tor or proxy).
140865
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
140866
+ // F7 (a live run, npm 0.3.169, Claude Code auto mode, 2026-11-05 07:00 UTC): listed again. Hidden since the 10-listed-tools
140867
+ // trim (356163fe, 2026-10-20: inference_chat with no prompt listed the models), so "which AI models" went to the tool
140868
+ // that pays, and Claude Code's auto mode blocked it as a real-world transaction. This tool is read only and free.
140808
140869
  // args: inference_chat's model and max_tokens when it is called with no prompt (the call the price is for).
140809
140870
  async run(args = {}) {
140810
140871
  const inference = await inferenceModule();
@@ -140913,7 +140974,7 @@ ${canonical5}`;
140913
140974
  ],
140914
140975
  inference_model_unknown: [
140915
140976
  "that model id is not one the AI provider serves through this wallet",
140916
- "call inference_chat with no prompt or messages (it lists the model ids, free), then pass one of its ids, for example qwen3-8-flash or claude-opus-5"
140977
+ "call inference_models (it lists the model ids, free), then pass one of its ids, for example qwen3-8-flash or claude-opus-5"
140917
140978
  ],
140918
140979
  inference_messages_invalid: [
140919
140980
  "messages must be a non-empty list of { role, content } with role system, user, or assistant and content text",
@@ -140924,10 +140985,10 @@ ${canonical5}`;
140924
140985
  // row stands only behind that check. Its steps fit under any limit (a higher max_payment can be above the user's own).
140925
140986
  inference_ceiling_over_cap: [
140926
140987
  "this call's ceiling is above the most this call may pay",
140927
- "lower max_tokens (the answer's length limit), or pick a cheaper model (inference_chat with no prompt lists them)"
140988
+ "lower max_tokens (the answer's length limit), or pick a cheaper model (inference_models lists them)"
140928
140989
  ],
140929
- inference_upstream_failed: ["the AI provider did not answer with a chat completion", "try again later, or pass a different model (inference_chat with no prompt lists them)"],
140930
- inference_response_invalid: ["the AI provider's answer could not be read", "try again later, or pass a different model (inference_chat with no prompt lists them)"],
140990
+ inference_upstream_failed: ["the AI provider did not answer with a chat completion", "try again later, or pass a different model (inference_models lists them)"],
140991
+ inference_response_invalid: ["the AI provider's answer could not be read", "try again later, or pass a different model (inference_models lists them)"],
140931
140992
  inference_temperature_invalid: ["temperature must be a number from 0 to 2", "pass temperature 0.7, or leave it out"],
140932
140993
  inference_max_payment_invalid: [
140933
140994
  "the max_payment_atomic argument must be a whole number of atomic units above 0",
@@ -140953,7 +141014,7 @@ ${canonical5}`;
140953
141014
  }
140954
141015
  );
140955
141016
  }
140956
- const known = INFERENCE_REFUSALS[code2] ?? ["the AI provider could not answer this call", "try again later, or pass a different model (inference_chat with no prompt lists them)"];
141017
+ const known = INFERENCE_REFUSALS[code2] ?? ["the AI provider could not answer this call", "try again later, or pass a different model (inference_models lists them)"];
140957
141018
  const detail = typeof error.detail === "string" && error.detail ? error.detail : `${known[0]}; nothing was paid`;
140958
141019
  const next = typeof error.next === "string" && error.next && code2 !== "inference_ceiling_over_cap" ? error.next : known[1];
140959
141020
  return refuse12(code2, detail, next, { ...extra, paid: false });
@@ -140961,11 +141022,11 @@ ${canonical5}`;
140961
141022
  const inferenceChat2 = {
140962
141023
  name: "inference_chat",
140963
141024
  title: "Ask an AI model, paid privately",
140964
- description: `Use this when the user wants an AI model's answer paid from the PRIVATE balance: it calls the AI provider's paid chat service (the AI provider picks the model's provider) and pays it privately (the chain does not show which wallet paid); use this tool, not x402_pay, for AI answers. Only prompt (or messages) is needed: model defaults to qwen3-8-flash and max_tokens to 4096 (512 for claude-opus-5). max_tokens is the answer's length limit, in tokens: tell the user "the answer's length limit", never the field name. Called with neither prompt nor messages, it lists the models and their prices and pays nothing (for example qwen3-8-flash, deepseek-v4-1-flash, claude-opus-5). COST: ${INFERENCE_COST_WORDS}. The total paid is never above the cap, and a larger cap never pays more. What max_tokens does not use is NOT refunded when the answer is shorter. max_tokens must be at least ${INFERENCE_MIN_MAX_TOKENS} (a reasoning model spends its first tokens thinking). Example: { "prompt": "Name three prime numbers" }. PRIVACY: the AI provider and the company that runs the model see the prompt and the answer; never put keys, passphrases, or secrets in it. It runs only when this wallet runs over Tor or its own proxy (else inference_tor_required, nothing paid), so they never see this machine's IP. The same caps as x402_pay apply (max_payment can lower the per-payment limit). When max_payment or what the call can cost is above that limit and this app can ask the user, the wallet asks the user once to allow this one call; else the answer says the cost and the limit. On an error code that ends in _retry_same_request, call inference_chat again with the SAME request_id and arguments: it never pays twice. No streaming.`,
141025
+ description: `Use this when the user wants an AI model's answer paid from the PRIVATE balance: it calls the AI provider's paid chat service (the AI provider picks the model's provider) and pays it privately (the chain does not show which wallet paid); use this tool, not x402_pay, for AI answers. Only prompt (or messages) is needed: model defaults to qwen3-8-flash and max_tokens to 4096 (512 for claude-opus-5). max_tokens is the answer's length limit, in tokens: tell the user "the answer's length limit", never the field name. To list the models and their prices (which models, what each costs), call inference_models, not this tool: it is read only and pays nothing (for example qwen3-8-flash, deepseek-v4-1-flash, claude-opus-5). COST: ${INFERENCE_COST_WORDS}. The total paid is never above the cap, and a larger cap never pays more. What max_tokens does not use is NOT refunded when the answer is shorter. max_tokens must be at least ${INFERENCE_MIN_MAX_TOKENS} (a reasoning model spends its first tokens thinking). Example: { "prompt": "Name three prime numbers" }. PRIVACY: the AI provider and the company that runs the model see the prompt and the answer; never put keys, passphrases, or secrets in it. It runs only when this wallet runs over Tor or its own proxy (else inference_tor_required, nothing paid), so they never see this machine's IP. The same caps as x402_pay apply (max_payment can lower the per-payment limit). When max_payment or what the call can cost is above that limit and this app can ask the user, the wallet asks the user once to allow this one call; else the answer says the cost and the limit. On an error code that ends in _retry_same_request, call inference_chat again with the SAME request_id and arguments: it never pays twice. No streaming.`,
140965
141026
  inputSchema: {
140966
141027
  type: "object",
140967
141028
  properties: {
140968
- model: { type: "string", description: "Optional, default qwen3-8-flash. A model id (inference_chat with no prompt lists them)." },
141029
+ model: { type: "string", description: "Optional, default qwen3-8-flash. A model id (inference_models lists them)." },
140969
141030
  messages: { type: "array", items: {
140970
141031
  type: "object",
140971
141032
  properties: { role: { type: "string", enum: ["system", "user", "assistant"] }, content: { type: "string" } },
@@ -141033,7 +141094,7 @@ ${canonical5}`;
141033
141094
  return inferenceRefusal(error) ?? refuse12(
141034
141095
  "inference_messages_invalid",
141035
141096
  "the model, messages, or max_tokens could not be priced; nothing was paid",
141036
- "pass messages (or prompt) and max_tokens, for example 256; with neither, inference_chat lists the model ids"
141097
+ "pass messages (or prompt) and max_tokens, for example 256; inference_models lists the model ids"
141037
141098
  );
141038
141099
  }
141039
141100
  const target = checkUrl(inference.USEPOD_X402_CHAT_URL);
@@ -141081,7 +141142,7 @@ ${canonical5}`;
141081
141142
  const canAsk = client?.canElicit?.();
141082
141143
  const needed = ceiling + SHINJUKU_FEE_ATOMIC;
141083
141144
  const over = overLimitStep(needed, launch, canAsk);
141084
- const smaller = `lower max_tokens (the answer's length limit; at least ${INFERENCE_MIN_MAX_TOKENS}), pick a cheaper model (inference_chat with no prompt lists them)`;
141145
+ const smaller = `lower max_tokens (the answer's length limit; at least ${INFERENCE_MIN_MAX_TOKENS}), pick a cheaper model (inference_models lists them)`;
141085
141146
  const higher = `pass max_payment "${usdcText3(needed)}" (the ceiling plus the fee)`;
141086
141147
  return refuse12(
141087
141148
  "inference_ceiling_over_cap",
@@ -141117,7 +141178,7 @@ ${canonical5}`;
141117
141178
  });
141118
141179
  if (!asked2.ok && asked2.why !== "unsupported") return notAllowed(asked2.why, { tool: "inference_chat", requestId, numbers }, facts);
141119
141180
  if (!asked2.ok) {
141120
- const fix = "lower max_tokens (the answer's length limit) or pick a cheaper model (inference_chat with no prompt lists them) to fit the limit";
141181
+ const fix = "lower max_tokens (the answer's length limit) or pick a cheaper model (inference_models lists them) to fit the limit";
141121
141182
  const limited = refuse12(
141122
141183
  "inference_ceiling_over_cap",
141123
141184
  detail,
@@ -141181,7 +141242,7 @@ ${canonical5}`;
141181
141242
  return refuse12(
141182
141243
  "fetch_price_over_ceiling",
141183
141244
  `the AI provider asked ${asked2 ? `${usdcText3(asked2)} USDC` : "more"}, above this call's ceiling of ${usdcText3(ceiling)} USDC; nothing was paid`,
141184
- "the AI provider asked more than this call's ceiling; call inference_chat with no prompt for the current prices and try again, or lower max_tokens",
141245
+ "the AI provider asked more than this call's ceiling; call inference_models for the current prices and try again, or lower max_tokens",
141185
141246
  { requestId, paid: false, ...facts, ...asked2 ? { askedAtomic: asked2 } : {} }
141186
141247
  );
141187
141248
  }
@@ -141982,7 +142043,7 @@ function createSetupTools({
141982
142043
  ...privateInference ? { privateInference: true } : {},
141983
142044
  ...current.userAddress?.saved ? { unshieldTo: current.userAddress.saved } : {},
141984
142045
  ...current.userAddress?.notSaved ? { ownWalletAddressNotSaved: current.userAddress.notSaved } : {},
141985
- next: `${ACCEPTED_NEXT}The wallet tools are live in this server: the tool list changed (the setup tools are gone, wallet_status included; wallet_balance answers it). This is not a disconnect: do not tell the user to restart or reconnect. Call wallet_balance.${recoveryNext(summary)}` + userAddressNext(current.userAddress) + (limitLine && !say3.includes(limitLine) ? ` No spending limit is set: tell the user "${limitLine}"${/restart/.test(limitLine) ? " (the restart is only for after that command)" : ""}.` : "") + (summary.tor === true ? " Setup ran over Tor, and the wallet runs over Tor: the servers it talks to do not see this computer's IP address." : "") + ` To add funds, call wallet_add_funds: it gives a one-time address for any amount from 0.01 USDC. After the user sends USDC there, ${SAFE_BALANCE_READ}.` + (privateInference ? " Private inference is on: after funding, call inference_chat (with no prompt it lists the models and prices); if this app's wallet entry turns Tor off, inference_chat refuses until the user removes that setting there and reconnects the wallet, so it runs behind Tor." : "") + ` Tell the user plainly: "${HOST_CHAT_NOT_PRIVATE}"` + commandPathNext(summary.commandPath)
142046
+ next: `${ACCEPTED_NEXT}The wallet tools are live in this server: the tool list changed (the setup tools are gone, wallet_status included; wallet_balance answers it). This is not a disconnect: do not tell the user to restart or reconnect. Call wallet_balance.${recoveryNext(summary)}` + userAddressNext(current.userAddress) + (limitLine && !say3.includes(limitLine) ? ` No spending limit is set: tell the user "${limitLine}"${/restart/.test(limitLine) ? " (the restart is only for after that command)" : ""}.` : "") + (summary.tor === true ? " Setup ran over Tor, and the wallet runs over Tor: the servers it talks to do not see this computer's IP address." : "") + ` To add funds, call wallet_add_funds: it gives a one-time address for any amount from 0.01 USDC. After the user sends USDC there, ${SAFE_BALANCE_READ}.` + (privateInference ? " Private inference is on: after funding, call inference_chat (inference_models lists the models and prices); if this app's wallet entry turns Tor off, inference_chat refuses until the user removes that setting there and reconnects the wallet, so it runs behind Tor." : "") + ` Tell the user plainly: "${HOST_CHAT_NOT_PRIVATE}"` + commandPathNext(summary.commandPath)
141986
142047
  });
141987
142048
  }
141988
142049
  if (current.state === "confirming") return json4({ say: SETUP_CONFIRMING_SAY, ok: true, stage: "confirming", next: SETUP_CONFIRMING_NEXT });
@@ -142226,7 +142287,7 @@ function createSetupTools({
142226
142287
  wallet_transfer_token: "Sells a Solana token this wallet holds for USDC and sends that USDC privately to an address.",
142227
142288
  wallet_transfer_token_status: "Shows how a token sale and send goes, and can stop it.",
142228
142289
  inference_server: "Starts a private AI address on this computer for another AI app (an OpenAI-compatible base URL and key): each AI answer is paid privately from the private balance.",
142229
- inference_chat: "Asks an AI model and pays for its answer privately from the private balance; with no prompt it lists the models and their prices."
142290
+ inference_chat: "Asks an AI model and pays for its answer privately from the private balance (inference_models lists the models and their prices)."
142230
142291
  };
142231
142292
  const notSetUp2 = (name) => ({
142232
142293
  name,
@@ -142452,7 +142513,7 @@ var init_tools = __esm({
142452
142513
  return capAtomic !== void 0 && day !== void 0 && String(day) !== NO_LIMIT_ATOMIC && String(capAtomic) === String(day) ? "--max-session" : "--max-payment";
142453
142514
  };
142454
142515
  noPriceFits = (roomAtomic) => ATOMIC_TEXT.test(String(roomAtomic ?? "")) && BigInt(roomAtomic) <= SHINJUKU_FEE_ATOMIC;
142455
- cheaperText = (tool, roomAtomic) => noPriceFits(roomAtomic) ? "" : tool === "inference_chat" ? " Or lower max_tokens (the answer's length limit) or pick a cheaper model (inference_chat with no prompt lists them)." : " Or call x402_discover to look for a cheaper seller of the same data.";
142516
+ cheaperText = (tool, roomAtomic) => noPriceFits(roomAtomic) ? "" : tool === "inference_chat" ? " Or lower max_tokens (the answer's length limit) or pick a cheaper model (inference_models lists them)." : " Or call x402_discover to look for a cheaper seller of the same data.";
142456
142517
  limitNext = ({ totalAtomic, capAtomic } = {}, { flag: flag3 = payCapFlag(capAtomic), verb = "paid", noun = "costs", tool } = {}) => `${totalAtomic && capAtomic ? `Nothing was ${verb}. Tell the user: this ${noun} ${usdcText3(totalAtomic)} USDC and the ${capName(flag3)} is ${usdcText3(capAtomic)} USDC.` : `Nothing was ${verb}. Tell the user this is above the ${capName(flag3)}.`} ${capRaiseText(flag3)}${verb === "paid" ? cheaperText(tool, capAtomic) : ""}`;
142457
142518
  overLimitStep = (neededAtomic, launchAtomic, canAsk) => {
142458
142519
  if (launchAtomic === void 0 || BigInt(neededAtomic) <= BigInt(launchAtomic)) return void 0;
@@ -142829,7 +142890,6 @@ var init_tools = __esm({
142829
142890
  "wallet_pay_me_status",
142830
142891
  "wallet_unshield_cancel",
142831
142892
  "wallet_move_status",
142832
- "inference_models",
142833
142893
  "wallet_receive_shielded"
142834
142894
  ]);
142835
142895
  setupTerminalNext = () => `Tell the user to run ${terminalCommand2("setup", { code: true })} in a terminal on this machine, then reconnect the wallet (${RESTART_STEPS})`;
@@ -144334,7 +144394,7 @@ var init_stdioServer = __esm({
144334
144394
  SUPPORTED_PROTOCOL_VERSIONS = Object.freeze(["2025-06-18", "2025-03-26", "2024-11-05"]);
144335
144395
  MAX_LINE_BYTES = 4 * 1024 * 1024;
144336
144396
  POSITIVE_ATOMIC7 = /^[1-9][0-9]{0,30}$/;
144337
- INSTRUCTIONS_BASE = `A self-custody Shinjuku Shield wallet on this machine; no tool takes or returns its keys or passphrase. Each answer's say is one plain sentence for the user; other fields hold numbers. Never tell the user a tool, field, code or protocol name (x402, MCP) unless told to. Map a plain request to one tool: "what is my balance" -> wallet_balance (safe at any time); "add money" / "deposit" / "move USDC in from Phantom or an exchange" -> wallet_add_funds (a one-time address; the next wallet_balance after the USDC arrives makes it private, up to 5 USDC); "shield the USDC on this wallet's own address" -> wallet_shield; "stop" / "cancel" -> wallet_cancel (the request_id of what to stop); "pay this URL" -> x402_pay (no preview needed); "what does this URL cost" -> x402_preview (only when asked); "find a paid API for X" -> x402_discover, then x402_pay on its url; "send 2 USDC to <address>" -> wallet_unshield; "show my payments" -> wallet_receipts; "send another token" -> wallet_transfer_token; "ask an AI model" / "which AI models" -> inference_chat (no prompt: it lists models and prices); "give my other AI app a private AI" -> inference_server (a local OpenAI-compatible URL and key). wallet_balance answers ONE balance (balanceAtomic); x402_pay pays any paid URL from it (a seller that cannot take a private payment is paid through Shinjuku; max_payment covers amountAtomic with fee). Fields ending in Atomic are atomic units (1000000 = 1 USDC); tell the user USDC. The wallet does its own upkeep (no user command). A shield, add-funds or unshield call can run for minutes: call again with the SAME request_id as next says. Pass your own request_id to x402_pay: the same one never pays or moves money twice (a code ending in _retry_same_request: call again with it). A wallet_unshield send to an address not approved ahead asks the user to confirm. x402_pay never pays above the spending limits (one payment; 24 hours); with none, the balance is the only bound. Never claim a payment happened unless the answer has a transaction. Privacy: the chain does not show which wallet paid, but this app and its model provider see every URL, body, price and answer you handle; reach a seller or its domain only through these tools, never yourself (no curl, browser, DNS or DNS-over-HTTPS lookup), also when the user asks for no Tor: that shows their IP address to the site or a DNS company. When an answer's poolSwitch.items[] item has tellUser true, tell the user its message once, in plain words; the wallet moves the balance by itself.`;
144397
+ INSTRUCTIONS_BASE = `A self-custody Shinjuku Shield wallet on this machine; no tool takes or returns its keys or passphrase. Each answer's say is one plain sentence for the user; other fields hold numbers. Never tell the user a tool, field, code or protocol name (x402, MCP) unless told to. Map a plain request to one tool: "what is my balance" -> wallet_balance (safe at any time); "add money" / "deposit" / "move USDC in from Phantom or an exchange" -> wallet_add_funds (a one-time address; the next wallet_balance after the USDC arrives makes it private, up to 5 USDC); "shield the USDC on this wallet's own address" -> wallet_shield; "stop" / "cancel" -> wallet_cancel (the request_id of what to stop); "pay this URL" -> x402_pay (no preview needed); "what does this URL cost" -> x402_preview (only when asked); "find a paid API for X" -> x402_discover, then x402_pay on its url; "send 2 USDC to <address>" -> wallet_unshield; "show my payments" -> wallet_receipts; "send another token" -> wallet_transfer_token; "which AI models" -> inference_models; "ask an AI model" -> inference_chat; "give my other AI app a private AI" -> inference_server (a local OpenAI-compatible URL and key). wallet_balance answers ONE balance (balanceAtomic); x402_pay pays any paid URL from it (a seller that cannot take a private payment is paid through Shinjuku; max_payment covers amountAtomic with fee). Fields ending in Atomic are atomic units (1000000 = 1 USDC); tell the user USDC. The wallet does its own upkeep (no user command). A shield, add-funds or unshield call can run for minutes: call again with the SAME request_id as next says. Pass your own request_id to x402_pay: the same one never pays or moves money twice (a code ending in _retry_same_request: call again with it). A wallet_unshield send to an address not approved ahead asks the user to confirm. x402_pay never pays above the spending limits (one payment; 24 hours); with none, the balance is the only bound. Never claim a payment happened unless the answer has a transaction. Privacy: the chain does not show which wallet paid, but this app and its model provider see every URL, body, price and answer you handle; reach a seller or its domain only through these tools, never yourself (no curl, browser, DNS or DNS-over-HTTPS lookup), also when the user asks for no Tor: that shows their IP address to the site or a DNS company. When an answer's poolSwitch.items[] item has tellUser true, tell the user its message once, in plain words; the wallet moves the balance by itself.`;
144338
144398
  SELL_LINE = "To sell or swap a token the wallet holds: wallet_transfer_token.";
144339
144399
  OWN_ADDRESS_LINE = '"Send to my (main) wallet": wallet_unshield with no to uses the address saved at setup; never ask for it.';
144340
144400
  INSTRUCTIONS = `${INSTRUCTIONS_BASE} ${SELL_LINE} ${OWN_ADDRESS_LINE} ${HOST_BLOCKED_LINE}`;
@@ -145210,7 +145270,7 @@ var init_serve = __esm({
145210
145270
 
145211
145271
  // wallet/src/inference/serveRunner.mjs
145212
145272
  import { randomBytes as randomBytes28 } from "node:crypto";
145213
- import { spawn as spawn6, spawnSync as spawnSync5 } from "node:child_process";
145273
+ import { spawn as spawn6, spawnSync as spawnSync6 } from "node:child_process";
145214
145274
  import { dirname as dirname31, join as join35, resolve as resolve29 } from "node:path";
145215
145275
  function writeAtomic4(path, text3) {
145216
145276
  const temp = `${path}.${randomBytes28(4).toString("hex")}.tmp`;
@@ -145480,7 +145540,7 @@ function logFailureLine(logPath, offset) {
145480
145540
  function endLaunched(pid, platform) {
145481
145541
  if (!pidAlive2(pid)) return;
145482
145542
  try {
145483
- if (platform === "win32") spawnSync5("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true, timeout: 1e4 });
145543
+ if (platform === "win32") spawnSync6("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true, timeout: 1e4 });
145484
145544
  else {
145485
145545
  try {
145486
145546
  process.kill(-pid, "SIGKILL");
@@ -149188,7 +149248,7 @@ var init_torMissingMcp = __esm({
149188
149248
  // wallet/src/seller/setup.mjs
149189
149249
  import http2 from "node:http";
149190
149250
  import { createHash as createHash36, randomBytes as randomBytes33 } from "node:crypto";
149191
- import { spawnSync as spawnSync9 } from "node:child_process";
149251
+ import { spawnSync as spawnSync10 } from "node:child_process";
149192
149252
  import { join as join43, resolve as resolve38 } from "node:path";
149193
149253
  function separateSellerHome(env, userHome) {
149194
149254
  return env.SHIELDED_WALLET_HOME ? `${resolve38(env.SHIELDED_WALLET_HOME)}-seller` : join43(userHome, ".shinjuku-shield-seller");
@@ -149559,7 +149619,7 @@ async function setUpWith({ values, deps, terminal, say: say3, home, wallet, make
149559
149619
  }
149560
149620
  say3("Making a new wallet for your sales...");
149561
149621
  const torRun = network?.tor === true ? ["--tor", "--proxy", network.tunnel] : [];
149562
- const made = spawnSync9(
149622
+ const made = spawnSync10(
149563
149623
  process.execPath,
149564
149624
  [
149565
149625
  ...process.execArgv,
@@ -150860,7 +150920,7 @@ init_fs();
150860
150920
  init_processLock();
150861
150921
  init_config();
150862
150922
  init_proofTools();
150863
- import { spawnSync as spawnSync6 } from "node:child_process";
150923
+ import { spawnSync as spawnSync7 } from "node:child_process";
150864
150924
  import { dirname as dirname32, join as join37, resolve as resolve33 } from "node:path";
150865
150925
  var NATIVE_SET_MOVE_FILE = "setup-files-move.json";
150866
150926
  function nativeSetMoveRecord(home) {
@@ -150903,7 +150963,7 @@ function processIdentity(pid) {
150903
150963
  if (!pidAlive3(pid)) return void 0;
150904
150964
  try {
150905
150965
  if (process.platform === "win32") {
150906
- const result2 = spawnSync6(
150966
+ const result2 = spawnSync7(
150907
150967
  "powershell.exe",
150908
150968
  [
150909
150969
  "-NoProfile",
@@ -150916,7 +150976,7 @@ function processIdentity(pid) {
150916
150976
  const [started2, ...rest] = String(result2.stdout ?? "").split(/\r?\n/);
150917
150977
  return /^\d+$/.test(started2.trim()) ? { startedMs: Number(started2.trim()), commandLine: rest.join(" ") } : void 0;
150918
150978
  }
150919
- const result = spawnSync6("ps", ["-o", "lstart=", "-o", "args=", "-p", String(Number(pid))], { encoding: "utf8", timeout: 1e4, env: { ...process.env, LC_ALL: "C" } });
150979
+ const result = spawnSync7("ps", ["-o", "lstart=", "-o", "args=", "-p", String(Number(pid))], { encoding: "utf8", timeout: 1e4, env: { ...process.env, LC_ALL: "C" } });
150920
150980
  const line = String(result.stdout ?? "").trim();
150921
150981
  const started = Date.parse(line.slice(0, 24));
150922
150982
  return Number.isFinite(started) ? { startedMs: started, commandLine: line.slice(24) } : void 0;
@@ -151060,8 +151120,8 @@ init_errorCodes();
151060
151120
  init_errorLine();
151061
151121
  init_cli();
151062
151122
  import { createInterface as createInterface2 } from "node:readline";
151063
- import { homedir as homedir4, tmpdir as tmpdir6 } from "node:os";
151064
- import { spawnSync as spawnSync10 } from "node:child_process";
151123
+ import { homedir as homedir5, tmpdir as tmpdir6 } from "node:os";
151124
+ import { spawnSync as spawnSync11 } from "node:child_process";
151065
151125
 
151066
151126
  // wallet/src/merge/cli.mjs
151067
151127
  init_fs();
@@ -155332,7 +155392,7 @@ init_fs();
155332
155392
  init_proxy();
155333
155393
  init_config();
155334
155394
  init_processLock();
155335
- import { spawn as spawn11, spawnSync as spawnSync7 } from "node:child_process";
155395
+ import { spawn as spawn11, spawnSync as spawnSync8 } from "node:child_process";
155336
155396
  import { createHash as createHash35, createHmac as createHmac10, randomBytes as randomBytes32, timingSafeEqual as timingSafeEqual4 } from "node:crypto";
155337
155397
  import net3 from "node:net";
155338
155398
  import { join as join41 } from "node:path";
@@ -155374,7 +155434,7 @@ var pidAlive4 = (pid) => {
155374
155434
  function processOf(pid) {
155375
155435
  if (!pidAlive4(pid)) return void 0;
155376
155436
  try {
155377
- const result = spawnSync7(
155437
+ const result = spawnSync8(
155378
155438
  "powershell.exe",
155379
155439
  [
155380
155440
  "-NoProfile",
@@ -155398,7 +155458,7 @@ function isOwnTor(home, state) {
155398
155458
  }
155399
155459
  function stopOwnTor(home, state) {
155400
155460
  if (!isOwnTor(home, state)) return;
155401
- spawnSync7("taskkill", ["/PID", String(state.pid), "/FI", "IMAGENAME eq tor.exe", "/F"], { windowsHide: true, timeout: 1e4 });
155461
+ spawnSync8("taskkill", ["/PID", String(state.pid), "/FI", "IMAGENAME eq tor.exe", "/F"], { windowsHide: true, timeout: 1e4 });
155402
155462
  }
155403
155463
  var cookieFile = (home) => join41(managedTorDir(home), "control.cookie");
155404
155464
  var CONTROL_TIMEOUT_MS = 3e3;
@@ -155543,7 +155603,7 @@ async function installBundle(home, say3) {
155543
155603
  rmSync(target, { recursive: true, force: true });
155544
155604
  mkdirSync(unpacking, { recursive: true });
155545
155605
  const tar = join41(process.env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
155546
- const result = spawnSync7(tar, ["-xzf", archive, "-C", unpacking], { windowsHide: true, encoding: "utf8", timeout: 12e4 });
155606
+ const result = spawnSync8(tar, ["-xzf", archive, "-C", unpacking], { windowsHide: true, encoding: "utf8", timeout: 12e4 });
155547
155607
  rmSync(archive, { force: true });
155548
155608
  if (result.status !== 0 || !BUNDLE_FILES.every((parts) => existsSync(join41(unpacking, ...parts)))) {
155549
155609
  rmSync(unpacking, { recursive: true, force: true });
@@ -155797,14 +155857,15 @@ init_backup();
155797
155857
 
155798
155858
  // wallet/src/setup/hostCheck.mjs
155799
155859
  init_fs();
155800
- import { spawn as spawn12, spawnSync as spawnSync8 } from "node:child_process";
155860
+ import { spawn as spawn12, spawnSync as spawnSync9 } from "node:child_process";
155861
+ import { homedir as homedir3 } from "node:os";
155801
155862
  import { dirname as dirname35, join as join42 } from "node:path";
155802
155863
  var INHERITED = {
155803
155864
  win32: ["APPDATA", "HOMEDRIVE", "HOMEPATH", "LOCALAPPDATA", "PROCESSOR_ARCHITECTURE", "SYSTEMDRIVE", "SYSTEMROOT", "TEMP", "USERNAME", "USERPROFILE", "PROGRAMFILES"],
155804
155865
  other: ["HOME", "LOGNAME", "SHELL", "TERM", "USER"]
155805
155866
  };
155806
155867
  var HOST_CHECK_TIMEOUT_MS = 24e4;
155807
- function appPath({ platform = process.platform, env = process.env, run: run2 = spawnSync8 } = {}) {
155868
+ function appPath({ platform = process.platform, env = process.env, run: run2 = spawnSync9 } = {}) {
155808
155869
  if (platform === "win32") {
155809
155870
  try {
155810
155871
  const result = run2(
@@ -155837,6 +155898,7 @@ function nodePathFix({ platform = process.platform, env = process.env, execPath
155837
155898
  var npmProxyEnvironment = (url) => ({
155838
155899
  npm_config_offline: "false",
155839
155900
  npm_config_prefer_offline: "false",
155901
+ npm_config_prefer_online: "true",
155840
155902
  npm_config_proxy: url,
155841
155903
  npm_config_https_proxy: url,
155842
155904
  npm_config_noproxy: "",
@@ -155847,7 +155909,9 @@ var npmProxyEnvironment = (url) => ({
155847
155909
  NO_PROXY: "",
155848
155910
  no_proxy: ""
155849
155911
  });
155912
+ var NPM_ONLINE_ENVIRONMENT = Object.freeze({ npm_config_offline: "false", npm_config_prefer_offline: "false", npm_config_prefer_online: "true" });
155850
155913
  var NPM_OFFLINE_ENVIRONMENT = Object.freeze({ npm_config_offline: "true" });
155914
+ var NPM_CACHE_KEYS = /* @__PURE__ */ new Set(["npm_config_cache", "npm_config_userconfig", "npm_config_globalconfig", "npm_config_prefix"]);
155851
155915
  function appEnvironment(entry, { platform = process.platform, env = process.env, terminal = false, path, extra } = {}) {
155852
155916
  const names = platform === "win32" ? INHERITED.win32 : INHERITED.other;
155853
155917
  const out = {};
@@ -155856,10 +155920,15 @@ function appEnvironment(entry, { platform = process.platform, env = process.env,
155856
155920
  if (key !== void 0 && env[key] !== void 0) out[name] = env[key];
155857
155921
  }
155858
155922
  out.PATH = terminal ? env.PATH ?? env.Path ?? "" : path ?? appPath({ platform, env });
155923
+ if (terminal) {
155924
+ for (const [key, value2] of Object.entries(env)) {
155925
+ if (value2 !== void 0 && NPM_CACHE_KEYS.has(key.toLowerCase())) out[key] = value2;
155926
+ }
155927
+ }
155859
155928
  return { ...out, ...entry.env ?? {}, ...extra ?? {} };
155860
155929
  }
155861
155930
  var nodeMissing = (code2, text3) => code2 === 9009 || code2 === 127 || /is not recognized|command not found|No such file or directory|env: .?node/i.test(text3);
155862
- function checkHostEntry(entry, { platform = process.platform, env = process.env, terminal = false, path, extraEnv, timeoutMs = HOST_CHECK_TIMEOUT_MS, spawnImpl = spawn12 } = {}) {
155931
+ function checkHostEntry(entry, { platform = process.platform, env = process.env, terminal = false, path, extraEnv, timeoutMs = HOST_CHECK_TIMEOUT_MS, spawnImpl = spawn12, cwd = homedir3() } = {}) {
155863
155932
  const started = Date.now();
155864
155933
  return new Promise((resolveCheck) => {
155865
155934
  let child;
@@ -155875,6 +155944,7 @@ function checkHostEntry(entry, { platform = process.platform, env = process.env,
155875
155944
  };
155876
155945
  try {
155877
155946
  child = spawnImpl(entry.command, entry.args, {
155947
+ cwd,
155878
155948
  env: appEnvironment(entry, { platform, env, terminal, path, extra: extraEnv }),
155879
155949
  stdio: ["pipe", "pipe", "pipe"],
155880
155950
  windowsHide: true,
@@ -155932,7 +156002,7 @@ function end(child, platform) {
155932
156002
  const killTree = () => {
155933
156003
  clearInterval(poll);
155934
156004
  if (platform === "win32") {
155935
- if (child.exitCode === null) spawnSync8("taskkill.exe", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, stdio: "ignore" });
156005
+ if (child.exitCode === null) spawnSync9("taskkill.exe", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, stdio: "ignore" });
155936
156006
  return;
155937
156007
  }
155938
156008
  if (!groupHoldsOwn(child.pid, child.spawnedAt)) return;
@@ -156740,7 +156810,7 @@ function personWords(text3, { homeJob = false } = {}) {
156740
156810
  init_fs();
156741
156811
  init_secretFile();
156742
156812
  init_config();
156743
- import { homedir as homedir3 } from "node:os";
156813
+ import { homedir as homedir4 } from "node:os";
156744
156814
  import { join as join45, resolve as resolve39 } from "node:path";
156745
156815
  init_commandName();
156746
156816
  init_store();
@@ -156964,7 +157034,7 @@ function runsThisWallet(servers, home) {
156964
157034
  return states.includes(true) ? true : states.includes(null) ? null : false;
156965
157035
  }
156966
157036
  function claudeCodeState(env, home) {
156967
- const config = readJsonFile(join45(env.CLAUDE_CONFIG_DIR || homedir3(), ".claude.json"));
157037
+ const config = readJsonFile(join45(env.CLAUDE_CONFIG_DIR || homedir4(), ".claude.json"));
156968
157038
  if (config === void 0 || config === null) return { linked: config === null ? null : false };
156969
157039
  const user = runsThisWallet(config.mcpServers, home);
156970
157040
  if (user === true) return { linked: true };
@@ -156978,7 +157048,7 @@ function agentHostsOf(env, home) {
156978
157048
  const jsonHost = (target) => {
156979
157049
  let file;
156980
157050
  try {
156981
- file = hostConfigFile(target, { env, home: homedir3() });
157051
+ file = hostConfigFile(target, { env, home: homedir4(), claudeRunning: () => [] });
156982
157052
  } catch {
156983
157053
  return null;
156984
157054
  }
@@ -156986,7 +157056,7 @@ function agentHostsOf(env, home) {
156986
157056
  return config === void 0 ? false : config === null ? null : runsThisWallet(config[hostServersKey(target)], home);
156987
157057
  };
156988
157058
  const continueHost = () => {
156989
- const file = hostConfigFile("continue", { env, home: homedir3() });
157059
+ const file = hostConfigFile("continue", { env, home: homedir4() });
156990
157060
  let size;
156991
157061
  try {
156992
157062
  size = statSync(file).size;
@@ -157002,7 +157072,7 @@ function agentHostsOf(env, home) {
157002
157072
  }
157003
157073
  };
157004
157074
  const codexHost = () => {
157005
- const file = hostConfigFile("codex", { env, home: homedir3() });
157075
+ const file = hostConfigFile("codex", { env, home: homedir4() });
157006
157076
  let size;
157007
157077
  try {
157008
157078
  size = statSync(file).size;
@@ -160245,7 +160315,7 @@ function claudeCodeEntryOf(deps) {
160245
160315
  function runClaude(args, program = "claude", stdio = "inherit") {
160246
160316
  const options = { stdio, windowsHide: true, timeout: 12e4 };
160247
160317
  const programWord = program === "claude" ? program : `"${program}"`;
160248
- const result = process.platform === "win32" && !/\.exe$/i.test(program) ? spawnSync10([programWord, ...args.map((word) => hostShellWord(word, "win32"))].join(" "), { ...options, shell: true }) : spawnSync10(program, args, options);
160318
+ const result = process.platform === "win32" && !/\.exe$/i.test(program) ? spawnSync11([programWord, ...args.map((word) => hostShellWord(word, "win32"))].join(" "), { ...options, shell: true }) : spawnSync11(program, args, options);
160249
160319
  return result.status ?? 1;
160250
160320
  }
160251
160321
  function claudeRemoveLines(program, platform) {
@@ -160296,7 +160366,7 @@ function hostStartCheck(app, options, deps, { terminal, noTor = false }) {
160296
160366
  deps.io.out(`Checking that ${app} can start the wallet (the first time, this downloads the wallet${net4.url ? " over Tor" : ""}: up to a few minutes)...
160297
160367
  `);
160298
160368
  const start = async (entry) => {
160299
- if (!net4.url) return check(entry, { platform, env, terminal });
160369
+ if (!net4.url) return check(entry, { platform, env, terminal, extraEnv: NPM_ONLINE_ENVIRONMENT });
160300
160370
  const filled = await check(entry, { platform, env, terminal, extraEnv: npmProxyEnvironment(net4.url) });
160301
160371
  if (!filled.ok) return filled;
160302
160372
  return check(entry, { platform, env, terminal, extraEnv: NPM_OFFLINE_ENVIRONMENT });
@@ -160342,12 +160412,6 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
160342
160412
  const options = { home, env: deps.env, platform: deps.platform ?? process.platform, npmVersion };
160343
160413
  const done = /* @__PURE__ */ new Set();
160344
160414
  const kept3 = /* @__PURE__ */ new Set();
160345
- let torOn;
160346
- try {
160347
- torOn = readSetupConfig(home)?.tor === true;
160348
- } catch {
160349
- torOn = false;
160350
- }
160351
160415
  for (const target of targets) {
160352
160416
  if (target === "claude-code") {
160353
160417
  const why = claudeCodeShellWhy(options);
@@ -160356,9 +160420,9 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
160356
160420
  `);
160357
160421
  continue;
160358
160422
  }
160359
- const first2 = torOn ? await hostStartCheck("Claude Code", options, deps, { terminal: true, noTor }) : void 0;
160360
- if (first2 && !first2.ok) {
160361
- io.out(`Not added to Claude Code: ${hostCheckWords("Claude Code", first2)}
160423
+ const first = await hostStartCheck("Claude Code", options, deps, { terminal: true, noTor });
160424
+ if (!first.ok) {
160425
+ io.out(`Not added to Claude Code: ${hostCheckWords("Claude Code", first)}
160362
160426
  `);
160363
160427
  continue;
160364
160428
  }
@@ -160405,9 +160469,6 @@ ${claudeCodeLines({ ...claudeOptions, claudeProgram }).map((line) => ` ${line}`
160405
160469
  const removed = olderOwn || replacedOther || status !== 0 && force && quiet(["mcp", "remove", "--scope", "user", MCP_SERVER_NAME]) === 0;
160406
160470
  if (removed && status !== 0) status = runClaudeCli(claudeCodeArgs(options));
160407
160471
  if (status === 0) done.add(target);
160408
- const check = status === 0 ? await hostStartCheck("Claude Code", options, deps, { terminal: true, noTor }) : void 0;
160409
- if (check && !check.ok) io.out(`${hostCheckWords("Claude Code", check)}
160410
- `);
160411
160472
  const homeNow = replacedOther ? ` Claude Code now uses the wallet in ${home}; the wallet in ${otherHome} is unchanged.` : "";
160412
160473
  io.out(status === 0 ? `${removed ? "Replaced the wallet in" : "Added the wallet to"} Claude Code, for all your folders.${homeNow} ${allowWalletChecks(deps).say} ${RESTART_APP("Claude Code")}
160413
160474
  ` : `Claude Code did not take the server; its message is above. Run this yourself:
@@ -160424,27 +160485,23 @@ ${claudeRemoveLines(claudeProgram, options.platform)}
160424
160485
  file = hostConfigFile(target, { ...options, home: deps.homedir() });
160425
160486
  } catch (error) {
160426
160487
  if (!String(error?.message).startsWith("setup_host_config_ambiguous:")) throw error;
160427
- io.out(`Not added to ${app}: this computer has more than one ${app} settings file (${error.files.join("; ")}), so the wallet did not pick one. In ${app}, Settings > Developer > Edit Config opens the file it reads: add the entry below to it by hand.
160488
+ io.out(`Not added to ${app}: this computer has more than one ${app} settings file (${error.files.join("; ")}), so the wallet did not pick one. ${error.openApp ? `Open ${app} and run this setup line again (the open app shows which file it reads), or: ` : ""}In ${app}, Settings > Developer > Edit Config opens the file it reads: add the entry below to it by hand.
160428
160489
  `);
160429
160490
  continue;
160430
160491
  }
160431
- const first = torOn ? await hostStartCheck(app, options, deps, { terminal: false, noTor }) : void 0;
160432
- if (first && !first.ok) {
160433
- io.out(`Not added to ${app}: ${hostCheckWords(app, first)}
160492
+ const check = await hostStartCheck(app, options, deps, { terminal: false, noTor });
160493
+ if (!check.ok) {
160494
+ io.out(`Not added to ${app}: ${hostCheckWords(app, check)}
160434
160495
  `);
160435
160496
  continue;
160436
160497
  }
160437
160498
  try {
160438
160499
  const write = (entry, writeForce) => target === "codex" ? addToCodexHost(file, entry, { force: writeForce }) : target === "continue" ? addToContinueHost(file, hostEntry(target, entry), { force: writeForce }) : addToJsonHost(file, hostEntry(target, entry), { force: writeForce, key: hostServersKey(target) });
160439
- let added = write(mcpServerEntry(options), force);
160500
+ const added = write(mcpServerEntry({ ...options, ...check.path ? { path: check.path } : {} }), force);
160440
160501
  for (const old of added.replaced ?? []) io.out(`Replaced the old ${old} entry in ${app}.
160441
160502
  `);
160442
- const check = await hostStartCheck(app, options, deps, { terminal: false, noTor });
160443
- if (check.path) added = { ...write(mcpServerEntry({ ...options, path: check.path }), false), changed: true };
160444
- io.out(!added.changed ? `${app} already has the wallet: ${file} (nothing changed).${check.ok ? ` ${app} starts it (checked).` : ""} If ${app} does not show the wallet yet: ${hostAddedNext(target, app, options.platform)}
160445
- ` : `Added the wallet to ${app}: ${file}${added.backup ? ` (the old file was copied to ${added.backup}, readable by you alone)` : ""}.${check.ok ? ` ${app} starts it (checked).` : ""} ${hostAddedNext(target, app, options.platform)}
160446
- `);
160447
- if (!check.ok) io.out(`${hostCheckWords(app, check)}
160503
+ io.out(!added.changed ? `${app} already has the wallet: ${file} (nothing changed). The wallet starts with this entry (checked). If ${app} does not show the wallet yet: ${hostAddedNext(target, app, options.platform)}
160504
+ ` : `Added the wallet to ${app}: ${file}${added.backup ? ` (the old file was copied to ${added.backup}, readable by you alone)` : ""}. The wallet starts with this entry (checked). ${hostAddedNext(target, app, options.platform)}
160448
160505
  `);
160449
160506
  done.add(target);
160450
160507
  } catch (error) {
@@ -160579,7 +160636,7 @@ function npmShinjukuBinExists(output2) {
160579
160636
  }
160580
160637
  function runNpm(args, env) {
160581
160638
  const windows = process.platform === "win32";
160582
- const result = windows ? spawnSync10(["npm", ...args].map((word) => hostShellWord(word, "win32")).join(" "), { env, shell: true, windowsHide: true, encoding: "utf8", timeout: 6e5, maxBuffer: 16 * 1024 * 1024 }) : spawnSync10("npm", args, { env, windowsHide: true, encoding: "utf8", timeout: 6e5, maxBuffer: 16 * 1024 * 1024 });
160639
+ const result = windows ? spawnSync11(["npm", ...args].map((word) => hostShellWord(word, "win32")).join(" "), { env, shell: true, windowsHide: true, encoding: "utf8", timeout: 6e5, maxBuffer: 16 * 1024 * 1024 }) : spawnSync11("npm", args, { env, windowsHide: true, encoding: "utf8", timeout: 6e5, maxBuffer: 16 * 1024 * 1024 });
160583
160640
  return { status: result.status ?? 1, output: `${result.stdout ?? ""}${result.stderr ?? ""}${result.error ? `
160584
160641
  ${result.error.message}` : ""}` };
160585
160642
  }
@@ -165605,7 +165662,7 @@ function defaultDependencies() {
165605
165662
  fetch: (...args) => fetch(...args),
165606
165663
  platform: process.platform,
165607
165664
  arch: process.arch,
165608
- homedir: () => homedir4(),
165665
+ homedir: () => homedir5(),
165609
165666
  stdinIsTTY: () => Boolean(process.stdin.isTTY),
165610
165667
  /** True when stdout is a terminal: add-funds then ends with a short summary instead of the status as JSON. */
165611
165668
  stdoutIsTTY: () => Boolean(process.stdout.isTTY),