claudemesh-cli 0.8.4 → 0.8.6

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 +77 -8
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -47674,6 +47674,7 @@ var TOOLS = [
47674
47674
  file_id: { type: "string", description: "File ID of uploaded zip (from share_file)" },
47675
47675
  git_url: { type: "string", description: "Git repo URL" },
47676
47676
  git_branch: { type: "string", description: "Branch to clone (default: main)" },
47677
+ npx_package: { type: "string", description: "npm package name to run via npx (e.g. @upstash/context7-mcp)" },
47677
47678
  env: { type: "object", description: "Environment variables. Use $vault:<key> for vault secrets." },
47678
47679
  runtime: { type: "string", enum: ["node", "python", "bun"], description: "Runtime (auto-detected if omitted)" },
47679
47680
  memory_mb: { type: "number", description: "Memory limit in MB (default: 256)" },
@@ -48823,6 +48824,17 @@ class BrokerClient {
48823
48824
  this.sendRaw({ type: "vault_delete", key, _reqId: reqId });
48824
48825
  });
48825
48826
  }
48827
+ async vaultGet(keys) {
48828
+ return new Promise((resolve) => {
48829
+ const reqId = `vget_${Date.now()}`;
48830
+ const timer = setTimeout(() => {
48831
+ this.vaultListResolvers.delete(reqId);
48832
+ resolve([]);
48833
+ }, 1e4);
48834
+ this.vaultListResolvers.set(reqId, { resolve, timer });
48835
+ this.sendRaw({ type: "vault_get", keys, _reqId: reqId });
48836
+ });
48837
+ }
48826
48838
  async mcpDeploy(serverName, source, config2, scope) {
48827
48839
  return new Promise((resolve) => {
48828
48840
  const reqId = `deploy_${Date.now()}`;
@@ -49441,6 +49453,15 @@ class BrokerClient {
49441
49453
  r.resolve(msg.entries ?? []);
49442
49454
  }
49443
49455
  }
49456
+ if (msg.type === "vault_get_result") {
49457
+ const reqId = msg._reqId;
49458
+ if (reqId && this.vaultListResolvers.has(reqId)) {
49459
+ const r = this.vaultListResolvers.get(reqId);
49460
+ clearTimeout(r.timer);
49461
+ this.vaultListResolvers.delete(reqId);
49462
+ r.resolve(msg.entries ?? []);
49463
+ }
49464
+ }
49444
49465
  if (msg.type === "mcp_deploy_status") {
49445
49466
  const reqId = msg._reqId;
49446
49467
  if (reqId && this.mcpDeployResolvers.has(reqId)) {
@@ -51051,18 +51072,60 @@ ${lines.join(`
51051
51072
  return text(ok ? `Vault entry "${key}" deleted.` : `Vault entry "${key}" not found.`);
51052
51073
  }
51053
51074
  case "mesh_mcp_deploy": {
51054
- const { server_name, file_id, git_url, git_branch, env: deployEnv, runtime, memory_mb, network_allow, scope } = args ?? {};
51075
+ const { server_name, file_id, git_url, git_branch, npx_package, env: deployEnv, runtime, memory_mb, network_allow, scope } = args ?? {};
51055
51076
  if (!server_name)
51056
51077
  return text("mesh_mcp_deploy: `server_name` required", true);
51057
- if (!file_id && !git_url)
51058
- return text("mesh_mcp_deploy: either `file_id` or `git_url` required", true);
51078
+ if (!file_id && !git_url && !npx_package)
51079
+ return text("mesh_mcp_deploy: one of `file_id`, `git_url`, or `npx_package` required", true);
51059
51080
  const client2 = allClients()[0];
51060
51081
  if (!client2)
51061
51082
  return text("mesh_mcp_deploy: not connected", true);
51062
- const source = file_id ? { type: "zip", file_id } : { type: "git", url: git_url, branch: git_branch };
51083
+ const source = npx_package ? { type: "npx", package: npx_package } : file_id ? { type: "zip", file_id } : { type: "git", url: git_url, branch: git_branch };
51084
+ const resolvedEnv = {};
51085
+ const vaultResolved = [];
51086
+ if (deployEnv) {
51087
+ const vaultRefs = [];
51088
+ for (const [envKey, envVal] of Object.entries(deployEnv)) {
51089
+ if (typeof envVal === "string" && envVal.startsWith("$vault:")) {
51090
+ const parts = envVal.slice(7).split(":");
51091
+ const vaultKey = parts[0];
51092
+ const isFile = parts[1] === "file";
51093
+ const mountPath = isFile ? parts.slice(2).join(":") : undefined;
51094
+ vaultRefs.push({ envKey, vaultKey, isFile, mountPath });
51095
+ } else {
51096
+ resolvedEnv[envKey] = envVal;
51097
+ }
51098
+ }
51099
+ if (vaultRefs.length > 0) {
51100
+ const { openSealedKey: openSealedKey2, decryptFile: decryptFile2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
51101
+ const { ensureSodium: ensureSodium2 } = await Promise.resolve().then(() => (init_keypair(), exports_keypair));
51102
+ const sodium2 = await ensureSodium2();
51103
+ const keys = vaultRefs.map((r) => r.vaultKey);
51104
+ const encryptedEntries = await client2.vaultGet(keys);
51105
+ for (const ref of vaultRefs) {
51106
+ const entry = encryptedEntries.find((e) => e.key === ref.vaultKey);
51107
+ if (!entry)
51108
+ return text(`mesh_mcp_deploy: vault key "${ref.vaultKey}" not found. Use vault_set first.`, true);
51109
+ const kf = await openSealedKey2(entry.sealed_key, client2.getMeshPubkey(), client2.getMeshSecretKey());
51110
+ if (!kf)
51111
+ return text(`mesh_mcp_deploy: failed to decrypt vault key "${ref.vaultKey}" — wrong keypair?`, true);
51112
+ const ciphertextBytes = sodium2.from_base64(entry.ciphertext, sodium2.base64_variants.ORIGINAL);
51113
+ const plainBytes = await decryptFile2(ciphertextBytes, entry.nonce, kf);
51114
+ if (!plainBytes)
51115
+ return text(`mesh_mcp_deploy: failed to decrypt vault entry "${ref.vaultKey}" — corrupted?`, true);
51116
+ if (ref.isFile && ref.mountPath) {
51117
+ resolvedEnv[ref.envKey] = `__vault_file__:${ref.mountPath}:${sodium2.to_base64(plainBytes, sodium2.base64_variants.ORIGINAL)}`;
51118
+ } else {
51119
+ resolvedEnv[ref.envKey] = new TextDecoder().decode(plainBytes);
51120
+ }
51121
+ vaultResolved.push(ref.vaultKey);
51122
+ }
51123
+ }
51124
+ }
51063
51125
  const config3 = {};
51064
- if (deployEnv)
51065
- config3.env = deployEnv;
51126
+ if (Object.keys(resolvedEnv).length > 0 || deployEnv && Object.keys(deployEnv).length > 0) {
51127
+ config3.env = Object.keys(resolvedEnv).length > 0 ? resolvedEnv : deployEnv;
51128
+ }
51066
51129
  if (runtime)
51067
51130
  config3.runtime = runtime;
51068
51131
  if (memory_mb)
@@ -51072,12 +51135,18 @@ ${lines.join(`
51072
51135
  const result = await client2.mcpDeploy(server_name, source, Object.keys(config3).length > 0 ? config3 : undefined, scope);
51073
51136
  const toolList = result.tools?.map((t) => ` - ${t.name}: ${t.description}`).join(`
51074
51137
  `) ?? " (pending)";
51138
+ let vaultNote = "";
51139
+ if (vaultResolved.length > 0) {
51140
+ vaultNote = `
51141
+
51142
+ Vault keys resolved: ${vaultResolved.join(", ")} (decrypted client-side, sent over TLS)`;
51143
+ }
51075
51144
  return text(`Deployed "${server_name}" (status: ${result.status}).
51076
51145
 
51077
51146
  Tools:
51078
51147
  ${toolList}
51079
51148
 
51080
- Default scope: peer (private). Use mesh_mcp_scope to share.`);
51149
+ Default scope: peer (private). Use mesh_mcp_scope to share.${vaultNote}`);
51081
51150
  }
51082
51151
  case "mesh_mcp_undeploy": {
51083
51152
  const { server_name } = args ?? {};
@@ -52535,7 +52604,7 @@ init_config();
52535
52604
  // package.json
52536
52605
  var package_default = {
52537
52606
  name: "claudemesh-cli",
52538
- version: "0.8.4",
52607
+ version: "0.8.6",
52539
52608
  description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
52540
52609
  keywords: [
52541
52610
  "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.6",
4
4
  "description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -50,8 +50,8 @@
50
50
  "vitest": "4.0.14",
51
51
  "@turbostarter/vitest-config": "0.1.0",
52
52
  "@turbostarter/tsconfig": "0.1.0",
53
- "@turbostarter/prettier-config": "0.1.0",
54
- "@turbostarter/eslint-config": "0.1.0"
53
+ "@turbostarter/eslint-config": "0.1.0",
54
+ "@turbostarter/prettier-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",