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.
Files changed (2) hide show
  1. package/dist/index.js +61 -28
  2. 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
- const sessionKP = await generateKeypair2();
46435
- this.sessionPubkey = sessionKP.publicKey;
46436
- this.sessionSecretKey = sessionKP.secretKey;
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
- let fromName = fromPubkey ? `peer-${fromPubkey.slice(0, 8)}` : "unknown";
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(" For peers to chat seamlessly, Claude needs to send and");
47627
- console.log(" receive messages without asking for approval each time.");
47628
- console.log(" This means tool calls (like sending a peer message) will");
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(" Claude still can't access anything outside your mesh —"));
47633
- console.log(dim(" peers only exchange text messages, not tool calls."));
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.13",
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 = statSync(configPath);
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 statSync2 } from "node:fs";
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 = statSync2(path);
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 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudemesh-cli",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
5
5
  "keywords": [
6
6
  "claude-code",