claudemesh-cli 0.8.0 → 0.8.2
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 +201 -2
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -47795,6 +47795,28 @@ async function signHello(meshId, memberId, pubkey, secretKeyHex) {
|
|
|
47795
47795
|
|
|
47796
47796
|
// src/ws/client.ts
|
|
47797
47797
|
init_keypair();
|
|
47798
|
+
function detectClaudeSessionId() {
|
|
47799
|
+
try {
|
|
47800
|
+
const { readdirSync, statSync, readFileSync: readFileSync2 } = __require("node:fs");
|
|
47801
|
+
const { join: join2 } = __require("node:path");
|
|
47802
|
+
const { homedir: homedir2 } = __require("node:os");
|
|
47803
|
+
const cwd = process.cwd();
|
|
47804
|
+
const projectsDir = join2(homedir2(), ".claude", "projects");
|
|
47805
|
+
const cwdHash = cwd.replace(/\//g, "-");
|
|
47806
|
+
const entries = readdirSync(projectsDir);
|
|
47807
|
+
const projectDir = entries.find((e) => e === cwdHash || e.startsWith(cwdHash));
|
|
47808
|
+
if (!projectDir)
|
|
47809
|
+
return null;
|
|
47810
|
+
const fullDir = join2(projectsDir, projectDir);
|
|
47811
|
+
const jsonls = readdirSync(fullDir).filter((f) => f.endsWith(".jsonl")).map((f) => ({ name: f, mtime: statSync(join2(fullDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
47812
|
+
if (jsonls.length === 0)
|
|
47813
|
+
return null;
|
|
47814
|
+
const latest = jsonls[0];
|
|
47815
|
+
return latest.name.replace(".jsonl", "");
|
|
47816
|
+
} catch {
|
|
47817
|
+
return null;
|
|
47818
|
+
}
|
|
47819
|
+
}
|
|
47798
47820
|
var MAX_QUEUED = 100;
|
|
47799
47821
|
var HELLO_ACK_TIMEOUT_MS = 5000;
|
|
47800
47822
|
var BACKOFF_CAPS = [1000, 2000, 4000, 8000, 16000, 30000];
|
|
@@ -47884,7 +47906,7 @@ class BrokerClient {
|
|
|
47884
47906
|
pubkey: this.mesh.pubkey,
|
|
47885
47907
|
sessionPubkey: this.sessionPubkey,
|
|
47886
47908
|
displayName: process.env.CLAUDEMESH_DISPLAY_NAME || this.opts.displayName || undefined,
|
|
47887
|
-
sessionId: `${process.pid}-${Date.now()}`,
|
|
47909
|
+
sessionId: process.env.CLAUDEMESH_SESSION_ID || detectClaudeSessionId() || `${process.pid}-${Date.now()}`,
|
|
47888
47910
|
pid: process.pid,
|
|
47889
47911
|
cwd: process.cwd(),
|
|
47890
47912
|
hostname: __require("os").hostname(),
|
|
@@ -50972,6 +50994,178 @@ ${lines.join(`
|
|
|
50972
50994
|
const ok = await client2.deleteWebhook(delName);
|
|
50973
50995
|
return text(ok ? `Webhook "${delName}" deactivated.` : `Failed to deactivate webhook "${delName}".`, !ok);
|
|
50974
50996
|
}
|
|
50997
|
+
case "vault_set": {
|
|
50998
|
+
const { key, value, type: vType, mount_path, description } = args ?? {};
|
|
50999
|
+
if (!key || !value)
|
|
51000
|
+
return text("vault_set: `key` and `value` required", true);
|
|
51001
|
+
const client2 = allClients()[0];
|
|
51002
|
+
if (!client2)
|
|
51003
|
+
return text("vault_set: not connected", true);
|
|
51004
|
+
const entryType = vType ?? "env";
|
|
51005
|
+
let plaintext = value;
|
|
51006
|
+
if (entryType === "file") {
|
|
51007
|
+
const { existsSync: existsSync2, readFileSync: readFileSync2 } = await import("node:fs");
|
|
51008
|
+
if (!existsSync2(value))
|
|
51009
|
+
return text(`vault_set: file not found: ${value}`, true);
|
|
51010
|
+
plaintext = readFileSync2(value, "base64");
|
|
51011
|
+
}
|
|
51012
|
+
const encoded = Buffer.from(plaintext).toString("base64");
|
|
51013
|
+
const ok = await client2.vaultSet(key, encoded, "placeholder-nonce", "placeholder-sealed", entryType, mount_path, description);
|
|
51014
|
+
if (!ok)
|
|
51015
|
+
return text("vault_set: broker did not acknowledge", true);
|
|
51016
|
+
return text(`Vault entry "${key}" stored (${entryType}).`);
|
|
51017
|
+
}
|
|
51018
|
+
case "vault_list": {
|
|
51019
|
+
const client2 = allClients()[0];
|
|
51020
|
+
if (!client2)
|
|
51021
|
+
return text("vault_list: not connected", true);
|
|
51022
|
+
const entries = await client2.vaultList();
|
|
51023
|
+
if (entries.length === 0)
|
|
51024
|
+
return text("Vault is empty.");
|
|
51025
|
+
const lines = entries.map((e) => `- **${e.key}** (${e.entry_type}${e.mount_path ? ` → ${e.mount_path}` : ""})${e.description ? ` — ${e.description}` : ""} (${e.updated_at})`);
|
|
51026
|
+
return text(`${entries.length} vault entry(s):
|
|
51027
|
+
${lines.join(`
|
|
51028
|
+
`)}`);
|
|
51029
|
+
}
|
|
51030
|
+
case "vault_delete": {
|
|
51031
|
+
const { key } = args ?? {};
|
|
51032
|
+
if (!key)
|
|
51033
|
+
return text("vault_delete: `key` required", true);
|
|
51034
|
+
const client2 = allClients()[0];
|
|
51035
|
+
if (!client2)
|
|
51036
|
+
return text("vault_delete: not connected", true);
|
|
51037
|
+
const ok = await client2.vaultDelete(key);
|
|
51038
|
+
return text(ok ? `Vault entry "${key}" deleted.` : `Vault entry "${key}" not found.`);
|
|
51039
|
+
}
|
|
51040
|
+
case "mesh_mcp_deploy": {
|
|
51041
|
+
const { server_name, file_id, git_url, git_branch, env: deployEnv, runtime, memory_mb, network_allow, scope } = args ?? {};
|
|
51042
|
+
if (!server_name)
|
|
51043
|
+
return text("mesh_mcp_deploy: `server_name` required", true);
|
|
51044
|
+
if (!file_id && !git_url)
|
|
51045
|
+
return text("mesh_mcp_deploy: either `file_id` or `git_url` required", true);
|
|
51046
|
+
const client2 = allClients()[0];
|
|
51047
|
+
if (!client2)
|
|
51048
|
+
return text("mesh_mcp_deploy: not connected", true);
|
|
51049
|
+
const source = file_id ? { type: "zip", file_id } : { type: "git", url: git_url, branch: git_branch };
|
|
51050
|
+
const config3 = {};
|
|
51051
|
+
if (deployEnv)
|
|
51052
|
+
config3.env = deployEnv;
|
|
51053
|
+
if (runtime)
|
|
51054
|
+
config3.runtime = runtime;
|
|
51055
|
+
if (memory_mb)
|
|
51056
|
+
config3.memory_mb = memory_mb;
|
|
51057
|
+
if (network_allow)
|
|
51058
|
+
config3.network_allow = network_allow;
|
|
51059
|
+
const result = await client2.mcpDeploy(server_name, source, Object.keys(config3).length > 0 ? config3 : undefined, scope);
|
|
51060
|
+
const toolList = result.tools?.map((t) => ` - ${t.name}: ${t.description}`).join(`
|
|
51061
|
+
`) ?? " (pending)";
|
|
51062
|
+
return text(`Deployed "${server_name}" (status: ${result.status}).
|
|
51063
|
+
|
|
51064
|
+
Tools:
|
|
51065
|
+
${toolList}
|
|
51066
|
+
|
|
51067
|
+
Default scope: peer (private). Use mesh_mcp_scope to share.`);
|
|
51068
|
+
}
|
|
51069
|
+
case "mesh_mcp_undeploy": {
|
|
51070
|
+
const { server_name } = args ?? {};
|
|
51071
|
+
if (!server_name)
|
|
51072
|
+
return text("mesh_mcp_undeploy: `server_name` required", true);
|
|
51073
|
+
const client2 = allClients()[0];
|
|
51074
|
+
if (!client2)
|
|
51075
|
+
return text("mesh_mcp_undeploy: not connected", true);
|
|
51076
|
+
const ok = await client2.mcpUndeploy(server_name);
|
|
51077
|
+
return text(ok ? `Service "${server_name}" undeployed.` : `Failed to undeploy "${server_name}".`);
|
|
51078
|
+
}
|
|
51079
|
+
case "mesh_mcp_update": {
|
|
51080
|
+
const { server_name } = args ?? {};
|
|
51081
|
+
if (!server_name)
|
|
51082
|
+
return text("mesh_mcp_update: `server_name` required", true);
|
|
51083
|
+
const client2 = allClients()[0];
|
|
51084
|
+
if (!client2)
|
|
51085
|
+
return text("mesh_mcp_update: not connected", true);
|
|
51086
|
+
const result = await client2.mcpUpdate(server_name);
|
|
51087
|
+
return text(`Updated "${server_name}" (status: ${result.status}).`);
|
|
51088
|
+
}
|
|
51089
|
+
case "mesh_mcp_logs": {
|
|
51090
|
+
const { server_name, lines: logLines } = args ?? {};
|
|
51091
|
+
if (!server_name)
|
|
51092
|
+
return text("mesh_mcp_logs: `server_name` required", true);
|
|
51093
|
+
const client2 = allClients()[0];
|
|
51094
|
+
if (!client2)
|
|
51095
|
+
return text("mesh_mcp_logs: not connected", true);
|
|
51096
|
+
const logs = await client2.mcpLogs(server_name, logLines);
|
|
51097
|
+
if (logs.length === 0)
|
|
51098
|
+
return text(`No logs for "${server_name}".`);
|
|
51099
|
+
return text(`Logs for "${server_name}" (${logs.length} lines):
|
|
51100
|
+
\`\`\`
|
|
51101
|
+
${logs.join(`
|
|
51102
|
+
`)}
|
|
51103
|
+
\`\`\``);
|
|
51104
|
+
}
|
|
51105
|
+
case "mesh_mcp_scope": {
|
|
51106
|
+
const { server_name, scope } = args ?? {};
|
|
51107
|
+
if (!server_name)
|
|
51108
|
+
return text("mesh_mcp_scope: `server_name` required", true);
|
|
51109
|
+
const client2 = allClients()[0];
|
|
51110
|
+
if (!client2)
|
|
51111
|
+
return text("mesh_mcp_scope: not connected", true);
|
|
51112
|
+
const result = await client2.mcpScope(server_name, scope);
|
|
51113
|
+
if (scope !== undefined) {
|
|
51114
|
+
return text(`Scope for "${server_name}" updated to: ${JSON.stringify(result.scope)}`);
|
|
51115
|
+
}
|
|
51116
|
+
return text(`**${server_name}** scope: ${JSON.stringify(result.scope)}
|
|
51117
|
+
Deployed by: ${result.deployed_by}`);
|
|
51118
|
+
}
|
|
51119
|
+
case "mesh_mcp_schema": {
|
|
51120
|
+
const { server_name, tool_name } = args ?? {};
|
|
51121
|
+
if (!server_name)
|
|
51122
|
+
return text("mesh_mcp_schema: `server_name` required", true);
|
|
51123
|
+
const client2 = allClients()[0];
|
|
51124
|
+
if (!client2)
|
|
51125
|
+
return text("mesh_mcp_schema: not connected", true);
|
|
51126
|
+
const tools = await client2.mcpServiceSchema(server_name, tool_name);
|
|
51127
|
+
if (tools.length === 0)
|
|
51128
|
+
return text(`No tools found for "${server_name}"${tool_name ? ` (tool: ${tool_name})` : ""}.`);
|
|
51129
|
+
const lines = tools.map((t) => `### ${t.name}
|
|
51130
|
+
${t.description}
|
|
51131
|
+
\`\`\`json
|
|
51132
|
+
${JSON.stringify(t.inputSchema, null, 2)}
|
|
51133
|
+
\`\`\``);
|
|
51134
|
+
return text(`Tools for "${server_name}":
|
|
51135
|
+
|
|
51136
|
+
${lines.join(`
|
|
51137
|
+
|
|
51138
|
+
`)}`);
|
|
51139
|
+
}
|
|
51140
|
+
case "mesh_mcp_catalog": {
|
|
51141
|
+
const client2 = allClients()[0];
|
|
51142
|
+
if (!client2)
|
|
51143
|
+
return text("mesh_mcp_catalog: not connected", true);
|
|
51144
|
+
const services = await client2.mcpCatalog();
|
|
51145
|
+
if (services.length === 0)
|
|
51146
|
+
return text("No services deployed in the mesh.");
|
|
51147
|
+
const lines = services.map((s) => {
|
|
51148
|
+
const scopeStr = typeof s.scope === "string" ? s.scope : JSON.stringify(s.scope);
|
|
51149
|
+
return `- **${s.name}** (${s.type}, ${s.status}) — ${s.description}
|
|
51150
|
+
${s.tool_count} tools | scope: ${scopeStr} | by ${s.deployed_by} | ${s.source_type}${s.runtime ? ` (${s.runtime})` : ""}`;
|
|
51151
|
+
});
|
|
51152
|
+
return text(`${services.length} service(s) in mesh:
|
|
51153
|
+
|
|
51154
|
+
${lines.join(`
|
|
51155
|
+
`)}`);
|
|
51156
|
+
}
|
|
51157
|
+
case "mesh_skill_deploy": {
|
|
51158
|
+
const { file_id, git_url, git_branch } = args ?? {};
|
|
51159
|
+
if (!file_id && !git_url)
|
|
51160
|
+
return text("mesh_skill_deploy: either `file_id` or `git_url` required", true);
|
|
51161
|
+
const client2 = allClients()[0];
|
|
51162
|
+
if (!client2)
|
|
51163
|
+
return text("mesh_skill_deploy: not connected", true);
|
|
51164
|
+
const source = file_id ? { type: "zip", file_id } : { type: "git", url: git_url, branch: git_branch };
|
|
51165
|
+
const result = await client2.skillDeploy(source);
|
|
51166
|
+
return text(`Skill "${result.name}" deployed.
|
|
51167
|
+
Files: ${result.files.join(", ")}`);
|
|
51168
|
+
}
|
|
50975
51169
|
default:
|
|
50976
51170
|
return text(`Unknown tool: ${name}`, true);
|
|
50977
51171
|
}
|
|
@@ -51940,6 +52134,7 @@ async function runHook(args) {
|
|
|
51940
52134
|
// src/commands/launch.ts
|
|
51941
52135
|
init_config();
|
|
51942
52136
|
import { spawn } from "node:child_process";
|
|
52137
|
+
import { randomUUID } from "node:crypto";
|
|
51943
52138
|
import { mkdtempSync, writeFileSync as writeFileSync4, rmSync, readdirSync, statSync, existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
51944
52139
|
import { tmpdir, hostname as hostname2, homedir as homedir4 } from "node:os";
|
|
51945
52140
|
import { join as join4 } from "node:path";
|
|
@@ -52248,9 +52443,12 @@ async function runLaunch(flags, rawArgs) {
|
|
|
52248
52443
|
}
|
|
52249
52444
|
filtered.push(args.claudeArgs[i]);
|
|
52250
52445
|
}
|
|
52446
|
+
const claudeSessionId = randomUUID();
|
|
52251
52447
|
const claudeArgs = [
|
|
52252
52448
|
"--dangerously-load-development-channels",
|
|
52253
52449
|
"server:claudemesh",
|
|
52450
|
+
"--session-id",
|
|
52451
|
+
claudeSessionId,
|
|
52254
52452
|
...args.skipPermConfirm ? ["--dangerously-skip-permissions"] : [],
|
|
52255
52453
|
...args.systemPrompt ? ["--system-prompt", args.systemPrompt] : [],
|
|
52256
52454
|
...filtered
|
|
@@ -52263,6 +52461,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
52263
52461
|
...process.env,
|
|
52264
52462
|
CLAUDEMESH_CONFIG_DIR: tmpDir,
|
|
52265
52463
|
CLAUDEMESH_DISPLAY_NAME: displayName,
|
|
52464
|
+
CLAUDEMESH_SESSION_ID: claudeSessionId,
|
|
52266
52465
|
MCP_TIMEOUT: process.env.MCP_TIMEOUT ?? "30000",
|
|
52267
52466
|
MAX_MCP_OUTPUT_TOKENS: process.env.MAX_MCP_OUTPUT_TOKENS ?? "50000",
|
|
52268
52467
|
...role ? { CLAUDEMESH_ROLE: role } : {}
|
|
@@ -52319,7 +52518,7 @@ init_config();
|
|
|
52319
52518
|
// package.json
|
|
52320
52519
|
var package_default = {
|
|
52321
52520
|
name: "claudemesh-cli",
|
|
52322
|
-
version: "0.8.
|
|
52521
|
+
version: "0.8.2",
|
|
52323
52522
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
52324
52523
|
keywords: [
|
|
52325
52524
|
"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.2",
|
|
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/eslint-config": "0.1.0",
|
|
52
51
|
"@turbostarter/prettier-config": "0.1.0",
|
|
53
|
-
"@turbostarter/
|
|
54
|
-
"@turbostarter/vitest-config": "0.1.0"
|
|
52
|
+
"@turbostarter/eslint-config": "0.1.0",
|
|
53
|
+
"@turbostarter/vitest-config": "0.1.0",
|
|
54
|
+
"@turbostarter/tsconfig": "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",
|