claudemesh-cli 1.34.18 → 1.35.1

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.18", env;
107
+ var URLS, VERSION = "1.35.1", env;
108
108
  var init_urls = __esm(() => {
109
109
  URLS = {
110
110
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -4337,6 +4337,76 @@ var init_session_hello_sig = __esm(() => {
4337
4337
  DEFAULT_ATTESTATION_TTL_MS = 12 * 60 * 60 * 1000;
4338
4338
  });
4339
4339
 
4340
+ // src/services/session/keypair-store.ts
4341
+ var exports_keypair_store = {};
4342
+ __export(exports_keypair_store, {
4343
+ sessionsDir: () => sessionsDir,
4344
+ loadOrCreateSessionKeypair: () => loadOrCreateSessionKeypair
4345
+ });
4346
+ import { randomBytes as randomBytes6 } from "node:crypto";
4347
+ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync7 } from "node:fs";
4348
+ import { homedir as homedir5 } from "node:os";
4349
+ import { join as join5 } from "node:path";
4350
+ function sessionsDir() {
4351
+ return process.env.CLAUDEMESH_SESSIONS_DIR || join5(homedir5(), ".claudemesh", "sessions");
4352
+ }
4353
+ function keyFilePath(meshSlug, sessionId) {
4354
+ return join5(sessionsDir(), meshSlug, `${sessionId}.json`);
4355
+ }
4356
+ function readValidKeypair(file) {
4357
+ try {
4358
+ if (!existsSync8(file))
4359
+ return null;
4360
+ const parsed = JSON.parse(readFileSync7(file, "utf8"));
4361
+ if (parsed && typeof parsed.publicKey === "string" && /^[0-9a-f]{64}$/.test(parsed.publicKey) && typeof parsed.secretKey === "string" && /^[0-9a-f]{128}$/.test(parsed.secretKey)) {
4362
+ return { publicKey: parsed.publicKey, secretKey: parsed.secretKey };
4363
+ }
4364
+ } catch {}
4365
+ return null;
4366
+ }
4367
+ async function loadOrCreateSessionKeypair(meshSlug, sessionId) {
4368
+ if (!SLUG_RE.test(meshSlug) || !UUID_RE.test(sessionId)) {
4369
+ return generateKeypair3();
4370
+ }
4371
+ const file = keyFilePath(meshSlug, sessionId);
4372
+ const existing = readValidKeypair(file);
4373
+ if (existing)
4374
+ return existing;
4375
+ const kp = await generateKeypair3();
4376
+ try {
4377
+ mkdirSync4(join5(sessionsDir(), meshSlug), { recursive: true, mode: 448 });
4378
+ const stored = {
4379
+ version: 1,
4380
+ meshSlug,
4381
+ sessionId,
4382
+ publicKey: kp.publicKey,
4383
+ secretKey: kp.secretKey,
4384
+ createdAt: new Date().toISOString()
4385
+ };
4386
+ const tmp = `${file}.${randomBytes6(6).toString("hex")}.tmp`;
4387
+ writeFileSync7(tmp, JSON.stringify(stored), { mode: 384 });
4388
+ try {
4389
+ if (existsSync8(file)) {
4390
+ const won = readValidKeypair(file);
4391
+ if (won) {
4392
+ try {
4393
+ rmSync(tmp, { force: true });
4394
+ } catch {}
4395
+ return won;
4396
+ }
4397
+ }
4398
+ renameSync2(tmp, file);
4399
+ } catch {}
4400
+ } catch {}
4401
+ return kp;
4402
+ }
4403
+ var UUID_RE, SLUG_RE;
4404
+ var init_keypair_store = __esm(() => {
4405
+ init_facade7();
4406
+ UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4407
+ SLUG_RE = /^[a-z0-9._-]+$/i;
4408
+ });
4409
+
4340
4410
  // src/commands/launch.ts
4341
4411
  var exports_launch = {};
4342
4412
  __export(exports_launch, {
@@ -4344,10 +4414,33 @@ __export(exports_launch, {
4344
4414
  });
4345
4415
  import { spawnSync as spawnSync2 } from "node:child_process";
4346
4416
  import { randomUUID } from "node:crypto";
4347
- import { mkdtempSync, writeFileSync as writeFileSync7, rmSync, readdirSync, statSync as statSync2, existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
4348
- import { tmpdir, hostname as hostname2, homedir as homedir5 } from "node:os";
4349
- import { join as join5 } from "node:path";
4417
+ import { mkdtempSync, writeFileSync as writeFileSync8, rmSync as rmSync2, readdirSync, statSync as statSync2, existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
4418
+ import { tmpdir, hostname as hostname2, homedir as homedir6 } from "node:os";
4419
+ import { join as join6 } from "node:path";
4350
4420
  import { createInterface as createInterface4 } from "node:readline";
4421
+ function resolveLatestSessionUuid(cwd) {
4422
+ try {
4423
+ const slug = cwd.replace(/\//g, "-");
4424
+ const dir = join6(homedir6(), ".claude", "projects", slug);
4425
+ if (!existsSync9(dir))
4426
+ return;
4427
+ const uuidRe = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
4428
+ let newest = null;
4429
+ for (const entry of readdirSync(dir)) {
4430
+ const m = uuidRe.exec(entry);
4431
+ if (!m)
4432
+ continue;
4433
+ try {
4434
+ const mtime = statSync2(join6(dir, entry)).mtimeMs;
4435
+ if (!newest || mtime > newest.mtime)
4436
+ newest = { id: m[1], mtime };
4437
+ } catch {}
4438
+ }
4439
+ return newest?.id;
4440
+ } catch {
4441
+ return;
4442
+ }
4443
+ }
4351
4444
  async function ensureDaemonRunning(meshSlug, quiet) {
4352
4445
  const { ensureDaemonReady: ensureDaemonReady2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
4353
4446
  if (!quiet)
@@ -4743,17 +4836,17 @@ async function runLaunch(flags, rawArgs) {
4743
4836
  for (const entry of readdirSync(tmpBase)) {
4744
4837
  if (!entry.startsWith("claudemesh-"))
4745
4838
  continue;
4746
- const full = join5(tmpBase, entry);
4839
+ const full = join6(tmpBase, entry);
4747
4840
  const age = Date.now() - statSync2(full).mtimeMs;
4748
4841
  if (age > 3600000)
4749
- rmSync(full, { recursive: true, force: true });
4842
+ rmSync2(full, { recursive: true, force: true });
4750
4843
  }
4751
4844
  } catch {}
4752
4845
  await ensureDaemonRunning(mesh.slug, args.quiet);
4753
4846
  try {
4754
- const claudeConfigPath = join5(homedir5(), ".claude.json");
4755
- if (existsSync8(claudeConfigPath)) {
4756
- const claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
4847
+ const claudeConfigPath = join6(homedir6(), ".claude.json");
4848
+ if (existsSync9(claudeConfigPath)) {
4849
+ const claudeConfig = JSON.parse(readFileSync8(claudeConfigPath, "utf-8"));
4757
4850
  const mcpServers = claudeConfig.mcpServers ?? {};
4758
4851
  let cleaned = 0;
4759
4852
  for (const key of Object.keys(mcpServers)) {
@@ -4771,7 +4864,7 @@ async function runLaunch(flags, rawArgs) {
4771
4864
  }
4772
4865
  if (cleaned > 0) {
4773
4866
  claudeConfig.mcpServers = mcpServers;
4774
- writeFileSync7(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
4867
+ writeFileSync8(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
4775
4868
  `, "utf-8");
4776
4869
  }
4777
4870
  }
@@ -4788,7 +4881,7 @@ async function runLaunch(flags, rawArgs) {
4788
4881
  console.log(" (Could not fetch service catalog — mesh services won't be natively available)");
4789
4882
  }
4790
4883
  }
4791
- const tmpDir = mkdtempSync(join5(tmpdir(), "claudemesh-"));
4884
+ const tmpDir = mkdtempSync(join6(tmpdir(), "claudemesh-"));
4792
4885
  const sessionConfig = {
4793
4886
  version: 1,
4794
4887
  meshes: [mesh],
@@ -4797,10 +4890,18 @@ async function runLaunch(flags, rawArgs) {
4797
4890
  ...parsedGroups.length > 0 ? { groups: parsedGroups } : {},
4798
4891
  messageMode
4799
4892
  };
4800
- writeFileSync7(join5(tmpDir, "config.json"), JSON.stringify(sessionConfig, null, 2) + `
4801
- `, "utf-8");
4893
+ writeFileSync8(join6(tmpDir, "config.json"), JSON.stringify(sessionConfig, null, 2) + `
4894
+ `, { encoding: "utf-8", mode: 384 });
4802
4895
  const isResume = args.resume !== null || args.continueSession;
4803
- const claudeSessionId = isResume ? undefined : randomUUID();
4896
+ let claudeSessionId;
4897
+ if (args.resume) {
4898
+ claudeSessionId = args.resume;
4899
+ } else if (args.continueSession) {
4900
+ claudeSessionId = resolveLatestSessionUuid(process.cwd());
4901
+ } else {
4902
+ claudeSessionId = randomUUID();
4903
+ }
4904
+ const passSessionIdFlag = !isResume;
4804
4905
  let sessionTokenFilePath = null;
4805
4906
  let sessionTokenForCleanup = null;
4806
4907
  try {
@@ -4812,7 +4913,7 @@ async function runLaunch(flags, rawArgs) {
4812
4913
  try {
4813
4914
  const { generateKeypair: generateKeypair4 } = await Promise.resolve().then(() => (init_facade7(), exports_facade4));
4814
4915
  const { signParentAttestation: signParentAttestation2 } = await Promise.resolve().then(() => (init_session_hello_sig(), exports_session_hello_sig));
4815
- const sessionKp = await generateKeypair4();
4916
+ const sessionKp = claudeSessionId ? await (await Promise.resolve().then(() => (init_keypair_store(), exports_keypair_store))).loadOrCreateSessionKeypair(mesh.slug, claudeSessionId) : await generateKeypair4();
4816
4917
  const att = await signParentAttestation2({
4817
4918
  parentMemberPubkey: mesh.pubkey,
4818
4919
  parentSecretKey: mesh.secretKey,
@@ -4858,10 +4959,10 @@ async function runLaunch(flags, rawArgs) {
4858
4959
  }
4859
4960
  const meshMcpEntries = [];
4860
4961
  if (serviceCatalog.length > 0) {
4861
- const claudeConfigPath = join5(homedir5(), ".claude.json");
4962
+ const claudeConfigPath = join6(homedir6(), ".claude.json");
4862
4963
  let claudeConfig = {};
4863
4964
  try {
4864
- claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
4965
+ claudeConfig = JSON.parse(readFileSync8(claudeConfigPath, "utf-8"));
4865
4966
  } catch {
4866
4967
  claudeConfig = {};
4867
4968
  }
@@ -4888,7 +4989,7 @@ async function runLaunch(flags, rawArgs) {
4888
4989
  meshMcpEntries.push({ key: entryKey, entry });
4889
4990
  }
4890
4991
  claudeConfig.mcpServers = mcpServers;
4891
- writeFileSync7(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
4992
+ writeFileSync8(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
4892
4993
  `, "utf-8");
4893
4994
  if (!args.quiet && meshMcpEntries.length > 0) {
4894
4995
  console.log(` ${meshMcpEntries.length} mesh service(s) registered as native MCPs:`);
@@ -4912,7 +5013,7 @@ async function runLaunch(flags, rawArgs) {
4912
5013
  const claudeArgs = [
4913
5014
  "--dangerously-load-development-channels",
4914
5015
  "server:claudemesh",
4915
- ...claudeSessionId ? ["--session-id", claudeSessionId] : [],
5016
+ ...passSessionIdFlag && claudeSessionId ? ["--session-id", claudeSessionId] : [],
4916
5017
  ...args.resume ? ["--resume", args.resume] : [],
4917
5018
  ...args.continueSession ? ["--continue"] : [],
4918
5019
  ...args.skipPermConfirm ? ["--dangerously-skip-permissions"] : [],
@@ -4923,12 +5024,12 @@ async function runLaunch(flags, rawArgs) {
4923
5024
  let claudeBin = "claude";
4924
5025
  if (!isWindows2) {
4925
5026
  const candidates = [
4926
- join5(homedir5(), ".local", "bin", "claude"),
5027
+ join6(homedir6(), ".local", "bin", "claude"),
4927
5028
  "/usr/local/bin/claude",
4928
- join5(homedir5(), ".claude", "bin", "claude")
5029
+ join6(homedir6(), ".claude", "bin", "claude")
4929
5030
  ];
4930
5031
  for (const c of candidates) {
4931
- if (existsSync8(c)) {
5032
+ if (existsSync9(c)) {
4932
5033
  claudeBin = c;
4933
5034
  break;
4934
5035
  }
@@ -4937,19 +5038,19 @@ async function runLaunch(flags, rawArgs) {
4937
5038
  const cleanup = () => {
4938
5039
  if (meshMcpEntries.length > 0) {
4939
5040
  try {
4940
- const claudeConfigPath = join5(homedir5(), ".claude.json");
4941
- const claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
5041
+ const claudeConfigPath = join6(homedir6(), ".claude.json");
5042
+ const claudeConfig = JSON.parse(readFileSync8(claudeConfigPath, "utf-8"));
4942
5043
  const mcpServers = claudeConfig.mcpServers ?? {};
4943
5044
  for (const { key } of meshMcpEntries) {
4944
5045
  delete mcpServers[key];
4945
5046
  }
4946
5047
  claudeConfig.mcpServers = mcpServers;
4947
- writeFileSync7(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
5048
+ writeFileSync8(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
4948
5049
  `, "utf-8");
4949
5050
  } catch {}
4950
5051
  }
4951
5052
  try {
4952
- rmSync(tmpDir, { recursive: true, force: true });
5053
+ rmSync2(tmpDir, { recursive: true, force: true });
4953
5054
  } catch {}
4954
5055
  };
4955
5056
  process.on("exit", cleanup);
@@ -5642,9 +5743,9 @@ __export(exports_join, {
5642
5743
  runJoin: () => runJoin
5643
5744
  });
5644
5745
  import sodium3 from "libsodium-wrappers";
5645
- import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync4 } from "node:fs";
5646
- import { join as join6, dirname as dirname3 } from "node:path";
5647
- import { homedir as homedir6, hostname as hostname3 } from "node:os";
5746
+ import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "node:fs";
5747
+ import { join as join7, dirname as dirname3 } from "node:path";
5748
+ import { homedir as homedir7, hostname as hostname3 } from "node:os";
5648
5749
  function deriveAppBaseUrl() {
5649
5750
  const override = process.env.CLAUDEMESH_APP_URL;
5650
5751
  if (override)
@@ -5763,11 +5864,11 @@ async function runJoin(args) {
5763
5864
  joinedAt: new Date().toISOString()
5764
5865
  });
5765
5866
  writeConfig(config);
5766
- const configDir = env.CLAUDEMESH_CONFIG_DIR ?? join6(homedir6(), ".claudemesh");
5767
- const inviteFile = join6(configDir, `invite-${payload.mesh_slug}.txt`);
5867
+ const configDir = env.CLAUDEMESH_CONFIG_DIR ?? join7(homedir7(), ".claudemesh");
5868
+ const inviteFile = join7(configDir, `invite-${payload.mesh_slug}.txt`);
5768
5869
  try {
5769
- mkdirSync4(dirname3(inviteFile), { recursive: true });
5770
- writeFileSync8(inviteFile, link, "utf-8");
5870
+ mkdirSync5(dirname3(inviteFile), { recursive: true });
5871
+ writeFileSync9(inviteFile, link, "utf-8");
5771
5872
  } catch {}
5772
5873
  console.log("");
5773
5874
  console.log(`✓ Joined "${payload.mesh_slug}" as ${displayName}${enroll.alreadyMember ? " (already a member — re-enrolled with same pubkey)" : ""}`);
@@ -6013,7 +6114,7 @@ async function rename(oldSlug, newSlug) {
6013
6114
  console.error(` ${icons.cross} Usage: ${bold("claudemesh rename")} <old-slug> <new-slug>`);
6014
6115
  return EXIT.INVALID_ARGS;
6015
6116
  }
6016
- if (!SLUG_RE.test(newSlug)) {
6117
+ if (!SLUG_RE2.test(newSlug)) {
6017
6118
  console.error(` ${icons.cross} Invalid slug: must be 2-32 chars, lowercase alnum + hyphens, start with alnum`);
6018
6119
  return EXIT.INVALID_ARGS;
6019
6120
  }
@@ -6064,7 +6165,7 @@ async function rename(oldSlug, newSlug) {
6064
6165
  return EXIT.INTERNAL_ERROR;
6065
6166
  }
6066
6167
  }
6067
- var SLUG_RE;
6168
+ var SLUG_RE2;
6068
6169
  var init_rename2 = __esm(() => {
6069
6170
  init_facade10();
6070
6171
  init_facade6();
@@ -6072,7 +6173,7 @@ var init_rename2 = __esm(() => {
6072
6173
  init_facade();
6073
6174
  init_styles();
6074
6175
  init_exit_codes();
6075
- SLUG_RE = /^[a-z0-9][a-z0-9-]{1,31}$/;
6176
+ SLUG_RE2 = /^[a-z0-9][a-z0-9-]{1,31}$/;
6076
6177
  });
6077
6178
 
6078
6179
  // src/services/clipboard/read.ts
@@ -9272,12 +9373,12 @@ var init_whoami = __esm(() => {
9272
9373
  });
9273
9374
 
9274
9375
  // src/daemon/lock.ts
9275
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync8, unlinkSync as unlinkSync3, writeFileSync as writeFileSync9 } from "node:fs";
9376
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync9, unlinkSync as unlinkSync3, writeFileSync as writeFileSync10 } from "node:fs";
9276
9377
  import { dirname as dirname4 } from "node:path";
9277
9378
  function acquireSingletonLock() {
9278
- mkdirSync5(dirname4(DAEMON_PATHS.PID_FILE), { recursive: true, mode: 448 });
9279
- if (existsSync9(DAEMON_PATHS.PID_FILE)) {
9280
- const raw = readFileSync8(DAEMON_PATHS.PID_FILE, "utf8").trim();
9379
+ mkdirSync6(dirname4(DAEMON_PATHS.PID_FILE), { recursive: true, mode: 448 });
9380
+ if (existsSync10(DAEMON_PATHS.PID_FILE)) {
9381
+ const raw = readFileSync9(DAEMON_PATHS.PID_FILE, "utf8").trim();
9281
9382
  const oldPid = Number.parseInt(raw, 10);
9282
9383
  if (Number.isFinite(oldPid) && oldPid > 0 && isProcessAlive(oldPid)) {
9283
9384
  return { result: "already-running", pid: oldPid };
@@ -9285,22 +9386,22 @@ function acquireSingletonLock() {
9285
9386
  try {
9286
9387
  unlinkSync3(DAEMON_PATHS.PID_FILE);
9287
9388
  } catch {}
9288
- writeFileSync9(DAEMON_PATHS.PID_FILE, String(process.pid), { mode: 384 });
9389
+ writeFileSync10(DAEMON_PATHS.PID_FILE, String(process.pid), { mode: 384 });
9289
9390
  return { result: "stale", pid: process.pid };
9290
9391
  }
9291
- writeFileSync9(DAEMON_PATHS.PID_FILE, String(process.pid), { mode: 384 });
9392
+ writeFileSync10(DAEMON_PATHS.PID_FILE, String(process.pid), { mode: 384 });
9292
9393
  return { result: "acquired", pid: process.pid };
9293
9394
  }
9294
9395
  function releaseSingletonLock() {
9295
9396
  try {
9296
- const raw = readFileSync8(DAEMON_PATHS.PID_FILE, "utf8").trim();
9397
+ const raw = readFileSync9(DAEMON_PATHS.PID_FILE, "utf8").trim();
9297
9398
  if (Number.parseInt(raw, 10) === process.pid)
9298
9399
  unlinkSync3(DAEMON_PATHS.PID_FILE);
9299
9400
  } catch {}
9300
9401
  }
9301
9402
  function readRunningPid() {
9302
9403
  try {
9303
- const raw = readFileSync8(DAEMON_PATHS.PID_FILE, "utf8").trim();
9404
+ const raw = readFileSync9(DAEMON_PATHS.PID_FILE, "utf8").trim();
9304
9405
  const pid = Number.parseInt(raw, 10);
9305
9406
  if (Number.isFinite(pid) && pid > 0 && isProcessAlive(pid))
9306
9407
  return pid;
@@ -9990,7 +10091,7 @@ var init_session_registry = __esm(() => {
9990
10091
 
9991
10092
  // src/daemon/ipc/server.ts
9992
10093
  import { createServer as createServer2 } from "node:http";
9993
- import { chmodSync as chmodSync3, existsSync as existsSync10, unlinkSync as unlinkSync4 } from "node:fs";
10094
+ import { chmodSync as chmodSync3, existsSync as existsSync11, unlinkSync as unlinkSync4 } from "node:fs";
9994
10095
  import { timingSafeEqual } from "node:crypto";
9995
10096
  import { randomUUID as randomUUID3 } from "node:crypto";
9996
10097
  function startIpcServer(opts) {
@@ -10006,7 +10107,7 @@ function startIpcServer(opts) {
10006
10107
  meshConfigs: opts.meshConfigs,
10007
10108
  onPendingInserted: opts.onPendingInserted
10008
10109
  });
10009
- if (existsSync10(DAEMON_PATHS.SOCK_FILE)) {
10110
+ if (existsSync11(DAEMON_PATHS.SOCK_FILE)) {
10010
10111
  try {
10011
10112
  unlinkSync4(DAEMON_PATHS.SOCK_FILE);
10012
10113
  } catch {}
@@ -10833,16 +10934,16 @@ function parseSendRequest(body, idempotencyHeader) {
10833
10934
  }
10834
10935
  async function resolveAndEncrypt(req, broker, meshSecretKey, meshSlug) {
10835
10936
  const { encryptDirect: encryptDirect2 } = await Promise.resolve().then(() => (init_box(), exports_box));
10836
- const { randomBytes: randomBytes6 } = await import("node:crypto");
10937
+ const { randomBytes: randomBytes7 } = await import("node:crypto");
10837
10938
  const to = req.to.trim();
10838
10939
  if (to.startsWith("#") && /^#[0-9a-z_-]{20,}$/i.test(to)) {
10839
10940
  const ciphertext = Buffer.from(req.message, "utf8").toString("base64");
10840
- const nonce = randomBytes6(24).toString("base64");
10941
+ const nonce = randomBytes7(24).toString("base64");
10841
10942
  return { target_spec: to, ciphertext, nonce, mesh: meshSlug ?? "" };
10842
10943
  }
10843
10944
  if (to.startsWith("@") || to === "*") {
10844
10945
  const ciphertext = Buffer.from(req.message, "utf8").toString("base64");
10845
- const nonce = randomBytes6(24).toString("base64");
10946
+ const nonce = randomBytes7(24).toString("base64");
10846
10947
  return { target_spec: to, ciphertext, nonce, mesh: meshSlug ?? "" };
10847
10948
  }
10848
10949
  if (/^[0-9a-f]{64}$/i.test(to)) {
@@ -11863,8 +11964,8 @@ function bufferToHex(b) {
11863
11964
  return s;
11864
11965
  }
11865
11966
  async function randomNonce2() {
11866
- const { randomBytes: randomBytes6 } = await import("node:crypto");
11867
- return randomBytes6(24).toString("base64");
11967
+ const { randomBytes: randomBytes7 } = await import("node:crypto");
11968
+ return randomBytes7(24).toString("base64");
11868
11969
  }
11869
11970
  function defaultLog4(level, msg, meta) {
11870
11971
  const line = JSON.stringify({ level, msg, ...meta, ts: new Date().toISOString() });
@@ -12039,13 +12140,13 @@ __export(exports_identity, {
12039
12140
  __resetHostIdCacheForTests: () => __resetHostIdCacheForTests,
12040
12141
  __computeV1FingerprintForTests: () => __computeV1FingerprintForTests
12041
12142
  });
12042
- import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "node:fs";
12043
- import { join as join7 } from "node:path";
12143
+ import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "node:fs";
12144
+ import { join as join8 } from "node:path";
12044
12145
  import { createHash as createHash2 } from "node:crypto";
12045
12146
  import { execFileSync } from "node:child_process";
12046
12147
  import { networkInterfaces } from "node:os";
12047
12148
  function path() {
12048
- return join7(DAEMON_PATHS.DAEMON_DIR, FILE_NAME);
12149
+ return join8(DAEMON_PATHS.DAEMON_DIR, FILE_NAME);
12049
12150
  }
12050
12151
  function computeCurrentFingerprint() {
12051
12152
  const host_id = readHostIdV2() ?? "";
@@ -12060,13 +12161,13 @@ function computeCurrentFingerprint() {
12060
12161
  }
12061
12162
  function checkFingerprint() {
12062
12163
  const current = computeCurrentFingerprint();
12063
- if (!existsSync11(path())) {
12064
- writeFileSync10(path(), JSON.stringify(current, null, 2), { mode: 384 });
12164
+ if (!existsSync12(path())) {
12165
+ writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12065
12166
  return { result: "first_run", current };
12066
12167
  }
12067
12168
  let stored;
12068
12169
  try {
12069
- stored = JSON.parse(readFileSync9(path(), "utf8"));
12170
+ stored = JSON.parse(readFileSync10(path(), "utf8"));
12070
12171
  } catch {
12071
12172
  return { result: "unavailable", current };
12072
12173
  }
@@ -12074,7 +12175,7 @@ function checkFingerprint() {
12074
12175
  if (stored.fingerprint === current.fingerprint)
12075
12176
  return { result: "match", current, stored };
12076
12177
  if (stored.host_id && stored.host_id === current.host_id) {
12077
- writeFileSync10(path(), JSON.stringify(current, null, 2), { mode: 384 });
12178
+ writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12078
12179
  return { result: "match", current, stored };
12079
12180
  }
12080
12181
  return { result: "mismatch", current, stored };
@@ -12082,7 +12183,7 @@ function checkFingerprint() {
12082
12183
  if (stored.schema_version === 1) {
12083
12184
  const v1 = computeCurrentFingerprintV1();
12084
12185
  if (stored.fingerprint === v1.fingerprint) {
12085
- writeFileSync10(path(), JSON.stringify(current, null, 2), { mode: 384 });
12186
+ writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12086
12187
  return { result: "match", current, stored };
12087
12188
  }
12088
12189
  return { result: "mismatch", current, stored };
@@ -12091,7 +12192,7 @@ function checkFingerprint() {
12091
12192
  }
12092
12193
  function acceptCurrentHost() {
12093
12194
  const current = computeCurrentFingerprint();
12094
- writeFileSync10(path(), JSON.stringify(current, null, 2), { mode: 384 });
12195
+ writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
12095
12196
  return current;
12096
12197
  }
12097
12198
  function fingerprintV2(host_id, stable_mac) {
@@ -12141,7 +12242,7 @@ function readHostIdV1() {
12141
12242
  if (process.platform === "linux") {
12142
12243
  for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
12143
12244
  try {
12144
- const raw = readFileSync9(p, "utf8").trim();
12245
+ const raw = readFileSync10(p, "utf8").trim();
12145
12246
  if (raw)
12146
12247
  return `linux:${raw}`;
12147
12248
  } catch {}
@@ -12187,7 +12288,7 @@ function readHostIdV2Uncached() {
12187
12288
  if (process.platform === "linux") {
12188
12289
  for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
12189
12290
  try {
12190
- const raw = readFileSync9(p, "utf8").trim();
12291
+ const raw = readFileSync10(p, "utf8").trim();
12191
12292
  if (raw)
12192
12293
  return `linux:${raw}`;
12193
12294
  } catch {}
@@ -12230,23 +12331,23 @@ var init_identity = __esm(() => {
12230
12331
  });
12231
12332
 
12232
12333
  // src/daemon/run.ts
12233
- import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10 } from "node:fs";
12334
+ import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11 } from "node:fs";
12234
12335
  function detectContainer() {
12235
12336
  if (process.env.KUBERNETES_SERVICE_HOST)
12236
12337
  return true;
12237
12338
  if (process.env.CONTAINER === "1")
12238
12339
  return true;
12239
12340
  try {
12240
- if (existsSync12("/.dockerenv"))
12341
+ if (existsSync13("/.dockerenv"))
12241
12342
  return true;
12242
- const cg = readFileSync10("/proc/1/cgroup", "utf8");
12343
+ const cg = readFileSync11("/proc/1/cgroup", "utf8");
12243
12344
  if (/(docker|kubepods|containerd)/.test(cg))
12244
12345
  return true;
12245
12346
  } catch {}
12246
12347
  return false;
12247
12348
  }
12248
12349
  async function runDaemon(opts = {}) {
12249
- mkdirSync6(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12350
+ mkdirSync7(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12250
12351
  const lock = acquireSingletonLock();
12251
12352
  if (lock.result === "already-running") {
12252
12353
  process.stderr.write(`daemon already running (pid ${lock.pid})
@@ -12389,6 +12490,17 @@ async function runDaemon(opts = {}) {
12389
12490
  }
12390
12491
  prior.close().catch(() => {});
12391
12492
  }
12493
+ const priorByPubkey = sessionBrokersByPubkey.get(info.presence.sessionPubkey);
12494
+ if (priorByPubkey && priorByPubkey !== prior) {
12495
+ for (const [tok, c] of sessionBrokers) {
12496
+ if (c === priorByPubkey) {
12497
+ sessionBrokers.delete(tok);
12498
+ break;
12499
+ }
12500
+ }
12501
+ sessionBrokersByPubkey.delete(info.presence.sessionPubkey);
12502
+ priorByPubkey.close().catch(() => {});
12503
+ }
12392
12504
  const sessionSecretKeyHex = info.presence.sessionSecretKey;
12393
12505
  const sessionPubkeyHex = info.presence.sessionPubkey;
12394
12506
  const client = new SessionBrokerClient({
@@ -12525,10 +12637,10 @@ __export(exports_service_install, {
12525
12637
  installService: () => installService,
12526
12638
  detectPlatform: () => detectPlatform
12527
12639
  });
12528
- import { existsSync as existsSync13, mkdirSync as mkdirSync7, writeFileSync as writeFileSync11, unlinkSync as unlinkSync5, readFileSync as readFileSync11 } from "node:fs";
12640
+ import { existsSync as existsSync14, mkdirSync as mkdirSync8, writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, readFileSync as readFileSync12 } from "node:fs";
12529
12641
  import { execSync as execSync2 } from "node:child_process";
12530
- import { homedir as homedir7 } from "node:os";
12531
- import { join as join8, dirname as dirname5 } from "node:path";
12642
+ import { homedir as homedir8 } from "node:os";
12643
+ import { join as join9, dirname as dirname5 } from "node:path";
12532
12644
  function detectPlatform() {
12533
12645
  if (process.platform === "darwin")
12534
12646
  return "darwin";
@@ -12546,10 +12658,10 @@ function installService(args) {
12546
12658
  if (isCi() && !args.allowCi) {
12547
12659
  throw new Error("Refusing to install persistent service in CI; pass --allow-ci-persistent to override.");
12548
12660
  }
12549
- if (!existsSync13(args.binaryPath)) {
12661
+ if (!existsSync14(args.binaryPath)) {
12550
12662
  throw new Error(`binary not found at ${args.binaryPath}`);
12551
12663
  }
12552
- mkdirSync7(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12664
+ mkdirSync8(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
12553
12665
  if (platform5 === "darwin")
12554
12666
  return installDarwin(args);
12555
12667
  return installLinux(args);
@@ -12562,7 +12674,7 @@ function uninstallService() {
12562
12674
  try {
12563
12675
  execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
12564
12676
  } catch {}
12565
- if (existsSync13(p)) {
12677
+ if (existsSync14(p)) {
12566
12678
  unlinkSync5(p);
12567
12679
  removed.push(p);
12568
12680
  }
@@ -12571,7 +12683,7 @@ function uninstallService() {
12571
12683
  try {
12572
12684
  execSync2(`systemctl --user disable --now ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
12573
12685
  } catch {}
12574
- if (existsSync13(p)) {
12686
+ if (existsSync14(p)) {
12575
12687
  unlinkSync5(p);
12576
12688
  removed.push(p);
12577
12689
  }
@@ -12579,11 +12691,11 @@ function uninstallService() {
12579
12691
  return { platform: platform5, removed };
12580
12692
  }
12581
12693
  function darwinPlistPath() {
12582
- return join8(homedir7(), "Library", "LaunchAgents", `${SERVICE_LABEL2}.plist`);
12694
+ return join9(homedir8(), "Library", "LaunchAgents", `${SERVICE_LABEL2}.plist`);
12583
12695
  }
12584
12696
  function installDarwin(args) {
12585
12697
  const plist = darwinPlistPath();
12586
- mkdirSync7(dirname5(plist), { recursive: true });
12698
+ mkdirSync8(dirname5(plist), { recursive: true });
12587
12699
  const log2 = DAEMON_PATHS.LOG_FILE;
12588
12700
  const nodeBin = process.execPath;
12589
12701
  const meshArgs = [
@@ -12615,25 +12727,25 @@ function installDarwin(args) {
12615
12727
  <key>StandardErrorPath</key>
12616
12728
  <string>${escapeXml(log2)}</string>
12617
12729
  <key>WorkingDirectory</key>
12618
- <string>${escapeXml(homedir7())}</string>
12730
+ <string>${escapeXml(homedir8())}</string>
12619
12731
  <key>EnvironmentVariables</key>
12620
12732
  <dict>
12621
12733
  <key>HOME</key>
12622
- <string>${escapeXml(homedir7())}</string>
12734
+ <string>${escapeXml(homedir8())}</string>
12623
12735
  <key>PATH</key>
12624
12736
  <string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
12625
12737
  </dict>
12626
12738
  </dict>
12627
12739
  </plist>
12628
12740
  `;
12629
- writeFileSync11(plist, xml, { mode: 420 });
12741
+ writeFileSync12(plist, xml, { mode: 420 });
12630
12742
  try {
12631
12743
  execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
12632
12744
  } catch {}
12633
12745
  try {
12634
12746
  const pidPath = DAEMON_PATHS.PID_FILE;
12635
- if (existsSync13(pidPath)) {
12636
- const pid = parseInt(readFileSync11(pidPath, "utf8").trim(), 10);
12747
+ if (existsSync14(pidPath)) {
12748
+ const pid = parseInt(readFileSync12(pidPath, "utf8").trim(), 10);
12637
12749
  if (Number.isFinite(pid) && pid > 0) {
12638
12750
  try {
12639
12751
  process.kill(pid, "SIGTERM");
@@ -12648,11 +12760,11 @@ function installDarwin(args) {
12648
12760
  };
12649
12761
  }
12650
12762
  function linuxUnitPath() {
12651
- return join8(homedir7(), ".config", "systemd", "user", SYSTEMD_UNIT2);
12763
+ return join9(homedir8(), ".config", "systemd", "user", SYSTEMD_UNIT2);
12652
12764
  }
12653
12765
  function installLinux(args) {
12654
12766
  const unit = linuxUnitPath();
12655
- mkdirSync7(dirname5(unit), { recursive: true });
12767
+ mkdirSync8(dirname5(unit), { recursive: true });
12656
12768
  const nodeBin = process.execPath;
12657
12769
  const execArgs = [
12658
12770
  "daemon",
@@ -12678,14 +12790,14 @@ Environment=PATH=/usr/local/bin:/usr/bin:/bin
12678
12790
  [Install]
12679
12791
  WantedBy=default.target
12680
12792
  `;
12681
- writeFileSync11(unit, content, { mode: 420 });
12793
+ writeFileSync12(unit, content, { mode: 420 });
12682
12794
  try {
12683
12795
  execSync2(`systemctl --user stop ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
12684
12796
  } catch {}
12685
12797
  try {
12686
12798
  const pidPath = DAEMON_PATHS.PID_FILE;
12687
- if (existsSync13(pidPath)) {
12688
- const pid = parseInt(readFileSync11(pidPath, "utf8").trim(), 10);
12799
+ if (existsSync14(pidPath)) {
12800
+ const pid = parseInt(readFileSync12(pidPath, "utf8").trim(), 10);
12689
12801
  if (Number.isFinite(pid) && pid > 0) {
12690
12802
  try {
12691
12803
  process.kill(pid, "SIGTERM");
@@ -12712,10 +12824,10 @@ function readInstalledUnit() {
12712
12824
  if (!platform5)
12713
12825
  return { platform: null, path: null, content: null };
12714
12826
  const path2 = platform5 === "darwin" ? darwinPlistPath() : linuxUnitPath();
12715
- if (!existsSync13(path2))
12827
+ if (!existsSync14(path2))
12716
12828
  return { platform: platform5, path: null, content: null };
12717
12829
  try {
12718
- return { platform: platform5, path: path2, content: readFileSync11(path2, "utf8") };
12830
+ return { platform: platform5, path: path2, content: readFileSync12(path2, "utf8") };
12719
12831
  } catch {
12720
12832
  return { platform: platform5, path: path2, content: null };
12721
12833
  }
@@ -12731,8 +12843,8 @@ __export(exports_daemon, {
12731
12843
  runDaemonCommand: () => runDaemonCommand
12732
12844
  });
12733
12845
  import { spawn } from "node:child_process";
12734
- import { existsSync as existsSync14, openSync as openSync3, mkdirSync as mkdirSync8 } from "node:fs";
12735
- import { join as join9 } from "node:path";
12846
+ import { existsSync as existsSync15, openSync as openSync3, mkdirSync as mkdirSync9 } from "node:fs";
12847
+ import { join as join10 } from "node:path";
12736
12848
  async function runDaemonCommand(sub, opts, rest = []) {
12737
12849
  switch (sub) {
12738
12850
  case undefined:
@@ -13054,8 +13166,8 @@ async function runStop(opts) {
13054
13166
  return 1;
13055
13167
  }
13056
13168
  async function spawnDetachedDaemon(opts) {
13057
- mkdirSync8(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
13058
- const logPath = join9(DAEMON_PATHS.DAEMON_DIR, "daemon.log");
13169
+ mkdirSync9(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
13170
+ const logPath = join10(DAEMON_PATHS.DAEMON_DIR, "daemon.log");
13059
13171
  const binary = process.argv[1] ?? "claudemesh";
13060
13172
  const args = ["daemon", "up", "--foreground"];
13061
13173
  if (opts.noTcp)
@@ -13073,7 +13185,7 @@ async function spawnDetachedDaemon(opts) {
13073
13185
  const sockPath = DAEMON_PATHS.SOCK_FILE;
13074
13186
  const startedAt = Date.now();
13075
13187
  while (Date.now() - startedAt < 3000) {
13076
- if (existsSync14(sockPath)) {
13188
+ if (existsSync15(sockPath)) {
13077
13189
  if (opts.json) {
13078
13190
  process.stdout.write(JSON.stringify({ ok: true, detached: true, pid: child.pid, log: logPath }) + `
13079
13191
  `);
@@ -13118,19 +13230,19 @@ __export(exports_install, {
13118
13230
  import {
13119
13231
  chmodSync as chmodSync4,
13120
13232
  copyFileSync,
13121
- existsSync as existsSync15,
13122
- mkdirSync as mkdirSync9,
13123
- readFileSync as readFileSync12,
13124
- writeFileSync as writeFileSync12
13233
+ existsSync as existsSync16,
13234
+ mkdirSync as mkdirSync10,
13235
+ readFileSync as readFileSync13,
13236
+ writeFileSync as writeFileSync13
13125
13237
  } from "node:fs";
13126
- import { homedir as homedir8, platform as platform5 } from "node:os";
13127
- import { dirname as dirname6, join as join10, resolve } from "node:path";
13238
+ import { homedir as homedir9, platform as platform5 } from "node:os";
13239
+ import { dirname as dirname6, join as join11, resolve } from "node:path";
13128
13240
  import { fileURLToPath } from "node:url";
13129
13241
  import { spawnSync as spawnSync3 } from "node:child_process";
13130
13242
  function readClaudeConfig() {
13131
- if (!existsSync15(CLAUDE_CONFIG))
13243
+ if (!existsSync16(CLAUDE_CONFIG))
13132
13244
  return {};
13133
- const text = readFileSync12(CLAUDE_CONFIG, "utf-8").trim();
13245
+ const text = readFileSync13(CLAUDE_CONFIG, "utf-8").trim();
13134
13246
  if (!text)
13135
13247
  return {};
13136
13248
  try {
@@ -13140,12 +13252,12 @@ function readClaudeConfig() {
13140
13252
  }
13141
13253
  }
13142
13254
  function backupClaudeConfig() {
13143
- if (!existsSync15(CLAUDE_CONFIG))
13255
+ if (!existsSync16(CLAUDE_CONFIG))
13144
13256
  return;
13145
- const backupDir = join10(dirname6(CLAUDE_CONFIG), ".claude", "backups");
13146
- mkdirSync9(backupDir, { recursive: true });
13257
+ const backupDir = join11(dirname6(CLAUDE_CONFIG), ".claude", "backups");
13258
+ mkdirSync10(backupDir, { recursive: true });
13147
13259
  const ts = Date.now();
13148
- const dest = join10(backupDir, `.claude.json.pre-claudemesh.${ts}`);
13260
+ const dest = join11(backupDir, `.claude.json.pre-claudemesh.${ts}`);
13149
13261
  copyFileSync(CLAUDE_CONFIG, dest);
13150
13262
  }
13151
13263
  function patchMcpServer(entry) {
@@ -13169,7 +13281,7 @@ function patchMcpServer(entry) {
13169
13281
  return action;
13170
13282
  }
13171
13283
  function removeMcpServer() {
13172
- if (!existsSync15(CLAUDE_CONFIG))
13284
+ if (!existsSync16(CLAUDE_CONFIG))
13173
13285
  return false;
13174
13286
  backupClaudeConfig();
13175
13287
  const cfg = readClaudeConfig();
@@ -13182,8 +13294,8 @@ function removeMcpServer() {
13182
13294
  return true;
13183
13295
  }
13184
13296
  function flushClaudeConfig(obj) {
13185
- mkdirSync9(dirname6(CLAUDE_CONFIG), { recursive: true });
13186
- writeFileSync12(CLAUDE_CONFIG, JSON.stringify(obj, null, 2) + `
13297
+ mkdirSync10(dirname6(CLAUDE_CONFIG), { recursive: true });
13298
+ writeFileSync13(CLAUDE_CONFIG, JSON.stringify(obj, null, 2) + `
13187
13299
  `, "utf-8");
13188
13300
  try {
13189
13301
  chmodSync4(CLAUDE_CONFIG, 384);
@@ -13205,8 +13317,8 @@ function resolveEntry() {
13205
13317
  function resolveBundledSkillsDir() {
13206
13318
  const here = fileURLToPath(import.meta.url);
13207
13319
  const pkgRoot = resolve(dirname6(here), "..", "..");
13208
- const skillsDir = join10(pkgRoot, "skills");
13209
- if (existsSync15(skillsDir))
13320
+ const skillsDir = join11(pkgRoot, "skills");
13321
+ if (existsSync16(skillsDir))
13210
13322
  return skillsDir;
13211
13323
  return null;
13212
13324
  }
@@ -13219,13 +13331,13 @@ function installSkills() {
13219
13331
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
13220
13332
  if (!entry.isDirectory())
13221
13333
  continue;
13222
- const srcDir = join10(src, entry.name);
13223
- const dstDir = join10(CLAUDE_SKILLS_ROOT, entry.name);
13224
- mkdirSync9(dstDir, { recursive: true });
13334
+ const srcDir = join11(src, entry.name);
13335
+ const dstDir = join11(CLAUDE_SKILLS_ROOT, entry.name);
13336
+ mkdirSync10(dstDir, { recursive: true });
13225
13337
  for (const file of fs.readdirSync(srcDir, { withFileTypes: true })) {
13226
13338
  if (!file.isFile())
13227
13339
  continue;
13228
- copyFileSync(join10(srcDir, file.name), join10(dstDir, file.name));
13340
+ copyFileSync(join11(srcDir, file.name), join11(dstDir, file.name));
13229
13341
  }
13230
13342
  installed.push(entry.name);
13231
13343
  }
@@ -13240,8 +13352,8 @@ function uninstallSkills() {
13240
13352
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
13241
13353
  if (!entry.isDirectory())
13242
13354
  continue;
13243
- const dstDir = join10(CLAUDE_SKILLS_ROOT, entry.name);
13244
- if (existsSync15(dstDir)) {
13355
+ const dstDir = join11(CLAUDE_SKILLS_ROOT, entry.name);
13356
+ if (existsSync16(dstDir)) {
13245
13357
  try {
13246
13358
  fs.rmSync(dstDir, { recursive: true, force: true });
13247
13359
  removed.push(entry.name);
@@ -13266,9 +13378,9 @@ function entriesEqual(a, b) {
13266
13378
  return a.command === b.command && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
13267
13379
  }
13268
13380
  function readClaudeSettings() {
13269
- if (!existsSync15(CLAUDE_SETTINGS))
13381
+ if (!existsSync16(CLAUDE_SETTINGS))
13270
13382
  return {};
13271
- const text = readFileSync12(CLAUDE_SETTINGS, "utf-8").trim();
13383
+ const text = readFileSync13(CLAUDE_SETTINGS, "utf-8").trim();
13272
13384
  if (!text)
13273
13385
  return {};
13274
13386
  try {
@@ -13278,8 +13390,8 @@ function readClaudeSettings() {
13278
13390
  }
13279
13391
  }
13280
13392
  function writeClaudeSettings(obj) {
13281
- mkdirSync9(dirname6(CLAUDE_SETTINGS), { recursive: true });
13282
- writeFileSync12(CLAUDE_SETTINGS, JSON.stringify(obj, null, 2) + `
13393
+ mkdirSync10(dirname6(CLAUDE_SETTINGS), { recursive: true });
13394
+ writeFileSync13(CLAUDE_SETTINGS, JSON.stringify(obj, null, 2) + `
13283
13395
  `, "utf-8");
13284
13396
  }
13285
13397
  function installAllowedTools() {
@@ -13293,7 +13405,7 @@ function installAllowedTools() {
13293
13405
  return { added: toAdd, unchanged: CLAUDEMESH_TOOLS.length - toAdd.length };
13294
13406
  }
13295
13407
  function uninstallAllowedTools() {
13296
- if (!existsSync15(CLAUDE_SETTINGS))
13408
+ if (!existsSync16(CLAUDE_SETTINGS))
13297
13409
  return 0;
13298
13410
  const settings = readClaudeSettings();
13299
13411
  const existing = settings.allowedTools ?? [];
@@ -13328,7 +13440,7 @@ function installHooks() {
13328
13440
  return { added, unchanged };
13329
13441
  }
13330
13442
  function uninstallHooks() {
13331
- if (!existsSync15(CLAUDE_SETTINGS))
13443
+ if (!existsSync16(CLAUDE_SETTINGS))
13332
13444
  return 0;
13333
13445
  const settings = readClaudeSettings();
13334
13446
  const hooks2 = settings.hooks;
@@ -13378,7 +13490,7 @@ async function runInstall(args = []) {
13378
13490
  render.err("`bun` is not on PATH.", "Install Bun first: https://bun.com");
13379
13491
  process.exit(1);
13380
13492
  }
13381
- if (!existsSync15(entry)) {
13493
+ if (!existsSync16(entry)) {
13382
13494
  render.err(`MCP entry not found at ${entry}`);
13383
13495
  process.exit(1);
13384
13496
  }
@@ -13429,7 +13541,7 @@ async function runInstall(args = []) {
13429
13541
  const installed = installSkills();
13430
13542
  if (installed.length > 0) {
13431
13543
  render.ok(`Claude skill${installed.length === 1 ? "" : "s"} installed`, installed.join(", "));
13432
- render.info(dim(` ${join10(CLAUDE_SKILLS_ROOT, installed[0])}/SKILL.md`));
13544
+ render.info(dim(` ${join11(CLAUDE_SKILLS_ROOT, installed[0])}/SKILL.md`));
13433
13545
  }
13434
13546
  } catch (e) {
13435
13547
  render.warn(`skill install failed: ${e instanceof Error ? e.message : String(e)}`);
@@ -13592,9 +13704,9 @@ var init_install = __esm(() => {
13592
13704
  init_facade();
13593
13705
  init_render();
13594
13706
  init_styles();
13595
- CLAUDE_CONFIG = join10(homedir8(), ".claude.json");
13596
- CLAUDE_SETTINGS = join10(homedir8(), ".claude", "settings.json");
13597
- CLAUDE_SKILLS_ROOT = join10(homedir8(), ".claude", "skills");
13707
+ CLAUDE_CONFIG = join11(homedir9(), ".claude.json");
13708
+ CLAUDE_SETTINGS = join11(homedir9(), ".claude", "settings.json");
13709
+ CLAUDE_SKILLS_ROOT = join11(homedir9(), ".claude", "skills");
13598
13710
  CLAUDEMESH_TOOLS = [
13599
13711
  "mcp__claudemesh__cancel_scheduled",
13600
13712
  "mcp__claudemesh__check_messages",
@@ -13649,35 +13761,35 @@ var exports_uninstall = {};
13649
13761
  __export(exports_uninstall, {
13650
13762
  uninstall: () => uninstall
13651
13763
  });
13652
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync16, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
13653
- import { join as join11, dirname as dirname7 } from "node:path";
13654
- import { homedir as homedir9 } from "node:os";
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";
13766
+ import { homedir as homedir10 } from "node:os";
13655
13767
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13656
13768
  function bundledSkillsDir() {
13657
13769
  const here = fileURLToPath2(import.meta.url);
13658
- const pkgRoot = join11(dirname7(here), "..", "..");
13659
- const skillsDir = join11(pkgRoot, "skills");
13660
- return existsSync16(skillsDir) ? skillsDir : null;
13770
+ const pkgRoot = join12(dirname7(here), "..", "..");
13771
+ const skillsDir = join12(pkgRoot, "skills");
13772
+ return existsSync17(skillsDir) ? skillsDir : null;
13661
13773
  }
13662
13774
  async function uninstall() {
13663
13775
  let removed = 0;
13664
- if (existsSync16(PATHS.CLAUDE_JSON)) {
13776
+ if (existsSync17(PATHS.CLAUDE_JSON)) {
13665
13777
  try {
13666
- const raw = readFileSync13(PATHS.CLAUDE_JSON, "utf-8");
13778
+ const raw = readFileSync14(PATHS.CLAUDE_JSON, "utf-8");
13667
13779
  const config = JSON.parse(raw);
13668
13780
  const servers = config.mcpServers;
13669
13781
  if (servers && "claudemesh" in servers) {
13670
13782
  delete servers.claudemesh;
13671
- writeFileSync13(PATHS.CLAUDE_JSON, JSON.stringify(config, null, 2) + `
13783
+ writeFileSync14(PATHS.CLAUDE_JSON, JSON.stringify(config, null, 2) + `
13672
13784
  `, "utf-8");
13673
13785
  render.ok("removed MCP server", dim("~/.claude.json"));
13674
13786
  removed++;
13675
13787
  }
13676
13788
  } catch {}
13677
13789
  }
13678
- if (existsSync16(PATHS.CLAUDE_SETTINGS)) {
13790
+ if (existsSync17(PATHS.CLAUDE_SETTINGS)) {
13679
13791
  try {
13680
- const raw = readFileSync13(PATHS.CLAUDE_SETTINGS, "utf-8");
13792
+ const raw = readFileSync14(PATHS.CLAUDE_SETTINGS, "utf-8");
13681
13793
  const config = JSON.parse(raw);
13682
13794
  const hooks2 = config.hooks;
13683
13795
  if (hooks2) {
@@ -13698,7 +13810,7 @@ async function uninstall() {
13698
13810
  }
13699
13811
  }
13700
13812
  if (removedHooks > 0) {
13701
- writeFileSync13(PATHS.CLAUDE_SETTINGS, JSON.stringify(config, null, 2) + `
13813
+ writeFileSync14(PATHS.CLAUDE_SETTINGS, JSON.stringify(config, null, 2) + `
13702
13814
  `, "utf-8");
13703
13815
  render.ok(`removed ${removedHooks} claudemesh hook${removedHooks === 1 ? "" : "s"}`, dim("settings.json"));
13704
13816
  removed++;
@@ -13713,10 +13825,10 @@ async function uninstall() {
13713
13825
  for (const entry of readdirSync2(src, { withFileTypes: true })) {
13714
13826
  if (!entry.isDirectory())
13715
13827
  continue;
13716
- const dst = join11(CLAUDE_SKILLS_ROOT2, entry.name);
13717
- if (existsSync16(dst)) {
13828
+ const dst = join12(CLAUDE_SKILLS_ROOT2, entry.name);
13829
+ if (existsSync17(dst)) {
13718
13830
  try {
13719
- rmSync2(dst, { recursive: true, force: true });
13831
+ rmSync3(dst, { recursive: true, force: true });
13720
13832
  removedSkills.push(entry.name);
13721
13833
  } catch {}
13722
13834
  }
@@ -13738,7 +13850,7 @@ var init_uninstall = __esm(() => {
13738
13850
  init_render();
13739
13851
  init_styles();
13740
13852
  init_exit_codes();
13741
- CLAUDE_SKILLS_ROOT2 = join11(homedir9(), ".claude", "skills");
13853
+ CLAUDE_SKILLS_ROOT2 = join12(homedir10(), ".claude", "skills");
13742
13854
  });
13743
13855
 
13744
13856
  // src/commands/doctor.ts
@@ -13746,9 +13858,9 @@ var exports_doctor = {};
13746
13858
  __export(exports_doctor, {
13747
13859
  runDoctor: () => runDoctor
13748
13860
  });
13749
- import { existsSync as existsSync17, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
13750
- import { homedir as homedir10, platform as platform6 } from "node:os";
13751
- import { join as join12 } from "node:path";
13861
+ import { existsSync as existsSync18, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
13862
+ import { homedir as homedir11, platform as platform6 } from "node:os";
13863
+ import { join as join13 } from "node:path";
13752
13864
  import { spawnSync as spawnSync4 } from "node:child_process";
13753
13865
  function checkNode() {
13754
13866
  const major = Number(process.versions.node.split(".")[0]);
@@ -13772,8 +13884,8 @@ function checkClaudeOnPath() {
13772
13884
  };
13773
13885
  }
13774
13886
  function checkMcpRegistered() {
13775
- const claudeConfig = join12(homedir10(), ".claude.json");
13776
- if (!existsSync17(claudeConfig)) {
13887
+ const claudeConfig = join13(homedir11(), ".claude.json");
13888
+ if (!existsSync18(claudeConfig)) {
13777
13889
  return {
13778
13890
  name: "claudemesh MCP registered in ~/.claude.json",
13779
13891
  pass: false,
@@ -13781,7 +13893,7 @@ function checkMcpRegistered() {
13781
13893
  };
13782
13894
  }
13783
13895
  try {
13784
- const cfg = JSON.parse(readFileSync14(claudeConfig, "utf-8"));
13896
+ const cfg = JSON.parse(readFileSync15(claudeConfig, "utf-8"));
13785
13897
  const registered = Boolean(cfg.mcpServers?.["claudemesh"]);
13786
13898
  return {
13787
13899
  name: "claudemesh MCP registered in ~/.claude.json",
@@ -13798,8 +13910,8 @@ function checkMcpRegistered() {
13798
13910
  }
13799
13911
  }
13800
13912
  function checkHooksRegistered() {
13801
- const settings = join12(homedir10(), ".claude", "settings.json");
13802
- if (!existsSync17(settings)) {
13913
+ const settings = join13(homedir11(), ".claude", "settings.json");
13914
+ if (!existsSync18(settings)) {
13803
13915
  return {
13804
13916
  name: "Status hooks registered in ~/.claude/settings.json",
13805
13917
  pass: false,
@@ -13807,7 +13919,7 @@ function checkHooksRegistered() {
13807
13919
  };
13808
13920
  }
13809
13921
  try {
13810
- const raw = readFileSync14(settings, "utf-8");
13922
+ const raw = readFileSync15(settings, "utf-8");
13811
13923
  const has = raw.includes("claudemesh hook ");
13812
13924
  return {
13813
13925
  name: "Status hooks registered in ~/.claude/settings.json",
@@ -13824,7 +13936,7 @@ function checkHooksRegistered() {
13824
13936
  }
13825
13937
  function checkConfigFile() {
13826
13938
  const path2 = getConfigPath();
13827
- if (!existsSync17(path2)) {
13939
+ if (!existsSync18(path2)) {
13828
13940
  return {
13829
13941
  name: "~/.claudemesh/config.json exists and parses",
13830
13942
  pass: true,
@@ -14007,7 +14119,7 @@ var exports_status = {};
14007
14119
  __export(exports_status, {
14008
14120
  runStatus: () => runStatus2
14009
14121
  });
14010
- import { statSync as statSync4, existsSync as existsSync18 } from "node:fs";
14122
+ import { statSync as statSync4, existsSync as existsSync19 } from "node:fs";
14011
14123
  import WebSocket3 from "ws";
14012
14124
  async function probeBroker(url, timeoutMs = 4000) {
14013
14125
  return new Promise((resolve2) => {
@@ -14037,7 +14149,7 @@ async function runStatus2() {
14037
14149
  render.section(`status (v${VERSION})`);
14038
14150
  const configPath = getConfigPath();
14039
14151
  let configPermsNote = "missing";
14040
- if (existsSync18(configPath)) {
14152
+ if (existsSync19(configPath)) {
14041
14153
  const mode = (statSync4(configPath).mode & 511).toString(8).padStart(4, "0");
14042
14154
  configPermsNote = mode === "0600" ? `${mode}` : `${mode} — expected 0600`;
14043
14155
  }
@@ -14183,13 +14295,13 @@ var init_check_claude_binary = __esm(() => {
14183
14295
  });
14184
14296
 
14185
14297
  // src/services/health/check-mcp-registered.ts
14186
- import { existsSync as existsSync19, readFileSync as readFileSync15 } from "node:fs";
14298
+ import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
14187
14299
  function checkMcpRegistered2() {
14188
14300
  try {
14189
- if (!existsSync19(PATHS.CLAUDE_JSON)) {
14301
+ if (!existsSync20(PATHS.CLAUDE_JSON)) {
14190
14302
  return { name: "mcp-registered", ok: false, message: "~/.claude.json not found" };
14191
14303
  }
14192
- const raw = readFileSync15(PATHS.CLAUDE_JSON, "utf-8");
14304
+ const raw = readFileSync16(PATHS.CLAUDE_JSON, "utf-8");
14193
14305
  const config = JSON.parse(raw);
14194
14306
  if (config.mcpServers && "claudemesh" in config.mcpServers) {
14195
14307
  return { name: "mcp-registered", ok: true, message: "MCP server registered" };
@@ -14204,13 +14316,13 @@ var init_check_mcp_registered = __esm(() => {
14204
14316
  });
14205
14317
 
14206
14318
  // src/services/health/check-hooks-registered.ts
14207
- import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
14319
+ import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
14208
14320
  function checkHooksRegistered2() {
14209
14321
  try {
14210
- if (!existsSync20(PATHS.CLAUDE_SETTINGS)) {
14322
+ if (!existsSync21(PATHS.CLAUDE_SETTINGS)) {
14211
14323
  return { name: "hooks-registered", ok: false, message: "~/.claude/settings.json not found" };
14212
14324
  }
14213
- const raw = readFileSync16(PATHS.CLAUDE_SETTINGS, "utf-8");
14325
+ const raw = readFileSync17(PATHS.CLAUDE_SETTINGS, "utf-8");
14214
14326
  const config = JSON.parse(raw);
14215
14327
  if (config.hooks) {
14216
14328
  return { name: "hooks-registered", ok: true, message: "Hooks configured" };
@@ -14225,10 +14337,10 @@ var init_check_hooks_registered = __esm(() => {
14225
14337
  });
14226
14338
 
14227
14339
  // src/services/health/check-config-perms.ts
14228
- import { existsSync as existsSync21, statSync as statSync5 } from "node:fs";
14340
+ import { existsSync as existsSync22, statSync as statSync5 } from "node:fs";
14229
14341
  function checkConfigPerms() {
14230
14342
  const configFile = PATHS.CONFIG_FILE;
14231
- if (!existsSync21(configFile)) {
14343
+ if (!existsSync22(configFile)) {
14232
14344
  return { name: "config-perms", ok: true, message: "No config file yet (first run)" };
14233
14345
  }
14234
14346
  try {
@@ -14246,13 +14358,13 @@ var init_check_config_perms = __esm(() => {
14246
14358
  });
14247
14359
 
14248
14360
  // src/services/health/check-keypairs-valid.ts
14249
- import { existsSync as existsSync22, readFileSync as readFileSync17 } from "node:fs";
14361
+ import { existsSync as existsSync23, readFileSync as readFileSync18 } from "node:fs";
14250
14362
  function checkKeypairsValid() {
14251
- if (!existsSync22(PATHS.CONFIG_FILE)) {
14363
+ if (!existsSync23(PATHS.CONFIG_FILE)) {
14252
14364
  return { name: "keypairs-valid", ok: true, message: "No config (first run)" };
14253
14365
  }
14254
14366
  try {
14255
- const raw = readFileSync17(PATHS.CONFIG_FILE, "utf-8");
14367
+ const raw = readFileSync18(PATHS.CONFIG_FILE, "utf-8");
14256
14368
  const config = JSON.parse(raw);
14257
14369
  const meshes = config.meshes ?? [];
14258
14370
  if (meshes.length === 0) {
@@ -14732,19 +14844,19 @@ var exports_url_handler = {};
14732
14844
  __export(exports_url_handler, {
14733
14845
  runUrlHandler: () => runUrlHandler
14734
14846
  });
14735
- import { platform as platform7, homedir as homedir11 } from "node:os";
14736
- import { existsSync as existsSync23, mkdirSync as mkdirSync10, writeFileSync as writeFileSync14, rmSync as rmSync3, chmodSync as chmodSync5 } from "node:fs";
14737
- import { join as join13 } from "node:path";
14847
+ 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";
14849
+ import { join as join14 } from "node:path";
14738
14850
  import { spawnSync as spawnSync5 } from "node:child_process";
14739
14851
  function resolveClaudemeshBin() {
14740
14852
  return process.argv[1] ?? "claudemesh";
14741
14853
  }
14742
14854
  function installDarwin2() {
14743
14855
  const binPath = resolveClaudemeshBin();
14744
- const appDir = join13(homedir11(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14745
- const contents = join13(appDir, "Contents");
14746
- const macOS = join13(contents, "MacOS");
14747
- mkdirSync10(macOS, { recursive: true });
14856
+ const appDir = join14(homedir12(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14857
+ const contents = join14(appDir, "Contents");
14858
+ const macOS = join14(contents, "MacOS");
14859
+ mkdirSync11(macOS, { recursive: true });
14748
14860
  const plist = `<?xml version="1.0" encoding="UTF-8"?>
14749
14861
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
14750
14862
  <plist version="1.0">
@@ -14767,7 +14879,7 @@ function installDarwin2() {
14767
14879
  </array>
14768
14880
  </dict>
14769
14881
  </plist>`;
14770
- writeFileSync14(join13(contents, "Info.plist"), plist);
14882
+ writeFileSync15(join14(contents, "Info.plist"), plist);
14771
14883
  const shim = `#!/bin/sh
14772
14884
  URL="$1"
14773
14885
  CODE=\${URL#claudemesh://}
@@ -14781,8 +14893,8 @@ tell application "Terminal"
14781
14893
  end tell
14782
14894
  EOF
14783
14895
  `;
14784
- const shimPath = join13(macOS, "open-url");
14785
- writeFileSync14(shimPath, shim);
14896
+ const shimPath = join14(macOS, "open-url");
14897
+ writeFileSync15(shimPath, shim);
14786
14898
  chmodSync5(shimPath, 493);
14787
14899
  const lsreg = spawnSync5("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister", ["-f", appDir], { encoding: "utf-8" });
14788
14900
  if (lsreg.status !== 0) {
@@ -14793,8 +14905,8 @@ EOF
14793
14905
  }
14794
14906
  function installLinux2() {
14795
14907
  const binPath = resolveClaudemeshBin();
14796
- const appsDir = join13(homedir11(), ".local", "share", "applications");
14797
- mkdirSync10(appsDir, { recursive: true });
14908
+ const appsDir = join14(homedir12(), ".local", "share", "applications");
14909
+ mkdirSync11(appsDir, { recursive: true });
14798
14910
  const desktop = `[Desktop Entry]
14799
14911
  Type=Application
14800
14912
  Name=Claudemesh
@@ -14805,8 +14917,8 @@ Terminal=true
14805
14917
  MimeType=x-scheme-handler/claudemesh;
14806
14918
  NoDisplay=true
14807
14919
  `;
14808
- const desktopPath = join13(appsDir, "claudemesh.desktop");
14809
- writeFileSync14(desktopPath, desktop);
14920
+ const desktopPath = join14(appsDir, "claudemesh.desktop");
14921
+ writeFileSync15(desktopPath, desktop);
14810
14922
  const xdg1 = spawnSync5("xdg-mime", ["default", "claudemesh.desktop", "x-scheme-handler/claudemesh"], { encoding: "utf-8" });
14811
14923
  if (xdg1.status !== 0) {
14812
14924
  render.warn("xdg-mime not available — skipped mime default registration");
@@ -14828,8 +14940,8 @@ function installWindows() {
14828
14940
  `[HKEY_CURRENT_USER\\Software\\Classes\\claudemesh\\shell\\open\\command]`,
14829
14941
  `@="\\"${binPath.replace(/\\/g, "\\\\")}\\" \\"%1\\""`
14830
14942
  ];
14831
- const regPath = join13(homedir11(), "claudemesh-handler.reg");
14832
- writeFileSync14(regPath, lines.join(`\r
14943
+ const regPath = join14(homedir12(), "claudemesh-handler.reg");
14944
+ writeFileSync15(regPath, lines.join(`\r
14833
14945
  `));
14834
14946
  const res = spawnSync5("reg.exe", ["import", regPath], { encoding: "utf-8" });
14835
14947
  if (res.status !== 0) {
@@ -14840,16 +14952,16 @@ function installWindows() {
14840
14952
  return EXIT.SUCCESS;
14841
14953
  }
14842
14954
  function uninstallDarwin() {
14843
- const appDir = join13(homedir11(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14844
- if (existsSync23(appDir))
14845
- rmSync3(appDir, { recursive: true, force: true });
14955
+ const appDir = join14(homedir12(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14956
+ if (existsSync24(appDir))
14957
+ rmSync4(appDir, { recursive: true, force: true });
14846
14958
  render.ok("removed claudemesh:// handler on macOS");
14847
14959
  return EXIT.SUCCESS;
14848
14960
  }
14849
14961
  function uninstallLinux() {
14850
- const desktopPath = join13(homedir11(), ".local", "share", "applications", "claudemesh.desktop");
14851
- if (existsSync23(desktopPath))
14852
- rmSync3(desktopPath, { force: true });
14962
+ const desktopPath = join14(homedir12(), ".local", "share", "applications", "claudemesh.desktop");
14963
+ if (existsSync24(desktopPath))
14964
+ rmSync4(desktopPath, { force: true });
14853
14965
  render.ok("removed claudemesh:// handler on Linux");
14854
14966
  return EXIT.SUCCESS;
14855
14967
  }
@@ -14893,9 +15005,9 @@ var exports_status_line = {};
14893
15005
  __export(exports_status_line, {
14894
15006
  runStatusLine: () => runStatusLine
14895
15007
  });
14896
- import { existsSync as existsSync24, readFileSync as readFileSync18 } from "node:fs";
14897
- import { join as join14 } from "node:path";
14898
- import { homedir as homedir12 } from "node:os";
15008
+ import { existsSync as existsSync25, readFileSync as readFileSync19 } from "node:fs";
15009
+ import { join as join15 } from "node:path";
15010
+ import { homedir as homedir13 } from "node:os";
14899
15011
  async function runStatusLine() {
14900
15012
  try {
14901
15013
  const config = readConfig();
@@ -14903,11 +15015,11 @@ async function runStatusLine() {
14903
15015
  process.stdout.write("◇ claudemesh (not joined)");
14904
15016
  return EXIT.SUCCESS;
14905
15017
  }
14906
- const cachePath = join14(homedir12(), ".claudemesh", "peer-cache.json");
15018
+ const cachePath = join15(homedir13(), ".claudemesh", "peer-cache.json");
14907
15019
  let cache = {};
14908
- if (existsSync24(cachePath)) {
15020
+ if (existsSync25(cachePath)) {
14909
15021
  try {
14910
- cache = JSON.parse(readFileSync18(cachePath, "utf-8"));
15022
+ cache = JSON.parse(readFileSync19(cachePath, "utf-8"));
14911
15023
  } catch {}
14912
15024
  }
14913
15025
  const pick = config.meshes[0];
@@ -14938,7 +15050,7 @@ __export(exports_backup, {
14938
15050
  runRestore: () => runRestore,
14939
15051
  runBackup: () => runBackup
14940
15052
  });
14941
- import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, existsSync as existsSync25 } from "node:fs";
15053
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, existsSync as existsSync26 } from "node:fs";
14942
15054
  import { createInterface as createInterface11 } from "node:readline";
14943
15055
  function readHidden(prompt5) {
14944
15056
  return new Promise((resolve2) => {
@@ -14980,11 +15092,11 @@ async function deriveKey(pass, salt, s) {
14980
15092
  }
14981
15093
  async function runBackup(outPath) {
14982
15094
  const configPath = getConfigPath();
14983
- if (!existsSync25(configPath)) {
15095
+ if (!existsSync26(configPath)) {
14984
15096
  console.error(" No config found — nothing to back up. Join a mesh first.");
14985
15097
  return EXIT.NOT_FOUND;
14986
15098
  }
14987
- const plaintext = readFileSync19(configPath);
15099
+ const plaintext = readFileSync20(configPath);
14988
15100
  const pass = await readHidden(" Passphrase (min 12 chars): ");
14989
15101
  if (pass.length < 12) {
14990
15102
  console.error(" ✗ Passphrase too short.");
@@ -15002,7 +15114,7 @@ async function runBackup(outPath) {
15002
15114
  const ciphertext = Buffer.from(s.crypto_aead_xchacha20poly1305_ietf_encrypt(plaintext, null, null, nonce, key));
15003
15115
  const blob = Buffer.concat([MAGIC, salt, nonce, ciphertext]);
15004
15116
  const file = outPath ?? `claudemesh-backup-${new Date().toISOString().replace(/[:.]/g, "-")}.cmb`;
15005
- writeFileSync15(file, blob, { mode: 384 });
15117
+ writeFileSync16(file, blob, { mode: 384 });
15006
15118
  console.log(`
15007
15119
  ✓ Backup saved: ${file}`);
15008
15120
  console.log(` Size: ${blob.length} bytes. Guard the passphrase — there is no recovery.
@@ -15014,11 +15126,11 @@ async function runRestore(inPath) {
15014
15126
  console.error(" Usage: claudemesh restore <backup-file>");
15015
15127
  return EXIT.INVALID_ARGS;
15016
15128
  }
15017
- if (!existsSync25(inPath)) {
15129
+ if (!existsSync26(inPath)) {
15018
15130
  console.error(` ✗ File not found: ${inPath}`);
15019
15131
  return EXIT.NOT_FOUND;
15020
15132
  }
15021
- const blob = readFileSync19(inPath);
15133
+ const blob = readFileSync20(inPath);
15022
15134
  if (blob.length < 4 + 16 + 24 + 17 || !blob.subarray(0, 4).equals(MAGIC)) {
15023
15135
  console.error(" ✗ Not a claudemesh backup file (bad magic).");
15024
15136
  return EXIT.INVALID_ARGS;
@@ -15037,12 +15149,12 @@ async function runRestore(inPath) {
15037
15149
  return EXIT.INTERNAL_ERROR;
15038
15150
  }
15039
15151
  const configPath = getConfigPath();
15040
- if (existsSync25(configPath)) {
15152
+ if (existsSync26(configPath)) {
15041
15153
  const backupOld = `${configPath}.before-restore.${Date.now()}`;
15042
- writeFileSync15(backupOld, readFileSync19(configPath), { mode: 384 });
15154
+ writeFileSync16(backupOld, readFileSync20(configPath), { mode: 384 });
15043
15155
  console.log(` ↻ Existing config saved to ${backupOld}`);
15044
15156
  }
15045
- writeFileSync15(configPath, Buffer.from(plaintext), { mode: 384 });
15157
+ writeFileSync16(configPath, Buffer.from(plaintext), { mode: 384 });
15046
15158
  console.log(`
15047
15159
  ✓ Config restored to ${configPath}`);
15048
15160
  console.log(" Run `claudemesh list` to verify your meshes.\n");
@@ -15062,8 +15174,8 @@ __export(exports_upgrade, {
15062
15174
  runUpgrade: () => runUpgrade
15063
15175
  });
15064
15176
  import { spawnSync as spawnSync6 } from "node:child_process";
15065
- import { existsSync as existsSync26 } from "node:fs";
15066
- import { dirname as dirname8, join as join15, resolve as resolve2 } from "node:path";
15177
+ import { existsSync as existsSync27 } from "node:fs";
15178
+ import { dirname as dirname8, join as join16, resolve as resolve2 } from "node:path";
15067
15179
  async function latestVersion() {
15068
15180
  try {
15069
15181
  const res = await fetch(URLS.NPM_REGISTRY, { signal: AbortSignal.timeout(8000) });
@@ -15076,15 +15188,15 @@ async function latestVersion() {
15076
15188
  }
15077
15189
  }
15078
15190
  function findNpm() {
15079
- const portable = join15(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
15080
- if (existsSync26(portable)) {
15081
- return { npm: portable, prefix: join15(process.env.HOME ?? "", ".claudemesh") };
15191
+ const portable = join16(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
15192
+ if (existsSync27(portable)) {
15193
+ return { npm: portable, prefix: join16(process.env.HOME ?? "", ".claudemesh") };
15082
15194
  }
15083
15195
  let cur = resolve2(process.argv[1] ?? ".");
15084
15196
  for (let i = 0;i < 6; i++) {
15085
15197
  cur = dirname8(cur);
15086
- const candidate = join15(cur, "bin", "npm");
15087
- if (existsSync26(candidate))
15198
+ const candidate = join16(cur, "bin", "npm");
15199
+ if (existsSync27(candidate))
15088
15200
  return { npm: candidate };
15089
15201
  }
15090
15202
  return { npm: "npm" };
@@ -15146,9 +15258,9 @@ __export(exports_grants, {
15146
15258
  runBlock: () => runBlock,
15147
15259
  isAllowed: () => isAllowed
15148
15260
  });
15149
- import { existsSync as existsSync27, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
15150
- import { homedir as homedir13 } from "node:os";
15151
- import { join as join16 } from "node:path";
15261
+ import { existsSync as existsSync28, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
15262
+ import { homedir as homedir14 } from "node:os";
15263
+ import { join as join17 } from "node:path";
15152
15264
  async function syncToBroker(meshSlug, grants) {
15153
15265
  const auth = getStoredToken();
15154
15266
  if (!auth)
@@ -15166,19 +15278,19 @@ async function syncToBroker(meshSlug, grants) {
15166
15278
  }
15167
15279
  }
15168
15280
  function readGrants() {
15169
- if (!existsSync27(GRANT_FILE))
15281
+ if (!existsSync28(GRANT_FILE))
15170
15282
  return {};
15171
15283
  try {
15172
- return JSON.parse(readFileSync20(GRANT_FILE, "utf-8"));
15284
+ return JSON.parse(readFileSync21(GRANT_FILE, "utf-8"));
15173
15285
  } catch {
15174
15286
  return {};
15175
15287
  }
15176
15288
  }
15177
15289
  function writeGrants(g) {
15178
- const dir = join16(homedir13(), ".claudemesh");
15179
- if (!existsSync27(dir))
15180
- mkdirSync11(dir, { recursive: true });
15181
- writeFileSync16(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
15290
+ 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 });
15182
15294
  }
15183
15295
  function resolveCaps(input) {
15184
15296
  if (input.includes("all"))
@@ -15334,7 +15446,7 @@ var init_grants = __esm(() => {
15334
15446
  BROKER_HTTP7 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
15335
15447
  ALL_CAPS = ["read", "dm", "broadcast", "state-read", "state-write", "file-read"];
15336
15448
  DEFAULT_CAPS = ["read", "dm", "broadcast", "state-read"];
15337
- GRANT_FILE = join16(homedir13(), ".claudemesh", "grants.json");
15449
+ GRANT_FILE = join17(homedir14(), ".claudemesh", "grants.json");
15338
15450
  });
15339
15451
 
15340
15452
  // src/commands/profile.ts
@@ -17055,7 +17167,7 @@ __export(exports_file, {
17055
17167
  });
17056
17168
  import { hostname as osHostname2 } from "node:os";
17057
17169
  import { resolve as resolvePath, basename, dirname as dirname9 } from "node:path";
17058
- import { statSync as statSync7, existsSync as existsSync28, writeFileSync as writeFileSync17, mkdirSync as mkdirSync12 } from "node:fs";
17170
+ import { statSync as statSync7, existsSync as existsSync29, writeFileSync as writeFileSync18, mkdirSync as mkdirSync13 } from "node:fs";
17059
17171
  function emitJson2(data) {
17060
17172
  console.log(JSON.stringify(data, null, 2));
17061
17173
  }
@@ -17072,7 +17184,7 @@ async function runFileShare(filePath, opts) {
17072
17184
  return EXIT.INVALID_ARGS;
17073
17185
  }
17074
17186
  const absPath = resolvePath(filePath);
17075
- if (!existsSync28(absPath)) {
17187
+ if (!existsSync29(absPath)) {
17076
17188
  render.err(`File not found: ${absPath}`);
17077
17189
  return EXIT.INVALID_ARGS;
17078
17190
  }
@@ -17151,8 +17263,8 @@ async function runFileGet(fileId, opts) {
17151
17263
  }
17152
17264
  const buf = Buffer.from(await res.arrayBuffer());
17153
17265
  const outPath = opts.out ? resolvePath(opts.out) : resolvePath(process.cwd(), meta.name);
17154
- mkdirSync12(dirname9(outPath), { recursive: true });
17155
- writeFileSync17(outPath, buf);
17266
+ mkdirSync13(dirname9(outPath), { recursive: true });
17267
+ writeFileSync18(outPath, buf);
17156
17268
  if (opts.json) {
17157
17269
  emitJson2({ fileId, name: meta.name, savedTo: outPath, sizeBytes: buf.length });
17158
17270
  } else {
@@ -17762,7 +17874,7 @@ __export(exports_bridge, {
17762
17874
  runBridge: () => runBridge,
17763
17875
  bridgeConfigTemplate: () => bridgeConfigTemplate
17764
17876
  });
17765
- import { readFileSync as readFileSync21, existsSync as existsSync29 } from "node:fs";
17877
+ import { readFileSync as readFileSync22, existsSync as existsSync30 } from "node:fs";
17766
17878
  function parseConfig(text) {
17767
17879
  const trimmed = text.trim();
17768
17880
  if (trimmed.startsWith("{"))
@@ -17806,13 +17918,13 @@ async function runBridge(configPath) {
17806
17918
  render.err("Usage: claudemesh bridge run <config.yaml>");
17807
17919
  return EXIT.INVALID_ARGS;
17808
17920
  }
17809
- if (!existsSync29(configPath)) {
17921
+ if (!existsSync30(configPath)) {
17810
17922
  render.err(`config file not found: ${configPath}`);
17811
17923
  return EXIT.NOT_FOUND;
17812
17924
  }
17813
17925
  let cfg;
17814
17926
  try {
17815
- cfg = parseConfig(readFileSync21(configPath, "utf-8"));
17927
+ cfg = parseConfig(readFileSync22(configPath, "utf-8"));
17816
17928
  } catch (e) {
17817
17929
  render.err(`failed to parse ${configPath}: ${e instanceof Error ? e.message : String(e)}`);
17818
17930
  return EXIT.INVALID_ARGS;
@@ -18786,12 +18898,12 @@ import {
18786
18898
  ListResourcesRequestSchema,
18787
18899
  ReadResourceRequestSchema
18788
18900
  } from "@modelcontextprotocol/sdk/types.js";
18789
- import { existsSync as existsSync30, appendFileSync as appendFileSync2 } from "node:fs";
18901
+ import { existsSync as existsSync31, appendFileSync as appendFileSync2 } from "node:fs";
18790
18902
  import { request as httpRequest2 } from "node:http";
18791
- import { join as join17 } from "node:path";
18903
+ import { join as join18 } from "node:path";
18792
18904
  async function daemonReady() {
18793
18905
  for (let i = 0;i < DAEMON_BOOT_RETRIES; i++) {
18794
- if (existsSync30(DAEMON_PATHS.SOCK_FILE))
18906
+ if (existsSync31(DAEMON_PATHS.SOCK_FILE))
18795
18907
  return true;
18796
18908
  await new Promise((r) => setTimeout(r, DAEMON_BOOT_RETRY_MS));
18797
18909
  }
@@ -19065,7 +19177,7 @@ ${mf.allowed_tools.map((t) => ` - ${t}`).join(`
19065
19177
  return { contents: [{ uri, mimeType: "text/markdown", text: fm.join(`
19066
19178
  `) + skill.instructions }] };
19067
19179
  });
19068
- const mcpLogPath = join17(DAEMON_PATHS.DAEMON_DIR, `mcp-${process.pid}.log`);
19180
+ const mcpLogPath = join18(DAEMON_PATHS.DAEMON_DIR, `mcp-${process.pid}.log`);
19069
19181
  const mcpLog = (msg, meta) => {
19070
19182
  const line = JSON.stringify({ ts: new Date().toISOString(), pid: process.pid, msg, ...meta }) + `
19071
19183
  `;
@@ -21392,4 +21504,4 @@ main().catch((err) => {
21392
21504
  process.exit(EXIT.INTERNAL_ERROR);
21393
21505
  });
21394
21506
 
21395
- //# debugId=C8B9D377DC161E3E64756E2164756E21
21507
+ //# debugId=A7ECB4BF81F2B4CE64756E2164756E21