claudemesh-cli 0.8.3 → 0.8.5
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/dist/index.js +91 -10
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -47880,6 +47880,12 @@ class BrokerClient {
|
|
|
47880
47880
|
getSessionSecretKey() {
|
|
47881
47881
|
return this.sessionSecretKey;
|
|
47882
47882
|
}
|
|
47883
|
+
getMeshPubkey() {
|
|
47884
|
+
return this.mesh.pubkey;
|
|
47885
|
+
}
|
|
47886
|
+
getMeshSecretKey() {
|
|
47887
|
+
return this.mesh.secretKey;
|
|
47888
|
+
}
|
|
47883
47889
|
makeReqId() {
|
|
47884
47890
|
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
47885
47891
|
}
|
|
@@ -48817,6 +48823,17 @@ class BrokerClient {
|
|
|
48817
48823
|
this.sendRaw({ type: "vault_delete", key, _reqId: reqId });
|
|
48818
48824
|
});
|
|
48819
48825
|
}
|
|
48826
|
+
async vaultGet(keys) {
|
|
48827
|
+
return new Promise((resolve) => {
|
|
48828
|
+
const reqId = `vget_${Date.now()}`;
|
|
48829
|
+
const timer = setTimeout(() => {
|
|
48830
|
+
this.vaultListResolvers.delete(reqId);
|
|
48831
|
+
resolve([]);
|
|
48832
|
+
}, 1e4);
|
|
48833
|
+
this.vaultListResolvers.set(reqId, { resolve, timer });
|
|
48834
|
+
this.sendRaw({ type: "vault_get", keys, _reqId: reqId });
|
|
48835
|
+
});
|
|
48836
|
+
}
|
|
48820
48837
|
async mcpDeploy(serverName, source, config2, scope) {
|
|
48821
48838
|
return new Promise((resolve) => {
|
|
48822
48839
|
const reqId = `deploy_${Date.now()}`;
|
|
@@ -49435,6 +49452,15 @@ class BrokerClient {
|
|
|
49435
49452
|
r.resolve(msg.entries ?? []);
|
|
49436
49453
|
}
|
|
49437
49454
|
}
|
|
49455
|
+
if (msg.type === "vault_get_result") {
|
|
49456
|
+
const reqId = msg._reqId;
|
|
49457
|
+
if (reqId && this.vaultListResolvers.has(reqId)) {
|
|
49458
|
+
const r = this.vaultListResolvers.get(reqId);
|
|
49459
|
+
clearTimeout(r.timer);
|
|
49460
|
+
this.vaultListResolvers.delete(reqId);
|
|
49461
|
+
r.resolve(msg.entries ?? []);
|
|
49462
|
+
}
|
|
49463
|
+
}
|
|
49438
49464
|
if (msg.type === "mcp_deploy_status") {
|
|
49439
49465
|
const reqId = msg._reqId;
|
|
49440
49466
|
if (reqId && this.mcpDeployResolvers.has(reqId)) {
|
|
@@ -51002,18 +51028,25 @@ ${lines.join(`
|
|
|
51002
51028
|
if (!client2)
|
|
51003
51029
|
return text("vault_set: not connected", true);
|
|
51004
51030
|
const entryType = vType ?? "env";
|
|
51005
|
-
let
|
|
51031
|
+
let plaintextBytes;
|
|
51006
51032
|
if (entryType === "file") {
|
|
51007
51033
|
const { existsSync: existsSync2, readFileSync: readFileSync2 } = await import("node:fs");
|
|
51008
51034
|
if (!existsSync2(value))
|
|
51009
51035
|
return text(`vault_set: file not found: ${value}`, true);
|
|
51010
|
-
|
|
51011
|
-
}
|
|
51012
|
-
|
|
51013
|
-
|
|
51036
|
+
plaintextBytes = new Uint8Array(readFileSync2(value));
|
|
51037
|
+
} else {
|
|
51038
|
+
plaintextBytes = new TextEncoder().encode(value);
|
|
51039
|
+
}
|
|
51040
|
+
const { encryptFile: encryptFile2, sealKeyForPeer: sealKeyForPeer2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
|
|
51041
|
+
const { ciphertext, nonce, key: kf } = await encryptFile2(plaintextBytes);
|
|
51042
|
+
const sealedKey = await sealKeyForPeer2(kf, client2.getMeshPubkey());
|
|
51043
|
+
const { ensureSodium: ensureSodium2 } = await Promise.resolve().then(() => (init_keypair(), exports_keypair));
|
|
51044
|
+
const sodium2 = await ensureSodium2();
|
|
51045
|
+
const ciphertextB64 = sodium2.to_base64(ciphertext, sodium2.base64_variants.ORIGINAL);
|
|
51046
|
+
const ok = await client2.vaultSet(key, ciphertextB64, nonce, sealedKey, entryType, mount_path, description);
|
|
51014
51047
|
if (!ok)
|
|
51015
51048
|
return text("vault_set: broker did not acknowledge", true);
|
|
51016
|
-
return text(`Vault entry "${key}" stored (${entryType}).`);
|
|
51049
|
+
return text(`Vault entry "${key}" stored (${entryType}, E2E encrypted).`);
|
|
51017
51050
|
}
|
|
51018
51051
|
case "vault_list": {
|
|
51019
51052
|
const client2 = allClients()[0];
|
|
@@ -51047,9 +51080,51 @@ ${lines.join(`
|
|
|
51047
51080
|
if (!client2)
|
|
51048
51081
|
return text("mesh_mcp_deploy: not connected", true);
|
|
51049
51082
|
const source = file_id ? { type: "zip", file_id } : { type: "git", url: git_url, branch: git_branch };
|
|
51083
|
+
const resolvedEnv = {};
|
|
51084
|
+
const vaultResolved = [];
|
|
51085
|
+
if (deployEnv) {
|
|
51086
|
+
const vaultRefs = [];
|
|
51087
|
+
for (const [envKey, envVal] of Object.entries(deployEnv)) {
|
|
51088
|
+
if (typeof envVal === "string" && envVal.startsWith("$vault:")) {
|
|
51089
|
+
const parts = envVal.slice(7).split(":");
|
|
51090
|
+
const vaultKey = parts[0];
|
|
51091
|
+
const isFile = parts[1] === "file";
|
|
51092
|
+
const mountPath = isFile ? parts.slice(2).join(":") : undefined;
|
|
51093
|
+
vaultRefs.push({ envKey, vaultKey, isFile, mountPath });
|
|
51094
|
+
} else {
|
|
51095
|
+
resolvedEnv[envKey] = envVal;
|
|
51096
|
+
}
|
|
51097
|
+
}
|
|
51098
|
+
if (vaultRefs.length > 0) {
|
|
51099
|
+
const { openSealedKey: openSealedKey2, decryptFile: decryptFile2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
|
|
51100
|
+
const { ensureSodium: ensureSodium2 } = await Promise.resolve().then(() => (init_keypair(), exports_keypair));
|
|
51101
|
+
const sodium2 = await ensureSodium2();
|
|
51102
|
+
const keys = vaultRefs.map((r) => r.vaultKey);
|
|
51103
|
+
const encryptedEntries = await client2.vaultGet(keys);
|
|
51104
|
+
for (const ref of vaultRefs) {
|
|
51105
|
+
const entry = encryptedEntries.find((e) => e.key === ref.vaultKey);
|
|
51106
|
+
if (!entry)
|
|
51107
|
+
return text(`mesh_mcp_deploy: vault key "${ref.vaultKey}" not found. Use vault_set first.`, true);
|
|
51108
|
+
const kf = await openSealedKey2(entry.sealed_key, client2.getMeshPubkey(), client2.getMeshSecretKey());
|
|
51109
|
+
if (!kf)
|
|
51110
|
+
return text(`mesh_mcp_deploy: failed to decrypt vault key "${ref.vaultKey}" — wrong keypair?`, true);
|
|
51111
|
+
const ciphertextBytes = sodium2.from_base64(entry.ciphertext, sodium2.base64_variants.ORIGINAL);
|
|
51112
|
+
const plainBytes = await decryptFile2(ciphertextBytes, entry.nonce, kf);
|
|
51113
|
+
if (!plainBytes)
|
|
51114
|
+
return text(`mesh_mcp_deploy: failed to decrypt vault entry "${ref.vaultKey}" — corrupted?`, true);
|
|
51115
|
+
if (ref.isFile && ref.mountPath) {
|
|
51116
|
+
resolvedEnv[ref.envKey] = `__vault_file__:${ref.mountPath}:${sodium2.to_base64(plainBytes, sodium2.base64_variants.ORIGINAL)}`;
|
|
51117
|
+
} else {
|
|
51118
|
+
resolvedEnv[ref.envKey] = new TextDecoder().decode(plainBytes);
|
|
51119
|
+
}
|
|
51120
|
+
vaultResolved.push(ref.vaultKey);
|
|
51121
|
+
}
|
|
51122
|
+
}
|
|
51123
|
+
}
|
|
51050
51124
|
const config3 = {};
|
|
51051
|
-
if (deployEnv)
|
|
51052
|
-
config3.env = deployEnv;
|
|
51125
|
+
if (Object.keys(resolvedEnv).length > 0 || deployEnv && Object.keys(deployEnv).length > 0) {
|
|
51126
|
+
config3.env = Object.keys(resolvedEnv).length > 0 ? resolvedEnv : deployEnv;
|
|
51127
|
+
}
|
|
51053
51128
|
if (runtime)
|
|
51054
51129
|
config3.runtime = runtime;
|
|
51055
51130
|
if (memory_mb)
|
|
@@ -51059,12 +51134,18 @@ ${lines.join(`
|
|
|
51059
51134
|
const result = await client2.mcpDeploy(server_name, source, Object.keys(config3).length > 0 ? config3 : undefined, scope);
|
|
51060
51135
|
const toolList = result.tools?.map((t) => ` - ${t.name}: ${t.description}`).join(`
|
|
51061
51136
|
`) ?? " (pending)";
|
|
51137
|
+
let vaultNote = "";
|
|
51138
|
+
if (vaultResolved.length > 0) {
|
|
51139
|
+
vaultNote = `
|
|
51140
|
+
|
|
51141
|
+
Vault keys resolved: ${vaultResolved.join(", ")} (decrypted client-side, sent over TLS)`;
|
|
51142
|
+
}
|
|
51062
51143
|
return text(`Deployed "${server_name}" (status: ${result.status}).
|
|
51063
51144
|
|
|
51064
51145
|
Tools:
|
|
51065
51146
|
${toolList}
|
|
51066
51147
|
|
|
51067
|
-
Default scope: peer (private). Use mesh_mcp_scope to share
|
|
51148
|
+
Default scope: peer (private). Use mesh_mcp_scope to share.${vaultNote}`);
|
|
51068
51149
|
}
|
|
51069
51150
|
case "mesh_mcp_undeploy": {
|
|
51070
51151
|
const { server_name } = args ?? {};
|
|
@@ -52522,7 +52603,7 @@ init_config();
|
|
|
52522
52603
|
// package.json
|
|
52523
52604
|
var package_default = {
|
|
52524
52605
|
name: "claudemesh-cli",
|
|
52525
|
-
version: "0.8.
|
|
52606
|
+
version: "0.8.5",
|
|
52526
52607
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
52527
52608
|
keywords: [
|
|
52528
52609
|
"claude-code",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudemesh-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"typescript": "5.9.3",
|
|
50
50
|
"vitest": "4.0.14",
|
|
51
51
|
"@turbostarter/tsconfig": "0.1.0",
|
|
52
|
-
"@turbostarter/prettier-config": "0.1.0",
|
|
53
52
|
"@turbostarter/eslint-config": "0.1.0",
|
|
53
|
+
"@turbostarter/prettier-config": "0.1.0",
|
|
54
54
|
"@turbostarter/vitest-config": "0.1.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|