claudemesh-cli 1.1.0 → 1.2.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.
@@ -3337,6 +3337,197 @@ var init_facade3 = __esm(() => {
3337
3337
  init_errors();
3338
3338
  });
3339
3339
 
3340
+ // src/services/bridge/protocol.ts
3341
+ import { homedir as homedir2 } from "node:os";
3342
+ import { join as join2 } from "node:path";
3343
+ function socketPath(meshSlug) {
3344
+ return join2(homedir2(), ".claudemesh", "sockets", `${meshSlug}.sock`);
3345
+ }
3346
+ function socketDir() {
3347
+ return join2(homedir2(), ".claudemesh", "sockets");
3348
+ }
3349
+ function frame(obj) {
3350
+ return JSON.stringify(obj) + `
3351
+ `;
3352
+ }
3353
+
3354
+ class LineParser {
3355
+ buf = "";
3356
+ feed(chunk) {
3357
+ this.buf += typeof chunk === "string" ? chunk : chunk.toString("utf-8");
3358
+ const lines = [];
3359
+ let nl = this.buf.indexOf(`
3360
+ `);
3361
+ while (nl !== -1) {
3362
+ lines.push(this.buf.slice(0, nl));
3363
+ this.buf = this.buf.slice(nl + 1);
3364
+ nl = this.buf.indexOf(`
3365
+ `);
3366
+ }
3367
+ return lines;
3368
+ }
3369
+ }
3370
+ var init_protocol = () => {};
3371
+
3372
+ // src/services/bridge/server.ts
3373
+ import { createServer } from "node:net";
3374
+ import { mkdirSync as mkdirSync2, unlinkSync, existsSync as existsSync2, chmodSync as chmodSync2 } from "node:fs";
3375
+ async function resolveTarget(client, to) {
3376
+ if (to.startsWith("@") || to === "*" || /^[0-9a-f]{64}$/i.test(to)) {
3377
+ return { ok: true, spec: to };
3378
+ }
3379
+ const peers = await client.listPeers();
3380
+ const match = peers.find((p) => p.displayName.toLowerCase() === to.toLowerCase());
3381
+ if (!match) {
3382
+ return {
3383
+ ok: false,
3384
+ error: `peer "${to}" not found. online: ${peers.map((p) => p.displayName).join(", ") || "(none)"}`
3385
+ };
3386
+ }
3387
+ return { ok: true, spec: match.pubkey };
3388
+ }
3389
+ async function dispatch(client, req) {
3390
+ const args = req.args ?? {};
3391
+ try {
3392
+ switch (req.verb) {
3393
+ case "ping": {
3394
+ const peers = await client.listPeers();
3395
+ return {
3396
+ id: req.id,
3397
+ ok: true,
3398
+ result: {
3399
+ mesh: client.meshSlug,
3400
+ ws_status: client.status,
3401
+ peers_online: peers.length,
3402
+ push_buffer: client.pushHistory.length
3403
+ }
3404
+ };
3405
+ }
3406
+ case "peers": {
3407
+ const peers = await client.listPeers();
3408
+ return { id: req.id, ok: true, result: peers };
3409
+ }
3410
+ case "send": {
3411
+ const to = String(args.to ?? "");
3412
+ const message = String(args.message ?? "");
3413
+ const priority = args.priority ?? "next";
3414
+ if (!to || !message) {
3415
+ return { id: req.id, ok: false, error: "send: `to` and `message` required" };
3416
+ }
3417
+ const resolved = await resolveTarget(client, to);
3418
+ if (!resolved.ok)
3419
+ return { id: req.id, ok: false, error: resolved.error };
3420
+ const result = await client.send(resolved.spec, message, priority);
3421
+ if (!result.ok) {
3422
+ return { id: req.id, ok: false, error: result.error ?? "send failed" };
3423
+ }
3424
+ return {
3425
+ id: req.id,
3426
+ ok: true,
3427
+ result: { messageId: result.messageId, target: resolved.spec }
3428
+ };
3429
+ }
3430
+ case "summary": {
3431
+ const text = String(args.summary ?? "");
3432
+ if (!text)
3433
+ return { id: req.id, ok: false, error: "summary: `summary` required" };
3434
+ await client.setSummary(text);
3435
+ return { id: req.id, ok: true, result: { summary: text } };
3436
+ }
3437
+ case "status_set": {
3438
+ const state = String(args.status ?? "");
3439
+ if (!["idle", "working", "dnd"].includes(state)) {
3440
+ return { id: req.id, ok: false, error: "status_set: must be idle | working | dnd" };
3441
+ }
3442
+ await client.setStatus(state);
3443
+ return { id: req.id, ok: true, result: { status: state } };
3444
+ }
3445
+ case "visible": {
3446
+ const visible = Boolean(args.visible);
3447
+ await client.setVisible(visible);
3448
+ return { id: req.id, ok: true, result: { visible } };
3449
+ }
3450
+ default:
3451
+ return { id: req.id, ok: false, error: `unknown verb: ${req.verb}` };
3452
+ }
3453
+ } catch (err) {
3454
+ return {
3455
+ id: req.id,
3456
+ ok: false,
3457
+ error: err instanceof Error ? err.message : String(err)
3458
+ };
3459
+ }
3460
+ }
3461
+ function handleConnection(socket, client) {
3462
+ const parser = new LineParser;
3463
+ socket.on("data", (chunk) => {
3464
+ const lines = parser.feed(chunk);
3465
+ for (const line of lines) {
3466
+ if (!line.trim())
3467
+ continue;
3468
+ let req;
3469
+ try {
3470
+ req = JSON.parse(line);
3471
+ } catch {
3472
+ continue;
3473
+ }
3474
+ if (!req || typeof req !== "object" || !req.id || !req.verb)
3475
+ continue;
3476
+ dispatch(client, req).then((res) => {
3477
+ try {
3478
+ socket.write(frame(res));
3479
+ } catch {}
3480
+ });
3481
+ }
3482
+ });
3483
+ socket.on("error", () => {});
3484
+ }
3485
+ function startBridgeServer(client) {
3486
+ const path = socketPath(client.meshSlug);
3487
+ const dir = socketDir();
3488
+ if (!existsSync2(dir)) {
3489
+ mkdirSync2(dir, { recursive: true, mode: 448 });
3490
+ }
3491
+ if (existsSync2(path)) {
3492
+ try {
3493
+ unlinkSync(path);
3494
+ } catch {}
3495
+ }
3496
+ const server = createServer((socket) => handleConnection(socket, client));
3497
+ try {
3498
+ server.listen(path);
3499
+ } catch (err) {
3500
+ process.stderr.write(`[claudemesh] bridge: failed to bind ${path}: ${String(err)}
3501
+ `);
3502
+ return null;
3503
+ }
3504
+ server.on("error", (err) => {
3505
+ process.stderr.write(`[claudemesh] bridge: ${String(err)}
3506
+ `);
3507
+ });
3508
+ try {
3509
+ chmodSync2(path, 384);
3510
+ } catch {}
3511
+ let stopped = false;
3512
+ return {
3513
+ path,
3514
+ stop() {
3515
+ if (stopped)
3516
+ return;
3517
+ stopped = true;
3518
+ try {
3519
+ server.close();
3520
+ } catch {}
3521
+ try {
3522
+ unlinkSync(path);
3523
+ } catch {}
3524
+ }
3525
+ };
3526
+ }
3527
+ var init_server = __esm(() => {
3528
+ init_protocol();
3529
+ });
3530
+
3340
3531
  // src/commands/connect.ts
