claudemesh-cli 0.8.4 → 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.
Files changed (2) hide show
  1. package/dist/index.js +72 -4
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -48823,6 +48823,17 @@ class BrokerClient {
48823
48823
  this.sendRaw({ type: "vault_delete", key, _reqId: reqId });
48824
48824
  });
48825
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
+ }
48826
48837
  async mcpDeploy(serverName, source, config2, scope) {
48827
48838
  return new Promise((resolve) => {
48828
48839
  const reqId = `deploy_${Date.now()}`;
@@ -49441,6 +49452,15 @@ class BrokerClient {
49441
49452
  r.resolve(msg.entries ?? []);
49442
49453
  }
49443
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
+ }
49444
49464
  if (msg.type === "mcp_deploy_status") {
49445
49465
  const reqId = msg._reqId;
49446
49466
  if (reqId && this.mcpDeployResolvers.has(reqId)) {
@@ -51060,9 +51080,51 @@ ${lines.join(`
51060
51080
  if (!client2)
51061
51081
  return text("mesh_mcp_deploy: not connected", true);
51062
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
+ }
51063
51124
  const config3 = {};
51064
- if (deployEnv)
51065
- 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
+ }
51066
51128
  if (runtime)
51067
51129
  config3.runtime = runtime;
51068
51130
  if (memory_mb)
@@ -51072,12 +51134,18 @@ ${lines.join(`
51072
51134
  const result = await client2.mcpDeploy(server_name, source, Object.keys(config3).length > 0 ? config3 : undefined, scope);
51073
51135
  const toolList = result.tools?.map((t) => ` - ${t.name}: ${t.description}`).join(`
51074
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
+ }
51075
51143
  return text(`Deployed "${server_name}" (status: ${result.status}).
51076
51144
 
51077
51145
  Tools:
51078
51146
  ${toolList}
51079
51147
 
51080
- Default scope: peer (private). Use mesh_mcp_scope to share.`);
51148
+ Default scope: peer (private). Use mesh_mcp_scope to share.${vaultNote}`);
51081
51149
  }
51082
51150
  case "mesh_mcp_undeploy": {
51083
51151
  const { server_name } = args ?? {};
@@ -52535,7 +52603,7 @@ init_config();
52535
52603
  // package.json
52536
52604
  var package_default = {
52537
52605
  name: "claudemesh-cli",
52538
- version: "0.8.4",
52606
+ version: "0.8.5",
52539
52607
  description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
52540
52608
  keywords: [
52541
52609
  "claude-code",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudemesh-cli",
3
- "version": "0.8.4",
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",
@@ -48,10 +48,10 @@
48
48
  "prettier": "3.6.2",
49
49
  "typescript": "5.9.3",
50
50
  "vitest": "4.0.14",
51
- "@turbostarter/vitest-config": "0.1.0",
52
51
  "@turbostarter/tsconfig": "0.1.0",
52
+ "@turbostarter/eslint-config": "0.1.0",
53
53
  "@turbostarter/prettier-config": "0.1.0",
54
- "@turbostarter/eslint-config": "0.1.0"
54
+ "@turbostarter/vitest-config": "0.1.0"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "bun build src/index.ts --target=node --outfile dist/index.js --banner \"#!/usr/bin/env node\" && chmod +x dist/index.js",