claudemesh-cli 1.27.3 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -103,7 +103,7 @@ __export(exports_urls, {
103
103
  VERSION: () => VERSION,
104
104
  URLS: () => URLS
105
105
  });
106
- var URLS, VERSION = "1.27.3", env;
106
+ var URLS, VERSION = "1.28.0", env;
107
107
  var init_urls = __esm(() => {
108
108
  URLS = {
109
109
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -150,6 +150,32 @@ function normaliseInviteUrl(input, host = "claudemesh.com") {
150
150
  return trimmed;
151
151
  }
152
152
 
153
+ // src/services/daemon/policy.ts
154
+ function readEnvDefault() {
155
+ if (process.env.CLAUDEMESH_NO_DAEMON === "1")
156
+ return { mode: "no-daemon" };
157
+ if (process.env.CLAUDEMESH_STRICT_DAEMON === "1")
158
+ return { mode: "strict" };
159
+ return { mode: "auto" };
160
+ }
161
+ function setDaemonPolicy(mode) {
162
+ policy = { mode };
163
+ }
164
+ function getDaemonPolicy() {
165
+ return policy;
166
+ }
167
+ function policyFromFlags(flags) {
168
+ if (flags["no-daemon"])
169
+ return "no-daemon";
170
+ if (flags.strict)
171
+ return "strict";
172
+ return readEnvDefault().mode;
173
+ }
174
+ var policy;
175
+ var init_policy = __esm(() => {
176
+ policy = readEnvDefault();
177
+ });
178
+
153
179
  // src/constants/paths.ts
154
180
  import { homedir as homedir2 } from "node:os";
155
181
  import { join as join2 } from "node:path";
@@ -6699,6 +6725,12 @@ async function pickMesh(meshes) {
6699
6725
  });
6700
6726
  }
6701
6727
  async function withMesh(opts, fn) {
6728
+ if (getDaemonPolicy().mode === "strict") {
6729
+ console.error(`
6730
+ ✘ daemon not reachable — --strict refuses cold-path fallback.
6731
+ ` + " run `claudemesh daemon up` (or `claudemesh doctor`) and retry.\n");
6732
+ process.exit(1);
6733
+ }
6702
6734
  const config = readConfig();
6703
6735
  if (config.meshes.length === 0) {
6704
6736
  console.error("No meshes joined. Run `claudemesh join <url>` first.");
@@ -6749,6 +6781,7 @@ async function withMesh(opts, fn) {
6749
6781
  var init_connect = __esm(() => {
6750
6782
  init_facade8();
6751
6783
  init_facade();
6784
+ init_policy();
6752
6785
  });
6753
6786
 
6754
6787
  // src/commands/info.ts
@@ -7385,107 +7418,6 @@ var init_ban = __esm(() => {
7385
7418
  init_exit_codes();
7386
7419
  });
7387
7420
 
7388
- // src/services/bridge/protocol.ts
7389
- import { homedir as homedir5 } from "node:os";
7390
- import { join as join7 } from "node:path";
7391
- function socketPath(meshSlug) {
7392
- return join7(homedir5(), ".claudemesh", "sockets", `${meshSlug}.sock`);
7393
- }
7394
- function frame(obj) {
7395
- return JSON.stringify(obj) + `
7396
- `;
7397
- }
7398
-
7399
- class LineParser {
7400
- buf = "";
7401
- feed(chunk) {
7402
- this.buf += typeof chunk === "string" ? chunk : chunk.toString("utf-8");
7403
- const lines = [];
7404
- let nl = this.buf.indexOf(`
7405
- `);
7406
- while (nl !== -1) {
7407
- lines.push(this.buf.slice(0, nl));
7408
- this.buf = this.buf.slice(nl + 1);
7409
- nl = this.buf.indexOf(`
7410
- `);
7411
- }
7412
- return lines;
7413
- }
7414
- }
7415
- var init_protocol = () => {};
7416
-
7417
- // src/services/bridge/client.ts
7418
- import { createConnection } from "node:net";
7419
- import { existsSync as existsSync7 } from "node:fs";
7420
- import { randomUUID as randomUUID2 } from "node:crypto";
7421
- async function tryBridge(meshSlug, verb, args = {}, timeoutMs = DEFAULT_TIMEOUT_MS) {
7422
- const path = socketPath(meshSlug);
7423
- if (!existsSync7(path))
7424
- return null;
7425
- return new Promise((resolve) => {
7426
- const id = randomUUID2();
7427
- const req = { id, verb, args };
7428
- const parser = new LineParser;
7429
- let settled = false;
7430
- const finish = (value) => {
7431
- if (settled)
7432
- return;
7433
- settled = true;
7434
- try {
7435
- socket.destroy();
7436
- } catch {}
7437
- clearTimeout(timer);
7438
- resolve(value);
7439
- };
7440
- const socket = createConnection({ path });
7441
- const timer = setTimeout(() => {
7442
- finish(null);
7443
- }, timeoutMs);
7444
- socket.on("connect", () => {
7445
- try {
7446
- socket.write(frame(req));
7447
- } catch {
7448
- finish(null);
7449
- }
7450
- });
7451
- socket.on("data", (chunk) => {
7452
- const lines = parser.feed(chunk);
7453
- for (const line of lines) {
7454
- if (!line.trim())
7455
- continue;
7456
- let res;
7457
- try {
7458
- res = JSON.parse(line);
7459
- } catch {
7460
- continue;
7461
- }
7462
- if (res.id !== id)
7463
- continue;
7464
- if (res.ok)
7465
- finish({ ok: true, result: res.result });
7466
- else
7467
- finish({ ok: false, error: res.error });
7468
- return;
7469
- }
7470
- });
7471
- socket.on("error", (err) => {
7472
- const code = err.code;
7473
- if (code === "ECONNREFUSED" || code === "ENOENT" || code === "EPERM") {
7474
- finish(null);
7475
- } else {
7476
- finish(null);
7477
- }
7478
- });
7479
- socket.on("close", () => {
7480
- finish(null);
7481
- });
7482
- });
7483
- }
7484
- var DEFAULT_TIMEOUT_MS = 5000;
7485
- var init_client4 = __esm(() => {
7486
- init_protocol();
7487
- });
7488
-
7489
7421
  // src/ui/warnings.ts
7490
7422
  function warnDaemonState(res, opts = {}) {
7491
7423
  if (alreadyWarned)
@@ -7494,6 +7426,8 @@ function warnDaemonState(res, opts = {}) {
7494
7426
  return false;
7495
7427
  if (res.state === "up")
7496
7428
  return false;
7429
+ if (getDaemonPolicy().mode === "strict" && res.state !== "started")
7430
+ return false;
7497
7431
  alreadyWarned = true;
7498
7432
  const tag = (label) => `[claudemesh] ${label}`;
7499
7433
  const hint = (s) => dim(s);
@@ -7519,6 +7453,7 @@ function warnDaemonState(res, opts = {}) {
7519
7453
  }
7520
7454
  var alreadyWarned = false;
7521
7455
  var init_warnings = __esm(() => {
7456
+ init_policy();
7522
7457
  init_styles();
7523
7458
  });
7524
7459
 
@@ -7540,7 +7475,10 @@ function meshQuery(mesh) {
7540
7475
  return mesh ? `?mesh=${encodeURIComponent(mesh)}` : "";
7541
7476
  }
7542
7477
  async function daemonReachable() {
7543
- const res = await ensureDaemonReady();
7478
+ const policy2 = getDaemonPolicy();
7479
+ if (policy2.mode === "no-daemon")
7480
+ return false;
7481
+ const res = await ensureDaemonReady({ noAutoSpawn: false });
7544
7482
  warnDaemonState(res, {});
7545
7483
  return res.state === "up" || res.state === "started";
7546
7484
  }
@@ -7718,6 +7656,7 @@ async function trySendViaDaemon(args) {
7718
7656
  var init_daemon_route = __esm(() => {
7719
7657
  init_client3();
7720
7658
  init_lifecycle();
7659
+ init_policy();
7721
7660
  init_warnings();
7722
7661
  });
7723
7662
 
@@ -7745,11 +7684,6 @@ async function listPeersForMesh(slug) {
7745
7684
  return dr.map((p) => annotateSelf(p, selfMemberPubkey, null));
7746
7685
  }
7747
7686
  } catch {}
7748
- const bridged = await tryBridge(slug, "peers");
7749
- if (bridged && bridged.ok) {
7750
- const peers = bridged.result;
7751
- return peers.map((p) => annotateSelf(p, selfMemberPubkey, null));
7752
- }
7753
7687
  let result = [];
7754
7688
  await withMesh({ meshSlug: slug }, async (client) => {
7755
7689
  const all = await client.listPeers();
@@ -7819,7 +7753,6 @@ var FIELD_ALIAS;
7819
7753
  var init_peers = __esm(() => {
7820
7754
  init_connect();
7821
7755
  init_facade();
7822
- init_client4();
7823
7756
  init_render();
7824
7757
  init_styles();
7825
7758
  FIELD_ALIAS = {
@@ -7865,26 +7798,6 @@ async function runSend(flags, to, message) {
7865
7798
  process.exit(1);
7866
7799
  }
7867
7800
  }
7868
- if (meshSlug) {
7869
- const bridged = await tryBridge(meshSlug, "send", { to, message, priority });
7870
- if (bridged !== null) {
7871
- if (bridged.ok) {
7872
- const r = bridged.result;
7873
- if (flags.json) {
7874
- console.log(JSON.stringify({ ok: true, messageId: r.messageId, target: to }));
7875
- } else {
7876
- render.ok(`sent to ${to}`, r.messageId ? dim(r.messageId.slice(0, 8)) : undefined);
7877
- }
7878
- return;
7879
- }
7880
- if (flags.json) {
7881
- console.log(JSON.stringify({ ok: false, error: bridged.error }));
7882
- } else {
7883
- render.err(`send failed: ${bridged.error}`);
7884
- }
7885
- process.exit(1);
7886
- }
7887
- }
7888
7801
  await withMesh({ meshSlug: flags.mesh ?? null }, async (client) => {
7889
7802
  let targetSpec = to;
7890
7803
  if (to.startsWith("#") && !/^#[0-9a-z_-]{20,}$/i.test(to)) {
@@ -7927,7 +7840,6 @@ async function runSend(flags, to, message) {
7927
7840
  var init_send = __esm(() => {
7928
7841
  init_connect();
7929
7842
  init_facade();
7930
- init_client4();
7931
7843
  init_daemon_route();
7932
7844
  init_render();
7933
7845
  init_styles();
@@ -8255,33 +8167,12 @@ __export(exports_broker_actions, {
8255
8167
  runForget: () => runForget,
8256
8168
  runClock: () => runClock
8257
8169
  });
8258
- function unambiguousMesh(opts) {
8259
- if (opts.mesh)
8260
- return opts.mesh;
8261
- const config = readConfig();
8262
- return config.meshes.length === 1 ? config.meshes[0].slug : null;
8263
- }
8264
8170
  async function runStatusSet(state, opts) {
8265
8171
  const valid = ["idle", "working", "dnd"];
8266
8172
  if (!valid.includes(state)) {
8267
8173
  render.err(`Invalid status: ${state}`, `must be one of: ${valid.join(", ")}`);
8268
8174
  return EXIT.INVALID_ARGS;
8269
8175
  }
8270
- const meshSlug = unambiguousMesh(opts);
8271
- if (meshSlug) {
8272
- const bridged = await tryBridge(meshSlug, "status_set", { status: state });
8273
- if (bridged !== null) {
8274
- if (bridged.ok) {
8275
- if (opts.json)
8276
- console.log(JSON.stringify({ status: state }));
8277
- else
8278
- render.ok(`status set to ${bold(state)}`);
8279
- return EXIT.SUCCESS;
8280
- }
8281
- render.err(bridged.error);
8282
- return EXIT.INTERNAL_ERROR;
8283
- }
8284
- }
8285
8176
  await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
8286
8177
  await client.setStatus(state);
8287
8178
  });
@@ -8296,21 +8187,6 @@ async function runSummary(text, opts) {
8296
8187
  render.err("Usage: claudemesh summary <text>");
8297
8188
  return EXIT.INVALID_ARGS;
8298
8189
  }
8299
- const meshSlug = unambiguousMesh(opts);
8300
- if (meshSlug) {
8301
- const bridged = await tryBridge(meshSlug, "summary", { summary: text });
8302
- if (bridged !== null) {
8303
- if (bridged.ok) {
8304
- if (opts.json)
8305
- console.log(JSON.stringify({ summary: text }));
8306
- else
8307
- render.ok("summary set", dim(text));
8308
- return EXIT.SUCCESS;
8309
- }
8310
- render.err(bridged.error);
8311
- return EXIT.INTERNAL_ERROR;
8312
- }
8313
- }
8314
8190
  await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
8315
8191
  await client.setSummary(text);
8316
8192
  });
@@ -8330,21 +8206,6 @@ async function runVisible(value, opts) {
8330
8206
  render.err("Usage: claudemesh visible <true|false>");
8331
8207
  return EXIT.INVALID_ARGS;
8332
8208
  }
8333
- const meshSlug = unambiguousMesh(opts);
8334
- if (meshSlug) {
8335
- const bridged = await tryBridge(meshSlug, "visible", { visible });
8336
- if (bridged !== null) {
8337
- if (bridged.ok) {
8338
- if (opts.json)
8339
- console.log(JSON.stringify({ visible }));
8340
- else
8341
- render.ok(visible ? "you are now visible to peers" : "you are now hidden", visible ? undefined : "direct messages still reach you");
8342
- return EXIT.SUCCESS;
8343
- }
8344
- render.err(bridged.error);
8345
- return EXIT.INTERNAL_ERROR;
8346
- }
8347
- }
8348
8209
  await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
8349
8210
  await client.setVisible(visible);
8350
8211
  });
@@ -8574,8 +8435,6 @@ async function runTaskComplete(id, result, opts) {
8574
8435
  }
8575
8436
  var init_broker_actions = __esm(() => {
8576
8437
  init_connect();
8577
- init_facade();
8578
- init_client4();
8579
8438
  init_daemon_route();
8580
8439
  init_render();
8581
8440
  init_styles();
@@ -8810,11 +8669,11 @@ var init_whoami = __esm(() => {
8810
8669
  });
8811
8670
 
8812
8671
  // src/daemon/lock.ts
8813
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
8672
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
8814
8673
  import { dirname as dirname4 } from "node:path";
8815
8674
  function acquireSingletonLock() {
8816
8675
  mkdirSync5(dirname4(DAEMON_PATHS.PID_FILE), { recursive: true, mode: 448 });
8817
- if (existsSync8(DAEMON_PATHS.PID_FILE)) {
8676
+ if (existsSync7(DAEMON_PATHS.PID_FILE)) {
8818
8677
  const raw = readFileSync7(DAEMON_PATHS.PID_FILE, "utf8").trim();
8819
8678
  const oldPid = Number.parseInt(raw, 10);
8820
8679
  if (Number.isFinite(oldPid) && oldPid > 0 && isProcessAlive(oldPid)) {
@@ -9074,10 +8933,10 @@ var init_fingerprint = __esm(() => {
9074
8933
  });
9075
8934
 
9076
8935
  // src/daemon/ipc/handlers/send.ts
9077
- import { randomUUID as randomUUID3 } from "node:crypto";
8936
+ import { randomUUID as randomUUID2 } from "node:crypto";
9078
8937
  function acceptSend(req, deps) {
9079
8938
  const now = (deps.now ?? Date.now)();
9080
- const newId = deps.newId ?? randomUUID3;
8939
+ const newId = deps.newId ?? randomUUID2;
9081
8940
  const clientId = req.client_message_id?.trim() || ulidLike(newId);
9082
8941
  const body = Buffer.from(req.message, "utf8");
9083
8942
  const fingerprint = computeRequestFingerprint({
@@ -9270,9 +9129,9 @@ function bindSseStream(res, bus) {
9270
9129
 
9271
9130
  // src/daemon/ipc/server.ts
9272
9131
  import { createServer as createServer2 } from "node:http";
9273
- import { chmodSync as chmodSync3, existsSync as existsSync9, unlinkSync as unlinkSync4 } from "node:fs";
9132
+ import { chmodSync as chmodSync3, existsSync as existsSync8, unlinkSync as unlinkSync4 } from "node:fs";
9274
9133
  import { timingSafeEqual } from "node:crypto";
9275
- import { randomUUID as randomUUID4 } from "node:crypto";
9134
+ import { randomUUID as randomUUID3 } from "node:crypto";
9276
9135
  function startIpcServer(opts) {
9277
9136
  const log2 = opts.log ?? defaultLogger;
9278
9137
  const handler = makeHandler({
@@ -9286,7 +9145,7 @@ function startIpcServer(opts) {
9286
9145
  meshConfigs: opts.meshConfigs,
9287
9146
  onPendingInserted: opts.onPendingInserted
9288
9147
  });
9289
- if (existsSync9(DAEMON_PATHS.SOCK_FILE)) {
9148
+ if (existsSync8(DAEMON_PATHS.SOCK_FILE)) {
9290
9149
  try {
9291
9150
  unlinkSync4(DAEMON_PATHS.SOCK_FILE);
9292
9151
  } catch {}
@@ -9743,11 +9602,11 @@ function makeHandler(opts) {
9743
9602
  respond(res, 400, { error: "missing 'id'" });
9744
9603
  return;
9745
9604
  }
9746
- const newId = typeof body.new_client_message_id === "string" && body.new_client_message_id.trim() ? body.new_client_message_id.trim() : randomUUID4();
9605
+ const newId = typeof body.new_client_message_id === "string" && body.new_client_message_id.trim() ? body.new_client_message_id.trim() : randomUUID3();
9747
9606
  const result = requeueDeadOrPending(opts.outboxDb, {
9748
9607
  id: body.id,
9749
9608
  newClientMessageId: newId,
9750
- newRowId: randomUUID4(),
9609
+ newRowId: randomUUID3(),
9751
9610
  now: Date.now(),
9752
9611
  abortedBy: typeof body.aborted_by === "string" ? body.aborted_by : "operator"
9753
9612
  });
@@ -10614,7 +10473,7 @@ var POLL_INTERVAL_MS = 500, MAX_ATTEMPTS_PER_ROW = 25, BACKOFF_BASE_MS = 500, BA
10614
10473
  var init_drain = () => {};
10615
10474
 
10616
10475
  // src/daemon/inbound.ts
10617
- import { randomUUID as randomUUID5 } from "node:crypto";
10476
+ import { randomUUID as randomUUID4 } from "node:crypto";
10618
10477
  async function handleBrokerPush(msg, ctx) {
10619
10478
  if (msg.subtype === "system" && typeof msg.event === "string") {
10620
10479
  ctx.bus.publish(mapSystemEventKind(msg.event), {
@@ -10637,14 +10496,14 @@ async function handleBrokerPush(msg, ctx) {
10637
10496
  const createdAt = stringOrNull(msg.createdAt);
10638
10497
  const priority = stringOrNull(msg.priority) ?? "next";
10639
10498
  const subtype = stringOrNull(msg.subtype);
10640
- const clientMessageId = stringOrNull(msg.client_message_id) ?? brokerMessageId ?? randomUUID5();
10499
+ const clientMessageId = stringOrNull(msg.client_message_id) ?? brokerMessageId ?? randomUUID4();
10641
10500
  const body = await decryptOrFallback({
10642
10501
  ciphertext,
10643
10502
  nonce,
10644
10503
  senderPubkey,
10645
10504
  ctx
10646
10505
  });
10647
- const id = randomUUID5();
10506
+ const id = randomUUID4();
10648
10507
  const inserted = insertIfNew(ctx.db, {
10649
10508
  id,
10650
10509
  client_message_id: clientMessageId,
@@ -10721,12 +10580,12 @@ __export(exports_identity, {
10721
10580
  checkFingerprint: () => checkFingerprint,
10722
10581
  acceptCurrentHost: () => acceptCurrentHost
10723
10582
  });
10724
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "node:fs";
10725
- import { join as join8 } from "node:path";
10583
+ import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "node:fs";
10584
+ import { join as join7 } from "node:path";
10726
10585
  import { createHash as createHash2 } from "node:crypto";
10727
10586
  import { networkInterfaces } from "node:os";
10728
10587
  function path() {
10729
- return join8(DAEMON_PATHS.DAEMON_DIR, FILE_NAME);
10588
+ return join7(DAEMON_PATHS.DAEMON_DIR, FILE_NAME);
10730
10589
  }
10731
10590
  function computeCurrentFingerprint() {
10732
10591
  const host_id = readHostId() ?? "";
@@ -10742,7 +10601,7 @@ function computeCurrentFingerprint() {
10742
10601
  }
10743
10602
  function checkFingerprint() {
10744
10603
  const current = computeCurrentFingerprint();
10745
- if (!existsSync10(path())) {
10604
+ if (!existsSync9(path())) {
10746
10605
  writeFileSync9(path(), JSON.stringify(current, null, 2), { mode: 384 });
10747
10606
  return { result: "first_run", current };
10748
10607
  }
@@ -10810,14 +10669,14 @@ var init_identity = __esm(() => {
10810
10669
  });
10811
10670
 
10812
10671
  // src/daemon/run.ts
10813
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9 } from "node:fs";
10672
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync9 } from "node:fs";
10814
10673
  function detectContainer() {
10815
10674
  if (process.env.KUBERNETES_SERVICE_HOST)
10816
10675
  return true;
10817
10676
  if (process.env.CONTAINER === "1")
10818
10677
  return true;
10819
10678
  try {
10820
- if (existsSync11("/.dockerenv"))
10679
+ if (existsSync10("/.dockerenv"))
10821
10680
  return true;
10822
10681
  const cg = readFileSync9("/proc/1/cgroup", "utf8");
10823
10682
  if (/(docker|kubepods|containerd)/.test(cg))
@@ -10838,10 +10697,10 @@ async function runDaemon(opts = {}) {
10838
10697
  `);
10839
10698
  }
10840
10699
  const fpCheck = checkFingerprint();
10841
- const policy = opts.clonePolicy ?? "refuse";
10700
+ const policy2 = opts.clonePolicy ?? "refuse";
10842
10701
  if (fpCheck.result === "mismatch") {
10843
10702
  const msg = `host_fingerprint mismatch: this daemon dir was started on a different host.`;
10844
- if (policy === "refuse") {
10703
+ if (policy2 === "refuse") {
10845
10704
  process.stderr.write(`${msg}
10846
10705
  `);
10847
10706
  process.stderr.write(` stored host_id: ${fpCheck.stored?.host_id}
@@ -10855,7 +10714,7 @@ async function runDaemon(opts = {}) {
10855
10714
  releaseSingletonLock();
10856
10715
  return 4;
10857
10716
  }
10858
- if (policy === "warn") {
10717
+ if (policy2 === "warn") {
10859
10718
  process.stderr.write(`WARN: ${msg} (continuing per [clone] policy=warn)
10860
10719
  `);
10861
10720
  }
@@ -11020,10 +10879,10 @@ __export(exports_service_install, {
11020
10879
  installService: () => installService,
11021
10880
  detectPlatform: () => detectPlatform
11022
10881
  });
11023
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5, readFileSync as readFileSync10 } from "node:fs";
10882
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5, readFileSync as readFileSync10 } from "node:fs";
11024
10883
  import { execSync as execSync2 } from "node:child_process";
11025
- import { homedir as homedir6 } from "node:os";
11026
- import { join as join9, dirname as dirname5 } from "node:path";
10884
+ import { homedir as homedir5 } from "node:os";
10885
+ import { join as join8, dirname as dirname5 } from "node:path";
11027
10886
  function detectPlatform() {
11028
10887
  if (process.platform === "darwin")
11029
10888
  return "darwin";
@@ -11041,7 +10900,7 @@ function installService(args) {
11041
10900
  if (isCi() && !args.allowCi) {
11042
10901
  throw new Error("Refusing to install persistent service in CI; pass --allow-ci-persistent to override.");
11043
10902
  }
11044
- if (!existsSync12(args.binaryPath)) {
10903
+ if (!existsSync11(args.binaryPath)) {
11045
10904
  throw new Error(`binary not found at ${args.binaryPath}`);
11046
10905
  }
11047
10906
  mkdirSync7(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
@@ -11057,7 +10916,7 @@ function uninstallService() {
11057
10916
  try {
11058
10917
  execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL}`, { stdio: "ignore" });
11059
10918
  } catch {}
11060
- if (existsSync12(p)) {
10919
+ if (existsSync11(p)) {
11061
10920
  unlinkSync5(p);
11062
10921
  removed.push(p);
11063
10922
  }
@@ -11066,7 +10925,7 @@ function uninstallService() {
11066
10925
  try {
11067
10926
  execSync2(`systemctl --user disable --now ${SYSTEMD_UNIT}`, { stdio: "ignore" });
11068
10927
  } catch {}
11069
- if (existsSync12(p)) {
10928
+ if (existsSync11(p)) {
11070
10929
  unlinkSync5(p);
11071
10930
  removed.push(p);
11072
10931
  }
@@ -11074,7 +10933,7 @@ function uninstallService() {
11074
10933
  return { platform: platform5, removed };
11075
10934
  }
11076
10935
  function darwinPlistPath() {
11077
- return join9(homedir6(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`);
10936
+ return join8(homedir5(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`);
11078
10937
  }
11079
10938
  function installDarwin(args) {
11080
10939
  const plist = darwinPlistPath();
@@ -11108,11 +10967,11 @@ function installDarwin(args) {
11108
10967
  <key>StandardErrorPath</key>
11109
10968
  <string>${escapeXml(log2)}</string>
11110
10969
  <key>WorkingDirectory</key>
11111
- <string>${escapeXml(homedir6())}</string>
10970
+ <string>${escapeXml(homedir5())}</string>
11112
10971
  <key>EnvironmentVariables</key>
11113
10972
  <dict>
11114
10973
  <key>HOME</key>
11115
- <string>${escapeXml(homedir6())}</string>
10974
+ <string>${escapeXml(homedir5())}</string>
11116
10975
  <key>PATH</key>
11117
10976
  <string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
11118
10977
  </dict>
@@ -11127,7 +10986,7 @@ function installDarwin(args) {
11127
10986
  };
11128
10987
  }
11129
10988
  function linuxUnitPath() {
11130
- return join9(homedir6(), ".config", "systemd", "user", SYSTEMD_UNIT);
10989
+ return join8(homedir5(), ".config", "systemd", "user", SYSTEMD_UNIT);
11131
10990
  }
11132
10991
  function installLinux(args) {
11133
10992
  const unit = linuxUnitPath();
@@ -11176,7 +11035,7 @@ function readInstalledUnit() {
11176
11035
  if (!platform5)
11177
11036
  return { platform: null, path: null, content: null };
11178
11037
  const path2 = platform5 === "darwin" ? darwinPlistPath() : linuxUnitPath();
11179
- if (!existsSync12(path2))
11038
+ if (!existsSync11(path2))
11180
11039
  return { platform: platform5, path: null, content: null };
11181
11040
  try {
11182
11041
  return { platform: platform5, path: path2, content: readFileSync10(path2, "utf8") };
@@ -11521,17 +11380,17 @@ __export(exports_install, {
11521
11380
  import {
11522
11381
  chmodSync as chmodSync4,
11523
11382
  copyFileSync,
11524
- existsSync as existsSync13,
11383
+ existsSync as existsSync12,
11525
11384
  mkdirSync as mkdirSync8,
11526
11385
  readFileSync as readFileSync11,
11527
11386
  writeFileSync as writeFileSync11
11528
11387
  } from "node:fs";
11529
- import { homedir as homedir7, platform as platform5 } from "node:os";
11530
- import { dirname as dirname6, join as join10, resolve } from "node:path";
11388
+ import { homedir as homedir6, platform as platform5 } from "node:os";
11389
+ import { dirname as dirname6, join as join9, resolve } from "node:path";
11531
11390
  import { fileURLToPath } from "node:url";
11532
11391
  import { spawnSync as spawnSync3 } from "node:child_process";
11533
11392
  function readClaudeConfig() {
11534
- if (!existsSync13(CLAUDE_CONFIG))
11393
+ if (!existsSync12(CLAUDE_CONFIG))
11535
11394
  return {};
11536
11395
  const text = readFileSync11(CLAUDE_CONFIG, "utf-8").trim();
11537
11396
  if (!text)
@@ -11543,12 +11402,12 @@ function readClaudeConfig() {
11543
11402
  }
11544
11403
  }
11545
11404
  function backupClaudeConfig() {
11546
- if (!existsSync13(CLAUDE_CONFIG))
11405
+ if (!existsSync12(CLAUDE_CONFIG))
11547
11406
  return;
11548
- const backupDir = join10(dirname6(CLAUDE_CONFIG), ".claude", "backups");
11407
+ const backupDir = join9(dirname6(CLAUDE_CONFIG), ".claude", "backups");
11549
11408
  mkdirSync8(backupDir, { recursive: true });
11550
11409
  const ts = Date.now();
11551
- const dest = join10(backupDir, `.claude.json.pre-claudemesh.${ts}`);
11410
+ const dest = join9(backupDir, `.claude.json.pre-claudemesh.${ts}`);
11552
11411
  copyFileSync(CLAUDE_CONFIG, dest);
11553
11412
  }
11554
11413
  function patchMcpServer(entry) {
@@ -11572,7 +11431,7 @@ function patchMcpServer(entry) {
11572
11431
  return action;
11573
11432
  }
11574
11433
  function removeMcpServer() {
11575
- if (!existsSync13(CLAUDE_CONFIG))
11434
+ if (!existsSync12(CLAUDE_CONFIG))
11576
11435
  return false;
11577
11436
  backupClaudeConfig();
11578
11437
  const cfg = readClaudeConfig();
@@ -11608,8 +11467,8 @@ function resolveEntry() {
11608
11467
  function resolveBundledSkillsDir() {
11609
11468
  const here = fileURLToPath(import.meta.url);
11610
11469
  const pkgRoot = resolve(dirname6(here), "..", "..");
11611
- const skillsDir = join10(pkgRoot, "skills");
11612
- if (existsSync13(skillsDir))
11470
+ const skillsDir = join9(pkgRoot, "skills");
11471
+ if (existsSync12(skillsDir))
11613
11472
  return skillsDir;
11614
11473
  return null;
11615
11474
  }
@@ -11622,13 +11481,13 @@ function installSkills() {
11622
11481
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
11623
11482
  if (!entry.isDirectory())
11624
11483
  continue;
11625
- const srcDir = join10(src, entry.name);
11626
- const dstDir = join10(CLAUDE_SKILLS_ROOT, entry.name);
11484
+ const srcDir = join9(src, entry.name);
11485
+ const dstDir = join9(CLAUDE_SKILLS_ROOT, entry.name);
11627
11486
  mkdirSync8(dstDir, { recursive: true });
11628
11487
  for (const file of fs.readdirSync(srcDir, { withFileTypes: true })) {
11629
11488
  if (!file.isFile())
11630
11489
  continue;
11631
- copyFileSync(join10(srcDir, file.name), join10(dstDir, file.name));
11490
+ copyFileSync(join9(srcDir, file.name), join9(dstDir, file.name));
11632
11491
  }
11633
11492
  installed.push(entry.name);
11634
11493
  }
@@ -11643,8 +11502,8 @@ function uninstallSkills() {
11643
11502
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
11644
11503
  if (!entry.isDirectory())
11645
11504
  continue;
11646
- const dstDir = join10(CLAUDE_SKILLS_ROOT, entry.name);
11647
- if (existsSync13(dstDir)) {
11505
+ const dstDir = join9(CLAUDE_SKILLS_ROOT, entry.name);
11506
+ if (existsSync12(dstDir)) {
11648
11507
  try {
11649
11508
  fs.rmSync(dstDir, { recursive: true, force: true });
11650
11509
  removed.push(entry.name);
@@ -11669,7 +11528,7 @@ function entriesEqual(a, b) {
11669
11528
  return a.command === b.command && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
11670
11529
  }
11671
11530
  function readClaudeSettings() {
11672
- if (!existsSync13(CLAUDE_SETTINGS))
11531
+ if (!existsSync12(CLAUDE_SETTINGS))
11673
11532
  return {};
11674
11533
  const text = readFileSync11(CLAUDE_SETTINGS, "utf-8").trim();
11675
11534
  if (!text)
@@ -11696,7 +11555,7 @@ function installAllowedTools() {
11696
11555
  return { added: toAdd, unchanged: CLAUDEMESH_TOOLS.length - toAdd.length };
11697
11556
  }
11698
11557
  function uninstallAllowedTools() {
11699
- if (!existsSync13(CLAUDE_SETTINGS))
11558
+ if (!existsSync12(CLAUDE_SETTINGS))
11700
11559
  return 0;
11701
11560
  const settings = readClaudeSettings();
11702
11561
  const existing = settings.allowedTools ?? [];
@@ -11731,7 +11590,7 @@ function installHooks() {
11731
11590
  return { added, unchanged };
11732
11591
  }
11733
11592
  function uninstallHooks() {
11734
- if (!existsSync13(CLAUDE_SETTINGS))
11593
+ if (!existsSync12(CLAUDE_SETTINGS))
11735
11594
  return 0;
11736
11595
  const settings = readClaudeSettings();
11737
11596
  const hooks = settings.hooks;
@@ -11781,7 +11640,7 @@ function runInstall(args = []) {
11781
11640
  render.err("`bun` is not on PATH.", "Install Bun first: https://bun.com");
11782
11641
  process.exit(1);
11783
11642
  }
11784
- if (!existsSync13(entry)) {
11643
+ if (!existsSync12(entry)) {
11785
11644
  render.err(`MCP entry not found at ${entry}`);
11786
11645
  process.exit(1);
11787
11646
  }
@@ -11832,7 +11691,7 @@ function runInstall(args = []) {
11832
11691
  const installed = installSkills();
11833
11692
  if (installed.length > 0) {
11834
11693
  render.ok(`Claude skill${installed.length === 1 ? "" : "s"} installed`, installed.join(", "));
11835
- render.info(dim(` ${join10(CLAUDE_SKILLS_ROOT, installed[0])}/SKILL.md`));
11694
+ render.info(dim(` ${join9(CLAUDE_SKILLS_ROOT, installed[0])}/SKILL.md`));
11836
11695
  }
11837
11696
  } catch (e) {
11838
11697
  render.warn(`skill install failed: ${e instanceof Error ? e.message : String(e)}`);
@@ -11969,9 +11828,9 @@ var init_install = __esm(() => {
11969
11828
  init_facade();
11970
11829
  init_render();
11971
11830
  init_styles();
11972
- CLAUDE_CONFIG = join10(homedir7(), ".claude.json");
11973
- CLAUDE_SETTINGS = join10(homedir7(), ".claude", "settings.json");
11974
- CLAUDE_SKILLS_ROOT = join10(homedir7(), ".claude", "skills");
11831
+ CLAUDE_CONFIG = join9(homedir6(), ".claude.json");
11832
+ CLAUDE_SETTINGS = join9(homedir6(), ".claude", "settings.json");
11833
+ CLAUDE_SKILLS_ROOT = join9(homedir6(), ".claude", "skills");
11975
11834
  CLAUDEMESH_TOOLS = [
11976
11835
  "mcp__claudemesh__cancel_scheduled",
11977
11836
  "mcp__claudemesh__check_messages",
@@ -12026,19 +11885,19 @@ var exports_uninstall = {};
12026
11885
  __export(exports_uninstall, {
12027
11886
  uninstall: () => uninstall
12028
11887
  });
12029
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync12, existsSync as existsSync14, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
12030
- import { join as join11, dirname as dirname7 } from "node:path";
12031
- import { homedir as homedir8 } from "node:os";
11888
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync12, existsSync as existsSync13, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
11889
+ import { join as join10, dirname as dirname7 } from "node:path";
11890
+ import { homedir as homedir7 } from "node:os";
12032
11891
  import { fileURLToPath as fileURLToPath2 } from "node:url";
12033
11892
  function bundledSkillsDir() {
12034
11893
  const here = fileURLToPath2(import.meta.url);
12035
- const pkgRoot = join11(dirname7(here), "..", "..");
12036
- const skillsDir = join11(pkgRoot, "skills");
12037
- return existsSync14(skillsDir) ? skillsDir : null;
11894
+ const pkgRoot = join10(dirname7(here), "..", "..");
11895
+ const skillsDir = join10(pkgRoot, "skills");
11896
+ return existsSync13(skillsDir) ? skillsDir : null;
12038
11897
  }
12039
11898
  async function uninstall() {
12040
11899
  let removed = 0;
12041
- if (existsSync14(PATHS.CLAUDE_JSON)) {
11900
+ if (existsSync13(PATHS.CLAUDE_JSON)) {
12042
11901
  try {
12043
11902
  const raw = readFileSync12(PATHS.CLAUDE_JSON, "utf-8");
12044
11903
  const config = JSON.parse(raw);
@@ -12052,7 +11911,7 @@ async function uninstall() {
12052
11911
  }
12053
11912
  } catch {}
12054
11913
  }
12055
- if (existsSync14(PATHS.CLAUDE_SETTINGS)) {
11914
+ if (existsSync13(PATHS.CLAUDE_SETTINGS)) {
12056
11915
  try {
12057
11916
  const raw = readFileSync12(PATHS.CLAUDE_SETTINGS, "utf-8");
12058
11917
  const config = JSON.parse(raw);
@@ -12090,8 +11949,8 @@ async function uninstall() {
12090
11949
  for (const entry of readdirSync2(src, { withFileTypes: true })) {
12091
11950
  if (!entry.isDirectory())
12092
11951
  continue;
12093
- const dst = join11(CLAUDE_SKILLS_ROOT2, entry.name);
12094
- if (existsSync14(dst)) {
11952
+ const dst = join10(CLAUDE_SKILLS_ROOT2, entry.name);
11953
+ if (existsSync13(dst)) {
12095
11954
  try {
12096
11955
  rmSync2(dst, { recursive: true, force: true });
12097
11956
  removedSkills.push(entry.name);
@@ -12115,7 +11974,7 @@ var init_uninstall = __esm(() => {
12115
11974
  init_render();
12116
11975
  init_styles();
12117
11976
  init_exit_codes();
12118
- CLAUDE_SKILLS_ROOT2 = join11(homedir8(), ".claude", "skills");
11977
+ CLAUDE_SKILLS_ROOT2 = join10(homedir7(), ".claude", "skills");
12119
11978
  });
12120
11979
 
12121
11980
  // src/commands/doctor.ts
@@ -12123,9 +11982,9 @@ var exports_doctor = {};
12123
11982
  __export(exports_doctor, {
12124
11983
  runDoctor: () => runDoctor
12125
11984
  });
12126
- import { existsSync as existsSync15, readFileSync as readFileSync13, statSync as statSync3 } from "node:fs";
12127
- import { homedir as homedir9, platform as platform6 } from "node:os";
12128
- import { join as join12 } from "node:path";
11985
+ import { existsSync as existsSync14, readFileSync as readFileSync13, statSync as statSync3 } from "node:fs";
11986
+ import { homedir as homedir8, platform as platform6 } from "node:os";
11987
+ import { join as join11 } from "node:path";
12129
11988
  import { spawnSync as spawnSync4 } from "node:child_process";
12130
11989
  function checkNode() {
12131
11990
  const major = Number(process.versions.node.split(".")[0]);
@@ -12149,8 +12008,8 @@ function checkClaudeOnPath() {
12149
12008
  };
12150
12009
  }
12151
12010
  function checkMcpRegistered() {
12152
- const claudeConfig = join12(homedir9(), ".claude.json");
12153
- if (!existsSync15(claudeConfig)) {
12011
+ const claudeConfig = join11(homedir8(), ".claude.json");
12012
+ if (!existsSync14(claudeConfig)) {
12154
12013
  return {
12155
12014
  name: "claudemesh MCP registered in ~/.claude.json",
12156
12015
  pass: false,
@@ -12175,8 +12034,8 @@ function checkMcpRegistered() {
12175
12034
  }
12176
12035
  }
12177
12036
  function checkHooksRegistered() {
12178
- const settings = join12(homedir9(), ".claude", "settings.json");
12179
- if (!existsSync15(settings)) {
12037
+ const settings = join11(homedir8(), ".claude", "settings.json");
12038
+ if (!existsSync14(settings)) {
12180
12039
  return {
12181
12040
  name: "Status hooks registered in ~/.claude/settings.json",
12182
12041
  pass: false,
@@ -12201,7 +12060,7 @@ function checkHooksRegistered() {
12201
12060
  }
12202
12061
  function checkConfigFile() {
12203
12062
  const path2 = getConfigPath();
12204
- if (!existsSync15(path2)) {
12063
+ if (!existsSync14(path2)) {
12205
12064
  return {
12206
12065
  name: "~/.claudemesh/config.json exists and parses",
12207
12066
  pass: true,
@@ -12384,7 +12243,7 @@ var exports_status = {};
12384
12243
  __export(exports_status, {
12385
12244
  runStatus: () => runStatus2
12386
12245
  });
12387
- import { statSync as statSync4, existsSync as existsSync16 } from "node:fs";
12246
+ import { statSync as statSync4, existsSync as existsSync15 } from "node:fs";
12388
12247
  import WebSocket3 from "ws";
12389
12248
  async function probeBroker(url, timeoutMs = 4000) {
12390
12249
  return new Promise((resolve2) => {
@@ -12414,7 +12273,7 @@ async function runStatus2() {
12414
12273
  render.section(`status (v${VERSION})`);
12415
12274
  const configPath = getConfigPath();
12416
12275
  let configPermsNote = "missing";
12417
- if (existsSync16(configPath)) {
12276
+ if (existsSync15(configPath)) {
12418
12277
  const mode = (statSync4(configPath).mode & 511).toString(8).padStart(4, "0");
12419
12278
  configPermsNote = mode === "0600" ? `${mode}` : `${mode} — expected 0600`;
12420
12279
  }
@@ -12560,10 +12419,10 @@ var init_check_claude_binary = __esm(() => {
12560
12419
  });
12561
12420
 
12562
12421
  // src/services/health/check-mcp-registered.ts
12563
- import { existsSync as existsSync17, readFileSync as readFileSync14 } from "node:fs";
12422
+ import { existsSync as existsSync16, readFileSync as readFileSync14 } from "node:fs";
12564
12423
  function checkMcpRegistered2() {
12565
12424
  try {
12566
- if (!existsSync17(PATHS.CLAUDE_JSON)) {
12425
+ if (!existsSync16(PATHS.CLAUDE_JSON)) {
12567
12426
  return { name: "mcp-registered", ok: false, message: "~/.claude.json not found" };
12568
12427
  }
12569
12428
  const raw = readFileSync14(PATHS.CLAUDE_JSON, "utf-8");
@@ -12581,10 +12440,10 @@ var init_check_mcp_registered = __esm(() => {
12581
12440
  });
12582
12441
 
12583
12442
  // src/services/health/check-hooks-registered.ts
12584
- import { existsSync as existsSync18, readFileSync as readFileSync15 } from "node:fs";
12443
+ import { existsSync as existsSync17, readFileSync as readFileSync15 } from "node:fs";
12585
12444
  function checkHooksRegistered2() {
12586
12445
  try {
12587
- if (!existsSync18(PATHS.CLAUDE_SETTINGS)) {
12446
+ if (!existsSync17(PATHS.CLAUDE_SETTINGS)) {
12588
12447
  return { name: "hooks-registered", ok: false, message: "~/.claude/settings.json not found" };
12589
12448
  }
12590
12449
  const raw = readFileSync15(PATHS.CLAUDE_SETTINGS, "utf-8");
@@ -12602,10 +12461,10 @@ var init_check_hooks_registered = __esm(() => {
12602
12461
  });
12603
12462
 
12604
12463
  // src/services/health/check-config-perms.ts
12605
- import { existsSync as existsSync19, statSync as statSync5 } from "node:fs";
12464
+ import { existsSync as existsSync18, statSync as statSync5 } from "node:fs";
12606
12465
  function checkConfigPerms() {
12607
12466
  const configFile = PATHS.CONFIG_FILE;
12608
- if (!existsSync19(configFile)) {
12467
+ if (!existsSync18(configFile)) {
12609
12468
  return { name: "config-perms", ok: true, message: "No config file yet (first run)" };
12610
12469
  }
12611
12470
  try {
@@ -12623,9 +12482,9 @@ var init_check_config_perms = __esm(() => {
12623
12482
  });
12624
12483
 
12625
12484
  // src/services/health/check-keypairs-valid.ts
12626
- import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
12485
+ import { existsSync as existsSync19, readFileSync as readFileSync16 } from "node:fs";
12627
12486
  function checkKeypairsValid() {
12628
- if (!existsSync20(PATHS.CONFIG_FILE)) {
12487
+ if (!existsSync19(PATHS.CONFIG_FILE)) {
12629
12488
  return { name: "keypairs-valid", ok: true, message: "No config (first run)" };
12630
12489
  }
12631
12490
  try {
@@ -13109,18 +12968,18 @@ var exports_url_handler = {};
13109
12968
  __export(exports_url_handler, {
13110
12969
  runUrlHandler: () => runUrlHandler
13111
12970
  });
13112
- import { platform as platform7, homedir as homedir10 } from "node:os";
13113
- import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync13, rmSync as rmSync3, chmodSync as chmodSync5 } from "node:fs";
13114
- import { join as join13 } from "node:path";
12971
+ import { platform as platform7, homedir as homedir9 } from "node:os";
12972
+ import { existsSync as existsSync20, mkdirSync as mkdirSync9, writeFileSync as writeFileSync13, rmSync as rmSync3, chmodSync as chmodSync5 } from "node:fs";
12973
+ import { join as join12 } from "node:path";
13115
12974
  import { spawnSync as spawnSync5 } from "node:child_process";
13116
12975
  function resolveClaudemeshBin() {
13117
12976
  return process.argv[1] ?? "claudemesh";
13118
12977
  }
13119
12978
  function installDarwin2() {
13120
12979
  const binPath = resolveClaudemeshBin();
13121
- const appDir = join13(homedir10(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
13122
- const contents = join13(appDir, "Contents");
13123
- const macOS = join13(contents, "MacOS");
12980
+ const appDir = join12(homedir9(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
12981
+ const contents = join12(appDir, "Contents");
12982
+ const macOS = join12(contents, "MacOS");
13124
12983
  mkdirSync9(macOS, { recursive: true });
13125
12984
  const plist = `<?xml version="1.0" encoding="UTF-8"?>
13126
12985
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -13144,7 +13003,7 @@ function installDarwin2() {
13144
13003
  </array>
13145
13004
  </dict>
13146
13005
  </plist>`;
13147
- writeFileSync13(join13(contents, "Info.plist"), plist);
13006
+ writeFileSync13(join12(contents, "Info.plist"), plist);
13148
13007
  const shim = `#!/bin/sh
13149
13008
  URL="$1"
13150
13009
  CODE=\${URL#claudemesh://}
@@ -13158,7 +13017,7 @@ tell application "Terminal"
13158
13017
  end tell
13159
13018
  EOF
13160
13019
  `;
13161
- const shimPath = join13(macOS, "open-url");
13020
+ const shimPath = join12(macOS, "open-url");
13162
13021
  writeFileSync13(shimPath, shim);
13163
13022
  chmodSync5(shimPath, 493);
13164
13023
  const lsreg = spawnSync5("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister", ["-f", appDir], { encoding: "utf-8" });
@@ -13170,7 +13029,7 @@ EOF
13170
13029
  }
13171
13030
  function installLinux2() {
13172
13031
  const binPath = resolveClaudemeshBin();
13173
- const appsDir = join13(homedir10(), ".local", "share", "applications");
13032
+ const appsDir = join12(homedir9(), ".local", "share", "applications");
13174
13033
  mkdirSync9(appsDir, { recursive: true });
13175
13034
  const desktop = `[Desktop Entry]
13176
13035
  Type=Application
@@ -13182,7 +13041,7 @@ Terminal=true
13182
13041
  MimeType=x-scheme-handler/claudemesh;
13183
13042
  NoDisplay=true
13184
13043
  `;
13185
- const desktopPath = join13(appsDir, "claudemesh.desktop");
13044
+ const desktopPath = join12(appsDir, "claudemesh.desktop");
13186
13045
  writeFileSync13(desktopPath, desktop);
13187
13046
  const xdg1 = spawnSync5("xdg-mime", ["default", "claudemesh.desktop", "x-scheme-handler/claudemesh"], { encoding: "utf-8" });
13188
13047
  if (xdg1.status !== 0) {
@@ -13205,7 +13064,7 @@ function installWindows() {
13205
13064
  `[HKEY_CURRENT_USER\\Software\\Classes\\claudemesh\\shell\\open\\command]`,
13206
13065
  `@="\\"${binPath.replace(/\\/g, "\\\\")}\\" \\"%1\\""`
13207
13066
  ];
13208
- const regPath = join13(homedir10(), "claudemesh-handler.reg");
13067
+ const regPath = join12(homedir9(), "claudemesh-handler.reg");
13209
13068
  writeFileSync13(regPath, lines.join(`\r
13210
13069
  `));
13211
13070
  const res = spawnSync5("reg.exe", ["import", regPath], { encoding: "utf-8" });
@@ -13217,15 +13076,15 @@ function installWindows() {
13217
13076
  return EXIT.SUCCESS;
13218
13077
  }
13219
13078
  function uninstallDarwin() {
13220
- const appDir = join13(homedir10(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
13221
- if (existsSync21(appDir))
13079
+ const appDir = join12(homedir9(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
13080
+ if (existsSync20(appDir))
13222
13081
  rmSync3(appDir, { recursive: true, force: true });
13223
13082
  render.ok("removed claudemesh:// handler on macOS");
13224
13083
  return EXIT.SUCCESS;
13225
13084
  }
13226
13085
  function uninstallLinux() {
13227
- const desktopPath = join13(homedir10(), ".local", "share", "applications", "claudemesh.desktop");
13228
- if (existsSync21(desktopPath))
13086
+ const desktopPath = join12(homedir9(), ".local", "share", "applications", "claudemesh.desktop");
13087
+ if (existsSync20(desktopPath))
13229
13088
  rmSync3(desktopPath, { force: true });
13230
13089
  render.ok("removed claudemesh:// handler on Linux");
13231
13090
  return EXIT.SUCCESS;
@@ -13270,9 +13129,9 @@ var exports_status_line = {};
13270
13129
  __export(exports_status_line, {
13271
13130
  runStatusLine: () => runStatusLine
13272
13131
  });
13273
- import { existsSync as existsSync22, readFileSync as readFileSync17 } from "node:fs";
13274
- import { join as join14 } from "node:path";
13275
- import { homedir as homedir11 } from "node:os";
13132
+ import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
13133
+ import { join as join13 } from "node:path";
13134
+ import { homedir as homedir10 } from "node:os";
13276
13135
  async function runStatusLine() {
13277
13136
  try {
13278
13137
  const config = readConfig();
@@ -13280,9 +13139,9 @@ async function runStatusLine() {
13280
13139
  process.stdout.write("◇ claudemesh (not joined)");
13281
13140
  return EXIT.SUCCESS;
13282
13141
  }
13283
- const cachePath = join14(homedir11(), ".claudemesh", "peer-cache.json");
13142
+ const cachePath = join13(homedir10(), ".claudemesh", "peer-cache.json");
13284
13143
  let cache = {};
13285
- if (existsSync22(cachePath)) {
13144
+ if (existsSync21(cachePath)) {
13286
13145
  try {
13287
13146
  cache = JSON.parse(readFileSync17(cachePath, "utf-8"));
13288
13147
  } catch {}
@@ -13315,7 +13174,7 @@ __export(exports_backup, {
13315
13174
  runRestore: () => runRestore,
13316
13175
  runBackup: () => runBackup
13317
13176
  });
13318
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync14, existsSync as existsSync23 } from "node:fs";
13177
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync14, existsSync as existsSync22 } from "node:fs";
13319
13178
  import { createInterface as createInterface11 } from "node:readline";
13320
13179
  function readHidden(prompt5) {
13321
13180
  return new Promise((resolve2) => {
@@ -13357,7 +13216,7 @@ async function deriveKey(pass, salt, s) {
13357
13216
  }
13358
13217
  async function runBackup(outPath) {
13359
13218
  const configPath = getConfigPath();
13360
- if (!existsSync23(configPath)) {
13219
+ if (!existsSync22(configPath)) {
13361
13220
  console.error(" No config found — nothing to back up. Join a mesh first.");
13362
13221
  return EXIT.NOT_FOUND;
13363
13222
  }
@@ -13391,7 +13250,7 @@ async function runRestore(inPath) {
13391
13250
  console.error(" Usage: claudemesh restore <backup-file>");
13392
13251
  return EXIT.INVALID_ARGS;
13393
13252
  }
13394
- if (!existsSync23(inPath)) {
13253
+ if (!existsSync22(inPath)) {
13395
13254
  console.error(` ✗ File not found: ${inPath}`);
13396
13255
  return EXIT.NOT_FOUND;
13397
13256
  }
@@ -13414,7 +13273,7 @@ async function runRestore(inPath) {
13414
13273
  return EXIT.INTERNAL_ERROR;
13415
13274
  }
13416
13275
  const configPath = getConfigPath();
13417
- if (existsSync23(configPath)) {
13276
+ if (existsSync22(configPath)) {
13418
13277
  const backupOld = `${configPath}.before-restore.${Date.now()}`;
13419
13278
  writeFileSync14(backupOld, readFileSync18(configPath), { mode: 384 });
13420
13279
  console.log(` ↻ Existing config saved to ${backupOld}`);
@@ -13439,8 +13298,8 @@ __export(exports_upgrade, {
13439
13298
  runUpgrade: () => runUpgrade
13440
13299
  });
13441
13300
  import { spawnSync as spawnSync6 } from "node:child_process";
13442
- import { existsSync as existsSync24 } from "node:fs";
13443
- import { dirname as dirname8, join as join15, resolve as resolve2 } from "node:path";
13301
+ import { existsSync as existsSync23 } from "node:fs";
13302
+ import { dirname as dirname8, join as join14, resolve as resolve2 } from "node:path";
13444
13303
  async function latestVersion() {
13445
13304
  try {
13446
13305
  const res = await fetch(URLS.NPM_REGISTRY, { signal: AbortSignal.timeout(8000) });
@@ -13453,15 +13312,15 @@ async function latestVersion() {
13453
13312
  }
13454
13313
  }
13455
13314
  function findNpm() {
13456
- const portable = join15(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
13457
- if (existsSync24(portable)) {
13458
- return { npm: portable, prefix: join15(process.env.HOME ?? "", ".claudemesh") };
13315
+ const portable = join14(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
13316
+ if (existsSync23(portable)) {
13317
+ return { npm: portable, prefix: join14(process.env.HOME ?? "", ".claudemesh") };
13459
13318
  }
13460
13319
  let cur = resolve2(process.argv[1] ?? ".");
13461
13320
  for (let i = 0;i < 6; i++) {
13462
13321
  cur = dirname8(cur);
13463
- const candidate = join15(cur, "bin", "npm");
13464
- if (existsSync24(candidate))
13322
+ const candidate = join14(cur, "bin", "npm");
13323
+ if (existsSync23(candidate))
13465
13324
  return { npm: candidate };
13466
13325
  }
13467
13326
  return { npm: "npm" };
@@ -13523,9 +13382,9 @@ __export(exports_grants, {
13523
13382
  runBlock: () => runBlock,
13524
13383
  isAllowed: () => isAllowed
13525
13384
  });
13526
- import { existsSync as existsSync25, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
13527
- import { homedir as homedir12 } from "node:os";
13528
- import { join as join16 } from "node:path";
13385
+ import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
13386
+ import { homedir as homedir11 } from "node:os";
13387
+ import { join as join15 } from "node:path";
13529
13388
  async function syncToBroker(meshSlug, grants) {
13530
13389
  const auth = getStoredToken();
13531
13390
  if (!auth)
@@ -13543,7 +13402,7 @@ async function syncToBroker(meshSlug, grants) {
13543
13402
  }
13544
13403
  }
13545
13404
  function readGrants() {
13546
- if (!existsSync25(GRANT_FILE))
13405
+ if (!existsSync24(GRANT_FILE))
13547
13406
  return {};
13548
13407
  try {
13549
13408
  return JSON.parse(readFileSync19(GRANT_FILE, "utf-8"));
@@ -13552,8 +13411,8 @@ function readGrants() {
13552
13411
  }
13553
13412
  }
13554
13413
  function writeGrants(g) {
13555
- const dir = join16(homedir12(), ".claudemesh");
13556
- if (!existsSync25(dir))
13414
+ const dir = join15(homedir11(), ".claudemesh");
13415
+ if (!existsSync24(dir))
13557
13416
  mkdirSync10(dir, { recursive: true });
13558
13417
  writeFileSync15(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
13559
13418
  }
@@ -13711,7 +13570,7 @@ var init_grants = __esm(() => {
13711
13570
  BROKER_HTTP7 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
13712
13571
  ALL_CAPS = ["read", "dm", "broadcast", "state-read", "state-write", "file-read"];
13713
13572
  DEFAULT_CAPS = ["read", "dm", "broadcast", "state-read"];
13714
- GRANT_FILE = join16(homedir12(), ".claudemesh", "grants.json");
13573
+ GRANT_FILE = join15(homedir11(), ".claudemesh", "grants.json");
13715
13574
  });
13716
13575
 
13717
13576
  // src/commands/profile.ts
@@ -15393,7 +15252,7 @@ __export(exports_file, {
15393
15252
  });
15394
15253
  import { hostname as osHostname } from "node:os";
15395
15254
  import { resolve as resolvePath, basename, dirname as dirname9 } from "node:path";
15396
- import { statSync as statSync7, existsSync as existsSync26, writeFileSync as writeFileSync16, mkdirSync as mkdirSync11 } from "node:fs";
15255
+ import { statSync as statSync7, existsSync as existsSync25, writeFileSync as writeFileSync16, mkdirSync as mkdirSync11 } from "node:fs";
15397
15256
  function emitJson2(data) {
15398
15257
  console.log(JSON.stringify(data, null, 2));
15399
15258
  }
@@ -15410,7 +15269,7 @@ async function runFileShare(filePath, opts) {
15410
15269
  return EXIT.INVALID_ARGS;
15411
15270
  }
15412
15271
  const absPath = resolvePath(filePath);
15413
- if (!existsSync26(absPath)) {
15272
+ if (!existsSync25(absPath)) {
15414
15273
  render.err(`File not found: ${absPath}`);
15415
15274
  return EXIT.INVALID_ARGS;
15416
15275
  }
@@ -16100,7 +15959,7 @@ __export(exports_bridge, {
16100
15959
  runBridge: () => runBridge,
16101
15960
  bridgeConfigTemplate: () => bridgeConfigTemplate
16102
15961
  });
16103
- import { readFileSync as readFileSync20, existsSync as existsSync27 } from "node:fs";
15962
+ import { readFileSync as readFileSync20, existsSync as existsSync26 } from "node:fs";
16104
15963
  function parseConfig(text) {
16105
15964
  const trimmed = text.trim();
16106
15965
  if (trimmed.startsWith("{"))
@@ -16144,7 +16003,7 @@ async function runBridge(configPath) {
16144
16003
  render.err("Usage: claudemesh bridge run <config.yaml>");
16145
16004
  return EXIT.INVALID_ARGS;
16146
16005
  }
16147
- if (!existsSync27(configPath)) {
16006
+ if (!existsSync26(configPath)) {
16148
16007
  render.err(`config file not found: ${configPath}`);
16149
16008
  return EXIT.NOT_FOUND;
16150
16009
  }
@@ -17124,11 +16983,11 @@ import {
17124
16983
  ListResourcesRequestSchema,
17125
16984
  ReadResourceRequestSchema
17126
16985
  } from "@modelcontextprotocol/sdk/types.js";
17127
- import { existsSync as existsSync28 } from "node:fs";
16986
+ import { existsSync as existsSync27 } from "node:fs";
17128
16987
  import { request as httpRequest2 } from "node:http";
17129
16988
  async function daemonReady() {
17130
16989
  for (let i = 0;i < DAEMON_BOOT_RETRIES; i++) {
17131
- if (existsSync28(DAEMON_PATHS.SOCK_FILE))
16990
+ if (existsSync27(DAEMON_PATHS.SOCK_FILE))
17132
16991
  return true;
17133
16992
  await new Promise((r) => setTimeout(r, DAEMON_BOOT_RETRY_MS));
17134
16993
  }
@@ -18205,10 +18064,12 @@ async function gate(ctx, opts) {
18205
18064
  }
18206
18065
 
18207
18066
  // src/entrypoints/cli.ts
18067
+ init_policy();
18208
18068
  init_styles();
18209
18069
  installSignalHandlers();
18210
18070
  installErrorHandlers();
18211
18071
  var { command, positionals, flags } = parseArgv(process.argv);
18072
+ setDaemonPolicy(policyFromFlags(flags));
18212
18073
  function resolveApprovalMode() {
18213
18074
  const raw = flags["approval-mode"] ?? process.env.CLAUDEMESH_APPROVAL_MODE ?? null;
18214
18075
  if (raw === "plan" || raw === "read-only" || raw === "write" || raw === "yolo")
@@ -18385,6 +18246,8 @@ Flags
18385
18246
  --policy <path> override policy file
18386
18247
  -y, --yes skip confirmations (= --approval-mode yolo)
18387
18248
  -q, --quiet suppress non-essential output
18249
+ --strict require daemon for broker-touching verbs (no cold-path fallback)
18250
+ --no-daemon skip daemon entirely; open broker WS directly (CI / sandboxed scripts)
18388
18251
  `;
18389
18252
  function colorizeHelp(raw) {
18390
18253
  const lines = raw.split(`
@@ -19426,4 +19289,4 @@ main().catch((err) => {
19426
19289
  process.exit(EXIT.INTERNAL_ERROR);
19427
19290
  });
19428
19291
 
19429
- //# debugId=1F2A51E3A3AE432A64756E2164756E21
19292
+ //# debugId=04E4A5313AE4F0EA64756E2164756E21