3341
3532
  import { hostname } from "node:os";
3342
3533
  import { createInterface } from "node:readline";
@@ -3558,7 +3749,7 @@ __export(exports_urls, {
3558
3749
  VERSION: () => VERSION,
3559
3750
  URLS: () => URLS
3560
3751
  });
3561
- var URLS, VERSION = "1.1.0", env;
3752
+ var URLS, VERSION = "1.2.0", env;
3562
3753
  var init_urls = __esm(() => {
3563
3754
  URLS = {
3564
3755
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -3799,7 +3990,7 @@ var init_facade6 = __esm(() => {
3799
3990
 
3800
3991
  // src/services/spawn/claude.ts
3801
3992
  import { spawnSync } from "node:child_process";
3802
- import { existsSync as existsSync2 } from "node:fs";
3993
+ import { existsSync as existsSync3 } from "node:fs";
3803
3994
  function findClaudeBinary() {
3804
3995
  const candidates = [
3805
3996
  process.env.CLAUDE_BIN,
@@ -3808,7 +3999,7 @@ function findClaudeBinary() {
3808
3999
  `${process.env.HOME}/.npm/bin/claude`
3809
4000
  ].filter(Boolean);
3810
4001
  for (const bin of candidates) {
3811
- if (existsSync2(bin))
4002
+ if (existsSync3(bin))
3812
4003
  return bin;
3813
4004
  }
3814
4005
  const which = spawnSync("which", ["claude"], { encoding: "utf-8" });
@@ -3869,9 +4060,9 @@ var init_facade7 = __esm(() => {
3869
4060
  });
3870
4061
 
3871
4062
  // src/services/auth/token-store.ts
3872
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync, existsSync as existsSync3, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
4063
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, existsSync as existsSync4, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
3873
4064
  function getStoredToken() {
3874
- if (!existsSync3(PATHS.AUTH_FILE))
4065
+ if (!existsSync4(PATHS.AUTH_FILE))
3875
4066
  return null;
3876
4067
  try {
3877
4068
  const raw = readFileSync2(PATHS.AUTH_FILE, "utf-8");
@@ -3894,7 +4085,7 @@ function storeToken(auth) {
3894
4085
  }
3895
4086
  function clearToken() {
3896
4087
  try {
3897
- unlinkSync(PATHS.AUTH_FILE);
4088
+ unlinkSync2(PATHS.AUTH_FILE);
3898
4089
  } catch {}
3899
4090
  }
3900
4091
  var init_token_store = __esm(() => {
@@ -4131,7 +4322,7 @@ var init_dashboard_sync = __esm(() => {
4131
4322
  });
4132
4323
 
4133
4324
  // src/services/auth/callback-listener.ts
4134
- import { createServer } from "node:http";
4325
+ import { createServer as createServer2 } from "node:http";
4135
4326
  function startCallbackListener() {
4136
4327
  return new Promise((resolveStart) => {
4137
4328
  let resolveToken;
@@ -4139,7 +4330,7 @@ function startCallbackListener() {
4139
4330
  const tokenPromise = new Promise((r) => {
4140
4331
  resolveToken = r;
4141
4332
  });
4142
- const server = createServer((req, res) => {
4333
+ const server = createServer2((req, res) => {
4143
4334
  const url = new URL(req.url, "http://localhost");
4144
4335
  if (req.method === "OPTIONS") {
4145
4336
  res.writeHead(204, {
@@ -4231,9 +4422,9 @@ __export(exports_grants, {
4231
4422
  runBlock: () => runBlock,
4232
4423
  isAllowed: () => isAllowed
4233
4424
  });
4234
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
4235
- import { homedir as homedir2 } from "node:os";
4236
- import { join as join2 } from "node:path";
4425
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
4426
+ import { homedir as homedir3 } from "node:os";
4427
+ import { join as join3 } from "node:path";
4237
4428
  async function syncToBroker(meshSlug, grants) {
4238
4429
  const auth = getStoredToken();
4239
4430
  if (!auth)
@@ -4251,7 +4442,7 @@ async function syncToBroker(meshSlug, grants) {
4251
4442
  }
4252
4443
  }
4253
4444
  function readGrants() {
4254
- if (!existsSync4(GRANT_FILE))
4445
+ if (!existsSync5(GRANT_FILE))
4255
4446
  return {};
4256
4447
  try {
4257
4448
  return JSON.parse(readFileSync3(GRANT_FILE, "utf-8"));
@@ -4260,9 +4451,9 @@ function readGrants() {
4260
4451
  }
4261
4452
  }
4262
4453
  function writeGrants(g) {
4263
- const dir = join2(homedir2(), ".claudemesh");
4264
- if (!existsSync4(dir))
4265
- mkdirSync2(dir, { recursive: true });
4454
+ const dir = join3(homedir3(), ".claudemesh");
4455
+ if (!existsSync5(dir))
4456
+ mkdirSync3(dir, { recursive: true });
4266
4457
  writeFileSync3(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
4267
4458
  }
4268
4459
  function resolveCaps(input) {
@@ -4419,7 +4610,7 @@ var init_grants = __esm(() => {
4419
4610
  BROKER_HTTP2 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
4420
4611
  ALL_CAPS = ["read", "dm", "broadcast", "state-read", "state-write", "file-read"];
4421
4612
  DEFAULT_CAPS = ["read", "dm", "broadcast", "state-read"];
4422
- GRANT_FILE = join2(homedir2(), ".claudemesh", "grants.json");
4613
+ GRANT_FILE = join3(homedir3(), ".claudemesh", "grants.json");
4423
4614
  });
4424
4615
 
4425
4616
  // src/mcp/server.ts
@@ -4987,12 +5178,12 @@ ${peerLines.join(`
4987
5178
  }
4988
5179
  }
4989
5180
  try {
4990
- const { writeFileSync: writeFileSync4, mkdirSync: mkdirSync3, existsSync: existsSync5 } = await import("node:fs");
5181
+ const { writeFileSync: writeFileSync4, mkdirSync: mkdirSync4, existsSync: existsSync6 } = await import("node:fs");
4991
5182
  const { join: joinPath } = await import("node:path");
4992
- const { homedir: homedir3 } = await import("node:os");
4993
- const dir = joinPath(homedir3(), ".claudemesh");
4994
- if (!existsSync5(dir))
4995
- mkdirSync3(dir, { recursive: true });
5183
+ const { homedir: homedir4 } = await import("node:os");
5184
+ const dir = joinPath(homedir4(), ".claudemesh");
5185
+ if (!existsSync6(dir))
5186
+ mkdirSync4(dir, { recursive: true });
4996
5187
  writeFileSync4(joinPath(dir, "peer-cache.json"), JSON.stringify(statusCache));
4997
5188
  } catch {}
4998
5189
  return text(sections.join(`
@@ -5235,17 +5426,17 @@ ${lines.join(`
5235
5426
  const { path: filePath, name: fileName, tags, to: fileTo } = args ?? {};
5236
5427
  if (!filePath)
5237
5428
  return text("share_file: `path` required", true);
5238
- const { existsSync: existsSync5 } = await import("node:fs");
5239
- if (!existsSync5(filePath))
5429
+ const { existsSync: existsSync6 } = await import("node:fs");
5430
+ if (!existsSync6(filePath))
5240
5431
  return text(`share_file: file not found: ${filePath}`, true);
5241
5432
  const client = allClients()[0];
5242
5433
  if (!client)
5243
5434
  return text("share_file: not connected", true);
5244
5435
  if (fileTo) {
5245
5436
  const { encryptFile: encryptFile2, sealKeyForPeer: sealKeyForPeer2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
5246
- const { readFileSync: readFileSync4, writeFileSync: writeFileSync4, mkdtempSync, unlinkSync: unlinkSync2, rmdirSync } = await import("node:fs");
5437
+ const { readFileSync: readFileSync4, writeFileSync: writeFileSync4, mkdtempSync, unlinkSync: unlinkSync3, rmdirSync } = await import("node:fs");
5247
5438
  const { tmpdir } = await import("node:os");
5248
- const { join: join3, basename } = await import("node:path");
5439
+ const { join: join4, basename } = await import("node:path");
5249
5440
  const peers = await client.listPeers();
5250
5441
  const targetPeer = peers.find((p) => p.pubkey === fileTo || p.displayName === fileTo);
5251
5442
  if (!targetPeer) {
@@ -5268,8 +5459,8 @@ ${lines.join(`
5268
5459
  combined.set(ciphertext, nonceBytes.length);
5269
5460
  const rawName = fileName ?? basename(filePath);
5270
5461
  const baseName = basename(rawName).replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 255);
5271
- const tmpDir = mkdtempSync(join3(tmpdir(), "cm-"));
5272
- const tmpPath = join3(tmpDir, baseName);
5462
+ const tmpDir = mkdtempSync(join4(tmpdir(), "cm-"));
5463
+ const tmpPath = join4(tmpDir, baseName);
5273
5464
  writeFileSync4(tmpPath, combined);
5274
5465
  try {
5275
5466
  const fileId = await client.uploadFile(tmpPath, client.meshId, client.meshSlug, {
@@ -5285,7 +5476,7 @@ ${lines.join(`
5285
5476
  return text(`share_file: upload failed — ${e instanceof Error ? e.message : String(e)}`, true);
5286
5477
  } finally {
5287
5478
  try {
5288
- unlinkSync2(tmpPath);
5479
+ unlinkSync3(tmpPath);
5289
5480
  } catch {}
5290
5481
  try {
5291
5482
  rmdirSync(tmpDir);
@@ -5345,9 +5536,9 @@ ${lines.join(`
5345
5536
  const plaintext = await decryptFile2(ciphertext, nonce, kf);
5346
5537
  if (!plaintext)
5347
5538
  return text(genericErr, true);
5348
- const { writeFileSync: writeFileSync5, mkdirSync: mkdirSync4 } = await import("node:fs");
5539
+ const { writeFileSync: writeFileSync5, mkdirSync: mkdirSync5 } = await import("node:fs");
5349
5540
  const { dirname: dirname2 } = await import("node:path");
5350
- mkdirSync4(dirname2(save_to), { recursive: true });
5541
+ mkdirSync5(dirname2(save_to), { recursive: true });
5351
5542
  writeFileSync5(save_to, plaintext);
5352
5543
  return text(`Downloaded and decrypted: ${result.name} → ${save_to}`);
5353
5544
  }
@@ -5358,9 +5549,9 @@ ${lines.join(`
5358
5549
  }
5359
5550
  if (!res.ok)
5360
5551
  return text(`get_file: download failed (${res.status})`, true);
5361
- const { writeFileSync: writeFileSync4, mkdirSync: mkdirSync3 } = await import("node:fs");
5552
+ const { writeFileSync: writeFileSync4, mkdirSync: mkdirSync4 } = await import("node:fs");
5362
5553
  const { dirname } = await import("node:path");
5363
- mkdirSync3(dirname(save_to), { recursive: true });
5554
+ mkdirSync4(dirname(save_to), { recursive: true });
5364
5555
  writeFileSync4(save_to, Buffer.from(await res.arrayBuffer()));
5365
5556
  return text(`Downloaded: ${result.name} → ${save_to}`);
5366
5557
  }
@@ -6119,8 +6310,8 @@ ${lines.join(`
6119
6310
  const entryType = vType ?? "env";
6120
6311
  let plaintextBytes;
6121
6312
  if (entryType === "file") {
6122
- const { existsSync: existsSync5, readFileSync: readFileSync4 } = await import("node:fs");
6123
- if (!existsSync5(value))
6313
+ const { existsSync: existsSync6, readFileSync: readFileSync4 } = await import("node:fs");
6314
+ if (!existsSync6(value))
6124
6315
  return text(`vault_set: file not found: ${value}`, true);
6125
6316
  plaintextBytes = new Uint8Array(readFileSync4(value));
6126
6317
  } else {
@@ -6379,8 +6570,14 @@ ${lines.join(`
6379
6570
  });
6380
6571
  const transport = new StdioServerTransport;
6381
6572
  await server.connect(transport);
6573
+ const bridges = [];
6382
6574
  startClients(config).then(() => {
6383
6575
  wirePushHandlers().catch(() => {});
6576
+ for (const client of allClients()) {
6577
+ const bridge = startBridgeServer(client);
6578
+ if (bridge)
6579
+ bridges.push(bridge);
6580
+ }
6384
6581
  }).catch(() => {
6385
6582
  wirePushHandlers().catch(() => {});
6386
6583
  });
@@ -6553,6 +6750,11 @@ ${lines.join(`
6553
6750
  const keepalive = setInterval(() => {}, 1000);
6554
6751
  const shutdown = () => {
6555
6752
  clearInterval(keepalive);
6753
+ for (const b of bridges) {
6754
+ try {
6755
+ b.stop();
6756
+ } catch {}
6757
+ }
6556
6758
  stopAll();
6557
6759
  process.exit(0);
6558
6760
  };
@@ -6674,10 +6876,11 @@ async function startServiceProxy(serviceName) {
6674
6876
  process.on("SIGINT", shutdown);
6675
6877
  }
6676
6878
  var peerNameCache, peerNameCacheAge = 0, CACHE_TTL_MS = 30000, DEPRECATED_TOOL_HINTS, warnedTools;
6677
- var init_server = __esm(() => {
6879
+ var init_server2 = __esm(() => {
6678
6880
  init_definitions();
6679
6881
  init_facade();
6680
6882
  init_facade3();
6883
+ init_server();
6681
6884
  peerNameCache = new Map;
6682
6885
  DEPRECATED_TOOL_HINTS = {
6683
6886
  send_message: "claudemesh send <to> <msg> [--mesh X] [--priority Y]",
@@ -6710,11 +6913,11 @@ var init_server = __esm(() => {
6710
6913
  });
6711
6914
 
6712
6915
  // src/entrypoints/mcp.ts
6713
- init_server();
6916
+ init_server2();
6714
6917
  startMcpServer().catch((err) => {
6715
6918
  process.stderr.write(`MCP server error: ${err instanceof Error ? err.message : err}
6716
6919
  `);
6717
6920
  process.exit(1);
6718
6921
  });
6719
6922
 
6720
- //# debugId=E023B34F6601185064756E2164756E21
6923
+ //# debugId=7613DACF856C905764756E2164756E21