claudemesh-cli 1.35.1 → 1.37.0

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.35.1", env;
107
+ var URLS, VERSION = "1.37.0", env;
108
108
  var init_urls = __esm(() => {
109
109
  URLS = {
110
110
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -3668,6 +3668,9 @@ var init_paths2 = __esm(() => {
3668
3668
  },
3669
3669
  get LOG_FILE() {
3670
3670
  return join3(this.DAEMON_DIR, "daemon.log");
3671
+ },
3672
+ get SESSIONS_FILE() {
3673
+ return join3(this.DAEMON_DIR, "sessions.json");
3671
3674
  }
3672
3675
  };
3673
3676
  });
@@ -8195,12 +8198,12 @@ async function runPeers(flags) {
8195
8198
  for (const slug of slugs) {
8196
8199
  try {
8197
8200
  const peers = await listPeersForMesh(slug);
8201
+ const visible = flags.all ? peers : peers.filter((p) => p.peerRole !== "control-plane");
8198
8202
  if (wantsJson) {
8199
- const projected = fieldList ? peers.map((p) => projectFields(p, fieldList)) : peers;
8203
+ const projected = fieldList ? visible.map((p) => projectFields(p, fieldList)) : visible;
8200
8204
  allJson.push({ mesh: slug, peers: projected });
8201
8205
  continue;
8202
8206
  }
8203
- const visible = flags.all ? peers : peers.filter((p) => p.peerRole !== "control-plane");
8204
8207
  const sorted = visible.slice().sort((a, b) => {
8205
8208
  const score = (p) => p.isThisSession ? 0 : p.isSelf ? 1 : 2;
8206
8209
  return score(a) - score(b);
@@ -8274,37 +8277,64 @@ async function runSend(flags, to, message) {
8274
8277
  }
8275
8278
  const priority = flags.priority === "now" ? "now" : flags.priority === "low" ? "low" : "next";
8276
8279
  const config = readConfig();
8277
- const meshSlug = flags.mesh ?? (config.meshes.length === 1 ? config.meshes[0].slug : null);
8278
- if (!to.startsWith("@") && !to.startsWith("#") && to !== "*" && /^[0-9a-f]{4,63}$/i.test(to)) {
8279
- try {
8280
- const { tryListPeersViaDaemon: tryListPeersViaDaemon2 } = await Promise.resolve().then(() => (init_daemon_route(), exports_daemon_route));
8281
- const peers = await tryListPeersViaDaemon2() ?? [];
8282
- const lower = to.toLowerCase();
8283
- const matches2 = peers.filter((p) => {
8284
- const pk = p.pubkey ?? "";
8285
- const mpk = p.memberPubkey ?? "";
8286
- return pk.toLowerCase().startsWith(lower) || mpk.toLowerCase().startsWith(lower);
8287
- });
8288
- if (matches2.length === 0) {
8289
- render.err(`No peer matches hex prefix "${to}".`);
8290
- const names = peers.map((p) => p.displayName).filter(Boolean).join(", ");
8291
- if (names)
8292
- render.hint(`online: ${names}`);
8293
- process.exit(1);
8294
- }
8295
- if (matches2.length > 1) {
8296
- const candidates = matches2.map((p) => {
8297
- const pk = p.pubkey ?? "";
8298
- const dn = p.displayName ?? "?";
8299
- return `${dn} ${pk.slice(0, 16)}…`;
8300
- }).join(", ");
8301
- render.err(`Ambiguous hex prefix "${to}" matches ${matches2.length} peers.`);
8280
+ let meshSlug = flags.mesh ?? (config.meshes.length === 1 ? config.meshes[0].slug : null);
8281
+ const isDirect = !to.startsWith("@") && !to.startsWith("#") && to !== "*";
8282
+ const isFullPubkey = /^[0-9a-f]{64}$/i.test(to);
8283
+ const isPrefix = /^[0-9a-f]{4,63}$/i.test(to);
8284
+ const isName = isDirect && !isFullPubkey && !isPrefix;
8285
+ if (isDirect && (isPrefix || isName || isFullPubkey && !meshSlug)) {
8286
+ const { tryListPeersViaDaemon: tryListPeersViaDaemon2 } = await Promise.resolve().then(() => (init_daemon_route(), exports_daemon_route));
8287
+ const searchSlugs = meshSlug ? [meshSlug] : config.meshes.map((m) => m.slug);
8288
+ const lower = to.toLowerCase();
8289
+ let daemonReachable2 = false;
8290
+ const matches2 = [];
8291
+ for (const slug of searchSlugs) {
8292
+ const peers = await tryListPeersViaDaemon2(slug);
8293
+ if (peers === null)
8294
+ continue;
8295
+ daemonReachable2 = true;
8296
+ for (const p of peers) {
8297
+ if (p.peerRole === "control-plane")
8298
+ continue;
8299
+ const pk = (p.pubkey ?? "").toLowerCase();
8300
+ const mpk = (p.memberPubkey ?? "").toLowerCase();
8301
+ const dn = p.displayName ?? "?";
8302
+ const hit = isName ? dn.toLowerCase() === lower : pk.startsWith(lower) || mpk.startsWith(lower);
8303
+ if (hit)
8304
+ matches2.push({ slug, pubkey: p.pubkey ?? "", displayName: dn });
8305
+ }
8306
+ }
8307
+ if (daemonReachable2) {
8308
+ const byPubkey = new Map;
8309
+ for (const m of matches2)
8310
+ if (!byPubkey.has(m.pubkey))
8311
+ byPubkey.set(m.pubkey, m);
8312
+ const uniq = [...byPubkey.values()];
8313
+ const meshesHit = [...new Set(uniq.map((m) => m.slug))];
8314
+ if (uniq.length === 0) {
8315
+ if (!isFullPubkey) {
8316
+ render.err(`No peer matches "${to}"${flags.mesh ? ` on mesh "${flags.mesh}"` : " on any joined mesh"}.`);
8317
+ render.hint("Check `claudemesh peer list` (add --mesh <slug> to scope).");
8318
+ process.exit(1);
8319
+ }
8320
+ } else if (uniq.length > 1) {
8321
+ if (meshesHit.length > 1 && !meshSlug) {
8322
+ const where = uniq.map((m) => `${m.displayName} ${m.pubkey.slice(0, 12)}… @${m.slug}`).join(", ");
8323
+ render.err(`"${to}" matches peers on ${meshesHit.length} meshes — pick one with --mesh <slug>.`);
8324
+ render.hint(`candidates: ${where}`);
8325
+ process.exit(1);
8326
+ }
8327
+ const candidates = uniq.map((m) => `${m.displayName} ${m.pubkey.slice(0, 16)}…`).join(", ");
8328
+ render.err(`Ambiguous ${isName ? "name" : "prefix"} "${to}" — matches ${uniq.length} peers.`);
8302
8329
  render.hint(`candidates: ${candidates}`);
8303
8330
  render.hint("Use a longer prefix or paste the full 64-char pubkey.");
8304
8331
  process.exit(1);
8332
+ } else {
8333
+ meshSlug = uniq[0].slug;
8334
+ if (!isFullPubkey)
8335
+ to = uniq[0].pubkey;
8305
8336
  }
8306
- to = matches2[0].pubkey ?? to;
8307
- } catch {}
8337
+ }
8308
8338
  }
8309
8339
  if (meshSlug) {
8310
8340
  const joined = config.meshes.find((m) => m.slug === meshSlug);
@@ -8327,7 +8357,7 @@ async function runSend(flags, to, message) {
8327
8357
  return false;
8328
8358
  if (ownSessionPk && r.pubkey.toLowerCase() === ownSessionPk)
8329
8359
  return false;
8330
- if (r.channel === "claudemesh-daemon")
8360
+ if (r.peerRole === "control-plane" || r.channel === "claudemesh-daemon")
8331
8361
  return false;
8332
8362
  return r.memberPubkey?.toLowerCase() === to.toLowerCase();
8333
8363
  });
@@ -8374,14 +8404,40 @@ async function runSend(flags, to, message) {
8374
8404
  }
8375
8405
  }
8376
8406
  }
8407
+ if (flags.self) {
8408
+ render.warn("--self had no effect: it only applies when the target is your own member pubkey (fan-out to your sibling sessions). Sending to this specific pubkey directly.");
8409
+ }
8410
+ let recipientOnline = null;
8411
+ let recipientName;
8412
+ if (isDirect && meshSlug) {
8413
+ const { tryListPeersViaDaemon: tryListPeersViaDaemon2 } = await Promise.resolve().then(() => (init_daemon_route(), exports_daemon_route));
8414
+ const peers = await tryListPeersViaDaemon2(meshSlug);
8415
+ if (peers !== null) {
8416
+ const lower = to.toLowerCase();
8417
+ const match = peers.find((p) => {
8418
+ const r = p;
8419
+ if (r.peerRole === "control-plane")
8420
+ return false;
8421
+ return r.pubkey?.toLowerCase() === lower || r.memberPubkey?.toLowerCase() === lower;
8422
+ });
8423
+ recipientOnline = !!match;
8424
+ recipientName = match ? match.displayName : undefined;
8425
+ }
8426
+ }
8427
+ const offlineHint = "Session pubkeys are ephemeral — a key from an ended session never reconnects, so the message can't be delivered. Re-fetch a live target with `claudemesh peer list --json`.";
8377
8428
  {
8378
8429
  const dr = await trySendViaDaemon({ to, message, priority, expectedMesh: meshSlug ?? undefined });
8379
8430
  if (dr !== null) {
8380
8431
  if (dr.ok) {
8381
- if (flags.json)
8382
- console.log(JSON.stringify({ ok: true, messageId: dr.messageId, target: to, via: "daemon", duplicate: !!dr.duplicate }));
8383
- else
8384
- render.ok(`sent to ${to} (daemon)`, dr.messageId ? dim(dr.messageId.slice(0, 8)) : undefined);
8432
+ if (flags.json) {
8433
+ console.log(JSON.stringify({ ok: true, messageId: dr.messageId, target: to, via: "daemon", duplicate: !!dr.duplicate, status: dr.status, recipientOnline }));
8434
+ } else if (recipientOnline === false) {
8435
+ render.warn(`queued for ${recipientName ?? to.slice(0, 16) + "…"} — no connected peer matches this key on "${meshSlug}".`);
8436
+ render.hint(offlineHint);
8437
+ } else {
8438
+ const who = recipientName ? `${recipientName} (${to.slice(0, 16)}…)` : to;
8439
+ render.ok(`sent to ${who}${recipientOnline === true ? " (online)" : " (daemon)"}`, dr.messageId ? dim(dr.messageId.slice(0, 8)) : undefined);
8440
+ }
8385
8441
  return;
8386
8442
  }
8387
8443
  if (flags.json)
@@ -8391,7 +8447,7 @@ async function runSend(flags, to, message) {
8391
8447
  process.exit(1);
8392
8448
  }
8393
8449
  }
8394
- await withMesh({ meshSlug: flags.mesh ?? null }, async (client) => {
8450
+ await withMesh({ meshSlug: meshSlug ?? flags.mesh ?? null }, async (client) => {
8395
8451
  let targetSpec = to;
8396
8452
  if (to.startsWith("#") && !/^#[0-9a-z_-]{20,}$/i.test(to)) {
8397
8453
  const name = to.slice(1);
@@ -8416,9 +8472,13 @@ async function runSend(flags, to, message) {
8416
8472
  const result = await client.send(targetSpec, message, priority);
8417
8473
  if (result.ok) {
8418
8474
  if (flags.json) {
8419
- console.log(JSON.stringify({ ok: true, messageId: result.messageId, target: to }));
8475
+ console.log(JSON.stringify({ ok: true, messageId: result.messageId, target: to, recipientOnline }));
8476
+ } else if (recipientOnline === false) {
8477
+ render.warn(`queued for ${recipientName ?? to} — no connected peer matches this key on "${meshSlug ?? flags.mesh ?? "default"}".`);
8478
+ render.hint(offlineHint);
8420
8479
  } else {
8421
- render.ok(`sent to ${to}`, result.messageId ? dim(result.messageId.slice(0, 8)) : undefined);
8480
+ const who = recipientName ? `${recipientName} (${to.slice(0, 16)}…)` : to;
8481
+ render.ok(`sent to ${who}${recipientOnline === true ? " (online)" : ""}`, result.messageId ? dim(result.messageId.slice(0, 8)) : undefined);
8422
8482
  }
8423
8483
  } else {
8424
8484
  if (flags.json) {
@@ -9924,6 +9984,12 @@ function bindSseStream(res, bus, filter = {}) {
9924
9984
  }
9925
9985
 
9926
9986
  // src/daemon/process-info.ts
9987
+ var exports_process_info = {};
9988
+ __export(exports_process_info, {
9989
+ isPidAlive: () => isPidAlive,
9990
+ getProcessStartTimes: () => getProcessStartTimes,
9991
+ getProcessStartTime: () => getProcessStartTime
9992
+ });
9927
9993
  import { execFile as execFile2 } from "node:child_process";
9928
9994
  import { promisify } from "node:util";
9929
9995
  async function getProcessStartTime(pid) {
@@ -9979,6 +10045,37 @@ var init_process_info = __esm(() => {
9979
10045
  });
9980
10046
 
9981
10047
  // src/daemon/session-registry.ts
10048
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync10, renameSync as renameSync3, writeFileSync as writeFileSync11 } from "node:fs";
10049
+ import { dirname as dirname5 } from "node:path";
10050
+ import { randomBytes as randomBytes7 } from "node:crypto";
10051
+ function toPersisted(info) {
10052
+ const { presence: _presence, ...rest } = info;
10053
+ return rest;
10054
+ }
10055
+ function setRegistryPersistence(path) {
10056
+ persistPath = path;
10057
+ }
10058
+ function persist() {
10059
+ if (!persistPath)
10060
+ return;
10061
+ try {
10062
+ mkdirSync7(dirname5(persistPath), { recursive: true, mode: 448 });
10063
+ const rows = [...byToken.values()].map(toPersisted);
10064
+ const tmp = `${persistPath}.${randomBytes7(6).toString("hex")}.tmp`;
10065
+ writeFileSync11(tmp, JSON.stringify({ version: 1, sessions: rows }), { mode: 384 });
10066
+ renameSync3(tmp, persistPath);
10067
+ } catch {}
10068
+ }
10069
+ function readPersistedSessions(path) {
10070
+ try {
10071
+ if (!existsSync11(path))
10072
+ return [];
10073
+ const parsed = JSON.parse(readFileSync10(path, "utf8"));
10074
+ return Array.isArray(parsed.sessions) ? parsed.sessions : [];
10075
+ } catch {
10076
+ return [];
10077
+ }
10078
+ }
9982
10079
  function startReaper() {
9983
10080
  if (reaperHandle)
9984
10081
  return;
@@ -10004,6 +10101,7 @@ function registerSession(info) {
10004
10101
  const stored = { ...info, registeredAt: Date.now() };
10005
10102
  byToken.set(info.token, stored);
10006
10103
  bySessionId.set(info.sessionId, info.token);
10104
+ persist();
10007
10105
  try {
10008
10106
  hooks.onRegister?.(stored);
10009
10107
  } catch {}
@@ -10020,6 +10118,7 @@ async function captureStartTimeAsync(token, pid) {
10020
10118
  if (!entry || entry.pid !== pid)
10021
10119
  return;
10022
10120
  entry.startTime = lstart;
10121
+ persist();
10023
10122
  }
10024
10123
  function deregisterByToken(token) {
10025
10124
  const entry = byToken.get(token);
@@ -10028,6 +10127,7 @@ function deregisterByToken(token) {
10028
10127
  byToken.delete(token);
10029
10128
  if (bySessionId.get(entry.sessionId) === token)
10030
10129
  bySessionId.delete(entry.sessionId);
10130
+ persist();
10031
10131
  try {
10032
10132
  hooks.onDeregister?.(entry);
10033
10133
  } catch {}
@@ -10079,7 +10179,7 @@ async function reapDead() {
10079
10179
  for (const t of dead)
10080
10180
  deregisterByToken(t);
10081
10181
  }
10082
- var TTL_MS, REAPER_INTERVAL_MS, byToken, bySessionId, hooks, reaperHandle = null;
10182
+ var TTL_MS, REAPER_INTERVAL_MS, byToken, bySessionId, hooks, reaperHandle = null, persistPath = null;
10083
10183
  var init_session_registry = __esm(() => {
10084
10184
  init_process_info();
10085
10185
  TTL_MS = 24 * 60 * 60 * 1000;
@@ -10091,7 +10191,7 @@ var init_session_registry = __esm(() => {
10091
10191
 
10092
10192
  // src/daemon/ipc/server.ts
10093
10193
  import { createServer as createServer2 } from "node:http";
10094
- import { chmodSync as chmodSync3, existsSync as existsSync11, unlinkSync as unlinkSync4 } from "node:fs";
10194
+ import { chmodSync as chmodSync3, existsSync as existsSync12, unlinkSync as unlinkSync4 } from "node:fs";
10095
10195
  import { timingSafeEqual } from "node:crypto";
10096
10196
  import { randomUUID as randomUUID3 } from "node:crypto";
10097
10197
  function startIpcServer(opts) {
@@ -10107,7 +10207,7 @@ function startIpcServer(opts) {
10107
10207
  meshConfigs: opts.meshConfigs,
10108
10208
  onPendingInserted: opts.onPendingInserted
10109
10209
  });
10110
- if (existsSync11(DAEMON_PATHS.SOCK_FILE)) {
10210
+ if (existsSync12(DAEMON_PATHS.SOCK_FILE)) {
10111
10211
  try {
10112
10212
  unlinkSync4(DAEMON_PATHS.SOCK_FILE);
10113
10213
  } catch {}
@@ -10934,16 +11034,16 @@ function parseSendRequest(body, idempotencyHeader) {
10934
11034
  }
10935
11035
  async function resolveAndEncrypt(req, broker, meshSecretKey, meshSlug) {
10936
11036
  const { encryptDirect: encryptDirect2 } = await Promise.resolve().then(() => (init_box(), exports_box));
10937
- const { randomBytes: randomBytes7 } = await import("node:crypto");
11037
+ const { randomBytes: randomBytes8 } = await import("node:crypto");
10938
11038
  const to = req.to.trim();
10939
11039
  if (to.startsWith("#") && /^#[0-9a-z_-]{20,}$/i.test(to)) {
10940
11040
  const ciphertext = Buffer.from(req.message, "utf8").toString("base64");
10941
- const nonce = randomBytes7(24).toString("base64");
11041
+ const nonce = randomBytes8(24).toString("base64");
10942
11042
  return { target_spec: to, ciphertext, nonce, mesh: meshSlug ?? "" };
10943
11043
  }
10944
11044
  if (to.startsWith("@") || to === "*") {
10945
11045
  const ciphertext = Buffer.from(req.message, "utf8").toString("base64");
10946
- const nonce = randomBytes7(24).toString("base64");
11046
+ const nonce = randomBytes8(24).toString("base64");
10947
11047
  return { target_spec: to, ciphertext, nonce, mesh: meshSlug ?? "" };
10948
11048
  }
10949
11049
  if (/^[0-9a-f]{64}$/i.test(to)) {
@@ -11635,13 +11735,23 @@ class SessionBrokerClient {
11635
11735
  sessionPubkey: this.opts.sessionPubkey,
11636
11736
  sessionSecretKey: this.opts.sessionSecretKey
11637
11737
  });
11738
+ let parentAttestation = this.opts.parentAttestation;
11739
+ try {
11740
+ parentAttestation = await signParentAttestation({
11741
+ parentMemberPubkey: this.opts.mesh.pubkey,
11742
+ parentSecretKey: this.opts.mesh.secretKey,
11743
+ sessionPubkey: this.opts.sessionPubkey
11744
+ });
11745
+ } catch (e) {
11746
+ this.log("warn", "parent attestation re-mint failed; reusing stored token (may be expired)", { err: String(e) });
11747
+ }
11638
11748
  return {
11639
11749
  type: "session_hello",
11640
11750
  meshId: this.opts.mesh.meshId,
11641
11751
  parentMemberId: this.opts.mesh.memberId,
11642
11752
  parentMemberPubkey: this.opts.mesh.pubkey,
11643
11753
  sessionPubkey: this.opts.sessionPubkey,
11644
- parentAttestation: this.opts.parentAttestation,
11754
+ parentAttestation,
11645
11755
  displayName: this.opts.displayName,
11646
11756
  sessionId: this.opts.sessionId,
11647
11757
  pid: this.opts.pid,
@@ -11964,8 +12074,8 @@ function bufferToHex(b) {
11964
12074
  return s;
11965
12075
  }
11966
12076
  async function randomNonce2() {
11967
- const { randomBytes: randomBytes7 } = await import("node:crypto");
11968
- return randomBytes7(24).toString("base64");
12077
+ const { randomBytes: randomBytes8 } = await import("node:crypto");
12078
+ return randomBytes8(24).toString("base64");
11969
12079
  }
11970
12080
  function defaultLog4(level, msg, meta) {
11971
12081
  const line = JSON.stringify({ level, msg, ...meta, ts: new Date().toISOString() });
@@ -12140,7 +12250,7 @@ __export(exports_identity, {
12140
12250
  __resetHostIdCacheForTests: () => __resetHostIdCacheForTests,
12141
12251
  __computeV1FingerprintForTests: () => __computeV1FingerprintForTests
12142
12252
  });
12143
- import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "node:fs";
12253
+ import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from "node:fs";
12144
12254
  import { join as join8 } from "node:path";
12145
12255
  import { createHash as createHash2 } from "node:crypto";
12146
12256
  import { execFileSync } from "node:child_process";
@@ -12161,13 +12271,13 @@ function computeCurrentFingerprint() {
12161
12271
  }
12162
12272
  function checkFingerprint() {
12163
12273
  const current = computeCurrentFingerprint();
12164
- if (!existsSync12(path())) {
12165
- writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12274
+ if (!existsSync13(path())) {
12275
+ writeFileSync12(path(), JSON.stringify(current, null, 2), { mode: 384 });
12166
12276
  return { result: "first_run", current };
12167
12277
  }
12168
12278
  let stored;
12169
12279
  try {
12170
- stored = JSON.parse(readFileSync10(path(), "utf8"));
12280
+ stored = JSON.parse(readFileSync11(path(), "utf8"));
12171
12281
  } catch {
12172
12282
  return { result: "unavailable", current };
12173
12283
  }
@@ -12175,7 +12285,7 @@ function checkFingerprint() {
12175
12285
  if (stored.fingerprint === current.fingerprint)
12176
12286
  return { result: "match", current, stored };
12177
12287
  if (stored.host_id && stored.host_id === current.host_id) {
12178
- writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12288
+ writeFileSync12(path(), JSON.stringify(current, null, 2), { mode: 384 });
12179
12289
  return { result: "match", current, stored };
12180
12290
  }
12181
12291
  return { result: "mismatch", current, stored };
@@ -12183,7 +12293,7 @@ function checkFingerprint() {
12183
12293
  if (stored.schema_version === 1) {
12184
12294
  const v1 = computeCurrentFingerprintV1();
12185
12295
  if (stored.fingerprint === v1.fingerprint) {
12186
- writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12296
+ writeFileSync12(path(), JSON.stringify(current, null, 2), { mode: 384 });
12187
12297
  return { result: "match", current, stored };
12188
12298
  }
12189
12299
  return { result: "mismatch", current, stored };
@@ -12192,7 +12302,7 @@ function checkFingerprint() {
12192
12302
  }
12193
12303
  function acceptCurrentHost() {
12194
12304
  const current = computeCurrentFingerprint();
12195
- writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12305
+ writeFileSync12(path(), JSON.stringify(current, null, 2), { mode: 384 });
12196
12306
  return current;
12197
12307
  }
12198
12308
  function fingerprintV2(host_id, stable_mac) {
@@ -12242,7 +12352,7 @@ function readHostIdV1() {
12242
12352
  if (process.platform === "linux") {
12243
12353
  for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
12244
12354
  try {
12245
- const raw = readFileSync10(p, "utf8").trim();
12355
+ const raw = readFileSync11(p, "utf8").trim();
12246
12356
  if (raw)
12247
12357
  return `linux:${raw}`;
12248
12358
  } catch {}
@@ -12288,7 +12398,7 @@ function readHostIdV2Uncached() {
12288
12398
  if (process.platform === "linux") {
12289
12399
  for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
12290
12400
  try {
12291
- const raw = readFileSync10(p, "utf8").trim();
12401
+ const raw = readFileSync11(p, "utf8").trim();
12292
12402
  if (raw)
12293
12403
  return `linux:${raw}`;
12294
12404
  } catch {}
@@ -12331,23 +12441,23 @@ var init_identity = __esm(() => {
12331
12441
  });
12332
12442
 
12333
12443
  // src/daemon/run.ts
12334
- import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11 } from "node:fs";
12444
+ import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync12 } from "node:fs";
12335
12445
  function detectContainer() {
12336
12446
  if (process.env.KUBERNETES_SERVICE_HOST)
12337
12447
  return true;
12338
12448
  if (process.env.CONTAINER === "1")
12339
12449
  return true;
12340
12450
  try {
12341
- if (existsSync13("/.dockerenv"))
12451
+ if (existsSync14("/.dockerenv"))
12342
12452
  return true;
12343
- const cg = readFileSync11("/proc/1/cgroup", "utf8");
12453
+ const cg = readFileSync12("/proc/1/cgroup", "utf8");
12344
12454
  if (/(docker|kubepods|containerd)/.test(cg))
12345
12455
  return true;
12346
12456
  } catch {}
12347
12457
  return false;
12348
12458
  }
12349
12459
  async function runDaemon(opts = {}) {
12350
- mkdirSync7(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12460
+ mkdirSync8(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12351
12461
  const lock = acquireSingletonLock();
12352
12462
  if (lock.result === "already-running") {
12353
12463
  process.stderr.write(`daemon already running (pid ${lock.pid})
@@ -12549,6 +12659,85 @@ async function runDaemon(opts = {}) {
12549
12659
  }
12550
12660
  });
12551
12661
  startReaper();
12662
+ try {
12663
+ const persisted = readPersistedSessions(DAEMON_PATHS.SESSIONS_FILE);
12664
+ if (persisted.length > 0) {
12665
+ const { loadOrCreateSessionKeypair: loadOrCreateSessionKeypair2 } = await Promise.resolve().then(() => (init_keypair_store(), exports_keypair_store));
12666
+ const { signParentAttestation: signParentAttestation2 } = await Promise.resolve().then(() => (init_session_hello_sig(), exports_session_hello_sig));
12667
+ const { isPidAlive: isPidAlive2, getProcessStartTimes: getProcessStartTimes2 } = await Promise.resolve().then(() => (init_process_info(), exports_process_info));
12668
+ const liveStartTimes = await getProcessStartTimes2(persisted.map((p) => p.pid)).catch(() => new Map);
12669
+ let revived = 0;
12670
+ for (const s of persisted) {
12671
+ if (!isPidAlive2(s.pid))
12672
+ continue;
12673
+ if (s.startTime !== undefined) {
12674
+ const live = liveStartTimes.get(s.pid);
12675
+ if (live !== undefined && live !== s.startTime)
12676
+ continue;
12677
+ }
12678
+ const meshConfig = meshConfigs.get(s.mesh);
12679
+ if (!meshConfig)
12680
+ continue;
12681
+ try {
12682
+ const kp = await loadOrCreateSessionKeypair2(meshConfig.slug, s.sessionId);
12683
+ const att = await signParentAttestation2({
12684
+ parentMemberPubkey: meshConfig.pubkey,
12685
+ parentSecretKey: meshConfig.secretKey,
12686
+ sessionPubkey: kp.publicKey
12687
+ });
12688
+ registerSession({
12689
+ token: s.token,
12690
+ sessionId: s.sessionId,
12691
+ mesh: s.mesh,
12692
+ displayName: s.displayName,
12693
+ pid: s.pid,
12694
+ ...s.cwd ? { cwd: s.cwd } : {},
12695
+ ...s.role ? { role: s.role } : {},
12696
+ ...s.groups ? { groups: s.groups } : {},
12697
+ ...s.startTime ? { startTime: s.startTime } : {},
12698
+ presence: {
12699
+ sessionPubkey: kp.publicKey,
12700
+ sessionSecretKey: kp.secretKey,
12701
+ parentAttestation: {
12702
+ sessionPubkey: att.sessionPubkey,
12703
+ parentMemberPubkey: att.parentMemberPubkey,
12704
+ expiresAt: att.expiresAt,
12705
+ signature: att.signature
12706
+ }
12707
+ }
12708
+ });
12709
+ revived++;
12710
+ } catch (err) {
12711
+ process.stderr.write(JSON.stringify({
12712
+ level: "warn",
12713
+ msg: "session_rehydrate_failed",
12714
+ token: s.token.slice(0, 8),
12715
+ mesh: s.mesh,
12716
+ err: String(err),
12717
+ ts: new Date().toISOString()
12718
+ }) + `
12719
+ `);
12720
+ }
12721
+ }
12722
+ process.stderr.write(JSON.stringify({
12723
+ level: "info",
12724
+ msg: "sessions_rehydrated",
12725
+ revived,
12726
+ persisted: persisted.length,
12727
+ ts: new Date().toISOString()
12728
+ }) + `
12729
+ `);
12730
+ }
12731
+ } catch (err) {
12732
+ process.stderr.write(JSON.stringify({
12733
+ level: "warn",
12734
+ msg: "session_rehydrate_scan_failed",
12735
+ err: String(err),
12736
+ ts: new Date().toISOString()
12737
+ }) + `
12738
+ `);
12739
+ }
12740
+ setRegistryPersistence(DAEMON_PATHS.SESSIONS_FILE);
12552
12741
  const ipc2 = startIpcServer({
12553
12742
  localToken,
12554
12743
  tcpEnabled,
@@ -12637,10 +12826,10 @@ __export(exports_service_install, {
12637
12826
  installService: () => installService,
12638
12827
  detectPlatform: () => detectPlatform
12639
12828
  });
12640
- import { existsSync as existsSync14, mkdirSync as mkdirSync8, writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, readFileSync as readFileSync12 } from "node:fs";
12829
+ import { existsSync as existsSync15, mkdirSync as mkdirSync9, writeFileSync as writeFileSync13, unlinkSync as unlinkSync5, readFileSync as readFileSync13 } from "node:fs";
12641
12830
  import { execSync as execSync2 } from "node:child_process";
12642
12831
  import { homedir as homedir8 } from "node:os";
12643
- import { join as join9, dirname as dirname5 } from "node:path";
12832
+ import { join as join9, dirname as dirname6 } from "node:path";
12644
12833
  function detectPlatform() {
12645
12834
  if (process.platform === "darwin")
12646
12835
  return "darwin";
@@ -12658,10 +12847,10 @@ function installService(args) {
12658
12847
  if (isCi() && !args.allowCi) {
12659
12848
  throw new Error("Refusing to install persistent service in CI; pass --allow-ci-persistent to override.");
12660
12849
  }
12661
- if (!existsSync14(args.binaryPath)) {
12850
+ if (!existsSync15(args.binaryPath)) {
12662
12851
  throw new Error(`binary not found at ${args.binaryPath}`);
12663
12852
  }
12664
- mkdirSync8(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12853
+ mkdirSync9(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12665
12854
  if (platform5 === "darwin")
12666
12855
  return installDarwin(args);
12667
12856
  return installLinux(args);
@@ -12674,7 +12863,7 @@ function uninstallService() {
12674
12863
  try {
12675
12864
  execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
12676
12865
  } catch {}
12677
- if (existsSync14(p)) {
12866
+ if (existsSync15(p)) {
12678
12867
  unlinkSync5(p);
12679
12868
  removed.push(p);
12680
12869
  }
@@ -12683,7 +12872,7 @@ function uninstallService() {
12683
12872
  try {
12684
12873
  execSync2(`systemctl --user disable --now ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
12685
12874
  } catch {}
12686
- if (existsSync14(p)) {
12875
+ if (existsSync15(p)) {
12687
12876
  unlinkSync5(p);
12688
12877
  removed.push(p);
12689
12878
  }
@@ -12695,7 +12884,7 @@ function darwinPlistPath() {
12695
12884
  }
12696
12885
  function installDarwin(args) {
12697
12886
  const plist = darwinPlistPath();
12698
- mkdirSync8(dirname5(plist), { recursive: true });
12887
+ mkdirSync9(dirname6(plist), { recursive: true });
12699
12888
  const log2 = DAEMON_PATHS.LOG_FILE;
12700
12889
  const nodeBin = process.execPath;
12701
12890
  const meshArgs = [
@@ -12738,14 +12927,14 @@ function installDarwin(args) {
12738
12927
  </dict>
12739
12928
  </plist>
12740
12929
  `;
12741
- writeFileSync12(plist, xml, { mode: 420 });
12930
+ writeFileSync13(plist, xml, { mode: 420 });
12742
12931
  try {
12743
12932
  execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
12744
12933
  } catch {}
12745
12934
  try {
12746
12935
  const pidPath = DAEMON_PATHS.PID_FILE;
12747
- if (existsSync14(pidPath)) {
12748
- const pid = parseInt(readFileSync12(pidPath, "utf8").trim(), 10);
12936
+ if (existsSync15(pidPath)) {
12937
+ const pid = parseInt(readFileSync13(pidPath, "utf8").trim(), 10);
12749
12938
  if (Number.isFinite(pid) && pid > 0) {
12750
12939
  try {
12751
12940
  process.kill(pid, "SIGTERM");
@@ -12764,7 +12953,7 @@ function linuxUnitPath() {
12764
12953
  }
12765
12954
  function installLinux(args) {
12766
12955
  const unit = linuxUnitPath();
12767
- mkdirSync8(dirname5(unit), { recursive: true });
12956
+ mkdirSync9(dirname6(unit), { recursive: true });
12768
12957
  const nodeBin = process.execPath;
12769
12958
  const execArgs = [
12770
12959
  "daemon",
@@ -12790,14 +12979,14 @@ Environment=PATH=/usr/local/bin:/usr/bin:/bin
12790
12979
  [Install]
12791
12980
  WantedBy=default.target
12792
12981
  `;
12793
- writeFileSync12(unit, content, { mode: 420 });
12982
+ writeFileSync13(unit, content, { mode: 420 });
12794
12983
  try {
12795
12984
  execSync2(`systemctl --user stop ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
12796
12985
  } catch {}
12797
12986
  try {
12798
12987
  const pidPath = DAEMON_PATHS.PID_FILE;
12799
- if (existsSync14(pidPath)) {
12800
- const pid = parseInt(readFileSync12(pidPath, "utf8").trim(), 10);
12988
+ if (existsSync15(pidPath)) {
12989
+ const pid = parseInt(readFileSync13(pidPath, "utf8").trim(), 10);
12801
12990
  if (Number.isFinite(pid) && pid > 0) {
12802
12991
  try {
12803
12992
  process.kill(pid, "SIGTERM");
@@ -12824,10 +13013,10 @@ function readInstalledUnit() {
12824
13013
  if (!platform5)
12825
13014
  return { platform: null, path: null, content: null };
12826
13015
  const path2 = platform5 === "darwin" ? darwinPlistPath() : linuxUnitPath();
12827
- if (!existsSync14(path2))
13016
+ if (!existsSync15(path2))
12828
13017
  return { platform: platform5, path: null, content: null };
12829
13018
  try {
12830
- return { platform: platform5, path: path2, content: readFileSync12(path2, "utf8") };
13019
+ return { platform: platform5, path: path2, content: readFileSync13(path2, "utf8") };
12831
13020
  } catch {
12832
13021
  return { platform: platform5, path: path2, content: null };
12833
13022
  }
@@ -12843,7 +13032,7 @@ __export(exports_daemon, {
12843
13032
  runDaemonCommand: () => runDaemonCommand
12844
13033
  });
12845
13034
  import { spawn } from "node:child_process";
12846
- import { existsSync as existsSync15, openSync as openSync3, mkdirSync as mkdirSync9 } from "node:fs";
13035
+ import { existsSync as existsSync16, openSync as openSync3, mkdirSync as mkdirSync10 } from "node:fs";
12847
13036
  import { join as join10 } from "node:path";
12848
13037
  async function runDaemonCommand(sub, opts, rest = []) {
12849
13038
  switch (sub) {
@@ -13166,7 +13355,7 @@ async function runStop(opts) {
13166
13355
  return 1;
13167
13356
  }
13168
13357
  async function spawnDetachedDaemon(opts) {
13169
- mkdirSync9(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
13358
+ mkdirSync10(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
13170
13359
  const logPath = join10(DAEMON_PATHS.DAEMON_DIR, "daemon.log");
13171
13360
  const binary = process.argv[1] ?? "claudemesh";
13172
13361
  const args = ["daemon", "up", "--foreground"];
@@ -13185,7 +13374,7 @@ async function spawnDetachedDaemon(opts) {
13185
13374
  const sockPath = DAEMON_PATHS.SOCK_FILE;
13186
13375
  const startedAt = Date.now();
13187
13376
  while (Date.now() - startedAt < 3000) {
13188
- if (existsSync15(sockPath)) {
13377
+ if (existsSync16(sockPath)) {
13189
13378
  if (opts.json) {
13190
13379
  process.stdout.write(JSON.stringify({ ok: true, detached: true, pid: child.pid, log: logPath }) + `
13191
13380
  `);
@@ -13230,19 +13419,19 @@ __export(exports_install, {
13230
13419
  import {
13231
13420
  chmodSync as chmodSync4,
13232
13421
  copyFileSync,
13233
- existsSync as existsSync16,
13234
- mkdirSync as mkdirSync10,
13235
- readFileSync as readFileSync13,
13236
- writeFileSync as writeFileSync13
13422
+ existsSync as existsSync17,
13423
+ mkdirSync as mkdirSync11,
13424
+ readFileSync as readFileSync14,
13425
+ writeFileSync as writeFileSync14
13237
13426
  } from "node:fs";
13238
13427
  import { homedir as homedir9, platform as platform5 } from "node:os";
13239
- import { dirname as dirname6, join as join11, resolve } from "node:path";
13428
+ import { dirname as dirname7, join as join11, resolve } from "node:path";
13240
13429
  import { fileURLToPath } from "node:url";
13241
13430
  import { spawnSync as spawnSync3 } from "node:child_process";
13242
13431
  function readClaudeConfig() {
13243
- if (!existsSync16(CLAUDE_CONFIG))
13432
+ if (!existsSync17(CLAUDE_CONFIG))
13244
13433
  return {};
13245
- const text = readFileSync13(CLAUDE_CONFIG, "utf-8").trim();
13434
+ const text = readFileSync14(CLAUDE_CONFIG, "utf-8").trim();
13246
13435
  if (!text)
13247
13436
  return {};
13248
13437
  try {
@@ -13252,10 +13441,10 @@ function readClaudeConfig() {
13252
13441
  }
13253
13442
  }
13254
13443
  function backupClaudeConfig() {
13255
- if (!existsSync16(CLAUDE_CONFIG))
13444
+ if (!existsSync17(CLAUDE_CONFIG))
13256
13445
  return;
13257
- const backupDir = join11(dirname6(CLAUDE_CONFIG), ".claude", "backups");
13258
- mkdirSync10(backupDir, { recursive: true });
13446
+ const backupDir = join11(dirname7(CLAUDE_CONFIG), ".claude", "backups");
13447
+ mkdirSync11(backupDir, { recursive: true });
13259
13448
  const ts = Date.now();
13260
13449
  const dest = join11(backupDir, `.claude.json.pre-claudemesh.${ts}`);
13261
13450
  copyFileSync(CLAUDE_CONFIG, dest);
@@ -13281,7 +13470,7 @@ function patchMcpServer(entry) {
13281
13470
  return action;
13282
13471
  }
13283
13472
  function removeMcpServer() {
13284
- if (!existsSync16(CLAUDE_CONFIG))
13473
+ if (!existsSync17(CLAUDE_CONFIG))
13285
13474
  return false;
13286
13475
  backupClaudeConfig();
13287
13476
  const cfg = readClaudeConfig();
@@ -13294,8 +13483,8 @@ function removeMcpServer() {
13294
13483
  return true;
13295
13484
  }
13296
13485
  function flushClaudeConfig(obj) {
13297
- mkdirSync10(dirname6(CLAUDE_CONFIG), { recursive: true });
13298
- writeFileSync13(CLAUDE_CONFIG, JSON.stringify(obj, null, 2) + `
13486
+ mkdirSync11(dirname7(CLAUDE_CONFIG), { recursive: true });
13487
+ writeFileSync14(CLAUDE_CONFIG, JSON.stringify(obj, null, 2) + `
13299
13488
  `, "utf-8");
13300
13489
  try {
13301
13490
  chmodSync4(CLAUDE_CONFIG, 384);
@@ -13312,13 +13501,13 @@ function resolveEntry() {
13312
13501
  const here = fileURLToPath(import.meta.url);
13313
13502
  if (isBundledFile(here))
13314
13503
  return here;
13315
- return resolve(dirname6(here), "..", "index.ts");
13504
+ return resolve(dirname7(here), "..", "index.ts");
13316
13505
  }
13317
13506
  function resolveBundledSkillsDir() {
13318
13507
  const here = fileURLToPath(import.meta.url);
13319
- const pkgRoot = resolve(dirname6(here), "..", "..");
13508
+ const pkgRoot = resolve(dirname7(here), "..", "..");
13320
13509
  const skillsDir = join11(pkgRoot, "skills");
13321
- if (existsSync16(skillsDir))
13510
+ if (existsSync17(skillsDir))
13322
13511
  return skillsDir;
13323
13512
  return null;
13324
13513
  }
@@ -13333,7 +13522,7 @@ function installSkills() {
13333
13522
  continue;
13334
13523
  const srcDir = join11(src, entry.name);
13335
13524
  const dstDir = join11(CLAUDE_SKILLS_ROOT, entry.name);
13336
- mkdirSync10(dstDir, { recursive: true });
13525
+ mkdirSync11(dstDir, { recursive: true });
13337
13526
  for (const file of fs.readdirSync(srcDir, { withFileTypes: true })) {
13338
13527
  if (!file.isFile())
13339
13528
  continue;
@@ -13353,7 +13542,7 @@ function uninstallSkills() {
13353
13542
  if (!entry.isDirectory())
13354
13543
  continue;
13355
13544
  const dstDir = join11(CLAUDE_SKILLS_ROOT, entry.name);
13356
- if (existsSync16(dstDir)) {
13545
+ if (existsSync17(dstDir)) {
13357
13546
  try {
13358
13547
  fs.rmSync(dstDir, { recursive: true, force: true });
13359
13548
  removed.push(entry.name);
@@ -13378,9 +13567,9 @@ function entriesEqual(a, b) {
13378
13567
  return a.command === b.command && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
13379
13568
  }
13380
13569
  function readClaudeSettings() {
13381
- if (!existsSync16(CLAUDE_SETTINGS))
13570
+ if (!existsSync17(CLAUDE_SETTINGS))
13382
13571
  return {};
13383
- const text = readFileSync13(CLAUDE_SETTINGS, "utf-8").trim();
13572
+ const text = readFileSync14(CLAUDE_SETTINGS, "utf-8").trim();
13384
13573
  if (!text)
13385
13574
  return {};
13386
13575
  try {
@@ -13390,8 +13579,8 @@ function readClaudeSettings() {
13390
13579
  }
13391
13580
  }
13392
13581
  function writeClaudeSettings(obj) {
13393
- mkdirSync10(dirname6(CLAUDE_SETTINGS), { recursive: true });
13394
- writeFileSync13(CLAUDE_SETTINGS, JSON.stringify(obj, null, 2) + `
13582
+ mkdirSync11(dirname7(CLAUDE_SETTINGS), { recursive: true });
13583
+ writeFileSync14(CLAUDE_SETTINGS, JSON.stringify(obj, null, 2) + `
13395
13584
  `, "utf-8");
13396
13585
  }
13397
13586
  function installAllowedTools() {
@@ -13405,7 +13594,7 @@ function installAllowedTools() {
13405
13594
  return { added: toAdd, unchanged: CLAUDEMESH_TOOLS.length - toAdd.length };
13406
13595
  }
13407
13596
  function uninstallAllowedTools() {
13408
- if (!existsSync16(CLAUDE_SETTINGS))
13597
+ if (!existsSync17(CLAUDE_SETTINGS))
13409
13598
  return 0;
13410
13599
  const settings = readClaudeSettings();
13411
13600
  const existing = settings.allowedTools ?? [];
@@ -13440,7 +13629,7 @@ function installHooks() {
13440
13629
  return { added, unchanged };
13441
13630
  }
13442
13631
  function uninstallHooks() {
13443
- if (!existsSync16(CLAUDE_SETTINGS))
13632
+ if (!existsSync17(CLAUDE_SETTINGS))
13444
13633
  return 0;
13445
13634
  const settings = readClaudeSettings();
13446
13635
  const hooks2 = settings.hooks;
@@ -13490,7 +13679,7 @@ async function runInstall(args = []) {
13490
13679
  render.err("`bun` is not on PATH.", "Install Bun first: https://bun.com");
13491
13680
  process.exit(1);
13492
13681
  }
13493
- if (!existsSync16(entry)) {
13682
+ if (!existsSync17(entry)) {
13494
13683
  render.err(`MCP entry not found at ${entry}`);
13495
13684
  process.exit(1);
13496
13685
  }
@@ -13761,35 +13950,35 @@ var exports_uninstall = {};
13761
13950
  __export(exports_uninstall, {
13762
13951
  uninstall: () => uninstall
13763
13952
  });
13764
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync14, existsSync as existsSync17, rmSync as rmSync3, readdirSync as readdirSync2 } from "node:fs";
13765
- import { join as join12, dirname as dirname7 } from "node:path";
13953
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync15, existsSync as existsSync18, rmSync as rmSync3, readdirSync as readdirSync2 } from "node:fs";
13954
+ import { join as join12, dirname as dirname8 } from "node:path";
13766
13955
  import { homedir as homedir10 } from "node:os";
13767
13956
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13768
13957
  function bundledSkillsDir() {
13769
13958
  const here = fileURLToPath2(import.meta.url);
13770
- const pkgRoot = join12(dirname7(here), "..", "..");
13959
+ const pkgRoot = join12(dirname8(here), "..", "..");
13771
13960
  const skillsDir = join12(pkgRoot, "skills");
13772
- return existsSync17(skillsDir) ? skillsDir : null;
13961
+ return existsSync18(skillsDir) ? skillsDir : null;
13773
13962
  }
13774
13963
  async function uninstall() {
13775
13964
  let removed = 0;
13776
- if (existsSync17(PATHS.CLAUDE_JSON)) {
13965
+ if (existsSync18(PATHS.CLAUDE_JSON)) {
13777
13966
  try {
13778
- const raw = readFileSync14(PATHS.CLAUDE_JSON, "utf-8");
13967
+ const raw = readFileSync15(PATHS.CLAUDE_JSON, "utf-8");
13779
13968
  const config = JSON.parse(raw);
13780
13969
  const servers = config.mcpServers;
13781
13970
  if (servers && "claudemesh" in servers) {
13782
13971
  delete servers.claudemesh;
13783
- writeFileSync14(PATHS.CLAUDE_JSON, JSON.stringify(config, null, 2) + `
13972
+ writeFileSync15(PATHS.CLAUDE_JSON, JSON.stringify(config, null, 2) + `
13784
13973
  `, "utf-8");
13785
13974
  render.ok("removed MCP server", dim("~/.claude.json"));
13786
13975
  removed++;
13787
13976
  }
13788
13977
  } catch {}
13789
13978
  }
13790
- if (existsSync17(PATHS.CLAUDE_SETTINGS)) {
13979
+ if (existsSync18(PATHS.CLAUDE_SETTINGS)) {
13791
13980
  try {
13792
- const raw = readFileSync14(PATHS.CLAUDE_SETTINGS, "utf-8");
13981
+ const raw = readFileSync15(PATHS.CLAUDE_SETTINGS, "utf-8");
13793
13982
  const config = JSON.parse(raw);
13794
13983
  const hooks2 = config.hooks;
13795
13984
  if (hooks2) {
@@ -13810,7 +13999,7 @@ async function uninstall() {
13810
13999
  }
13811
14000
  }
13812
14001
  if (removedHooks > 0) {
13813
- writeFileSync14(PATHS.CLAUDE_SETTINGS, JSON.stringify(config, null, 2) + `
14002
+ writeFileSync15(PATHS.CLAUDE_SETTINGS, JSON.stringify(config, null, 2) + `
13814
14003
  `, "utf-8");
13815
14004
  render.ok(`removed ${removedHooks} claudemesh hook${removedHooks === 1 ? "" : "s"}`, dim("settings.json"));
13816
14005
  removed++;
@@ -13826,7 +14015,7 @@ async function uninstall() {
13826
14015
  if (!entry.isDirectory())
13827
14016
  continue;
13828
14017
  const dst = join12(CLAUDE_SKILLS_ROOT2, entry.name);
13829
- if (existsSync17(dst)) {
14018
+ if (existsSync18(dst)) {
13830
14019
  try {
13831
14020
  rmSync3(dst, { recursive: true, force: true });
13832
14021
  removedSkills.push(entry.name);
@@ -13858,7 +14047,7 @@ var exports_doctor = {};
13858
14047
  __export(exports_doctor, {
13859
14048
  runDoctor: () => runDoctor
13860
14049
  });
13861
- import { existsSync as existsSync18, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
14050
+ import { existsSync as existsSync19, readFileSync as readFileSync16, statSync as statSync3 } from "node:fs";
13862
14051
  import { homedir as homedir11, platform as platform6 } from "node:os";
13863
14052
  import { join as join13 } from "node:path";
13864
14053
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -13885,7 +14074,7 @@ function checkClaudeOnPath() {
13885
14074
  }
13886
14075
  function checkMcpRegistered() {
13887
14076
  const claudeConfig = join13(homedir11(), ".claude.json");
13888
- if (!existsSync18(claudeConfig)) {
14077
+ if (!existsSync19(claudeConfig)) {
13889
14078
  return {
13890
14079
  name: "claudemesh MCP registered in ~/.claude.json",
13891
14080
  pass: false,
@@ -13893,7 +14082,7 @@ function checkMcpRegistered() {
13893
14082
  };
13894
14083
  }
13895
14084
  try {
13896
- const cfg = JSON.parse(readFileSync15(claudeConfig, "utf-8"));
14085
+ const cfg = JSON.parse(readFileSync16(claudeConfig, "utf-8"));
13897
14086
  const registered = Boolean(cfg.mcpServers?.["claudemesh"]);
13898
14087
  return {
13899
14088
  name: "claudemesh MCP registered in ~/.claude.json",
@@ -13911,7 +14100,7 @@ function checkMcpRegistered() {
13911
14100
  }
13912
14101
  function checkHooksRegistered() {
13913
14102
  const settings = join13(homedir11(), ".claude", "settings.json");
13914
- if (!existsSync18(settings)) {
14103
+ if (!existsSync19(settings)) {
13915
14104
  return {
13916
14105
  name: "Status hooks registered in ~/.claude/settings.json",
13917
14106
  pass: false,
@@ -13919,7 +14108,7 @@ function checkHooksRegistered() {
13919
14108
  };
13920
14109
  }
13921
14110
  try {
13922
- const raw = readFileSync15(settings, "utf-8");
14111
+ const raw = readFileSync16(settings, "utf-8");
13923
14112
  const has = raw.includes("claudemesh hook ");
13924
14113
  return {
13925
14114
  name: "Status hooks registered in ~/.claude/settings.json",
@@ -13936,7 +14125,7 @@ function checkHooksRegistered() {
13936
14125
  }
13937
14126
  function checkConfigFile() {
13938
14127
  const path2 = getConfigPath();
13939
- if (!existsSync18(path2)) {
14128
+ if (!existsSync19(path2)) {
13940
14129
  return {
13941
14130
  name: "~/.claudemesh/config.json exists and parses",
13942
14131
  pass: true,
@@ -14119,7 +14308,7 @@ var exports_status = {};
14119
14308
  __export(exports_status, {
14120
14309
  runStatus: () => runStatus2
14121
14310
  });
14122
- import { statSync as statSync4, existsSync as existsSync19 } from "node:fs";
14311
+ import { statSync as statSync4, existsSync as existsSync20 } from "node:fs";
14123
14312
  import WebSocket3 from "ws";
14124
14313
  async function probeBroker(url, timeoutMs = 4000) {
14125
14314
  return new Promise((resolve2) => {
@@ -14149,7 +14338,7 @@ async function runStatus2() {
14149
14338
  render.section(`status (v${VERSION})`);
14150
14339
  const configPath = getConfigPath();
14151
14340
  let configPermsNote = "missing";
14152
- if (existsSync19(configPath)) {
14341
+ if (existsSync20(configPath)) {
14153
14342
  const mode = (statSync4(configPath).mode & 511).toString(8).padStart(4, "0");
14154
14343
  configPermsNote = mode === "0600" ? `${mode}` : `${mode} — expected 0600`;
14155
14344
  }
@@ -14295,13 +14484,13 @@ var init_check_claude_binary = __esm(() => {
14295
14484
  });
14296
14485
 
14297
14486
  // src/services/health/check-mcp-registered.ts
14298
- import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
14487
+ import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
14299
14488
  function checkMcpRegistered2() {
14300
14489
  try {
14301
- if (!existsSync20(PATHS.CLAUDE_JSON)) {
14490
+ if (!existsSync21(PATHS.CLAUDE_JSON)) {
14302
14491
  return { name: "mcp-registered", ok: false, message: "~/.claude.json not found" };
14303
14492
  }
14304
- const raw = readFileSync16(PATHS.CLAUDE_JSON, "utf-8");
14493
+ const raw = readFileSync17(PATHS.CLAUDE_JSON, "utf-8");
14305
14494
  const config = JSON.parse(raw);
14306
14495
  if (config.mcpServers && "claudemesh" in config.mcpServers) {
14307
14496
  return { name: "mcp-registered", ok: true, message: "MCP server registered" };
@@ -14316,13 +14505,13 @@ var init_check_mcp_registered = __esm(() => {
14316
14505
  });
14317
14506
 
14318
14507
  // src/services/health/check-hooks-registered.ts
14319
- import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
14508
+ import { existsSync as existsSync22, readFileSync as readFileSync18 } from "node:fs";
14320
14509
  function checkHooksRegistered2() {
14321
14510
  try {
14322
- if (!existsSync21(PATHS.CLAUDE_SETTINGS)) {
14511
+ if (!existsSync22(PATHS.CLAUDE_SETTINGS)) {
14323
14512
  return { name: "hooks-registered", ok: false, message: "~/.claude/settings.json not found" };
14324
14513
  }
14325
- const raw = readFileSync17(PATHS.CLAUDE_SETTINGS, "utf-8");
14514
+ const raw = readFileSync18(PATHS.CLAUDE_SETTINGS, "utf-8");
14326
14515
  const config = JSON.parse(raw);
14327
14516
  if (config.hooks) {
14328
14517
  return { name: "hooks-registered", ok: true, message: "Hooks configured" };
@@ -14337,10 +14526,10 @@ var init_check_hooks_registered = __esm(() => {
14337
14526
  });
14338
14527
 
14339
14528
  // src/services/health/check-config-perms.ts
14340
- import { existsSync as existsSync22, statSync as statSync5 } from "node:fs";
14529
+ import { existsSync as existsSync23, statSync as statSync5 } from "node:fs";
14341
14530
  function checkConfigPerms() {
14342
14531
  const configFile = PATHS.CONFIG_FILE;
14343
- if (!existsSync22(configFile)) {
14532
+ if (!existsSync23(configFile)) {
14344
14533
  return { name: "config-perms", ok: true, message: "No config file yet (first run)" };
14345
14534
  }
14346
14535
  try {
@@ -14358,13 +14547,13 @@ var init_check_config_perms = __esm(() => {
14358
14547
  });
14359
14548
 
14360
14549
  // src/services/health/check-keypairs-valid.ts
14361
- import { existsSync as existsSync23, readFileSync as readFileSync18 } from "node:fs";
14550
+ import { existsSync as existsSync24, readFileSync as readFileSync19 } from "node:fs";
14362
14551
  function checkKeypairsValid() {
14363
- if (!existsSync23(PATHS.CONFIG_FILE)) {
14552
+ if (!existsSync24(PATHS.CONFIG_FILE)) {
14364
14553
  return { name: "keypairs-valid", ok: true, message: "No config (first run)" };
14365
14554
  }
14366
14555
  try {
14367
- const raw = readFileSync18(PATHS.CONFIG_FILE, "utf-8");
14556
+ const raw = readFileSync19(PATHS.CONFIG_FILE, "utf-8");
14368
14557
  const config = JSON.parse(raw);
14369
14558
  const meshes = config.meshes ?? [];
14370
14559
  if (meshes.length === 0) {
@@ -14845,7 +15034,7 @@ __export(exports_url_handler, {
14845
15034
  runUrlHandler: () => runUrlHandler
14846
15035
  });
14847
15036
  import { platform as platform7, homedir as homedir12 } from "node:os";
14848
- import { existsSync as existsSync24, mkdirSync as mkdirSync11, writeFileSync as writeFileSync15, rmSync as rmSync4, chmodSync as chmodSync5 } from "node:fs";
15037
+ import { existsSync as existsSync25, mkdirSync as mkdirSync12, writeFileSync as writeFileSync16, rmSync as rmSync4, chmodSync as chmodSync5 } from "node:fs";
14849
15038
  import { join as join14 } from "node:path";
14850
15039
  import { spawnSync as spawnSync5 } from "node:child_process";
14851
15040
  function resolveClaudemeshBin() {
@@ -14856,7 +15045,7 @@ function installDarwin2() {
14856
15045
  const appDir = join14(homedir12(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14857
15046
  const contents = join14(appDir, "Contents");
14858
15047
  const macOS = join14(contents, "MacOS");
14859
- mkdirSync11(macOS, { recursive: true });
15048
+ mkdirSync12(macOS, { recursive: true });
14860
15049
  const plist = `<?xml version="1.0" encoding="UTF-8"?>
14861
15050
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
14862
15051
  <plist version="1.0">
@@ -14879,7 +15068,7 @@ function installDarwin2() {
14879
15068
  </array>
14880
15069
  </dict>
14881
15070
  </plist>`;
14882
- writeFileSync15(join14(contents, "Info.plist"), plist);
15071
+ writeFileSync16(join14(contents, "Info.plist"), plist);
14883
15072
  const shim = `#!/bin/sh
14884
15073
  URL="$1"
14885
15074
  CODE=\${URL#claudemesh://}
@@ -14894,7 +15083,7 @@ end tell
14894
15083
  EOF
14895
15084
  `;
14896
15085
  const shimPath = join14(macOS, "open-url");
14897
- writeFileSync15(shimPath, shim);
15086
+ writeFileSync16(shimPath, shim);
14898
15087
  chmodSync5(shimPath, 493);
14899
15088
  const lsreg = spawnSync5("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister", ["-f", appDir], { encoding: "utf-8" });
14900
15089
  if (lsreg.status !== 0) {
@@ -14906,7 +15095,7 @@ EOF
14906
15095
  function installLinux2() {
14907
15096
  const binPath = resolveClaudemeshBin();
14908
15097
  const appsDir = join14(homedir12(), ".local", "share", "applications");
14909
- mkdirSync11(appsDir, { recursive: true });
15098
+ mkdirSync12(appsDir, { recursive: true });
14910
15099
  const desktop = `[Desktop Entry]
14911
15100
  Type=Application
14912
15101
  Name=Claudemesh
@@ -14918,7 +15107,7 @@ MimeType=x-scheme-handler/claudemesh;
14918
15107
  NoDisplay=true
14919
15108
  `;
14920
15109
  const desktopPath = join14(appsDir, "claudemesh.desktop");
14921
- writeFileSync15(desktopPath, desktop);
15110
+ writeFileSync16(desktopPath, desktop);
14922
15111
  const xdg1 = spawnSync5("xdg-mime", ["default", "claudemesh.desktop", "x-scheme-handler/claudemesh"], { encoding: "utf-8" });
14923
15112
  if (xdg1.status !== 0) {
14924
15113
  render.warn("xdg-mime not available — skipped mime default registration");
@@ -14941,7 +15130,7 @@ function installWindows() {
14941
15130
  `@="\\"${binPath.replace(/\\/g, "\\\\")}\\" \\"%1\\""`
14942
15131
  ];
14943
15132
  const regPath = join14(homedir12(), "claudemesh-handler.reg");
14944
- writeFileSync15(regPath, lines.join(`\r
15133
+ writeFileSync16(regPath, lines.join(`\r
14945
15134
  `));
14946
15135
  const res = spawnSync5("reg.exe", ["import", regPath], { encoding: "utf-8" });
14947
15136
  if (res.status !== 0) {
@@ -14953,14 +15142,14 @@ function installWindows() {
14953
15142
  }
14954
15143
  function uninstallDarwin() {
14955
15144
  const appDir = join14(homedir12(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14956
- if (existsSync24(appDir))
15145
+ if (existsSync25(appDir))
14957
15146
  rmSync4(appDir, { recursive: true, force: true });
14958
15147
  render.ok("removed claudemesh:// handler on macOS");
14959
15148
  return EXIT.SUCCESS;
14960
15149
  }
14961
15150
  function uninstallLinux() {
14962
15151
  const desktopPath = join14(homedir12(), ".local", "share", "applications", "claudemesh.desktop");
14963
- if (existsSync24(desktopPath))
15152
+ if (existsSync25(desktopPath))
14964
15153
  rmSync4(desktopPath, { force: true });
14965
15154
  render.ok("removed claudemesh:// handler on Linux");
14966
15155
  return EXIT.SUCCESS;
@@ -15005,7 +15194,7 @@ var exports_status_line = {};
15005
15194
  __export(exports_status_line, {
15006
15195
  runStatusLine: () => runStatusLine
15007
15196
  });
15008
- import { existsSync as existsSync25, readFileSync as readFileSync19 } from "node:fs";
15197
+ import { existsSync as existsSync26, readFileSync as readFileSync20 } from "node:fs";
15009
15198
  import { join as join15 } from "node:path";
15010
15199
  import { homedir as homedir13 } from "node:os";
15011
15200
  async function runStatusLine() {
@@ -15017,9 +15206,9 @@ async function runStatusLine() {
15017
15206
  }
15018
15207
  const cachePath = join15(homedir13(), ".claudemesh", "peer-cache.json");
15019
15208
  let cache = {};
15020
- if (existsSync25(cachePath)) {
15209
+ if (existsSync26(cachePath)) {
15021
15210
  try {
15022
- cache = JSON.parse(readFileSync19(cachePath, "utf-8"));
15211
+ cache = JSON.parse(readFileSync20(cachePath, "utf-8"));
15023
15212
  } catch {}
15024
15213
  }
15025
15214
  const pick = config.meshes[0];
@@ -15050,7 +15239,7 @@ __export(exports_backup, {
15050
15239
  runRestore: () => runRestore,
15051
15240
  runBackup: () => runBackup
15052
15241
  });
15053
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, existsSync as existsSync26 } from "node:fs";
15242
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync17, existsSync as existsSync27 } from "node:fs";
15054
15243
  import { createInterface as createInterface11 } from "node:readline";
15055
15244
  function readHidden(prompt5) {
15056
15245
  return new Promise((resolve2) => {
@@ -15092,11 +15281,11 @@ async function deriveKey(pass, salt, s) {
15092
15281
  }
15093
15282
  async function runBackup(outPath) {
15094
15283
  const configPath = getConfigPath();
15095
- if (!existsSync26(configPath)) {
15284
+ if (!existsSync27(configPath)) {
15096
15285
  console.error(" No config found — nothing to back up. Join a mesh first.");
15097
15286
  return EXIT.NOT_FOUND;
15098
15287
  }
15099
- const plaintext = readFileSync20(configPath);
15288
+ const plaintext = readFileSync21(configPath);
15100
15289
  const pass = await readHidden(" Passphrase (min 12 chars): ");
15101
15290
  if (pass.length < 12) {
15102
15291
  console.error(" ✗ Passphrase too short.");
@@ -15114,7 +15303,7 @@ async function runBackup(outPath) {
15114
15303
  const ciphertext = Buffer.from(s.crypto_aead_xchacha20poly1305_ietf_encrypt(plaintext, null, null, nonce, key));
15115
15304
  const blob = Buffer.concat([MAGIC, salt, nonce, ciphertext]);
15116
15305
  const file = outPath ?? `claudemesh-backup-${new Date().toISOString().replace(/[:.]/g, "-")}.cmb`;
15117
- writeFileSync16(file, blob, { mode: 384 });
15306
+ writeFileSync17(file, blob, { mode: 384 });
15118
15307
  console.log(`
15119
15308
  ✓ Backup saved: ${file}`);
15120
15309
  console.log(` Size: ${blob.length} bytes. Guard the passphrase — there is no recovery.
@@ -15126,11 +15315,11 @@ async function runRestore(inPath) {
15126
15315
  console.error(" Usage: claudemesh restore <backup-file>");
15127
15316
  return EXIT.INVALID_ARGS;
15128
15317
  }
15129
- if (!existsSync26(inPath)) {
15318
+ if (!existsSync27(inPath)) {
15130
15319
  console.error(` ✗ File not found: ${inPath}`);
15131
15320
  return EXIT.NOT_FOUND;
15132
15321
  }
15133
- const blob = readFileSync20(inPath);
15322
+ const blob = readFileSync21(inPath);
15134
15323
  if (blob.length < 4 + 16 + 24 + 17 || !blob.subarray(0, 4).equals(MAGIC)) {
15135
15324
  console.error(" ✗ Not a claudemesh backup file (bad magic).");
15136
15325
  return EXIT.INVALID_ARGS;
@@ -15149,12 +15338,12 @@ async function runRestore(inPath) {
15149
15338
  return EXIT.INTERNAL_ERROR;
15150
15339
  }
15151
15340
  const configPath = getConfigPath();
15152
- if (existsSync26(configPath)) {
15341
+ if (existsSync27(configPath)) {
15153
15342
  const backupOld = `${configPath}.before-restore.${Date.now()}`;
15154
- writeFileSync16(backupOld, readFileSync20(configPath), { mode: 384 });
15343
+ writeFileSync17(backupOld, readFileSync21(configPath), { mode: 384 });
15155
15344
  console.log(` ↻ Existing config saved to ${backupOld}`);
15156
15345
  }
15157
- writeFileSync16(configPath, Buffer.from(plaintext), { mode: 384 });
15346
+ writeFileSync17(configPath, Buffer.from(plaintext), { mode: 384 });
15158
15347
  console.log(`
15159
15348
  ✓ Config restored to ${configPath}`);
15160
15349
  console.log(" Run `claudemesh list` to verify your meshes.\n");
@@ -15174,8 +15363,8 @@ __export(exports_upgrade, {
15174
15363
  runUpgrade: () => runUpgrade
15175
15364
  });
15176
15365
  import { spawnSync as spawnSync6 } from "node:child_process";
15177
- import { existsSync as existsSync27 } from "node:fs";
15178
- import { dirname as dirname8, join as join16, resolve as resolve2 } from "node:path";
15366
+ import { existsSync as existsSync28 } from "node:fs";
15367
+ import { dirname as dirname9, join as join16, resolve as resolve2 } from "node:path";
15179
15368
  async function latestVersion() {
15180
15369
  try {
15181
15370
  const res = await fetch(URLS.NPM_REGISTRY, { signal: AbortSignal.timeout(8000) });
@@ -15189,14 +15378,14 @@ async function latestVersion() {
15189
15378
  }
15190
15379
  function findNpm() {
15191
15380
  const portable = join16(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
15192
- if (existsSync27(portable)) {
15381
+ if (existsSync28(portable)) {
15193
15382
  return { npm: portable, prefix: join16(process.env.HOME ?? "", ".claudemesh") };
15194
15383
  }
15195
15384
  let cur = resolve2(process.argv[1] ?? ".");
15196
15385
  for (let i = 0;i < 6; i++) {
15197
- cur = dirname8(cur);
15386
+ cur = dirname9(cur);
15198
15387
  const candidate = join16(cur, "bin", "npm");
15199
- if (existsSync27(candidate))
15388
+ if (existsSync28(candidate))
15200
15389
  return { npm: candidate };
15201
15390
  }
15202
15391
  return { npm: "npm" };
@@ -15258,7 +15447,7 @@ __export(exports_grants, {
15258
15447
  runBlock: () => runBlock,
15259
15448
  isAllowed: () => isAllowed
15260
15449
  });
15261
- import { existsSync as existsSync28, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
15450
+ import { existsSync as existsSync29, mkdirSync as mkdirSync13, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "node:fs";
15262
15451
  import { homedir as homedir14 } from "node:os";
15263
15452
  import { join as join17 } from "node:path";
15264
15453
  async function syncToBroker(meshSlug, grants) {
@@ -15278,19 +15467,19 @@ async function syncToBroker(meshSlug, grants) {
15278
15467
  }
15279
15468
  }
15280
15469
  function readGrants() {
15281
- if (!existsSync28(GRANT_FILE))
15470
+ if (!existsSync29(GRANT_FILE))
15282
15471
  return {};
15283
15472
  try {
15284
- return JSON.parse(readFileSync21(GRANT_FILE, "utf-8"));
15473
+ return JSON.parse(readFileSync22(GRANT_FILE, "utf-8"));
15285
15474
  } catch {
15286
15475
  return {};
15287
15476
  }
15288
15477
  }
15289
15478
  function writeGrants(g) {
15290
15479
  const dir = join17(homedir14(), ".claudemesh");
15291
- if (!existsSync28(dir))
15292
- mkdirSync12(dir, { recursive: true });
15293
- writeFileSync17(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
15480
+ if (!existsSync29(dir))
15481
+ mkdirSync13(dir, { recursive: true });
15482
+ writeFileSync18(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
15294
15483
  }
15295
15484
  function resolveCaps(input) {
15296
15485
  if (input.includes("all"))
@@ -17166,8 +17355,8 @@ __export(exports_file, {
17166
17355
  runFileGet: () => runFileGet
17167
17356
  });
17168
17357
  import { hostname as osHostname2 } from "node:os";
17169
- import { resolve as resolvePath, basename, dirname as dirname9 } from "node:path";
17170
- import { statSync as statSync7, existsSync as existsSync29, writeFileSync as writeFileSync18, mkdirSync as mkdirSync13 } from "node:fs";
17358
+ import { resolve as resolvePath, basename, dirname as dirname10 } from "node:path";
17359
+ import { statSync as statSync7, existsSync as existsSync30, writeFileSync as writeFileSync19, mkdirSync as mkdirSync14 } from "node:fs";
17171
17360
  function emitJson2(data) {
17172
17361
  console.log(JSON.stringify(data, null, 2));
17173
17362
  }
@@ -17184,7 +17373,7 @@ async function runFileShare(filePath, opts) {
17184
17373
  return EXIT.INVALID_ARGS;
17185
17374
  }
17186
17375
  const absPath = resolvePath(filePath);
17187
- if (!existsSync29(absPath)) {
17376
+ if (!existsSync30(absPath)) {
17188
17377
  render.err(`File not found: ${absPath}`);
17189
17378
  return EXIT.INVALID_ARGS;
17190
17379
  }
@@ -17263,8 +17452,8 @@ async function runFileGet(fileId, opts) {
17263
17452
  }
17264
17453
  const buf = Buffer.from(await res.arrayBuffer());
17265
17454
  const outPath = opts.out ? resolvePath(opts.out) : resolvePath(process.cwd(), meta.name);
17266
- mkdirSync13(dirname9(outPath), { recursive: true });
17267
- writeFileSync18(outPath, buf);
17455
+ mkdirSync14(dirname10(outPath), { recursive: true });
17456
+ writeFileSync19(outPath, buf);
17268
17457
  if (opts.json) {
17269
17458
  emitJson2({ fileId, name: meta.name, savedTo: outPath, sizeBytes: buf.length });
17270
17459
  } else {
@@ -17874,7 +18063,7 @@ __export(exports_bridge, {
17874
18063
  runBridge: () => runBridge,
17875
18064
  bridgeConfigTemplate: () => bridgeConfigTemplate
17876
18065
  });
17877
- import { readFileSync as readFileSync22, existsSync as existsSync30 } from "node:fs";
18066
+ import { readFileSync as readFileSync23, existsSync as existsSync31 } from "node:fs";
17878
18067
  function parseConfig(text) {
17879
18068
  const trimmed = text.trim();
17880
18069
  if (trimmed.startsWith("{"))
@@ -17918,13 +18107,13 @@ async function runBridge(configPath) {
17918
18107
  render.err("Usage: claudemesh bridge run <config.yaml>");
17919
18108
  return EXIT.INVALID_ARGS;
17920
18109
  }
17921
- if (!existsSync30(configPath)) {
18110
+ if (!existsSync31(configPath)) {
17922
18111
  render.err(`config file not found: ${configPath}`);
17923
18112
  return EXIT.NOT_FOUND;
17924
18113
  }
17925
18114
  let cfg;
17926
18115
  try {
17927
- cfg = parseConfig(readFileSync22(configPath, "utf-8"));
18116
+ cfg = parseConfig(readFileSync23(configPath, "utf-8"));
17928
18117
  } catch (e) {
17929
18118
  render.err(`failed to parse ${configPath}: ${e instanceof Error ? e.message : String(e)}`);
17930
18119
  return EXIT.INVALID_ARGS;
@@ -18898,12 +19087,12 @@ import {
18898
19087
  ListResourcesRequestSchema,
18899
19088
  ReadResourceRequestSchema
18900
19089
  } from "@modelcontextprotocol/sdk/types.js";
18901
- import { existsSync as existsSync31, appendFileSync as appendFileSync2 } from "node:fs";
19090
+ import { existsSync as existsSync32, appendFileSync as appendFileSync2 } from "node:fs";
18902
19091
  import { request as httpRequest2 } from "node:http";
18903
19092
  import { join as join18 } from "node:path";
18904
19093
  async function daemonReady() {
18905
19094
  for (let i = 0;i < DAEMON_BOOT_RETRIES; i++) {
18906
- if (existsSync31(DAEMON_PATHS.SOCK_FILE))
19095
+ if (existsSync32(DAEMON_PATHS.SOCK_FILE))
18907
19096
  return true;
18908
19097
  await new Promise((r) => setTimeout(r, DAEMON_BOOT_RETRY_MS));
18909
19098
  }
@@ -21504,4 +21693,4 @@ main().catch((err) => {
21504
21693
  process.exit(EXIT.INTERNAL_ERROR);
21505
21694
  });
21506
21695
 
21507
- //# debugId=A7ECB4BF81F2B4CE64756E2164756E21
21696
+ //# debugId=2228CF546341C88264756E2164756E21