claudemesh-cli 1.34.13 → 1.34.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -104,7 +104,7 @@ __export(exports_urls, {
104
104
  VERSION: () => VERSION,
105
105
  URLS: () => URLS
106
106
  });
107
- var URLS, VERSION = "1.34.13", env;
107
+ var URLS, VERSION = "1.34.15", env;
108
108
  var init_urls = __esm(() => {
109
109
  URLS = {
110
110
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -178,13 +178,40 @@ var init_policy = __esm(() => {
178
178
  });
179
179
 
180
180
  // src/constants/paths.ts
181
+ import { existsSync as existsSync2 } from "node:fs";
181
182
  import { homedir as homedir2 } from "node:os";
182
183
  import { join as join2 } from "node:path";
183
- var home, PATHS;
184
+ function resolveConfigDir() {
185
+ if (_resolvedConfigDir !== null)
186
+ return _resolvedConfigDir;
187
+ const envDir = process.env.CLAUDEMESH_CONFIG_DIR;
188
+ if (!envDir) {
189
+ _resolvedConfigDir = DEFAULT_CONFIG_DIR;
190
+ return DEFAULT_CONFIG_DIR;
191
+ }
192
+ if (existsSync2(envDir)) {
193
+ _resolvedConfigDir = envDir;
194
+ return envDir;
195
+ }
196
+ if (!_warnedStaleEnv && process.stderr.isTTY) {
197
+ _warnedStaleEnv = true;
198
+ const unsetHint = process.env.SHELL?.endsWith("fish") ? "set -e CLAUDEMESH_CONFIG_DIR CLAUDEMESH_IPC_TOKEN_FILE" : "unset CLAUDEMESH_CONFIG_DIR CLAUDEMESH_IPC_TOKEN_FILE";
199
+ process.stderr.write(`claudemesh: ignoring stale CLAUDEMESH_CONFIG_DIR=${envDir} (no config.json there); using ${DEFAULT_CONFIG_DIR}.
200
+ ` + ` Hint: this is usually a leftover env from a previous \`claudemesh launch\`. Clean it with:
201
+ ` + ` ${unsetHint}
202
+ `);
203
+ }
204
+ _resolvedConfigDir = DEFAULT_CONFIG_DIR;
205
+ return DEFAULT_CONFIG_DIR;
206
+ }
207
+ var home, DEFAULT_CONFIG_DIR, _resolvedConfigDir = null, _warnedStaleEnv = false, PATHS;
184
208
  var init_paths = __esm(() => {
185
209
  home = homedir2();
210
+ DEFAULT_CONFIG_DIR = join2(home, ".claudemesh");
186
211
  PATHS = {
187
- CONFIG_DIR: process.env.CLAUDEMESH_CONFIG_DIR || join2(home, ".claudemesh"),
212
+ get CONFIG_DIR() {
213
+ return resolveConfigDir();
214
+ },
188
215
  get CONFIG_FILE() {
189
216
  return join2(this.CONFIG_DIR, "config.json");
190
217
  },
@@ -208,9 +235,9 @@ function emptyConfig() {
208
235
  }
209
236
 
210
237
  // src/services/config/read.ts
211
- import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
238
+ import { readFileSync as readFileSync2, existsSync as existsSync3 } from "node:fs";
212
239
  function readConfig() {
213
- if (!existsSync2(PATHS.CONFIG_FILE))
240
+ if (!existsSync3(PATHS.CONFIG_FILE))
214
241
  return emptyConfig();
215
242
  try {
216
243
  const raw = readFileSync2(PATHS.CONFIG_FILE, "utf-8");
@@ -542,7 +569,7 @@ var init_facade4 = __esm(() => {
542
569
 
543
570
  // src/services/spawn/claude.ts
544
571
  import { spawnSync } from "node:child_process";
545
- import { existsSync as existsSync3 } from "node:fs";
572
+ import { existsSync as existsSync4 } from "node:fs";
546
573
  function findClaudeBinary() {
547
574
  const candidates = [
548
575
  process.env.CLAUDE_BIN,
@@ -551,7 +578,7 @@ function findClaudeBinary() {
551
578
  `${process.env.HOME}/.npm/bin/claude`
552
579
  ].filter(Boolean);
553
580
  for (const bin of candidates) {
554
- if (existsSync3(bin))
581
+ if (existsSync4(bin))
555
582
  return bin;
556
583
  }
557
584
  const which = spawnSync("which", ["claude"], { encoding: "utf-8" });
@@ -612,9 +639,9 @@ var init_facade5 = __esm(() => {
612
639
  });
613
640
 
614
641
  // src/services/auth/token-store.ts
615
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, unlinkSync, existsSync as existsSync4, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
642
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, unlinkSync, existsSync as existsSync5, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
616
643
  function getStoredToken() {
617
- if (!existsSync4(PATHS.AUTH_FILE))
644
+ if (!existsSync5(PATHS.AUTH_FILE))
618
645
  return null;
619
646
  try {
620
647
  const raw = readFileSync3(PATHS.AUTH_FILE, "utf-8");
@@ -3678,7 +3705,7 @@ __export(exports_token, {
3678
3705
  TOKEN_FILE_ENV: () => TOKEN_FILE_ENV
3679
3706
  });
3680
3707
  import { randomBytes as randomBytes5 } from "node:crypto";
3681
- import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
3708
+ import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
3682
3709
  function mintSessionToken(dir, fileName = "session-token") {
3683
3710
  const token = randomBytes5(32).toString("hex");
3684
3711
  const filePath = `${dir}/${fileName}`;
@@ -3693,7 +3720,7 @@ function readSessionTokenFromEnv(env2 = process.env) {
3693
3720
  if (!path)
3694
3721
  return null;
3695
3722
  try {
3696
- if (!existsSync5(path))
3723
+ if (!existsSync6(path))
3697
3724
  return null;
3698
3725
  const raw = readFileSync5(path, "utf8").trim();
3699
3726
  if (/^[0-9a-f]{64}$/i.test(raw))
@@ -3780,7 +3807,7 @@ __export(exports_lifecycle, {
3780
3807
  ensureDaemonReady: () => ensureDaemonReady,
3781
3808
  _resetDaemonReadyCache: () => _resetDaemonReadyCache
3782
3809
  });
3783
- import { existsSync as existsSync6, readFileSync as readFileSync6, statSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
3810
+ import { existsSync as existsSync7, readFileSync as readFileSync6, statSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
3784
3811
  import { homedir as homedir4 } from "node:os";
3785
3812
  import { join as join4 } from "node:path";
3786
3813
  async function ensureDaemonReady(opts = {}) {
@@ -3836,15 +3863,15 @@ async function runEnsureDaemon(opts) {
3836
3863
  }
3837
3864
  function isServiceManaged() {
3838
3865
  if (process.platform === "darwin") {
3839
- return existsSync6(join4(homedir4(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`));
3866
+ return existsSync7(join4(homedir4(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`));
3840
3867
  }
3841
3868
  if (process.platform === "linux") {
3842
- return existsSync6(join4(homedir4(), ".config", "systemd", "user", SYSTEMD_UNIT));
3869
+ return existsSync7(join4(homedir4(), ".config", "systemd", "user", SYSTEMD_UNIT));
3843
3870
  }
3844
3871
  return false;
3845
3872
  }
3846
3873
  async function probeDaemon() {
3847
- if (!existsSync6(DAEMON_PATHS.SOCK_FILE))
3874
+ if (!existsSync7(DAEMON_PATHS.SOCK_FILE))
3848
3875
  return "absent";
3849
3876
  try {
3850
3877
  const res = await ipc({ path: "/v1/version", timeoutMs: PROBE_TIMEOUT_MS });
@@ -3912,7 +3939,7 @@ async function spawnDaemon(opts) {
3912
3939
  }
3913
3940
  async function acquireOrShareLock(_opts) {
3914
3941
  const lockPath = SPAWN_LOCK_FILE();
3915
- if (existsSync6(lockPath)) {
3942
+ if (existsSync7(lockPath)) {
3916
3943
  try {
3917
3944
  const pidStr = readFileSync6(lockPath, "utf8").trim();
3918
3945
  const pid = Number.parseInt(pidStr, 10);
@@ -3937,7 +3964,7 @@ function releaseLock() {
3937
3964
  async function pollForSocket(budgetMs) {
3938
3965
  const start = Date.now();
3939
3966
  while (Date.now() - start < budgetMs) {
3940
- if (existsSync6(DAEMON_PATHS.SOCK_FILE)) {
3967
+ if (existsSync7(DAEMON_PATHS.SOCK_FILE)) {
3941
3968
  const probe = await probeDaemon();
3942
3969
  if (probe === "up")
3943
3970
  return { ok: true };
@@ -4317,7 +4344,7 @@ __export(exports_launch, {
4317
4344
  });
4318
4345
  import { spawnSync as spawnSync2 } from "node:child_process";
4319
4346
  import { randomUUID } from "node:crypto";
4320
- import { mkdtempSync, writeFileSync as writeFileSync7, rmSync, readdirSync, statSync as statSync2, existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
4347
+ import { mkdtempSync, writeFileSync as writeFileSync7, rmSync, readdirSync, statSync as statSync2, existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
4321
4348
  import { tmpdir, hostname as hostname2, homedir as homedir5 } from "node:os";
4322
4349
  import { join as join5 } from "node:path";
4323
4350
  import { createInterface as createInterface4 } from "node:readline";
@@ -4513,7 +4540,7 @@ async function printBrokerWelcome(meshSlug) {
4513
4540
  let peerCount = -1;
4514
4541
  try {
4515
4542
  const { tryListPeersViaDaemon: tryListPeersViaDaemon2 } = await Promise.resolve().then(() => (init_daemon_route(), exports_daemon_route));
4516
- const peers = await tryListPeersViaDaemon2() ?? [];
4543
+ const peers = await tryListPeersViaDaemon2(meshSlug) ?? [];
4517
4544
  peerCount = peers.filter((p) => p.channel !== "claudemesh-daemon").length;
4518
4545
  } catch {}
4519
4546
  let unread = -1;
@@ -4725,7 +4752,7 @@ async function runLaunch(flags, rawArgs) {
4725
4752
  await ensureDaemonRunning(mesh.slug, args.quiet);
4726
4753
  try {
4727
4754
  const claudeConfigPath = join5(homedir5(), ".claude.json");
4728
- if (existsSync7(claudeConfigPath)) {
4755
+ if (existsSync8(claudeConfigPath)) {
4729
4756
  const claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
4730
4757
  const mcpServers = claudeConfig.mcpServers ?? {};
4731
4758
  let cleaned = 0;
@@ -4901,7 +4928,7 @@ async function runLaunch(flags, rawArgs) {
4901
4928
  join5(homedir5(), ".claude", "bin", "claude")
4902
4929
  ];
4903
4930
  for (const c of candidates) {
4904
- if (existsSync7(c)) {
4931
+ if (existsSync8(c)) {
4905
4932
  claudeBin = c;
4906
4933
  break;
4907
4934
  }
@@ -7849,11 +7876,17 @@ async function runKick(target, opts = {}) {
7849
7876
  return await withMesh({ meshSlug }, async (client) => {
7850
7877
  const result = await client.sendAndWait(built);
7851
7878
  const peers = result?.affected ?? result?.kicked ?? [];
7852
- if (peers.length === 0)
7879
+ const skipped = result?.skipped_control_plane ?? [];
7880
+ if (peers.length === 0 && skipped.length === 0) {
7853
7881
  render.info("No peers matched.");
7854
- else {
7882
+ } else if (peers.length === 0 && skipped.length > 0) {
7883
+ render.warn(`${skipped.length} match(es) refused: ${skipped.join(", ")} — control-plane connections (daemon / dashboard) auto-reconnect, so kick is a no-op.`, "To take a daemon offline locally, run `claudemesh daemon down` on that machine. To remove a member from the mesh, use `claudemesh ban <peer>`.");
7884
+ } else {
7855
7885
  render.ok(`Kicked ${peers.length} peer(s): ${peers.join(", ")}`);
7856
7886
  render.hint("Their Claude Code session ended. They can rejoin anytime by running `claudemesh`.");
7887
+ if (skipped.length > 0) {
7888
+ render.warn(`(also refused ${skipped.length} control-plane connection(s): ${skipped.join(", ")})`, "Daemon / dashboard connections auto-reconnect; kick is a no-op against them. Use `claudemesh ban <peer>` to remove a member entirely.");
7889
+ }
7857
7890
  }
7858
7891
  return EXIT.SUCCESS;
7859
7892
  });
@@ -8014,7 +8047,7 @@ async function listPeersForMesh(slug) {
8014
8047
  } catch {}
8015
8048
  try {
8016
8049
  const { tryListPeersViaDaemon: tryListPeersViaDaemon2 } = await Promise.resolve().then(() => (init_daemon_route(), exports_daemon_route));
8017
- const dr = await tryListPeersViaDaemon2();
8050
+ const dr = await tryListPeersViaDaemon2(slug);
8018
8051
  if (dr !== null) {
8019
8052
  return dr.map((p) => annotateSelf(p, selfMemberPubkey, selfSessionPubkey));
8020
8053
  }
@@ -9239,11 +9272,11 @@ var init_whoami = __esm(() => {
9239
9272
  });
9240
9273
 
9241
9274
  // src/daemon/lock.ts
9242
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync8, unlinkSync as unlinkSync3, writeFileSync as writeFileSync9 } from "node:fs";
9275
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync8, unlinkSync as unlinkSync3, writeFileSync as writeFileSync9 } from "node:fs";
9243
9276
  import { dirname as dirname4 } from "node:path";
9244
9277
  function acquireSingletonLock() {
9245
9278
  mkdirSync5(dirname4(DAEMON_PATHS.PID_FILE), { recursive: true, mode: 448 });
9246
- if (existsSync8(DAEMON_PATHS.PID_FILE)) {
9279
+ if (existsSync9(DAEMON_PATHS.PID_FILE)) {
9247
9280
  const raw = readFileSync8(DAEMON_PATHS.PID_FILE, "utf8").trim();
9248
9281
  const oldPid = Number.parseInt(raw, 10);
9249
9282
  if (Number.isFinite(oldPid) && oldPid > 0 && isProcessAlive(oldPid)) {
@@ -9957,7 +9990,7 @@ var init_session_registry = __esm(() => {
9957
9990
 
9958
9991
  // src/daemon/ipc/server.ts
9959
9992
  import { createServer as createServer2 } from "node:http";
9960
- import { chmodSync as chmodSync3, existsSync as existsSync9, unlinkSync as unlinkSync4 } from "node:fs";
9993
+ import { chmodSync as chmodSync3, existsSync as existsSync10, unlinkSync as unlinkSync4 } from "node:fs";
9961
9994
  import { timingSafeEqual } from "node:crypto";
9962
9995
  import { randomUUID as randomUUID3 } from "node:crypto";
9963
9996
  function startIpcServer(opts) {
@@ -9973,7 +10006,7 @@ function startIpcServer(opts) {
9973
10006
  meshConfigs: opts.meshConfigs,
9974
10007
  onPendingInserted: opts.onPendingInserted
9975
10008
  });
9976
- if (existsSync9(DAEMON_PATHS.SOCK_FILE)) {
10009
+ if (existsSync10(DAEMON_PATHS.SOCK_FILE)) {
9977
10010
  try {
9978
10011
  unlinkSync4(DAEMON_PATHS.SOCK_FILE);
9979
10012
  } catch {}
@@ -11965,7 +11998,7 @@ __export(exports_identity, {
11965
11998
  checkFingerprint: () => checkFingerprint,
11966
11999
  acceptCurrentHost: () => acceptCurrentHost
11967
12000
  });
11968
- import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "node:fs";
12001
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "node:fs";
11969
12002
  import { join as join7 } from "node:path";
11970
12003
  import { createHash as createHash2 } from "node:crypto";
11971
12004
  import { networkInterfaces } from "node:os";
@@ -11986,7 +12019,7 @@ function computeCurrentFingerprint() {
11986
12019
  }
11987
12020
  function checkFingerprint() {
11988
12021
  const current = computeCurrentFingerprint();
11989
- if (!existsSync10(path())) {
12022
+ if (!existsSync11(path())) {
11990
12023
  writeFileSync10(path(), JSON.stringify(current, null, 2), { mode: 384 });
11991
12024
  return { result: "first_run", current };
11992
12025
  }
@@ -12054,14 +12087,14 @@ var init_identity = __esm(() => {
12054
12087
  });
12055
12088
 
12056
12089
  // src/daemon/run.ts
12057
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync10 } from "node:fs";
12090
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10 } from "node:fs";
12058
12091
  function detectContainer() {
12059
12092
  if (process.env.KUBERNETES_SERVICE_HOST)
12060
12093
  return true;
12061
12094
  if (process.env.CONTAINER === "1")
12062
12095
  return true;
12063
12096
  try {
12064
- if (existsSync11("/.dockerenv"))
12097
+ if (existsSync12("/.dockerenv"))
12065
12098
  return true;
12066
12099
  const cg = readFileSync10("/proc/1/cgroup", "utf8");
12067
12100
  if (/(docker|kubepods|containerd)/.test(cg))
@@ -12349,7 +12382,7 @@ __export(exports_service_install, {
12349
12382
  installService: () => installService,
12350
12383
  detectPlatform: () => detectPlatform
12351
12384
  });
12352
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, writeFileSync as writeFileSync11, unlinkSync as unlinkSync5, readFileSync as readFileSync11 } from "node:fs";
12385
+ import { existsSync as existsSync13, mkdirSync as mkdirSync7, writeFileSync as writeFileSync11, unlinkSync as unlinkSync5, readFileSync as readFileSync11 } from "node:fs";
12353
12386
  import { execSync as execSync2 } from "node:child_process";
12354
12387
  import { homedir as homedir7 } from "node:os";
12355
12388
  import { join as join8, dirname as dirname5 } from "node:path";
@@ -12370,7 +12403,7 @@ function installService(args) {
12370
12403
  if (isCi() && !args.allowCi) {
12371
12404
  throw new Error("Refusing to install persistent service in CI; pass --allow-ci-persistent to override.");
12372
12405
  }
12373
- if (!existsSync12(args.binaryPath)) {
12406
+ if (!existsSync13(args.binaryPath)) {
12374
12407
  throw new Error(`binary not found at ${args.binaryPath}`);
12375
12408
  }
12376
12409
  mkdirSync7(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
@@ -12386,7 +12419,7 @@ function uninstallService() {
12386
12419
  try {
12387
12420
  execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
12388
12421
  } catch {}
12389
- if (existsSync12(p)) {
12422
+ if (existsSync13(p)) {
12390
12423
  unlinkSync5(p);
12391
12424
  removed.push(p);
12392
12425
  }
@@ -12395,7 +12428,7 @@ function uninstallService() {
12395
12428
  try {
12396
12429
  execSync2(`systemctl --user disable --now ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
12397
12430
  } catch {}
12398
- if (existsSync12(p)) {
12431
+ if (existsSync13(p)) {
12399
12432
  unlinkSync5(p);
12400
12433
  removed.push(p);
12401
12434
  }
@@ -12456,7 +12489,7 @@ function installDarwin(args) {
12456
12489
  } catch {}
12457
12490
  try {
12458
12491
  const pidPath = DAEMON_PATHS.PID_FILE;
12459
- if (existsSync12(pidPath)) {
12492
+ if (existsSync13(pidPath)) {
12460
12493
  const pid = parseInt(readFileSync11(pidPath, "utf8").trim(), 10);
12461
12494
  if (Number.isFinite(pid) && pid > 0) {
12462
12495
  try {
@@ -12508,7 +12541,7 @@ WantedBy=default.target
12508
12541
  } catch {}
12509
12542
  try {
12510
12543
  const pidPath = DAEMON_PATHS.PID_FILE;
12511
- if (existsSync12(pidPath)) {
12544
+ if (existsSync13(pidPath)) {
12512
12545
  const pid = parseInt(readFileSync11(pidPath, "utf8").trim(), 10);
12513
12546
  if (Number.isFinite(pid) && pid > 0) {
12514
12547
  try {
@@ -12536,7 +12569,7 @@ function readInstalledUnit() {
12536
12569
  if (!platform5)
12537
12570
  return { platform: null, path: null, content: null };
12538
12571
  const path2 = platform5 === "darwin" ? darwinPlistPath() : linuxUnitPath();
12539
- if (!existsSync12(path2))
12572
+ if (!existsSync13(path2))
12540
12573
  return { platform: platform5, path: null, content: null };
12541
12574
  try {
12542
12575
  return { platform: platform5, path: path2, content: readFileSync11(path2, "utf8") };
@@ -12555,7 +12588,7 @@ __export(exports_daemon, {
12555
12588
  runDaemonCommand: () => runDaemonCommand
12556
12589
  });
12557
12590
  import { spawn } from "node:child_process";
12558
- import { existsSync as existsSync13, openSync as openSync3, mkdirSync as mkdirSync8 } from "node:fs";
12591
+ import { existsSync as existsSync14, openSync as openSync3, mkdirSync as mkdirSync8 } from "node:fs";
12559
12592
  import { join as join9 } from "node:path";
12560
12593
  async function runDaemonCommand(sub, opts, rest = []) {
12561
12594
  switch (sub) {
@@ -12897,7 +12930,7 @@ async function spawnDetachedDaemon(opts) {
12897
12930
  const sockPath = DAEMON_PATHS.SOCK_FILE;
12898
12931
  const startedAt = Date.now();
12899
12932
  while (Date.now() - startedAt < 3000) {
12900
- if (existsSync13(sockPath)) {
12933
+ if (existsSync14(sockPath)) {
12901
12934
  if (opts.json) {
12902
12935
  process.stdout.write(JSON.stringify({ ok: true, detached: true, pid: child.pid, log: logPath }) + `
12903
12936
  `);
@@ -12942,7 +12975,7 @@ __export(exports_install, {
12942
12975
  import {
12943
12976
  chmodSync as chmodSync4,
12944
12977
  copyFileSync,
12945
- existsSync as existsSync14,
12978
+ existsSync as existsSync15,
12946
12979
  mkdirSync as mkdirSync9,
12947
12980
  readFileSync as readFileSync12,
12948
12981
  writeFileSync as writeFileSync12
@@ -12952,7 +12985,7 @@ import { dirname as dirname6, join as join10, resolve } from "node:path";
12952
12985
  import { fileURLToPath } from "node:url";
12953
12986
  import { spawnSync as spawnSync3 } from "node:child_process";
12954
12987
  function readClaudeConfig() {
12955
- if (!existsSync14(CLAUDE_CONFIG))
12988
+ if (!existsSync15(CLAUDE_CONFIG))
12956
12989
  return {};
12957
12990
  const text = readFileSync12(CLAUDE_CONFIG, "utf-8").trim();
12958
12991
  if (!text)
@@ -12964,7 +12997,7 @@ function readClaudeConfig() {
12964
12997
  }
12965
12998
  }
12966
12999
  function backupClaudeConfig() {
12967
- if (!existsSync14(CLAUDE_CONFIG))
13000
+ if (!existsSync15(CLAUDE_CONFIG))
12968
13001
  return;
12969
13002
  const backupDir = join10(dirname6(CLAUDE_CONFIG), ".claude", "backups");
12970
13003
  mkdirSync9(backupDir, { recursive: true });
@@ -12993,7 +13026,7 @@ function patchMcpServer(entry) {
12993
13026
  return action;
12994
13027
  }
12995
13028
  function removeMcpServer() {
12996
- if (!existsSync14(CLAUDE_CONFIG))
13029
+ if (!existsSync15(CLAUDE_CONFIG))
12997
13030
  return false;
12998
13031
  backupClaudeConfig();
12999
13032
  const cfg = readClaudeConfig();
@@ -13030,7 +13063,7 @@ function resolveBundledSkillsDir() {
13030
13063
  const here = fileURLToPath(import.meta.url);
13031
13064
  const pkgRoot = resolve(dirname6(here), "..", "..");
13032
13065
  const skillsDir = join10(pkgRoot, "skills");
13033
- if (existsSync14(skillsDir))
13066
+ if (existsSync15(skillsDir))
13034
13067
  return skillsDir;
13035
13068
  return null;
13036
13069
  }
@@ -13065,7 +13098,7 @@ function uninstallSkills() {
13065
13098
  if (!entry.isDirectory())
13066
13099
  continue;
13067
13100
  const dstDir = join10(CLAUDE_SKILLS_ROOT, entry.name);
13068
- if (existsSync14(dstDir)) {
13101
+ if (existsSync15(dstDir)) {
13069
13102
  try {
13070
13103
  fs.rmSync(dstDir, { recursive: true, force: true });
13071
13104
  removed.push(entry.name);
@@ -13090,7 +13123,7 @@ function entriesEqual(a, b) {
13090
13123
  return a.command === b.command && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
13091
13124
  }
13092
13125
  function readClaudeSettings() {
13093
- if (!existsSync14(CLAUDE_SETTINGS))
13126
+ if (!existsSync15(CLAUDE_SETTINGS))
13094
13127
  return {};
13095
13128
  const text = readFileSync12(CLAUDE_SETTINGS, "utf-8").trim();
13096
13129
  if (!text)
@@ -13117,7 +13150,7 @@ function installAllowedTools() {
13117
13150
  return { added: toAdd, unchanged: CLAUDEMESH_TOOLS.length - toAdd.length };
13118
13151
  }
13119
13152
  function uninstallAllowedTools() {
13120
- if (!existsSync14(CLAUDE_SETTINGS))
13153
+ if (!existsSync15(CLAUDE_SETTINGS))
13121
13154
  return 0;
13122
13155
  const settings = readClaudeSettings();
13123
13156
  const existing = settings.allowedTools ?? [];
@@ -13152,7 +13185,7 @@ function installHooks() {
13152
13185
  return { added, unchanged };
13153
13186
  }
13154
13187
  function uninstallHooks() {
13155
- if (!existsSync14(CLAUDE_SETTINGS))
13188
+ if (!existsSync15(CLAUDE_SETTINGS))
13156
13189
  return 0;
13157
13190
  const settings = readClaudeSettings();
13158
13191
  const hooks2 = settings.hooks;
@@ -13202,7 +13235,7 @@ async function runInstall(args = []) {
13202
13235
  render.err("`bun` is not on PATH.", "Install Bun first: https://bun.com");
13203
13236
  process.exit(1);
13204
13237
  }
13205
- if (!existsSync14(entry)) {
13238
+ if (!existsSync15(entry)) {
13206
13239
  render.err(`MCP entry not found at ${entry}`);
13207
13240
  process.exit(1);
13208
13241
  }
@@ -13473,7 +13506,7 @@ var exports_uninstall = {};
13473
13506
  __export(exports_uninstall, {
13474
13507
  uninstall: () => uninstall
13475
13508
  });
13476
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync15, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
13509
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync16, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
13477
13510
  import { join as join11, dirname as dirname7 } from "node:path";
13478
13511
  import { homedir as homedir9 } from "node:os";
13479
13512
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -13481,11 +13514,11 @@ function bundledSkillsDir() {
13481
13514
  const here = fileURLToPath2(import.meta.url);
13482
13515
  const pkgRoot = join11(dirname7(here), "..", "..");
13483
13516
  const skillsDir = join11(pkgRoot, "skills");
13484
- return existsSync15(skillsDir) ? skillsDir : null;
13517
+ return existsSync16(skillsDir) ? skillsDir : null;
13485
13518
  }
13486
13519
  async function uninstall() {
13487
13520
  let removed = 0;
13488
- if (existsSync15(PATHS.CLAUDE_JSON)) {
13521
+ if (existsSync16(PATHS.CLAUDE_JSON)) {
13489
13522
  try {
13490
13523
  const raw = readFileSync13(PATHS.CLAUDE_JSON, "utf-8");
13491
13524
  const config = JSON.parse(raw);
@@ -13499,7 +13532,7 @@ async function uninstall() {
13499
13532
  }
13500
13533
  } catch {}
13501
13534
  }
13502
- if (existsSync15(PATHS.CLAUDE_SETTINGS)) {
13535
+ if (existsSync16(PATHS.CLAUDE_SETTINGS)) {
13503
13536
  try {
13504
13537
  const raw = readFileSync13(PATHS.CLAUDE_SETTINGS, "utf-8");
13505
13538
  const config = JSON.parse(raw);
@@ -13538,7 +13571,7 @@ async function uninstall() {
13538
13571
  if (!entry.isDirectory())
13539
13572
  continue;
13540
13573
  const dst = join11(CLAUDE_SKILLS_ROOT2, entry.name);
13541
- if (existsSync15(dst)) {
13574
+ if (existsSync16(dst)) {
13542
13575
  try {
13543
13576
  rmSync2(dst, { recursive: true, force: true });
13544
13577
  removedSkills.push(entry.name);
@@ -13570,7 +13603,7 @@ var exports_doctor = {};
13570
13603
  __export(exports_doctor, {
13571
13604
  runDoctor: () => runDoctor
13572
13605
  });
13573
- import { existsSync as existsSync16, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
13606
+ import { existsSync as existsSync17, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
13574
13607
  import { homedir as homedir10, platform as platform6 } from "node:os";
13575
13608
  import { join as join12 } from "node:path";
13576
13609
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -13597,7 +13630,7 @@ function checkClaudeOnPath() {
13597
13630
  }
13598
13631
  function checkMcpRegistered() {
13599
13632
  const claudeConfig = join12(homedir10(), ".claude.json");
13600
- if (!existsSync16(claudeConfig)) {
13633
+ if (!existsSync17(claudeConfig)) {
13601
13634
  return {
13602
13635
  name: "claudemesh MCP registered in ~/.claude.json",
13603
13636
  pass: false,
@@ -13623,7 +13656,7 @@ function checkMcpRegistered() {
13623
13656
  }
13624
13657
  function checkHooksRegistered() {
13625
13658
  const settings = join12(homedir10(), ".claude", "settings.json");
13626
- if (!existsSync16(settings)) {
13659
+ if (!existsSync17(settings)) {
13627
13660
  return {
13628
13661
  name: "Status hooks registered in ~/.claude/settings.json",
13629
13662
  pass: false,
@@ -13648,7 +13681,7 @@ function checkHooksRegistered() {
13648
13681
  }
13649
13682
  function checkConfigFile() {
13650
13683
  const path2 = getConfigPath();
13651
- if (!existsSync16(path2)) {
13684
+ if (!existsSync17(path2)) {
13652
13685
  return {
13653
13686
  name: "~/.claudemesh/config.json exists and parses",
13654
13687
  pass: true,
@@ -13831,7 +13864,7 @@ var exports_status = {};
13831
13864
  __export(exports_status, {
13832
13865
  runStatus: () => runStatus2
13833
13866
  });
13834
- import { statSync as statSync4, existsSync as existsSync17 } from "node:fs";
13867
+ import { statSync as statSync4, existsSync as existsSync18 } from "node:fs";
13835
13868
  import WebSocket3 from "ws";
13836
13869
  async function probeBroker(url, timeoutMs = 4000) {
13837
13870
  return new Promise((resolve2) => {
@@ -13861,7 +13894,7 @@ async function runStatus2() {
13861
13894
  render.section(`status (v${VERSION})`);
13862
13895
  const configPath = getConfigPath();
13863
13896
  let configPermsNote = "missing";
13864
- if (existsSync17(configPath)) {
13897
+ if (existsSync18(configPath)) {
13865
13898
  const mode = (statSync4(configPath).mode & 511).toString(8).padStart(4, "0");
13866
13899
  configPermsNote = mode === "0600" ? `${mode}` : `${mode} — expected 0600`;
13867
13900
  }
@@ -14007,10 +14040,10 @@ var init_check_claude_binary = __esm(() => {
14007
14040
  });
14008
14041
 
14009
14042
  // src/services/health/check-mcp-registered.ts
14010
- import { existsSync as existsSync18, readFileSync as readFileSync15 } from "node:fs";
14043
+ import { existsSync as existsSync19, readFileSync as readFileSync15 } from "node:fs";
14011
14044
  function checkMcpRegistered2() {
14012
14045
  try {
14013
- if (!existsSync18(PATHS.CLAUDE_JSON)) {
14046
+ if (!existsSync19(PATHS.CLAUDE_JSON)) {
14014
14047
  return { name: "mcp-registered", ok: false, message: "~/.claude.json not found" };
14015
14048
  }
14016
14049
  const raw = readFileSync15(PATHS.CLAUDE_JSON, "utf-8");
@@ -14028,10 +14061,10 @@ var init_check_mcp_registered = __esm(() => {
14028
14061
  });
14029
14062
 
14030
14063
  // src/services/health/check-hooks-registered.ts
14031
- import { existsSync as existsSync19, readFileSync as readFileSync16 } from "node:fs";
14064
+ import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
14032
14065
  function checkHooksRegistered2() {
14033
14066
  try {
14034
- if (!existsSync19(PATHS.CLAUDE_SETTINGS)) {
14067
+ if (!existsSync20(PATHS.CLAUDE_SETTINGS)) {
14035
14068
  return { name: "hooks-registered", ok: false, message: "~/.claude/settings.json not found" };
14036
14069
  }
14037
14070
  const raw = readFileSync16(PATHS.CLAUDE_SETTINGS, "utf-8");
@@ -14049,10 +14082,10 @@ var init_check_hooks_registered = __esm(() => {
14049
14082
  });
14050
14083
 
14051
14084
  // src/services/health/check-config-perms.ts
14052
- import { existsSync as existsSync20, statSync as statSync5 } from "node:fs";
14085
+ import { existsSync as existsSync21, statSync as statSync5 } from "node:fs";
14053
14086
  function checkConfigPerms() {
14054
14087
  const configFile = PATHS.CONFIG_FILE;
14055
- if (!existsSync20(configFile)) {
14088
+ if (!existsSync21(configFile)) {
14056
14089
  return { name: "config-perms", ok: true, message: "No config file yet (first run)" };
14057
14090
  }
14058
14091
  try {
@@ -14070,9 +14103,9 @@ var init_check_config_perms = __esm(() => {
14070
14103
  });
14071
14104
 
14072
14105
  // src/services/health/check-keypairs-valid.ts
14073
- import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
14106
+ import { existsSync as existsSync22, readFileSync as readFileSync17 } from "node:fs";
14074
14107
  function checkKeypairsValid() {
14075
- if (!existsSync21(PATHS.CONFIG_FILE)) {
14108
+ if (!existsSync22(PATHS.CONFIG_FILE)) {
14076
14109
  return { name: "keypairs-valid", ok: true, message: "No config (first run)" };
14077
14110
  }
14078
14111
  try {
@@ -14557,7 +14590,7 @@ __export(exports_url_handler, {
14557
14590
  runUrlHandler: () => runUrlHandler
14558
14591
  });
14559
14592
  import { platform as platform7, homedir as homedir11 } from "node:os";
14560
- import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync14, rmSync as rmSync3, chmodSync as chmodSync5 } from "node:fs";
14593
+ import { existsSync as existsSync23, mkdirSync as mkdirSync10, writeFileSync as writeFileSync14, rmSync as rmSync3, chmodSync as chmodSync5 } from "node:fs";
14561
14594
  import { join as join13 } from "node:path";
14562
14595
  import { spawnSync as spawnSync5 } from "node:child_process";
14563
14596
  function resolveClaudemeshBin() {
@@ -14665,14 +14698,14 @@ function installWindows() {
14665
14698
  }
14666
14699
  function uninstallDarwin() {
14667
14700
  const appDir = join13(homedir11(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
14668
- if (existsSync22(appDir))
14701
+ if (existsSync23(appDir))
14669
14702
  rmSync3(appDir, { recursive: true, force: true });
14670
14703
  render.ok("removed claudemesh:// handler on macOS");
14671
14704
  return EXIT.SUCCESS;
14672
14705
  }
14673
14706
  function uninstallLinux() {
14674
14707
  const desktopPath = join13(homedir11(), ".local", "share", "applications", "claudemesh.desktop");
14675
- if (existsSync22(desktopPath))
14708
+ if (existsSync23(desktopPath))
14676
14709
  rmSync3(desktopPath, { force: true });
14677
14710
  render.ok("removed claudemesh:// handler on Linux");
14678
14711
  return EXIT.SUCCESS;
@@ -14717,7 +14750,7 @@ var exports_status_line = {};
14717
14750
  __export(exports_status_line, {
14718
14751
  runStatusLine: () => runStatusLine
14719
14752
  });
14720
- import { existsSync as existsSync23, readFileSync as readFileSync18 } from "node:fs";
14753
+ import { existsSync as existsSync24, readFileSync as readFileSync18 } from "node:fs";
14721
14754
  import { join as join14 } from "node:path";
14722
14755
  import { homedir as homedir12 } from "node:os";
14723
14756
  async function runStatusLine() {
@@ -14729,7 +14762,7 @@ async function runStatusLine() {
14729
14762
  }
14730
14763
  const cachePath = join14(homedir12(), ".claudemesh", "peer-cache.json");
14731
14764
  let cache = {};
14732
- if (existsSync23(cachePath)) {
14765
+ if (existsSync24(cachePath)) {
14733
14766
  try {
14734
14767
  cache = JSON.parse(readFileSync18(cachePath, "utf-8"));
14735
14768
  } catch {}
@@ -14762,7 +14795,7 @@ __export(exports_backup, {
14762
14795
  runRestore: () => runRestore,
14763
14796
  runBackup: () => runBackup
14764
14797
  });
14765
- import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, existsSync as existsSync24 } from "node:fs";
14798
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, existsSync as existsSync25 } from "node:fs";
14766
14799
  import { createInterface as createInterface11 } from "node:readline";
14767
14800
  function readHidden(prompt5) {
14768
14801
  return new Promise((resolve2) => {
@@ -14804,7 +14837,7 @@ async function deriveKey(pass, salt, s) {
14804
14837
  }
14805
14838
  async function runBackup(outPath) {
14806
14839
  const configPath = getConfigPath();
14807
- if (!existsSync24(configPath)) {
14840
+ if (!existsSync25(configPath)) {
14808
14841
  console.error(" No config found — nothing to back up. Join a mesh first.");
14809
14842
  return EXIT.NOT_FOUND;
14810
14843
  }
@@ -14838,7 +14871,7 @@ async function runRestore(inPath) {
14838
14871
  console.error(" Usage: claudemesh restore <backup-file>");
14839
14872
  return EXIT.INVALID_ARGS;
14840
14873
  }
14841
- if (!existsSync24(inPath)) {
14874
+ if (!existsSync25(inPath)) {
14842
14875
  console.error(` ✗ File not found: ${inPath}`);
14843
14876
  return EXIT.NOT_FOUND;
14844
14877
  }
@@ -14861,7 +14894,7 @@ async function runRestore(inPath) {
14861
14894
  return EXIT.INTERNAL_ERROR;
14862
14895
  }
14863
14896
  const configPath = getConfigPath();
14864
- if (existsSync24(configPath)) {
14897
+ if (existsSync25(configPath)) {
14865
14898
  const backupOld = `${configPath}.before-restore.${Date.now()}`;
14866
14899
  writeFileSync15(backupOld, readFileSync19(configPath), { mode: 384 });
14867
14900
  console.log(` ↻ Existing config saved to ${backupOld}`);
@@ -14886,7 +14919,7 @@ __export(exports_upgrade, {
14886
14919
  runUpgrade: () => runUpgrade
14887
14920
  });
14888
14921
  import { spawnSync as spawnSync6 } from "node:child_process";
14889
- import { existsSync as existsSync25 } from "node:fs";
14922
+ import { existsSync as existsSync26 } from "node:fs";
14890
14923
  import { dirname as dirname8, join as join15, resolve as resolve2 } from "node:path";
14891
14924
  async function latestVersion() {
14892
14925
  try {
@@ -14901,14 +14934,14 @@ async function latestVersion() {
14901
14934
  }
14902
14935
  function findNpm() {
14903
14936
  const portable = join15(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
14904
- if (existsSync25(portable)) {
14937
+ if (existsSync26(portable)) {
14905
14938
  return { npm: portable, prefix: join15(process.env.HOME ?? "", ".claudemesh") };
14906
14939
  }
14907
14940
  let cur = resolve2(process.argv[1] ?? ".");
14908
14941
  for (let i = 0;i < 6; i++) {
14909
14942
  cur = dirname8(cur);
14910
14943
  const candidate = join15(cur, "bin", "npm");
14911
- if (existsSync25(candidate))
14944
+ if (existsSync26(candidate))
14912
14945
  return { npm: candidate };
14913
14946
  }
14914
14947
  return { npm: "npm" };
@@ -14970,7 +15003,7 @@ __export(exports_grants, {
14970
15003
  runBlock: () => runBlock,
14971
15004
  isAllowed: () => isAllowed
14972
15005
  });
14973
- import { existsSync as existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
15006
+ import { existsSync as existsSync27, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
14974
15007
  import { homedir as homedir13 } from "node:os";
14975
15008
  import { join as join16 } from "node:path";
14976
15009
  async function syncToBroker(meshSlug, grants) {
@@ -14990,7 +15023,7 @@ async function syncToBroker(meshSlug, grants) {
14990
15023
  }
14991
15024
  }
14992
15025
  function readGrants() {
14993
- if (!existsSync26(GRANT_FILE))
15026
+ if (!existsSync27(GRANT_FILE))
14994
15027
  return {};
14995
15028
  try {
14996
15029
  return JSON.parse(readFileSync20(GRANT_FILE, "utf-8"));
@@ -15000,7 +15033,7 @@ function readGrants() {
15000
15033
  }
15001
15034
  function writeGrants(g) {
15002
15035
  const dir = join16(homedir13(), ".claudemesh");
15003
- if (!existsSync26(dir))
15036
+ if (!existsSync27(dir))
15004
15037
  mkdirSync11(dir, { recursive: true });
15005
15038
  writeFileSync16(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
15006
15039
  }
@@ -16879,7 +16912,7 @@ __export(exports_file, {
16879
16912
  });
16880
16913
  import { hostname as osHostname2 } from "node:os";
16881
16914
  import { resolve as resolvePath, basename, dirname as dirname9 } from "node:path";
16882
- import { statSync as statSync7, existsSync as existsSync27, writeFileSync as writeFileSync17, mkdirSync as mkdirSync12 } from "node:fs";
16915
+ import { statSync as statSync7, existsSync as existsSync28, writeFileSync as writeFileSync17, mkdirSync as mkdirSync12 } from "node:fs";
16883
16916
  function emitJson2(data) {
16884
16917
  console.log(JSON.stringify(data, null, 2));
16885
16918
  }
@@ -16896,7 +16929,7 @@ async function runFileShare(filePath, opts) {
16896
16929
  return EXIT.INVALID_ARGS;
16897
16930
  }
16898
16931
  const absPath = resolvePath(filePath);
16899
- if (!existsSync27(absPath)) {
16932
+ if (!existsSync28(absPath)) {
16900
16933
  render.err(`File not found: ${absPath}`);
16901
16934
  return EXIT.INVALID_ARGS;
16902
16935
  }
@@ -17586,7 +17619,7 @@ __export(exports_bridge, {
17586
17619
  runBridge: () => runBridge,
17587
17620
  bridgeConfigTemplate: () => bridgeConfigTemplate
17588
17621
  });
17589
- import { readFileSync as readFileSync21, existsSync as existsSync28 } from "node:fs";
17622
+ import { readFileSync as readFileSync21, existsSync as existsSync29 } from "node:fs";
17590
17623
  function parseConfig(text) {
17591
17624
  const trimmed = text.trim();
17592
17625
  if (trimmed.startsWith("{"))
@@ -17630,7 +17663,7 @@ async function runBridge(configPath) {
17630
17663
  render.err("Usage: claudemesh bridge run <config.yaml>");
17631
17664
  return EXIT.INVALID_ARGS;
17632
17665
  }
17633
- if (!existsSync28(configPath)) {
17666
+ if (!existsSync29(configPath)) {
17634
17667
  render.err(`config file not found: ${configPath}`);
17635
17668
  return EXIT.NOT_FOUND;
17636
17669
  }
@@ -18610,12 +18643,12 @@ import {
18610
18643
  ListResourcesRequestSchema,
18611
18644
  ReadResourceRequestSchema
18612
18645
  } from "@modelcontextprotocol/sdk/types.js";
18613
- import { existsSync as existsSync29, appendFileSync as appendFileSync2 } from "node:fs";
18646
+ import { existsSync as existsSync30, appendFileSync as appendFileSync2 } from "node:fs";
18614
18647
  import { request as httpRequest2 } from "node:http";
18615
18648
  import { join as join17 } from "node:path";
18616
18649
  async function daemonReady() {
18617
18650
  for (let i = 0;i < DAEMON_BOOT_RETRIES; i++) {
18618
- if (existsSync29(DAEMON_PATHS.SOCK_FILE))
18651
+ if (existsSync30(DAEMON_PATHS.SOCK_FILE))
18619
18652
  return true;
18620
18653
  await new Promise((r) => setTimeout(r, DAEMON_BOOT_RETRY_MS));
18621
18654
  }
@@ -21216,4 +21249,4 @@ main().catch((err) => {
21216
21249
  process.exit(EXIT.INTERNAL_ERROR);
21217
21250
  });
21218
21251
 
21219
- //# debugId=CB6FEE3C98D7D19864756E2164756E21
21252
+ //# debugId=89AC9B5F79C7438764756E2164756E21