shinjuku-shielded 0.3.160 → 0.3.161
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 +6 -6
- package/manifest.json +4 -4
- package/package.json +3 -3
- package/shinjuku-wallet.mjs +182 -48
package/README.md
CHANGED
|
@@ -6,19 +6,19 @@ 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.
|
|
9
|
+
This is version 0.3.161. 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.
|
|
15
|
+
npm install -g shinjuku@0.3.161
|
|
16
16
|
shinjuku setup
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Type the two lines as they are. `npx install shinjuku` does not work: npx
|
|
20
20
|
reads `install` as the name of another npm package. To set up without
|
|
21
|
-
installing, type `npx shinjuku@0.3.
|
|
21
|
+
installing, type `npx shinjuku@0.3.161 setup`.
|
|
22
22
|
|
|
23
23
|
Setup makes the wallet on this machine, a private passphrase file, and the
|
|
24
24
|
checked proof tools (about 191 MB), and writes `config.json`. It also writes
|
|
@@ -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 -- npx -y --no-audit --no-fund shinjuku-shield@0.3.
|
|
39
|
+
claude mcp add --scope user shinjuku -- npx -y --no-audit --no-fund shinjuku-shield@0.3.161 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": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
45
|
+
{ "mcpServers": { "shinjuku": { "command": "npx", "args": ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.161", "mcp"] } } }
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
On native Windows, if the host cannot find `npx`, use `"command": "cmd"` and
|
|
@@ -55,7 +55,7 @@ Codex (the Codex app and Codex CLI read the same file, `~/.codex/config.toml`):
|
|
|
55
55
|
```toml
|
|
56
56
|
[mcp_servers.shinjuku]
|
|
57
57
|
command = "npx"
|
|
58
|
-
args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.
|
|
58
|
+
args = ["-y", "--no-audit", "--no-fund", "shinjuku-shield@0.3.161", "mcp"]
|
|
59
59
|
startup_timeout_sec = 120
|
|
60
60
|
tool_timeout_sec = 300
|
|
61
61
|
```
|
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": "
|
|
5
|
-
"bytes":
|
|
6
|
-
"sourceCommit": "
|
|
4
|
+
"sha256": "9bbc535c39d7f3ca35992be853e343d8374075618e0130ef2ab4f526a300b091",
|
|
5
|
+
"bytes": 9260169,
|
|
6
|
+
"sourceCommit": "157e988ee5f4ca6c609f49b296feabd64217eba7",
|
|
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-
|
|
1041
|
+
"publishedAt": "2026-11-04T06:13:30.270Z"
|
|
1042
1042
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shinjuku-shielded",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.161",
|
|
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": "
|
|
7
|
-
"shinjukuSha256": "
|
|
6
|
+
"shinjukuRelease": "9bbc535c",
|
|
7
|
+
"shinjukuSha256": "9bbc535c39d7f3ca35992be853e343d8374075618e0130ef2ab4f526a300b091",
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
9
9
|
"author": "Shinjuku Shielded",
|
|
10
10
|
"homepage": "https://github.com/ShinjukuStaition/shinjuku-shield#readme",
|
package/shinjuku-wallet.mjs
CHANGED
|
@@ -48011,12 +48011,12 @@ var init_proxy = __esm({
|
|
|
48011
48011
|
TOR_DEB_KEY = "https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc";
|
|
48012
48012
|
TOR_DEB_KEYRING = "/usr/share/keyrings/deb.torproject.org-keyring.gpg";
|
|
48013
48013
|
TOR_INSTALL = Object.freeze({
|
|
48014
|
-
windows: `iwr ${TOR_EXPERT_BUNDLE_URL} -OutFile $env:TEMP\\tor.tar.gz; if ((Get-FileHash $env:TEMP\\tor.tar.gz -Algorithm SHA256).Hash -ne '${TOR_EXPERT_BUNDLE_SHA256}') { Remove-Item $env:TEMP\\tor.tar.gz; throw 'The Tor download does not match its pinned sha256, so it was deleted and not run' }; mkdir -Force $env:LOCALAPPDATA\\tor | Out-Null; & $env:SystemRoot\\System32\\tar.exe -xzf $env:TEMP\\tor.tar.gz -C $env:LOCALAPPDATA\\tor;
|
|
48014
|
+
windows: `iwr ${TOR_EXPERT_BUNDLE_URL} -OutFile $env:TEMP\\tor.tar.gz; if ((Get-FileHash $env:TEMP\\tor.tar.gz -Algorithm SHA256).Hash -ne '${TOR_EXPERT_BUNDLE_SHA256}') { Remove-Item $env:TEMP\\tor.tar.gz; throw 'The Tor download does not match its pinned sha256, so it was deleted and not run' }; mkdir -Force $env:LOCALAPPDATA\\tor | Out-Null; & $env:SystemRoot\\System32\\tar.exe -xzf $env:TEMP\\tor.tar.gz -C $env:LOCALAPPDATA\\tor; Start-Process -WindowStyle Hidden -FilePath $env:LOCALAPPDATA\\tor\\tor\\tor.exe -ArgumentList '--HTTPTunnelPort "127.0.0.1:9080 IsolateDestAddr" --SocksPort 0'`,
|
|
48015
48015
|
macos: `brew install tor && (grep -qxF '${TUNNEL_LINE}' "$(brew --prefix)/etc/tor/torrc" || echo '${TUNNEL_LINE}' >> "$(brew --prefix)/etc/tor/torrc") && brew services restart tor`,
|
|
48016
48016
|
linux: `sudo apt install -y apt-transport-https gnupg wget && wget -qO- ${TOR_DEB_KEY} | gpg --dearmor | sudo tee ${TOR_DEB_KEYRING} >/dev/null && printf 'Types: deb\\nURIs: https://deb.torproject.org/torproject.org/\\nSuites: %s\\nComponents: main\\nSigned-By: ${TOR_DEB_KEYRING}\\n' "$(. /etc/os-release && echo "$VERSION_CODENAME")" | sudo tee /etc/apt/sources.list.d/tor.sources >/dev/null && sudo apt update && sudo apt install -y tor deb.torproject.org-keyring && (grep -qxF '${TUNNEL_LINE}' /etc/tor/torrc || echo '${TUNNEL_LINE}' | sudo tee -a /etc/tor/torrc) && sudo service tor restart`
|
|
48017
48017
|
});
|
|
48018
48018
|
torStart = (platform = process.platform, tunnelHost) => {
|
|
48019
|
-
const base = platform === "win32" ? { where: "PowerShell (
|
|
48019
|
+
const base = platform === "win32" ? { where: "PowerShell (Tor then runs in the background, so you can close that window)", command: TOR_INSTALL.windows } : platform === "darwin" ? { where: "Terminal", command: TOR_INSTALL.macos } : { where: "a terminal", command: TOR_INSTALL.linux };
|
|
48020
48020
|
return LOCAL_TUNNEL.test(tunnelHost ?? "") ? { ...base, command: base.command.replaceAll("127.0.0.1:9080", tunnelHost) } : base;
|
|
48021
48021
|
};
|
|
48022
48022
|
LOCAL_TUNNEL = /^127\.0\.0\.1:\d{1,5}$/;
|
|
@@ -48036,12 +48036,12 @@ ${command}`;
|
|
|
48036
48036
|
TOR_WINDOW = Object.freeze({ win32: "PowerShell", darwin: "Terminal" });
|
|
48037
48037
|
torNotRunningMessage = (address4, platform = process.platform, { fromConfig = false } = {}) => {
|
|
48038
48038
|
const { command } = torStart(platform);
|
|
48039
|
-
const keep = platform === "win32" ? "
|
|
48039
|
+
const keep = platform === "win32" ? " (Tor then runs in the background, so you can close that window)" : "";
|
|
48040
48040
|
return `tor_not_running: Tor is not running on this machine, so nothing was sent.${fromConfig ? TOR_FROM_CONFIG_SENTENCE : ""} Tor hides your IP address. Start it with the command below in ${TOR_WINDOW[platform] ?? "a terminal"}${keep}:
|
|
48041
48041
|
${command}`;
|
|
48042
48042
|
};
|
|
48043
|
-
torUpdateHow = (platform = process.platform) => platform === "win32" ? `${TOR_STOP_OLD_WINDOWS} Then start a newer Tor with the command below in PowerShell
|
|
48044
|
-
TOR_STOP_OLD_WINDOWS = "Stop your old Tor first:
|
|
48043
|
+
torUpdateHow = (platform = process.platform) => platform === "win32" ? `${TOR_STOP_OLD_WINDOWS} Then start a newer Tor with the command below in PowerShell (it runs in the background, so you can close that window)` : `Install a newer Tor with the command below in ${TOR_WINDOW[platform] ?? "a terminal"}`;
|
|
48044
|
+
TOR_STOP_OLD_WINDOWS = "Stop your old Tor first: in PowerShell run Stop-Process -Name tor , or for a Tor in WSL run wsl -u root service tor stop .";
|
|
48045
48045
|
torTooOldWhy = (version3) => `Your Tor program is too old (${version3}). It has a known fault that can link two of your payments, so the wallet sent nothing.`;
|
|
48046
48046
|
torTooOldMessage = (version3, platform = process.platform, { fromConfig = false, tunnelHost } = {}) => {
|
|
48047
48047
|
const { command } = torStart(platform, tunnelHost);
|
|
@@ -54272,8 +54272,22 @@ function hostShellWord(word, platform = process.platform) {
|
|
|
54272
54272
|
return `"${word}"`;
|
|
54273
54273
|
}
|
|
54274
54274
|
function hostConfigFile(target, { platform = process.platform, env = process.env, home = homedir() } = {}) {
|
|
54275
|
+
const set = (name) => typeof env[name] === "string" && env[name].trim() ? env[name].trim() : void 0;
|
|
54275
54276
|
if (target === "cursor") return join8(home, ".cursor", "mcp.json");
|
|
54276
54277
|
if (target === "codex") return join8(env.CODEX_HOME || join8(home, ".codex"), "config.toml");
|
|
54278
|
+
if (target === "vscode") {
|
|
54279
|
+
const appData = platform === "win32" ? env.APPDATA || join8(home, "AppData", "Roaming") : platform === "darwin" ? join8(home, "Library", "Application Support") : env.XDG_CONFIG_HOME || join8(home, ".config");
|
|
54280
|
+
return join8(appData, "Code", "User", "mcp.json");
|
|
54281
|
+
}
|
|
54282
|
+
if (target === "devin") {
|
|
54283
|
+
return join8(platform === "win32" ? join8(home, "AppData", "Roaming", "devin") : join8(env.XDG_CONFIG_HOME || join8(home, ".config"), "devin"), "mcp_config.json");
|
|
54284
|
+
}
|
|
54285
|
+
if (target === "cline") {
|
|
54286
|
+
return set("CLINE_MCP_SETTINGS_PATH") ?? join8(set("CLINE_DATA_DIR") ?? join8(set("CLINE_DIR") ?? join8(home, ".cline"), "data"), "settings", "cline_mcp_settings.json");
|
|
54287
|
+
}
|
|
54288
|
+
if (target === "continue") return join8(set("CONTINUE_GLOBAL_DIR") ? resolve6(set("CONTINUE_GLOBAL_DIR")) : join8(home, ".continue"), "mcpServers", `${MCP_SERVER_NAME}.yaml`);
|
|
54289
|
+
if (target === "gemini") return join8(set("GEMINI_CLI_HOME") ?? home, ".gemini", "settings.json");
|
|
54290
|
+
if (target === "antigravity") return join8(home, ".gemini", "config", "mcp_config.json");
|
|
54277
54291
|
if (target === "claude-desktop") {
|
|
54278
54292
|
if (platform === "win32") return join8(env.APPDATA || join8(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
54279
54293
|
if (platform === "darwin") return join8(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
@@ -54281,8 +54295,17 @@ function hostConfigFile(target, { platform = process.platform, env = process.env
|
|
|
54281
54295
|
}
|
|
54282
54296
|
return void 0;
|
|
54283
54297
|
}
|
|
54284
|
-
function hostConfigText({ home, env = process.env, platform = process.platform, npmVersion, skip = /* @__PURE__ */ new Set() } = {}) {
|
|
54298
|
+
function hostConfigText({ home, env = process.env, platform = process.platform, npmVersion, skip = /* @__PURE__ */ new Set(), userHome = homedir() } = {}) {
|
|
54285
54299
|
const entry = mcpServerEntry({ home, platform, npmVersion });
|
|
54300
|
+
const more = ["vscode", "devin", "cline", "continue", "gemini", "antigravity"].filter((target) => !skip.has(target)).flatMap((target) => {
|
|
54301
|
+
const file = hostConfigFile(target, { platform, env, home: userHome });
|
|
54302
|
+
if (target === "continue") return [`${HOST_NAMES[target]}: save these lines as ${file}:`, ...continueBlockText(hostEntry(target, entry)).trimEnd().split("\n").map((line) => ` ${line}`)];
|
|
54303
|
+
const key = hostServersKey(target);
|
|
54304
|
+
return [
|
|
54305
|
+
`${HOST_NAMES[target]} (${file}): in that file, add these lines inside the { } after "${key}" (put a comma after the entry before them; a file with no "${key}" gets "${key}": { } first):`,
|
|
54306
|
+
...`${JSON.stringify(MCP_SERVER_NAME)}: ${JSON.stringify(hostEntry(target, entry), null, 2)}`.split("\n").map((line) => ` ${line}`)
|
|
54307
|
+
];
|
|
54308
|
+
});
|
|
54286
54309
|
const member = `${JSON.stringify(MCP_SERVER_NAME)}: ${JSON.stringify(entry, null, 2)}`;
|
|
54287
54310
|
const files = [["claude-desktop", "Claude Desktop (claude_desktop_config.json)"], ["cursor", "Cursor (~/.cursor/mcp.json)"]].filter(([target]) => !skip.has(target)).map(([, label]) => label);
|
|
54288
54311
|
return [
|
|
@@ -54294,9 +54317,48 @@ function hostConfigText({ home, env = process.env, platform = process.platform,
|
|
|
54294
54317
|
...skip.has("codex") ? [] : [
|
|
54295
54318
|
"Codex (the Codex app and Codex CLI), at the end of ~/.codex/config.toml:",
|
|
54296
54319
|
...codexTomlBlock(entry).trimEnd().split("\n").map((line) => ` ${line}`)
|
|
54297
|
-
]
|
|
54320
|
+
],
|
|
54321
|
+
...more
|
|
54298
54322
|
].join("\n");
|
|
54299
54323
|
}
|
|
54324
|
+
function continueBlockText(entry) {
|
|
54325
|
+
return [
|
|
54326
|
+
"# The Shinjuku Shield wallet's server, written by its setup.",
|
|
54327
|
+
...CONTINUE_HEADER,
|
|
54328
|
+
` - ${JSON.stringify({ name: MCP_SERVER_NAME, ...entry })}`,
|
|
54329
|
+
""
|
|
54330
|
+
].join("\n");
|
|
54331
|
+
}
|
|
54332
|
+
function continueServersIn(text3) {
|
|
54333
|
+
const lines = text3.replace(/^/, "").split(/\r?\n/).filter((line) => line.trim() && !/^\s*#/.test(line));
|
|
54334
|
+
const items = lines.filter((line) => /^\s*-\s/.test(line));
|
|
54335
|
+
if (items.length !== 1 || !sameJson(lines.filter((line) => !/^\s*-\s/.test(line)).map((line) => line.trim()), CONTINUE_HEADER)) return void 0;
|
|
54336
|
+
let value2;
|
|
54337
|
+
try {
|
|
54338
|
+
value2 = JSON.parse(items[0].replace(/^\s*-\s*/, ""));
|
|
54339
|
+
} catch {
|
|
54340
|
+
return void 0;
|
|
54341
|
+
}
|
|
54342
|
+
if (!isPlainObject(value2) || typeof value2.name !== "string") return void 0;
|
|
54343
|
+
const { name, ...entry } = value2;
|
|
54344
|
+
return { [name]: entry };
|
|
54345
|
+
}
|
|
54346
|
+
function addToContinueHost(file, entry, { now = /* @__PURE__ */ new Date(), force = false, platform = process.platform, restrict = restrictToOwnerWindows } = {}) {
|
|
54347
|
+
const result = changeJsonFile(file, (text3) => {
|
|
54348
|
+
if (!text3.trim()) return continueBlockText(entry);
|
|
54349
|
+
const servers = continueServersIn(text3);
|
|
54350
|
+
if (!servers) {
|
|
54351
|
+
throw new Error("setup_host_config_unreadable: Continue's block file for the wallet was changed by hand, so setup left it alone; add the printed entry by hand");
|
|
54352
|
+
}
|
|
54353
|
+
const [[name, existing]] = Object.entries(servers);
|
|
54354
|
+
if (name === MCP_SERVER_NAME && sameJson(existing, entry)) return void 0;
|
|
54355
|
+
if (!force && !(name === MCP_SERVER_NAME && isOlderSetupEntry(existing, entry))) {
|
|
54356
|
+
throw new Error(`setup_host_config_conflict: Continue's block file for the wallet holds a different server, so setup left it alone; rerun setup with --force to replace it (the old file is backed up first), or edit it by hand`);
|
|
54357
|
+
}
|
|
54358
|
+
return continueBlockText(entry);
|
|
54359
|
+
}, { now, platform, restrict, codec: TEXT_CODEC });
|
|
54360
|
+
return { file, ...result, replaced: [] };
|
|
54361
|
+
}
|
|
54300
54362
|
function codexTomlBlock(entry) {
|
|
54301
54363
|
const lines = [
|
|
54302
54364
|
`[mcp_servers.${tomlKey(MCP_SERVER_NAME)}]`,
|
|
@@ -54581,31 +54643,32 @@ function restrictToOwnerWindows(file, { run: run2 = execFileSync2 } = {}) {
|
|
|
54581
54643
|
throw new Error("setup_host_config_acl_failed: setup could not limit the file to only you on this computer (icacls), so it did not write it; add the printed entry by hand");
|
|
54582
54644
|
}
|
|
54583
54645
|
}
|
|
54584
|
-
function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force = false, platform = process.platform, restrict = restrictToOwnerWindows } = {}) {
|
|
54646
|
+
function addToJsonHost(file, entry, { now = /* @__PURE__ */ new Date(), force = false, platform = process.platform, restrict = restrictToOwnerWindows, key = "mcpServers" } = {}) {
|
|
54585
54647
|
try {
|
|
54586
|
-
return addToStrictJsonHost(file, entry, { now, force, platform, restrict });
|
|
54648
|
+
return addToStrictJsonHost(file, entry, { now, force, platform, restrict, key });
|
|
54587
54649
|
} catch (error) {
|
|
54588
54650
|
if (error?.jsonc !== true) throw error;
|
|
54589
|
-
const result = changeJsonFile(file, (text3) => jsoncWithMember(text3, entry, { force }), { now, platform, restrict, codec: TEXT_CODEC });
|
|
54651
|
+
const result = changeJsonFile(file, (text3) => jsoncWithMember(text3, entry, { force, key }), { now, platform, restrict, codec: TEXT_CODEC });
|
|
54590
54652
|
return { file, ...result, replaced: [] };
|
|
54591
54653
|
}
|
|
54592
54654
|
}
|
|
54593
|
-
function addToStrictJsonHost(file, entry, { now, force, platform, restrict }) {
|
|
54655
|
+
function addToStrictJsonHost(file, entry, { now, force, platform, restrict, key }) {
|
|
54594
54656
|
let replaced = [];
|
|
54595
54657
|
const result = changeJsonFile(file, (current) => {
|
|
54596
|
-
|
|
54597
|
-
|
|
54658
|
+
const held = current[key];
|
|
54659
|
+
if (held !== void 0 && !isPlainObject(held)) {
|
|
54660
|
+
throw new Error(`setup_host_config_unreadable: the host's config file has a ${key} that is not a JSON object, so setup left it alone; fix it or add the printed entry by hand`);
|
|
54598
54661
|
}
|
|
54599
|
-
replaced = OLD_MCP_SERVER_NAMES.filter((name) =>
|
|
54600
|
-
const existing =
|
|
54662
|
+
replaced = OLD_MCP_SERVER_NAMES.filter((name) => held !== void 0 && Object.hasOwn(held, name));
|
|
54663
|
+
const existing = held !== void 0 && Object.hasOwn(held, MCP_SERVER_NAME) ? held[MCP_SERVER_NAME] : void 0;
|
|
54601
54664
|
if (existing !== void 0) {
|
|
54602
54665
|
if (sameJson(existing, entry) && replaced.length === 0) return void 0;
|
|
54603
54666
|
if (!force && !sameJson(existing, entry) && !isOlderSetupEntry(existing, entry)) {
|
|
54604
54667
|
throw new Error(`setup_host_config_conflict: the host's config file already has a different "${MCP_SERVER_NAME}" server, so setup left it alone; rerun setup with --force to replace it (the old file is backed up first), or edit it by hand`);
|
|
54605
54668
|
}
|
|
54606
54669
|
}
|
|
54607
|
-
const servers = Object.fromEntries(Object.entries(
|
|
54608
|
-
return { ...current,
|
|
54670
|
+
const servers = Object.fromEntries(Object.entries(held ?? {}).filter(([name]) => !OLD_MCP_SERVER_NAMES.includes(name)));
|
|
54671
|
+
return { ...current, [key]: { ...servers, [MCP_SERVER_NAME]: entry } };
|
|
54609
54672
|
}, { now, platform, restrict });
|
|
54610
54673
|
return { file, ...result, replaced };
|
|
54611
54674
|
}
|
|
@@ -54725,13 +54788,13 @@ function memberSlot(src, object) {
|
|
|
54725
54788
|
}
|
|
54726
54789
|
return { at: close, comma: src[at] === "," ? void 0 : last.value.end };
|
|
54727
54790
|
}
|
|
54728
|
-
function jsoncWithMember(text3, entry, { force }) {
|
|
54791
|
+
function jsoncWithMember(text3, entry, { force, key = "mcpServers" }) {
|
|
54729
54792
|
const unreadable = () => {
|
|
54730
54793
|
throw new Error("setup_host_config_unreadable: the host's config file has comments and names the wallet's server in a way setup does not change by itself, so setup left it alone; add the printed entry by hand");
|
|
54731
54794
|
};
|
|
54732
54795
|
const root = parseJsonc(text3);
|
|
54733
54796
|
if (root.kind !== "object") unreadable();
|
|
54734
|
-
const servers = root.members.filter((member) => member.key ===
|
|
54797
|
+
const servers = root.members.filter((member) => member.key === key);
|
|
54735
54798
|
if (servers.length > 1 || servers[0] && servers[0].value.kind !== "object") unreadable();
|
|
54736
54799
|
const holder = servers[0]?.value;
|
|
54737
54800
|
if (holder && holder.members.some((member) => OLD_MCP_SERVER_NAMES.includes(member.key))) unreadable();
|
|
@@ -54752,7 +54815,7 @@ ${indent}`) });
|
|
|
54752
54815
|
const slot3 = memberSlot(text3, object);
|
|
54753
54816
|
const indent = `${indentAt(text3, object.start)} `;
|
|
54754
54817
|
const member = holder ? `${JSON.stringify(MCP_SERVER_NAME)}: ${JSON.stringify(entry, null, 2).replace(/\n/g, `
|
|
54755
|
-
${indent}`)}` :
|
|
54818
|
+
${indent}`)}` : `${JSON.stringify(key)}: ${JSON.stringify({ [MCP_SERVER_NAME]: entry }, null, 2).replace(/\n/g, `
|
|
54756
54819
|
${indent}`)}`;
|
|
54757
54820
|
const lineStart = text3.lastIndexOf("\n", slot3.at - 1) + 1;
|
|
54758
54821
|
edits.push(/^[ \t]*$/.test(text3.slice(lineStart, slot3.at)) ? { at: lineStart, end: lineStart, text: `${indent}${member}
|
|
@@ -54764,11 +54827,34 @@ ${indentAt(text3, slot3.at)}` });
|
|
|
54764
54827
|
let next = text3;
|
|
54765
54828
|
for (const edit of edits.sort((a, b) => b.at - a.at)) next = `${next.slice(0, edit.at)}${edit.text}${next.slice(edit.end)}`;
|
|
54766
54829
|
const after = parseJsonc(next).value;
|
|
54767
|
-
const want = { ...root.value,
|
|
54830
|
+
const want = { ...root.value, [key]: { ...root.value[key] ?? {}, [MCP_SERVER_NAME]: entry } };
|
|
54768
54831
|
if (!sameJson(after, want)) unreadable();
|
|
54769
54832
|
return next;
|
|
54770
54833
|
}
|
|
54771
|
-
function changeJsonFile(file, change,
|
|
54834
|
+
function changeJsonFile(file, change, options) {
|
|
54835
|
+
const target = realFileOf(file);
|
|
54836
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
54837
|
+
const result = changeFileOnce(target, change, options, attempt);
|
|
54838
|
+
if (result !== RACED) return result;
|
|
54839
|
+
}
|
|
54840
|
+
throw new Error("setup_host_config_changed: the app changed its settings file while setup wrote it, so setup left the file as the app wrote it; run setup again");
|
|
54841
|
+
}
|
|
54842
|
+
function realFileOf(file) {
|
|
54843
|
+
let link2;
|
|
54844
|
+
try {
|
|
54845
|
+
link2 = lstatSync(file).isSymbolicLink();
|
|
54846
|
+
} catch (error) {
|
|
54847
|
+
if (error?.code === "ENOENT") return file;
|
|
54848
|
+
throw error;
|
|
54849
|
+
}
|
|
54850
|
+
if (!link2) return file;
|
|
54851
|
+
try {
|
|
54852
|
+
return realpathSync(file);
|
|
54853
|
+
} catch {
|
|
54854
|
+
throw new Error("setup_host_config_link_broken: the host's config file is a link to a file that does not exist, so setup did not change it; fix the link or add the printed entry by hand");
|
|
54855
|
+
}
|
|
54856
|
+
}
|
|
54857
|
+
function changeFileOnce(file, change, { now, platform, restrict, codec = JSON_CODEC }, attempt) {
|
|
54772
54858
|
let current = codec.empty();
|
|
54773
54859
|
let bytes2;
|
|
54774
54860
|
if (existsSync(file)) {
|
|
@@ -54781,7 +54867,7 @@ function changeJsonFile(file, change, { now, platform, restrict, codec = JSON_CO
|
|
|
54781
54867
|
let backup;
|
|
54782
54868
|
if (bytes2 !== void 0) {
|
|
54783
54869
|
mode = statSync(file).mode & 511;
|
|
54784
|
-
backup = `${file}.bak-${now.toISOString().replace(/[:.]/g, "-")}`;
|
|
54870
|
+
backup = `${file}.bak-${now.toISOString().replace(/[:.]/g, "-")}${attempt ? `-${attempt + 1}` : ""}`;
|
|
54785
54871
|
const fd = openSync(backup, "wx", 384);
|
|
54786
54872
|
let restrictFailed = false;
|
|
54787
54873
|
try {
|
|
@@ -54813,6 +54899,11 @@ function changeJsonFile(file, change, { now, platform, restrict, codec = JSON_CO
|
|
|
54813
54899
|
writeFileSync(temp, codec.write(next), { mode: mode ?? 384, flag: "wx" });
|
|
54814
54900
|
}
|
|
54815
54901
|
if (mode !== void 0 && platform !== "win32") chmodSync(temp, mode);
|
|
54902
|
+
const nowBytes = existsSync(file) ? readFileSync(file) : void 0;
|
|
54903
|
+
if (bytes2 === void 0 ? nowBytes !== void 0 : nowBytes === void 0 || !nowBytes.equals(bytes2)) {
|
|
54904
|
+
rmSync(temp, { force: true });
|
|
54905
|
+
return RACED;
|
|
54906
|
+
}
|
|
54816
54907
|
renameSync(temp, file);
|
|
54817
54908
|
} catch (error) {
|
|
54818
54909
|
rmSync(temp, { force: true });
|
|
@@ -54820,7 +54911,7 @@ function changeJsonFile(file, change, { now, platform, restrict, codec = JSON_CO
|
|
|
54820
54911
|
}
|
|
54821
54912
|
return { changed: true, ...backup ? { backup } : {} };
|
|
54822
54913
|
}
|
|
54823
|
-
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, CODEX_STARTUP_TIMEOUT_SEC, CODEX_TOOL_TIMEOUT_SEC, PINNED_PACKAGE, LAUNCHER_PACKAGE, NPM_VERSION, knownNpmVersion, RELEASES_URL, npmStartEnvironment, NPM_START_KEYS, defaultWalletHome, WINDOWS_SHELL_CODE, tomlString, tomlKey, codexEntryOf, isPlainObject, sameJson, claudeCodeEntry, READ_ONLY_TOOL_NAMES, claudeCodeAllowRules, claudeCodeSettingsFile, UNREADABLE_JSON, JSON_CODEC, indentAt, TEXT_CODEC;
|
|
54914
|
+
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, RELEASES_URL, npmStartEnvironment, NPM_START_KEYS, defaultWalletHome, 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;
|
|
54824
54915
|
var init_config = __esm({
|
|
54825
54916
|
"wallet/src/setup/config.mjs"() {
|
|
54826
54917
|
"use strict";
|
|
@@ -54880,8 +54971,21 @@ var init_config = __esm({
|
|
|
54880
54971
|
isOwnAddressText = (value2) => isPubkey(value2);
|
|
54881
54972
|
salvagePath = (home) => join8(home, "config.salvage.json");
|
|
54882
54973
|
clearConfigSalvage = (home) => rmSync(salvagePath(home), { force: true });
|
|
54883
|
-
HOST_TARGETS = Object.freeze(["claude-code", "claude-desktop", "cursor", "codex"]);
|
|
54884
|
-
HOST_NAMES = Object.freeze({
|
|
54974
|
+
HOST_TARGETS = Object.freeze(["claude-code", "claude-desktop", "cursor", "codex", "vscode", "devin", "cline", "continue", "gemini", "antigravity"]);
|
|
54975
|
+
HOST_NAMES = Object.freeze({
|
|
54976
|
+
"claude-code": "Claude Code",
|
|
54977
|
+
"claude-desktop": "Claude Desktop",
|
|
54978
|
+
cursor: "Cursor",
|
|
54979
|
+
codex: "Codex",
|
|
54980
|
+
vscode: "VS Code",
|
|
54981
|
+
devin: "Devin Desktop",
|
|
54982
|
+
cline: "Cline",
|
|
54983
|
+
continue: "Continue",
|
|
54984
|
+
gemini: "Gemini CLI",
|
|
54985
|
+
antigravity: "Antigravity"
|
|
54986
|
+
});
|
|
54987
|
+
hostServersKey = (target) => target === "vscode" ? "servers" : "mcpServers";
|
|
54988
|
+
hostEntry = (target, entry) => ["vscode", "cline", "continue"].includes(target) ? { type: "stdio", ...entry } : entry;
|
|
54885
54989
|
CODEX_STARTUP_TIMEOUT_SEC = 120;
|
|
54886
54990
|
CODEX_TOOL_TIMEOUT_SEC = 300;
|
|
54887
54991
|
PINNED_PACKAGE = /^shinjuku(?:-shield(?:ed)?)?@(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/;
|
|
@@ -54893,6 +54997,7 @@ var init_config = __esm({
|
|
|
54893
54997
|
NPM_START_KEYS = ["npm_config_offline", "npm_config_prefer_offline"];
|
|
54894
54998
|
defaultWalletHome = (home = homedir()) => setupHome({}, home);
|
|
54895
54999
|
WINDOWS_SHELL_CODE = /[%$`"\r\n]/;
|
|
55000
|
+
CONTINUE_HEADER = Object.freeze(["name: Shinjuku Shield", "version: 0.0.1", "schema: v1", "mcpServers:"]);
|
|
54896
55001
|
tomlString = (value2) => `"${String(value2).replace(/[\\"]/g, (c) => `\\${c}`).replace(/[\u0000-\u001f\u007f]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`)}"`;
|
|
54897
55002
|
tomlKey = (key) => /^[A-Za-z0-9_-]+$/.test(key) ? key : tomlString(key);
|
|
54898
55003
|
codexEntryOf = (server) => ({
|
|
@@ -54947,6 +55052,7 @@ var init_config = __esm({
|
|
|
54947
55052
|
});
|
|
54948
55053
|
indentAt = (src, at) => /^[ \t]*/.exec(src.slice(src.lastIndexOf("\n", at - 1) + 1))[0];
|
|
54949
55054
|
TEXT_CODEC = Object.freeze({ empty: () => "", read: (text3) => text3, write: (next) => next });
|
|
55055
|
+
RACED = /* @__PURE__ */ Symbol("raced");
|
|
54950
55056
|
}
|
|
54951
55057
|
});
|
|
54952
55058
|
|
|
@@ -156212,8 +156318,13 @@ function readJsonFile(file) {
|
|
|
156212
156318
|
}
|
|
156213
156319
|
if (size > HOST_CONFIG_MAX_BYTES) return null;
|
|
156214
156320
|
try {
|
|
156215
|
-
const text3 = readFileSync(file, "utf8");
|
|
156216
|
-
|
|
156321
|
+
const text3 = readFileSync(file, "utf8").replace(/^/, "");
|
|
156322
|
+
let value2;
|
|
156323
|
+
try {
|
|
156324
|
+
value2 = text3.trim() ? JSON.parse(text3) : {};
|
|
156325
|
+
} catch {
|
|
156326
|
+
value2 = parseJsonc(text3).value;
|
|
156327
|
+
}
|
|
156217
156328
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
156218
156329
|
} catch {
|
|
156219
156330
|
return null;
|
|
@@ -156246,7 +156357,23 @@ function claudeCodeState(env, home) {
|
|
|
156246
156357
|
function agentHostsOf(env, home) {
|
|
156247
156358
|
const jsonHost = (target) => {
|
|
156248
156359
|
const config = readJsonFile(hostConfigFile(target, { env, home: homedir3() }));
|
|
156249
|
-
return config === void 0 ? false : config === null ? null : runsThisWallet(config
|
|
156360
|
+
return config === void 0 ? false : config === null ? null : runsThisWallet(config[hostServersKey(target)], home);
|
|
156361
|
+
};
|
|
156362
|
+
const continueHost = () => {
|
|
156363
|
+
const file = hostConfigFile("continue", { env, home: homedir3() });
|
|
156364
|
+
let size;
|
|
156365
|
+
try {
|
|
156366
|
+
size = statSync(file).size;
|
|
156367
|
+
} catch (error) {
|
|
156368
|
+
return error?.code === "ENOENT" ? false : null;
|
|
156369
|
+
}
|
|
156370
|
+
if (size > HOST_CONFIG_MAX_BYTES) return null;
|
|
156371
|
+
try {
|
|
156372
|
+
const servers = continueServersIn(readFileSync(file, "utf8"));
|
|
156373
|
+
return servers ? runsThisWallet(servers, home) : null;
|
|
156374
|
+
} catch {
|
|
156375
|
+
return null;
|
|
156376
|
+
}
|
|
156250
156377
|
};
|
|
156251
156378
|
const codexHost = () => {
|
|
156252
156379
|
const file = hostConfigFile("codex", { env, home: homedir3() });
|
|
@@ -156268,7 +156395,9 @@ function agentHostsOf(env, home) {
|
|
|
156268
156395
|
{ app: "Claude Code", ...claudeCodeState(env, home) },
|
|
156269
156396
|
{ app: "Claude Desktop", linked: jsonHost("claude-desktop") },
|
|
156270
156397
|
{ app: "Cursor", linked: jsonHost("cursor") },
|
|
156271
|
-
{ app: "Codex", linked: codexHost() }
|
|
156398
|
+
{ app: "Codex", linked: codexHost() },
|
|
156399
|
+
...["vscode", "devin", "cline", "gemini", "antigravity"].map((target) => ({ app: HOST_NAMES[target], linked: jsonHost(target) })),
|
|
156400
|
+
{ app: HOST_NAMES.continue, linked: continueHost() }
|
|
156272
156401
|
];
|
|
156273
156402
|
}
|
|
156274
156403
|
function readHomeData({ env = process.env, walletVersion: walletVersion2, torRun } = {}) {
|
|
@@ -158891,12 +159020,14 @@ function privateInferencePath(config) {
|
|
|
158891
159020
|
}
|
|
158892
159021
|
function agentAppLines({ skip = /* @__PURE__ */ new Set() }) {
|
|
158893
159022
|
if (inHomeJob()) return "To add the wallet to an agent app (Claude, Codex, Cursor and others), press [c] on the home screen.";
|
|
158894
|
-
const
|
|
158895
|
-
|
|
158896
|
-
|
|
158897
|
-
|
|
158898
|
-
}
|
|
158899
|
-
|
|
159023
|
+
const targets = HOST_TARGETS.filter((target) => !skip.has(target));
|
|
159024
|
+
return targets.length ? hostLines(targets).join("\n") : "";
|
|
159025
|
+
}
|
|
159026
|
+
function hostLines(targets) {
|
|
159027
|
+
const commands = targets.map((target) => `${cli4()} setup --add-to ${target}`);
|
|
159028
|
+
const width = Math.max(...commands.map((command) => command.length));
|
|
159029
|
+
const label = { codex: "Codex (the Codex app or Codex CLI)", devin: "Devin Desktop (the app that was Windsurf)", vscode: "VS Code (GitHub Copilot)" };
|
|
159030
|
+
return targets.map((target, index) => ` ${commands[index].padEnd(width)} ${label[target] ?? HOST_NAMES[target]}`);
|
|
158900
159031
|
}
|
|
158901
159032
|
function setupNextText({ home, deps, npmVersion, config, fundAsked, rerun, targets = [], added = /* @__PURE__ */ new Set() }) {
|
|
158902
159033
|
const parts = [];
|
|
@@ -158909,20 +159040,18 @@ function setupNextText({ home, deps, npmVersion, config, fundAsked, rerun, targe
|
|
|
158909
159040
|
env: deps.env,
|
|
158910
159041
|
platform: deps.platform ?? process.platform,
|
|
158911
159042
|
npmVersion,
|
|
159043
|
+
userHome: deps.homedir(),
|
|
158912
159044
|
skip: new Set(HOST_TARGETS.filter((target) => !failed.includes(target)))
|
|
158913
159045
|
});
|
|
158914
159046
|
if (byHand) parts.push(`Or add it by hand:
|
|
158915
159047
|
${byHand}
|
|
158916
159048
|
`);
|
|
158917
159049
|
} else if (rerun && !targets.length) {
|
|
158918
|
-
parts.push([
|
|
158919
|
-
"To add the wallet to an agent app, run one of these:",
|
|
158920
|
-
...HOST_TARGETS.map((target) => ` ${cli4()} setup --add-to ${target}`),
|
|
158921
|
-
""
|
|
158922
|
-
].join("\n"));
|
|
159050
|
+
parts.push(["To add the wallet to an agent app, run the line for that app:", ...hostLines(HOST_TARGETS), ""].join("\n"));
|
|
158923
159051
|
} else {
|
|
158924
159052
|
const hosts = agentAppLines({ skip: added });
|
|
158925
|
-
|
|
159053
|
+
const head = inHomeJob() ? added.size ? "To add the wallet to another agent app" : "Use the wallet in your agent app" : `${added.size ? "To add the wallet to another agent app" : "To use the wallet in your agent app"}, run the line for that app once (setup adds the wallet there)`;
|
|
159054
|
+
if (hosts) parts.push(`${head}:
|
|
158926
159055
|
${hosts}
|
|
158927
159056
|
`);
|
|
158928
159057
|
}
|
|
@@ -159465,7 +159594,7 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
|
|
|
159465
159594
|
continue;
|
|
159466
159595
|
}
|
|
159467
159596
|
try {
|
|
159468
|
-
const write = (entry, writeForce) =>
|
|
159597
|
+
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) });
|
|
159469
159598
|
let added = write(mcpServerEntry(options), force);
|
|
159470
159599
|
for (const old of added.replaced ?? []) io.out(`Replaced the old ${old} entry in ${app}.
|
|
159471
159600
|
`);
|
|
@@ -159479,7 +159608,7 @@ async function addToHosts(targets, home, deps, { force = false, npmVersion, ask,
|
|
|
159479
159608
|
done.add(target);
|
|
159480
159609
|
} catch (error) {
|
|
159481
159610
|
const code2 = String(error.message).match(/^(setup_host_config_[a-z_]+): /)?.[1];
|
|
159482
|
-
const why = code2 === "setup_host_config_conflict" ? `${file} already has another server named "${MCP_SERVER_NAME}", and the wallet did not change that file; to use the wallet there, put the entry below in its place` : code2 === "setup_host_config_unreadable" ? `the wallet cannot read the settings in ${file}, so it did not change that file; fix that file, then add the entry below to it by hand` : code2 === "setup_host_config_acl_failed" ? `the wallet could not limit a new copy of ${file} to you alone, so it did not change that file; add the entry below to it by hand` : `the wallet could not write ${file}, so that file is unchanged; add the entry below to it by hand`;
|
|
159611
|
+
const why = code2 === "setup_host_config_conflict" ? `${file} already has another server named "${MCP_SERVER_NAME}", and the wallet did not change that file; to use the wallet there, put the entry below in its place` : code2 === "setup_host_config_unreadable" ? `the wallet cannot read the settings in ${file}, so it did not change that file; fix that file, then add the entry below to it by hand` : code2 === "setup_host_config_acl_failed" ? `the wallet could not limit a new copy of ${file} to you alone, so it did not change that file; add the entry below to it by hand` : code2 === "setup_host_config_changed" ? `${app} changed its settings while setup ran, so the wallet left ${file} as ${app} wrote it; run this step again` : code2 === "setup_host_config_link_broken" ? `${file} is a link to a file that does not exist, so the wallet did not change it; fix that link, or add the entry below by hand` : `the wallet could not write ${file}, so that file is unchanged; add the entry below to it by hand`;
|
|
159483
159612
|
io.out(`Not added to ${app}: ${why}.
|
|
159484
159613
|
`);
|
|
159485
159614
|
}
|
|
@@ -160812,7 +160941,7 @@ var COMMANDS = [
|
|
|
160812
160941
|
flag2("--own-address", "<address>", `optional, in your own terminal only (the same as the answer to setup's address question): your own wallet address (Phantom, Solflare, an exchange's deposit address), for sending money back to yourself: the MCP sends to it without asking each time (as mcp --unshield-to), also in an agent app that cannot show a question. Not this wallet's own key (the address this wallet itself receives on). Refused in a script, a pipe, or an agent's tool (no terminal), also with --yes: an agent must never approve an address. A rerun adds it to the ones config.json records (at most ${MAX_OWN_ADDRESSES})`),
|
|
160813
160942
|
flag2("--passphrase-file", "<file>", "your own passphrase file (8 or more characters); default: setup writes a new random passphrase to <home>/passphrase.txt, readable by you alone. Needed for a wallet that exists already"),
|
|
160814
160943
|
flag2("--facilitator", "<https origin>", `the server whose release, pool, and setup files setup uses; default ${GUIDE.facilitator}`, { check: "origin" }),
|
|
160815
|
-
flag2("--add-to", "
|
|
160944
|
+
flag2("--add-to", `<${HOST_TARGETS.join("|")}>`, `also add the server (npx -y --no-audit --no-fund ${NPX_AT_VERSION} mcp: the host starts this npm version; a wallet not installed from npm writes shinjuku-shield without a version) to this agent host's config; repeat it for more. Without it, setup prints the configs`, { repeat: true, check: "host" }),
|
|
160816
160945
|
// 0.3.97 key rename: the host key is MCP_SERVER_NAME; the old keys go by themselves.
|
|
160817
160946
|
bool2("--force", `with --add-to: replace a different ${MCP_SERVER_NAME} entry already in a JSON host config (the old file is backed up first, mode 0600), or in Claude Code (claude mcp remove of that one server, then add). An old ${OLD_MCP_SERVER_NAMES.join(" or ")} entry is replaced by itself, without --force`),
|
|
160818
160947
|
flag2("--trust-proof-tools", "<sha256>", `ADVANCED: install the set of setup files whose SHA256SUMS has this SHA-256 instead of the set this wallet build pins (needed for a server the build does not pin). Check the set out of band first; the normal fix for a new set is to update the wallet: ${UPDATE_SETUP}`)
|
|
@@ -160830,7 +160959,8 @@ var COMMANDS = [
|
|
|
160830
160959
|
"The passphrase is never printed and no MCP tool takes or returns it. The recovery file holds the seed and the key: copy it to two offline places, then delete it from this machine.",
|
|
160831
160960
|
`The setup files are the set this wallet build PINS (its SHA256SUMS hash is in the wallet; --trust-proof-tools replaces it). A server whose /api/wallet/release names another set is refused (setup_proof_tools_pin_mismatch; to update the wallet, ${UPDATE_SETUP}). SHA256SUMS must have the pinned SHA-256, and every file must have the SHA-256 its line names, as /skill.md section 7b; bin/ and house/bin/ get the execute bit. A file that does not match is not kept. Each download has a hard size limit.`,
|
|
160832
160961
|
"Your own --passphrase-file must be private: on Linux and macOS setup refuses a file that group or other may read or write, or that another user owns (setup_passphrase_file_insecure: chmod 600 <file>). On Windows setup cannot read the access list; it accepts the file with a warning.",
|
|
160833
|
-
`--add-to
|
|
160962
|
+
`--add-to writes each app's own user file: vscode (VS Code with Copilot) mcp.json in VS Code's User folder, under "servers"; devin (Devin Desktop, the app that was Windsurf) mcp_config.json in AppData\\Roaming\\devin on Windows, else ~/.config/devin; cline ~/.cline/data/settings/cline_mcp_settings.json (or CLINE_MCP_SETTINGS_PATH, CLINE_DATA_DIR, CLINE_DIR); continue its own block file ~/.continue/mcpServers/shinjuku.yaml (or in CONTINUE_GLOBAL_DIR); gemini (Gemini CLI) ~/.gemini/settings.json (or in GEMINI_CLI_HOME); antigravity (Antigravity) ~/.gemini/config/mcp_config.json. Every other key and server in a file stays as it is.`,
|
|
160963
|
+
`--add-to for a JSON file (Claude Desktop, Cursor and the apps above): a host config whose server list is not a JSON object, or that has a different ${MCP_SERVER_NAME} entry (without --force), is left alone. Otherwise the old file is copied to <file>.bak-<time> (mode 0600 on Linux and macOS; on Windows the folder's access list) and the new file replaces it in one rename. An entry an older setup wrote (no version, another version, or an old package name, shinjuku or shinjuku-shielded; the same home) is replaced without --force, in a JSON host and in Claude Code. An entry under an old key (${OLD_MCP_SERVER_NAMES.join(" or ")}) is replaced by itself, in every host, so the host never starts two wallet servers. For Claude Code, a different ${MCP_SERVER_NAME} server (not an older entry of this wallet) needs --force.`,
|
|
160834
160964
|
`--add-to codex: the Codex app and Codex CLI read one file, config.toml in CODEX_HOME (else ~/.codex). Setup writes the [mcp_servers.${MCP_SERVER_NAME}] tables at its end with startup_timeout_sec = 120 (a first start downloads the wallet) and tool_timeout_sec = 300, and keeps every other line; the same rules as a JSON host (a different entry stays without --force; the old file is backed up first). Then type /mcp in Codex to see the tools.`,
|
|
160835
160965
|
"The proof programs run natively: Windows x64, Linux x64 and Linux arm64 each download their own set (no WSL). Setup downloads the programs first and starts each one once before it makes a key; when Windows app control or an antivirus blocks one, setup stops and says which. macOS and other systems: not supported yet; setup says so and creates nothing.",
|
|
160836
160966
|
"Run it again at any time: it never changes an existing wallet, keeps the recorded caps unless you pass new ones, checks every setup file again, downloads what is missing or newer, and rewrites config.json.",
|
|
@@ -161565,8 +161695,8 @@ function shortHelpText() {
|
|
|
161565
161695
|
"Everyday commands:",
|
|
161566
161696
|
...rows2.map(([word, about]) => ` ${word.padEnd(width)}${about}`),
|
|
161567
161697
|
"",
|
|
161568
|
-
"Add the wallet to your agent app
|
|
161569
|
-
|
|
161698
|
+
"Add the wallet to your agent app: run the line for that app once.",
|
|
161699
|
+
...hostLines(HOST_TARGETS),
|
|
161570
161700
|
"",
|
|
161571
161701
|
`One command, with an example: ${cli4()} help <command>`,
|
|
161572
161702
|
`All commands: ${cli4()} help all`,
|
|
@@ -161731,6 +161861,9 @@ var flagLabel = (index) => `the flag at position ${index + 1}`;
|
|
|
161731
161861
|
var TRANSFER_START_FLAGS = /* @__PURE__ */ new Set(["--mint", "--token-mint", "--amount-atomic", "--amount", "--to", "--max-slippage-bps", "--allow-impact", "--yes"]);
|
|
161732
161862
|
var NOT_SHOWN = "; the value given is not one (it is not repeated here)";
|
|
161733
161863
|
function checkValue(spec, value2) {
|
|
161864
|
+
if (spec.check === "host" && (Array.isArray(value2) ? value2 : [value2]).some((name) => !HOST_TARGETS.includes(name))) {
|
|
161865
|
+
return `${spec.name} takes the name of an agent app: ${HOST_TARGETS.join(", ")}${NOT_SHOWN}`;
|
|
161866
|
+
}
|
|
161734
161867
|
if (spec.check === "atomic" && !(spec.usdc === "or-all" && value2 === "all") && !/^[1-9][0-9]*$/.test(value2)) {
|
|
161735
161868
|
return `${spec.name} must be a whole number of atomic units above 0 (1 USDC = 1000000)${NOT_SHOWN}`;
|
|
161736
161869
|
}
|
|
@@ -164883,6 +165016,7 @@ ${HOST_TARGETS.map((host, index) => ` ${index + 1} ${hostNames[host] ?? host}`
|
|
|
164883
165016
|
env: deps.env,
|
|
164884
165017
|
platform: deps.platform ?? process.platform,
|
|
164885
165018
|
npmVersion,
|
|
165019
|
+
userHome: deps.homedir(),
|
|
164886
165020
|
skip: new Set(HOST_TARGETS.filter((target) => target !== host))
|
|
164887
165021
|
});
|
|
164888
165022
|
if (byHand) io.out(`${byHand}
|