claudemesh-cli 1.34.9 → 1.34.11

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.
@@ -104,7 +104,7 @@ __export(exports_urls, {
104
104
  VERSION: () => VERSION,
105
105
  URLS: () => URLS
106
106
  });
107
- var URLS, VERSION = "1.34.9", env;
107
+ var URLS, VERSION = "1.34.11", env;
108
108
  var init_urls = __esm(() => {
109
109
  URLS = {
110
110
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -4339,7 +4339,7 @@ async function ensureDaemonRunning(meshSlug, quiet) {
4339
4339
  render.ok(`daemon ready (${res.durationMs}ms)`);
4340
4340
  return;
4341
4341
  }
4342
- render.warn(`daemon ${res.state}${res.reason ? `: ${res.reason}` : ""}`, "Run `claudemesh daemon up --mesh " + meshSlug + "` manually, then re-launch.");
4342
+ render.warn(`daemon ${res.state}${res.reason ? `: ${res.reason}` : ""}`, "Run `claudemesh daemon up` manually, then re-launch.");
4343
4343
  }
4344
4344
  async function warnIfDaemonStale(quiet) {
4345
4345
  if (quiet)
@@ -4353,7 +4353,7 @@ async function warnIfDaemonStale(quiet) {
4353
4353
  const daemonVersion = res.body.daemon_version ?? "";
4354
4354
  if (!daemonVersion || daemonVersion === VERSION2)
4355
4355
  return;
4356
- render.warn(`daemon is ${daemonVersion}, CLI is ${VERSION2} — restart to pick up new fixes.`, "Run: `claudemesh daemon down && claudemesh daemon up` (or restart the launchd / systemd-user unit).");
4356
+ render.warn(`daemon is ${daemonVersion}, CLI is ${VERSION2} — restart to pick up new fixes.`, "Run: `claudemesh daemon down && claudemesh daemon up` (no --mesh — daemon attaches to every joined mesh; restart the launchd / systemd-user unit if you installed one).");
4357
4357
  } catch {}
4358
4358
  }
4359
4359
  function parseGroupsString(raw) {
@@ -9615,6 +9615,11 @@ function migrateInbox(db) {
9615
9615
  db.exec(`ALTER TABLE inbox ADD COLUMN seen_at INTEGER`);
9616
9616
  db.exec(`CREATE INDEX IF NOT EXISTS inbox_seen_at ON inbox(seen_at)`);
9617
9617
  }
9618
+ if (!cols.some((c) => c.name === "recipient_pubkey")) {
9619
+ db.exec(`ALTER TABLE inbox ADD COLUMN recipient_pubkey TEXT`);
9620
+ db.exec(`ALTER TABLE inbox ADD COLUMN recipient_kind TEXT`);
9621
+ db.exec(`CREATE INDEX IF NOT EXISTS inbox_recipient ON inbox(recipient_pubkey)`);
9622
+ }
9618
9623
  }
9619
9624
  function insertIfNew(db, row) {
9620
9625
  const before = db.prepare(`SELECT id FROM inbox WHERE client_message_id = ?`).get(row.client_message_id);
@@ -9623,10 +9628,11 @@ function insertIfNew(db, row) {
9623
9628
  db.prepare(`
9624
9629
  INSERT INTO inbox (
9625
9630
  id, client_message_id, broker_message_id, mesh, topic,
9626
- sender_pubkey, sender_name, body, meta, received_at, reply_to_id
9627
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
9631
+ sender_pubkey, sender_name, body, meta, received_at, reply_to_id,
9632
+ recipient_pubkey, recipient_kind
9633
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
9628
9634
  ON CONFLICT(client_message_id) DO NOTHING
9629
- `).run(row.id, row.client_message_id, row.broker_message_id, row.mesh, row.topic, row.sender_pubkey, row.sender_name, row.body, row.meta, row.received_at, row.reply_to_id);
9635
+ `).run(row.id, row.client_message_id, row.broker_message_id, row.mesh, row.topic, row.sender_pubkey, row.sender_name, row.body, row.meta, row.received_at, row.reply_to_id, row.recipient_pubkey, row.recipient_kind);
9630
9636
  const after = db.prepare(`SELECT id FROM inbox WHERE client_message_id = ?`).get(row.client_message_id);
9631
9637
  return after?.id === row.id ? row.id : null;
9632
9638
  }
@@ -9652,9 +9658,19 @@ function listInbox(db, p) {
9652
9658
  if (p.unreadOnly === true) {
9653
9659
  where.push("seen_at IS NULL");
9654
9660
  }
9661
+ if (p.recipientPubkey) {
9662
+ const ors = ["recipient_pubkey IS NULL", "recipient_pubkey = ?"];
9663
+ args.push(p.recipientPubkey);
9664
+ if (p.recipientMemberPubkey) {
9665
+ ors.push("recipient_pubkey = ?");
9666
+ args.push(p.recipientMemberPubkey);
9667
+ }
9668
+ where.push(`(${ors.join(" OR ")})`);
9669
+ }
9655
9670
  const sql = `
9656
9671
  SELECT id, client_message_id, broker_message_id, mesh, topic,
9657
- sender_pubkey, sender_name, body, meta, received_at, reply_to_id, seen_at
9672
+ sender_pubkey, sender_name, body, meta, received_at, reply_to_id, seen_at,
9673
+ recipient_pubkey, recipient_kind
9658
9674
  FROM inbox
9659
9675
  ${where.length ? "WHERE " + where.join(" AND ") : ""}
9660
9676
  ORDER BY received_at DESC
@@ -9719,7 +9735,29 @@ function writeSse(res, e, idCounter) {
9719
9735
 
9720
9736
  `);
9721
9737
  }
9722
- function bindSseStream(res, bus) {
9738
+ function shouldDeliver(e, f) {
9739
+ if (!f.sessionPubkey && !f.memberPubkey && !f.meshSlug)
9740
+ return true;
9741
+ if (f.meshSlug) {
9742
+ const eventMesh = typeof e.data.mesh === "string" ? e.data.mesh : null;
9743
+ if (eventMesh && eventMesh !== f.meshSlug)
9744
+ return false;
9745
+ }
9746
+ if (e.kind !== "message")
9747
+ return true;
9748
+ const recipientKind = typeof e.data.recipient_kind === "string" ? e.data.recipient_kind : null;
9749
+ const recipientPubkey = typeof e.data.recipient_pubkey === "string" ? e.data.recipient_pubkey.toLowerCase() : null;
9750
+ if (!recipientKind || !recipientPubkey)
9751
+ return true;
9752
+ if (recipientKind === "session") {
9753
+ return !!f.sessionPubkey && f.sessionPubkey.toLowerCase() === recipientPubkey;
9754
+ }
9755
+ if (recipientKind === "member") {
9756
+ return !!f.memberPubkey && f.memberPubkey.toLowerCase() === recipientPubkey;
9757
+ }
9758
+ return true;
9759
+ }
9760
+ function bindSseStream(res, bus, filter = {}) {
9723
9761
  res.statusCode = 200;
9724
9762
  res.setHeader("Content-Type", "text/event-stream");
9725
9763
  res.setHeader("Cache-Control", "no-cache, no-transform");
@@ -9729,7 +9767,11 @@ function bindSseStream(res, bus) {
9729
9767
 
9730
9768
  `);
9731
9769
  let counter = 0;
9732
- const unsubscribe = bus.subscribe((e) => writeSse(res, e, ++counter));
9770
+ const unsubscribe = bus.subscribe((e) => {
9771
+ if (!shouldDeliver(e, filter))
9772
+ return;
9773
+ writeSse(res, e, ++counter);
9774
+ });
9733
9775
  const heartbeat = setInterval(() => {
9734
9776
  try {
9735
9777
  res.write(`: keepalive
@@ -10146,7 +10188,16 @@ function makeHandler(opts) {
10146
10188
  respond(res, 503, { error: "event bus not initialised" });
10147
10189
  return;
10148
10190
  }
10149
- bindSseStream(res, opts.bus);
10191
+ const filter = {};
10192
+ if (session?.presence?.sessionPubkey)
10193
+ filter.sessionPubkey = session.presence.sessionPubkey;
10194
+ if (session?.mesh) {
10195
+ filter.meshSlug = session.mesh;
10196
+ const meshCfg = opts.meshConfigs?.get(session.mesh);
10197
+ if (meshCfg?.pubkey)
10198
+ filter.memberPubkey = meshCfg.pubkey;
10199
+ }
10200
+ bindSseStream(res, opts.bus, filter);
10150
10201
  return;
10151
10202
  }
10152
10203
  if (req.method === "GET" && url.pathname === "/v1/peers") {
@@ -10436,12 +10487,17 @@ function makeHandler(opts) {
10436
10487
  const meshFilter = meshFromCtx(url.searchParams.get("mesh")) ?? undefined;
10437
10488
  const unreadOnly = url.searchParams.get("unread_only") === "true";
10438
10489
  const markSeen = url.searchParams.get("mark_seen") !== "false";
10490
+ const recipientPubkey = session?.presence?.sessionPubkey;
10491
+ const meshCfgForRecipient = session?.mesh ? opts.meshConfigs?.get(session.mesh) : undefined;
10492
+ const recipientMemberPubkey = meshCfgForRecipient?.pubkey;
10439
10493
  const rows = listInbox(opts.inboxDb, {
10440
10494
  since: Number.isFinite(since) ? since : undefined,
10441
10495
  topic,
10442
10496
  fromPubkey,
10443
10497
  ...meshFilter ? { mesh: meshFilter } : {},
10444
10498
  unreadOnly,
10499
+ ...recipientPubkey ? { recipientPubkey } : {},
10500
+ ...recipientMemberPubkey ? { recipientMemberPubkey } : {},
10445
10501
  limit: Number.isFinite(limit ?? NaN) ? limit : undefined
10446
10502
  });
10447
10503
  let flippedCount = 0;
@@ -10463,7 +10519,9 @@ function makeHandler(opts) {
10463
10519
  body: r.body,
10464
10520
  received_at: new Date(r.received_at).toISOString(),
10465
10521
  reply_to_id: r.reply_to_id,
10466
- seen_at: r.seen_at ? new Date(r.seen_at).toISOString() : null
10522
+ seen_at: r.seen_at ? new Date(r.seen_at).toISOString() : null,
10523
+ recipient_pubkey: r.recipient_pubkey,
10524
+ recipient_kind: r.recipient_kind
10467
10525
  })),
10468
10526
  marked_seen: flippedCount
10469
10527
  });
@@ -11839,7 +11897,9 @@ async function handleBrokerPush(msg, ctx) {
11839
11897
  body,
11840
11898
  meta: createdAt ? JSON.stringify({ created_at: createdAt }) : null,
11841
11899
  received_at: Date.now(),
11842
- reply_to_id: replyToId
11900
+ reply_to_id: replyToId,
11901
+ recipient_pubkey: ctx.recipientPubkey ?? null,
11902
+ recipient_kind: ctx.recipientKind ?? null
11843
11903
  });
11844
11904
  ctx.ackClientMessage?.(clientMessageId, brokerMessageId);
11845
11905
  if (!inserted)
@@ -11857,7 +11917,9 @@ async function handleBrokerPush(msg, ctx) {
11857
11917
  priority,
11858
11918
  ...subtype ? { subtype } : {},
11859
11919
  body,
11860
- created_at: createdAt
11920
+ created_at: createdAt,
11921
+ ...ctx.recipientPubkey ? { recipient_pubkey: ctx.recipientPubkey } : {},
11922
+ ...ctx.recipientKind ? { recipient_kind: ctx.recipientKind } : {}
11861
11923
  });
11862
11924
  }
11863
11925
  async function decryptOrFallback(args) {
@@ -12069,22 +12131,7 @@ async function runDaemon(opts = {}) {
12069
12131
  }
12070
12132
  const bus = new EventBus;
12071
12133
  const cfg = readConfig();
12072
- let meshes;
12073
- if (opts.mesh) {
12074
- const found = cfg.meshes.find((m) => m.slug === opts.mesh);
12075
- if (!found) {
12076
- process.stderr.write(`mesh not found: ${opts.mesh}
12077
- `);
12078
- process.stderr.write(`joined meshes: ${cfg.meshes.map((m) => m.slug).join(", ") || "(none)"}
12079
- `);
12080
- releaseSingletonLock();
12081
- try {
12082
- outboxDb.close();
12083
- } catch {}
12084
- return 2;
12085
- }
12086
- meshes = [found];
12087
- } else if (cfg.meshes.length === 0) {
12134
+ if (cfg.meshes.length === 0) {
12088
12135
  process.stderr.write(`no mesh joined; run \`claudemesh join <invite-url>\` first
12089
12136
  `);
12090
12137
  releaseSingletonLock();
@@ -12092,9 +12139,8 @@ async function runDaemon(opts = {}) {
12092
12139
  outboxDb.close();
12093
12140
  } catch {}
12094
12141
  return 2;
12095
- } else {
12096
- meshes = cfg.meshes;
12097
12142
  }
12143
+ const meshes = cfg.meshes;
12098
12144
  const sessionBrokers = new Map;
12099
12145
  const sessionBrokersByPubkey = new Map;
12100
12146
  const brokers = new Map;
@@ -12102,7 +12148,6 @@ async function runDaemon(opts = {}) {
12102
12148
  for (const mesh of meshes) {
12103
12149
  meshConfigs.set(mesh.slug, mesh);
12104
12150
  const broker = new DaemonBrokerClient(mesh, {
12105
- displayName: opts.displayName,
12106
12151
  onStatusChange: (s) => {
12107
12152
  process.stdout.write(JSON.stringify({
12108
12153
  msg: "broker_status",
@@ -12130,7 +12175,9 @@ async function runDaemon(opts = {}) {
12130
12175
  if (lower === ownMember)
12131
12176
  return true;
12132
12177
  return sessionBrokersByPubkey.has(lower);
12133
- }
12178
+ },
12179
+ recipientPubkey: mesh.pubkey,
12180
+ recipientKind: "member"
12134
12181
  });
12135
12182
  }
12136
12183
  });
@@ -12169,6 +12216,7 @@ async function runDaemon(opts = {}) {
12169
12216
  prior.close().catch(() => {});
12170
12217
  }
12171
12218
  const sessionSecretKeyHex = info.presence.sessionSecretKey;
12219
+ const sessionPubkeyHex = info.presence.sessionPubkey;
12172
12220
  const client = new SessionBrokerClient({
12173
12221
  mesh: meshConfig,
12174
12222
  sessionPubkey: info.presence.sessionPubkey,
@@ -12186,7 +12234,9 @@ async function runDaemon(opts = {}) {
12186
12234
  meshSlug: meshConfig.slug,
12187
12235
  recipientSecretKeyHex: meshConfig.secretKey,
12188
12236
  sessionSecretKeyHex,
12189
- ackClientMessage: (cmid, bmid) => client.sendClientAck(cmid, bmid)
12237
+ ackClientMessage: (cmid, bmid) => client.sendClientAck(cmid, bmid),
12238
+ recipientPubkey: sessionPubkeyHex,
12239
+ recipientKind: "session"
12190
12240
  });
12191
12241
  }
12192
12242
  });
@@ -12234,6 +12284,7 @@ async function runDaemon(opts = {}) {
12234
12284
  }
12235
12285
  process.stdout.write(JSON.stringify({
12236
12286
  msg: "daemon_started",
12287
+ version: VERSION,
12237
12288
  pid: process.pid,
12238
12289
  sock: DAEMON_PATHS.SOCK_FILE,
12239
12290
  tcp: tcpEnabled ? `127.0.0.1:47823` : null,
@@ -12289,6 +12340,7 @@ var init_run = __esm(() => {
12289
12340
  init_inbound();
12290
12341
  init_identity();
12291
12342
  init_facade();
12343
+ init_urls();
12292
12344
  });
12293
12345
 
12294
12346
  // src/daemon/service-install.ts
@@ -12508,11 +12560,17 @@ async function runDaemonCommand(sub, opts, rest = []) {
12508
12560
  return printDaemonUsage();
12509
12561
  case "up":
12510
12562
  case "start":
12563
+ if (opts.mesh) {
12564
+ process.stderr.write(`[claudemesh] --mesh on \`daemon up\` is deprecated; the daemon attaches to every joined mesh automatically. ` + `Ignoring --mesh ${opts.mesh}.
12565
+ `);
12566
+ }
12567
+ if (opts.displayName) {
12568
+ process.stderr.write(`[claudemesh] --name on \`daemon up\` is deprecated; per-mesh display names live in config.json (set at join time), ` + `and session display names come from \`claudemesh launch --name\`. Ignoring --name ${opts.displayName}.
12569
+ `);
12570
+ }
12511
12571
  return runDaemon({
12512
12572
  tcpEnabled: !opts.noTcp,
12513
- publicHealthCheck: opts.publicHealth,
12514
- mesh: opts.mesh,
12515
- displayName: opts.displayName
12573
+ publicHealthCheck: opts.publicHealth
12516
12574
  });
12517
12575
  case "help":
12518
12576
  case "--help":
@@ -12555,11 +12613,10 @@ COMMANDS
12555
12613
  accept-host pin the current host fingerprint
12556
12614
  outbox list list local outbox rows (newest first)
12557
12615
  outbox requeue <id> re-enqueue an aborted / dead outbox row
12558
- install-service --mesh <s> write launchd (macOS) / systemd-user (Linux) unit
12616
+ install-service write launchd (macOS) / systemd-user (Linux) unit
12559
12617
  uninstall-service remove the platform service unit
12560
12618
 
12561
12619
  OPTIONS
12562
- --mesh <slug> attach to / target this mesh
12563
12620
  --name <displayName> override CLAUDEMESH_DISPLAY_NAME
12564
12621
  --no-tcp disable the loopback TCP listener (UDS only)
12565
12622
  --public-health expose /v1/health unauthenticated on TCP
@@ -12667,11 +12724,17 @@ async function runInstallService(opts) {
12667
12724
  return 1;
12668
12725
  }
12669
12726
  }
12727
+ if (opts.mesh) {
12728
+ process.stderr.write(`[claudemesh] --mesh on \`daemon install-service\` is deprecated and ignored; the daemon attaches to every joined mesh.
12729
+ `);
12730
+ }
12731
+ if (opts.displayName) {
12732
+ process.stderr.write(`[claudemesh] --name on \`daemon install-service\` is deprecated and ignored; per-mesh names live in config.json, session names come from \`claudemesh launch --name\`.
12733
+ `);
12734
+ }
12670
12735
  try {
12671
12736
  const r = installService2({
12672
- binaryPath: binary,
12673
- ...opts.mesh ? { meshSlug: opts.mesh } : {},
12674
- ...opts.displayName ? { displayName: opts.displayName } : {}
12737
+ binaryPath: binary
12675
12738
  });
12676
12739
  if (opts.json) {
12677
12740
  process.stdout.write(JSON.stringify({ ok: true, ...r }) + `
@@ -19978,16 +20041,18 @@ Security
19978
20041
  claudemesh backup [file] encrypt config → portable recovery file
19979
20042
  claudemesh restore <file> restore config from a backup file
19980
20043
 
19981
- Daemon (long-lived peer mesh runtime, v0.9.0)
19982
- claudemesh daemon up start daemon (alias: start) [--mesh <slug>] [--no-tcp]
20044
+ Daemon (long-lived peer mesh runtime — universal across every joined mesh)
20045
+ claudemesh daemon up start daemon (alias: start) [--no-tcp]
19983
20046
  claudemesh daemon status show running pid + IPC health [--json]
19984
20047
  claudemesh daemon down stop daemon (alias: stop)
19985
20048
  claudemesh daemon version ipc + schema version of running daemon
19986
20049
  claudemesh daemon outbox list list local outbox rows [--failed|--pending|--inflight|--done]
19987
20050
  claudemesh daemon outbox requeue <id> re-enqueue an aborted/dead row [--new-client-id <id>]
19988
20051
  claudemesh daemon accept-host pin current host fingerprint
19989
- claudemesh daemon install-service --mesh <slug> write launchd / systemd-user unit
19990
- claudemesh daemon uninstall-service remove the unit
20052
+ claudemesh daemon install-service write launchd / systemd-user unit
20053
+ claudemesh daemon uninstall-service remove the unit
20054
+ Note: the daemon attaches to every mesh in ~/.claudemesh/config.json
20055
+ automatically; --mesh on up / install-service is deprecated and ignored.
19991
20056
 
19992
20057
  Setup
19993
20058
  claudemesh install register MCP server + hooks
@@ -21089,4 +21154,4 @@ main().catch((err) => {
21089
21154
  process.exit(EXIT.INTERNAL_ERROR);
21090
21155
  });
21091
21156
 
21092
- //# debugId=7232363C9624744664756E2164756E21
21157
+ //# debugId=3D8CCE13DCC94B5264756E2164756E21