claudemesh-cli 0.1.13 → 0.1.15
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 +61 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6514,7 +6514,7 @@ function loadConfig() {
|
|
|
6514
6514
|
if (!parsed || !Array.isArray(parsed.meshes)) {
|
|
6515
6515
|
return { version: 1, meshes: [] };
|
|
6516
6516
|
}
|
|
6517
|
-
return { version: 1, meshes: parsed.meshes };
|
|
6517
|
+
return { version: 1, meshes: parsed.meshes, displayName: parsed.displayName };
|
|
6518
6518
|
} catch (e) {
|
|
6519
6519
|
throw new Error(`Failed to load ${CONFIG_PATH}: ${e instanceof Error ? e.message : String(e)}`);
|
|
6520
6520
|
}
|
|
@@ -46431,9 +46431,11 @@ class BrokerClient {
|
|
|
46431
46431
|
const onOpen = async () => {
|
|
46432
46432
|
this.debug("ws open → generating session keypair + signing hello");
|
|
46433
46433
|
try {
|
|
46434
|
-
|
|
46435
|
-
|
|
46436
|
-
|
|
46434
|
+
if (!this.sessionPubkey) {
|
|
46435
|
+
const sessionKP = await generateKeypair2();
|
|
46436
|
+
this.sessionPubkey = sessionKP.publicKey;
|
|
46437
|
+
this.sessionSecretKey = sessionKP.secretKey;
|
|
46438
|
+
}
|
|
46437
46439
|
const { timestamp, signature } = await signHello(this.mesh.meshId, this.mesh.memberId, this.mesh.pubkey, this.mesh.secretKey);
|
|
46438
46440
|
ws.send(JSON.stringify({
|
|
46439
46441
|
type: "hello",
|
|
@@ -46441,7 +46443,7 @@ class BrokerClient {
|
|
|
46441
46443
|
memberId: this.mesh.memberId,
|
|
46442
46444
|
pubkey: this.mesh.pubkey,
|
|
46443
46445
|
sessionPubkey: this.sessionPubkey,
|
|
46444
|
-
displayName: process.env.CLAUDEMESH_DISPLAY_NAME || undefined,
|
|
46446
|
+
displayName: process.env.CLAUDEMESH_DISPLAY_NAME || this.opts.displayName || undefined,
|
|
46445
46447
|
sessionId: `${process.pid}-${Date.now()}`,
|
|
46446
46448
|
pid: process.pid,
|
|
46447
46449
|
cwd: process.cwd(),
|
|
@@ -46637,6 +46639,16 @@ class BrokerClient {
|
|
|
46637
46639
|
plaintext = null;
|
|
46638
46640
|
}
|
|
46639
46641
|
}
|
|
46642
|
+
if (plaintext === null && ciphertext) {
|
|
46643
|
+
try {
|
|
46644
|
+
const decoded = Buffer.from(ciphertext, "base64").toString("utf-8");
|
|
46645
|
+
if (/^[\x20-\x7E\s\u00A0-\uFFFF]*$/.test(decoded) && decoded.length > 0) {
|
|
46646
|
+
plaintext = decoded;
|
|
46647
|
+
}
|
|
46648
|
+
} catch {
|
|
46649
|
+
plaintext = null;
|
|
46650
|
+
}
|
|
46651
|
+
}
|
|
46640
46652
|
const push = {
|
|
46641
46653
|
messageId: String(msg.messageId ?? ""),
|
|
46642
46654
|
meshId: String(msg.meshId ?? ""),
|
|
@@ -46715,11 +46727,12 @@ function randomNonce() {
|
|
|
46715
46727
|
// src/ws/manager.ts
|
|
46716
46728
|
init_env();
|
|
46717
46729
|
var clients = new Map;
|
|
46730
|
+
var configDisplayName;
|
|
46718
46731
|
async function ensureClient(mesh) {
|
|
46719
46732
|
const existing = clients.get(mesh.meshId);
|
|
46720
46733
|
if (existing)
|
|
46721
46734
|
return existing;
|
|
46722
|
-
const client = new BrokerClient(mesh, { debug: env.CLAUDEMESH_DEBUG });
|
|
46735
|
+
const client = new BrokerClient(mesh, { debug: env.CLAUDEMESH_DEBUG, displayName: configDisplayName });
|
|
46723
46736
|
clients.set(mesh.meshId, client);
|
|
46724
46737
|
try {
|
|
46725
46738
|
await client.connect();
|
|
@@ -46727,6 +46740,7 @@ async function ensureClient(mesh) {
|
|
|
46727
46740
|
return client;
|
|
46728
46741
|
}
|
|
46729
46742
|
async function startClients(config2) {
|
|
46743
|
+
configDisplayName = config2.displayName;
|
|
46730
46744
|
await Promise.allSettled(config2.meshes.map(ensureClient));
|
|
46731
46745
|
}
|
|
46732
46746
|
function findClient(needle) {
|
|
@@ -46802,6 +46816,22 @@ async function resolveClient(to) {
|
|
|
46802
46816
|
error: `peer "${target}" not found in any mesh (joined: ${clients2.map((c) => c.meshSlug).join(", ")})`
|
|
46803
46817
|
};
|
|
46804
46818
|
}
|
|
46819
|
+
var peerNameCache = new Map;
|
|
46820
|
+
var peerNameCacheAge = 0;
|
|
46821
|
+
var CACHE_TTL_MS = 30000;
|
|
46822
|
+
async function resolvePeerName(client, pubkey) {
|
|
46823
|
+
const now = Date.now();
|
|
46824
|
+
if (now - peerNameCacheAge > CACHE_TTL_MS) {
|
|
46825
|
+
peerNameCache.clear();
|
|
46826
|
+
try {
|
|
46827
|
+
const peers = await client.listPeers();
|
|
46828
|
+
for (const p of peers)
|
|
46829
|
+
peerNameCache.set(p.pubkey, p.displayName);
|
|
46830
|
+
} catch {}
|
|
46831
|
+
peerNameCacheAge = now;
|
|
46832
|
+
}
|
|
46833
|
+
return peerNameCache.get(pubkey) ?? `peer-${pubkey.slice(0, 8)}`;
|
|
46834
|
+
}
|
|
46805
46835
|
function decryptFailedWarning(senderPubkey) {
|
|
46806
46836
|
const who = senderPubkey ? senderPubkey.slice(0, 12) + "…" : "unknown sender";
|
|
46807
46837
|
return `⚠ message from ${who} failed to decrypt (tampered or wrong keypair)`;
|
|
@@ -46929,13 +46959,7 @@ ${drained.join(`
|
|
|
46929
46959
|
for (const client of allClients()) {
|
|
46930
46960
|
client.onPush(async (msg) => {
|
|
46931
46961
|
const fromPubkey = msg.senderPubkey || "";
|
|
46932
|
-
|
|
46933
|
-
try {
|
|
46934
|
-
const peers = await client.listPeers();
|
|
46935
|
-
const match = peers.find((p) => p.pubkey === fromPubkey);
|
|
46936
|
-
if (match)
|
|
46937
|
-
fromName = match.displayName;
|
|
46938
|
-
} catch {}
|
|
46962
|
+
const fromName = fromPubkey ? await resolvePeerName(client, fromPubkey) : "unknown";
|
|
46939
46963
|
const content = msg.plaintext ?? decryptFailedWarning(fromPubkey);
|
|
46940
46964
|
try {
|
|
46941
46965
|
await server.notification({
|
|
@@ -47551,7 +47575,7 @@ async function runHook(args) {
|
|
|
47551
47575
|
// src/commands/launch.ts
|
|
47552
47576
|
init_config();
|
|
47553
47577
|
import { spawn } from "node:child_process";
|
|
47554
|
-
import { mkdtempSync, writeFileSync as writeFileSync4, rmSync } from "node:fs";
|
|
47578
|
+
import { mkdtempSync, writeFileSync as writeFileSync4, rmSync, readdirSync, statSync } from "node:fs";
|
|
47555
47579
|
import { tmpdir, hostname as hostname2 } from "node:os";
|
|
47556
47580
|
import { join as join4 } from "node:path";
|
|
47557
47581
|
import { createInterface } from "node:readline";
|
|
@@ -47623,15 +47647,12 @@ async function confirmPermissions() {
|
|
|
47623
47647
|
const yellow = (s) => useColor ? `\x1B[33m${s}\x1B[39m` : s;
|
|
47624
47648
|
console.log(yellow(bold(" Autonomous mode")));
|
|
47625
47649
|
console.log("");
|
|
47626
|
-
console.log("
|
|
47627
|
-
console.log("
|
|
47628
|
-
console.log("
|
|
47629
|
-
console.log(" run automatically — the same as running claude with");
|
|
47630
|
-
console.log(" --dangerously-skip-permissions.");
|
|
47650
|
+
console.log(" Claude will send and receive peer messages without asking");
|
|
47651
|
+
console.log(" you first. Peers exchange text only — no file access,");
|
|
47652
|
+
console.log(" no tool calls, no code execution.");
|
|
47631
47653
|
console.log("");
|
|
47632
|
-
console.log(dim("
|
|
47633
|
-
console.log(dim("
|
|
47634
|
-
console.log(dim(" Skip this prompt next time with: claudemesh launch -y"));
|
|
47654
|
+
console.log(dim(" Same as: claude --dangerously-skip-permissions"));
|
|
47655
|
+
console.log(dim(" Skip this prompt: claudemesh launch -y"));
|
|
47635
47656
|
console.log("");
|
|
47636
47657
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
47637
47658
|
return new Promise((resolve2, reject) => {
|
|
@@ -47710,10 +47731,22 @@ async function runLaunch(extraArgs) {
|
|
|
47710
47731
|
mesh = await pickMesh(config2.meshes);
|
|
47711
47732
|
}
|
|
47712
47733
|
const displayName = args.name ?? `${hostname2()}-${process.pid}`;
|
|
47734
|
+
const tmpBase = tmpdir();
|
|
47735
|
+
try {
|
|
47736
|
+
for (const entry of readdirSync(tmpBase)) {
|
|
47737
|
+
if (!entry.startsWith("claudemesh-"))
|
|
47738
|
+
continue;
|
|
47739
|
+
const full = join4(tmpBase, entry);
|
|
47740
|
+
const age = Date.now() - statSync(full).mtimeMs;
|
|
47741
|
+
if (age > 3600000)
|
|
47742
|
+
rmSync(full, { recursive: true, force: true });
|
|
47743
|
+
}
|
|
47744
|
+
} catch {}
|
|
47713
47745
|
const tmpDir = mkdtempSync(join4(tmpdir(), "claudemesh-"));
|
|
47714
47746
|
const sessionConfig = {
|
|
47715
47747
|
version: 1,
|
|
47716
|
-
meshes: [mesh]
|
|
47748
|
+
meshes: [mesh],
|
|
47749
|
+
displayName
|
|
47717
47750
|
};
|
|
47718
47751
|
writeFileSync4(join4(tmpDir, "config.json"), JSON.stringify(sessionConfig, null, 2) + `
|
|
47719
47752
|
`, "utf-8");
|
|
@@ -47781,12 +47814,12 @@ async function runLaunch(extraArgs) {
|
|
|
47781
47814
|
}
|
|
47782
47815
|
|
|
47783
47816
|
// src/commands/status.ts
|
|
47784
|
-
import { statSync, existsSync as existsSync3 } from "node:fs";
|
|
47817
|
+
import { statSync as statSync2, existsSync as existsSync3 } from "node:fs";
|
|
47785
47818
|
init_config();
|
|
47786
47819
|
// package.json
|
|
47787
47820
|
var package_default = {
|
|
47788
47821
|
name: "claudemesh-cli",
|
|
47789
|
-
version: "0.1.
|
|
47822
|
+
version: "0.1.15",
|
|
47790
47823
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
47791
47824
|
keywords: [
|
|
47792
47825
|
"claude-code",
|
|
@@ -47887,7 +47920,7 @@ async function runStatus() {
|
|
|
47887
47920
|
const configPath = getConfigPath();
|
|
47888
47921
|
let configPerms = "missing";
|
|
47889
47922
|
if (existsSync3(configPath)) {
|
|
47890
|
-
const st =
|
|
47923
|
+
const st = statSync2(configPath);
|
|
47891
47924
|
const mode = (st.mode & 511).toString(8).padStart(4, "0");
|
|
47892
47925
|
configPerms = mode === "0600" ? `${mode} ✓` : `${mode} ⚠ (expected 0600)`;
|
|
47893
47926
|
}
|
|
@@ -47935,7 +47968,7 @@ async function runStatus() {
|
|
|
47935
47968
|
|
|
47936
47969
|
// src/commands/doctor.ts
|
|
47937
47970
|
init_config();
|
|
47938
|
-
import { existsSync as existsSync4, readFileSync as readFileSync3, statSync as
|
|
47971
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
|
|
47939
47972
|
import { homedir as homedir4, platform as platform2 } from "node:os";
|
|
47940
47973
|
import { join as join5 } from "node:path";
|
|
47941
47974
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
@@ -48022,7 +48055,7 @@ function checkConfigFile() {
|
|
|
48022
48055
|
}
|
|
48023
48056
|
try {
|
|
48024
48057
|
loadConfig();
|
|
48025
|
-
const st =
|
|
48058
|
+
const st = statSync3(path);
|
|
48026
48059
|
const mode = (st.mode & 511).toString(8);
|
|
48027
48060
|
const secure = platform2() === "win32" || mode === "600";
|
|
48028
48061
|
return {
|